From 83b341877835ad3aefc8e1b83d6fc4d019ecb4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Wed, 3 Jun 2026 14:25:22 +0200 Subject: [PATCH] =?UTF-8?q?feat(pl=5Feditor):=20Yjs=20collaborative=20brid?= =?UTF-8?q?ge=20=E2=80=94=20differ/apply=20+=20generic=20reconciler=20(yjs?= =?UTF-8?q?-bridge=20commit=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bidirectional bridge between pl_editor's DS_DATA_MODEL and a Yjs doc, two same-origin tabs syncing over BroadcastChannel. Full architecture in features/yjs-bridge/0001-0002. C++ (wasm layer, wasm/bindings/pl_editor_embind.cpp — public DS_DATA_MODEL API only, zero added fork divergence beyond the OnModify hook): - snapshot-differ ChangeSource: diff model vs last-emitted snapshot on OnModify, emit per-item delta JSON via EM_ASM window.kicadCollab.onDelta - kicadCollabApply(json): apply remote delta by uuid — scalars (text/segment/rect) by field, polygon/bitmap via SetPageLayout-append blob; reseed snapshot + HardRedraw - kicadCollabSnapshot() (seed/baseline), s_applyingRemote echo guard, and a kicadCollabTestAddText() PoC local-edit hook - wire format: {added:[item],changed:[item],removed:[uuid]}, item = {id,type,...fields} JS (web/apps/frontend/src/wasm/collab/, generic + schema-agnostic): - reconciler: uuid-keyed Y.Map of per-item Y.Map; down = onDelta→Y, up = observe→apply, origin-tagged echo suppression; seed-once join adopts the doc authoritatively - broadcast-transport: minimal BroadcastChannel Yjs provider (query/state catch-up) - WasmTool wiring behind ?collab=1 (pl_editor only); gated debug logging Tests: tests/kicad/pl_editor-collab.spec.ts — single-page C++ contract (snapshot/apply changed+removed+added/echo-suppression) + two-tab BroadcastChannel A<->B propagation. Reconciler+yjs bundled via esbuild (tests/collab/build.mjs, npm run build:collab). Co-Authored-By: Claude Opus 4.8 (1M context) --- kicad | 2 +- tests/collab/browser-entry.ts | 25 + tests/collab/build.mjs | 21 + tests/kicad/pl_editor-collab.spec.ts | 228 ++++++++ tests/package-lock.json | 539 +++++++++++++++++- tests/package.json | 5 +- wasm/bindings/pl_editor_embind.cpp | 353 ++++++++++++ web/apps/frontend/package.json | 1 + web/apps/frontend/src/components/WasmTool.tsx | 57 ++ .../src/wasm/collab/broadcast-transport.ts | 65 +++ web/apps/frontend/src/wasm/collab/debug.ts | 23 + web/apps/frontend/src/wasm/collab/index.ts | 82 +++ .../frontend/src/wasm/collab/reconciler.ts | 203 +++++++ web/apps/frontend/src/wasm/collab/types.ts | 36 ++ web/pnpm-lock.yaml | 25 + 15 files changed, 1662 insertions(+), 3 deletions(-) create mode 100644 tests/collab/browser-entry.ts create mode 100644 tests/collab/build.mjs create mode 100644 tests/kicad/pl_editor-collab.spec.ts create mode 100644 web/apps/frontend/src/wasm/collab/broadcast-transport.ts create mode 100644 web/apps/frontend/src/wasm/collab/debug.ts create mode 100644 web/apps/frontend/src/wasm/collab/index.ts create mode 100644 web/apps/frontend/src/wasm/collab/reconciler.ts create mode 100644 web/apps/frontend/src/wasm/collab/types.ts diff --git a/kicad b/kicad index 9053a26..9cde940 160000 --- a/kicad +++ b/kicad @@ -1 +1 @@ -Subproject commit 9053a260c7f497f3df05c36090c2f5f768bae453 +Subproject commit 9cde940836ae05b4f6e79c014a4f7a4b75d41045 diff --git a/tests/collab/browser-entry.ts b/tests/collab/browser-entry.ts new file mode 100644 index 0000000..311e3cd --- /dev/null +++ b/tests/collab/browser-entry.ts @@ -0,0 +1,25 @@ +// Browser bundle entry for the collab e2e: bundles the generic reconciler + Yjs + +// BroadcastChannel transport (from the web frontend) into a single IIFE that the +// pl_editor static harness page can load via