docs/plans/2026-03-22-yjs-testing-plan.md
Add high-value non-React coverage for @platejs/yjs without doing dumb wrapper vanity tests.
This package currently has:
10/react worktypes.tswithTYjs, withTCursors, or withTYHistory unless they still lack honest coverage after withPlateYjs and BaseYjsPluginBaseYjsPlugin init, connect, disconnect, and destroywithPlateYjs composition order and branch behaviorproviderConfigs, customProviders, and waitForAllProviders, while the runtime source exposes providers and does not implement that README shape here. Tests should follow source, not docs fanfic.window.crypto.subtle directly. In Bun this may be fine, but if it is not, that is a real compatibility seam worth testing and fixing.BaseYjsPlugin editor API and init orchestrationwithPlateYjs composition order and conditional cursor wiringcreateSlateEditor for plugin tests.Best first slice. Cheap, deterministic, high signal.
guid + same nodes produce bit-identical updatesguid or nodes produce different updatescontent statecreateProvider returns the registered classregisterProviderType overrides or extends the registry intentionallywindow.crypto.subtle needs a shim in Bun, isolate that in the spec helper and treat missing support as a real compatibility findingSecond slice. Still cheap. Still real value.
doc and awareness through when providedwsOptions is presentonErroronConnect flips isConnectedonSynced flips isSynced and only emits sync change on the first transitiononDisconnect clears connect and sync state and emits sync false onceonErrordisconnect and destroy are safe no-ops when already disconnecteddoc or creates onestatus: { connected: true } emits connect once and marks synced truestatus: { connected: false } emits disconnect and sync false only when previously connecteddisconnect clears both flags and emits sync false if neededonError and leaves the wrapper non-throwingconnect, disconnect, and destroy swallow provider-side throws without crashing@hocuspocus/provider and y-webrtcwithPlateYjs CompositionThird slice. Worth it because this file contains real branching and composition, unlike the one-line wrappers under it.
sharedType from options when providedydoc.get('content', Y.XmlText) when no custom shared type existswithTYjs first with autoConnect: falsewithTCursors only when cursors is enabled and awareness existscursors.autoSend === falseawareness is missingwithTYHistory lastBaseYjsPlugin Editor APIFourth slice. This is the core of the package.
ydoc and awareness when omittedconnect() connects all providersconnect('webrtc') and connect(['webrtc', 'hocuspocus']) filter correctlyconnect() errors go to onErrordisconnect() disconnects connected providers in reverse orderdestroy() only destroys connected providers and still calls YjsEditor.disconnectdestroy() swallows disconnect errors instead of exploding cleanupBaseYjsPlugin Init OrchestrationFifth slice. Highest value, highest harness cost.
providers is empty_providersautoConnect: false skips provider connectionautoConnect: true connects all providersvalue is an array, seeds initial contentvalue is a string, uses editor.api.html.deserializevalue is an async function, awaits iteditor.api.create.value()sharedType path uses delta insertionY.applyUpdateYjsEditor only after the provider sync windoweditor.tf.init with shouldNormalizeEditor: falseeditor.api.onChange()onReady with the async flag and final childrencreateSlateEditor with the plugin configuredcreateProvider, YjsEditor.connect, Y.applyUpdate, and editor APIsExpected new runtime specs:
Optional helper-only files under __tests__/ are fine if repeated doubles become noisy, but keep them package-local and tiny.
react plugin coverageTargeted first:
bun test packages/yjs/src/utils/slateToDeterministicYjsState.spec.ts packages/yjs/src/lib/providers/registry.spec.ts packages/yjs/src/lib/providers/hocuspocus-provider.spec.ts packages/yjs/src/lib/providers/webrtc-provider.spec.ts packages/yjs/src/lib/withPlateYjs.spec.ts packages/yjs/src/lib/BaseYjsPlugin.api.spec.ts packages/yjs/src/lib/BaseYjsPlugin.init.spec.tsbun test packages/yjs/srcbun run test:slowest -- --top 15 packages/yjs/srcPackage verification:
pnpm installpnpm turbo build --filter=./packages/yjspnpm turbo typecheck --filter=./packages/yjspnpm lint:fixFallback if workspace-built exports bite:
pnpm buildpnpm turbo typecheck --filter=./packages/yjsDo Slice 1 and Slice 2 first.
Reason:
BaseYjsPlugin tests