# @continuity-editor/editor Accessible `` Web Component and synchronous, storage-neutral Continuity editor engine compiled to WebAssembly. The package contains the component, TypeScript declarations, styles, source map, optimized WASM, license, and per-file integrity metadata. ## Browser use Importing the package defines the component. Initialize the shared WASM module, set the initial value as a property, and wait for `ready` before reading state: ```js import { initialize } from "@continuity-editor/editor"; await initialize(); const editor = document.querySelector("continuity-editor"); editor.value = "# Hello\n"; editor.initialRevision = savedRevision; await editor.ready; editor.addEventListener("continuity-change", async ({ detail }) => { if (detail.commitOrigin === "user") { await saveInYourHost(detail.sequence, detail.snapshot); } }); ``` ```html ``` ## Deploying For Vite and compatible bundlers, import the exported WASM asset as a URL and pass it explicitly. This is the canonical browser deployment path: ```js import { initialize } from "@continuity-editor/editor"; import wasmUrl from "@continuity-editor/editor/wasm?url"; await initialize({ wasm: wasmUrl }); ``` Serve `.wasm` as `Content-Type: application/wasm`; this is required by `WebAssembly.instantiateStreaming`, and is mandatory when `X-Content-Type-Options: nosniff` is enabled. Python's Windows MIME table may not contain the mapping, so an aiohttp host can register it during startup: ```py import mimetypes mimetypes.add_type("application/wasm", ".wasm") ``` A strict Chromium Content Security Policy must allow WASM compilation. Add `'wasm-unsafe-eval'` to `script-src` (or the effective `default-src`), for example `script-src 'self' 'wasm-unsafe-eval'`. This does not enable general JavaScript `eval`, and a same-origin bundled asset needs no additional `connect-src` permission. See the [CSP specification](https://www.w3.org/TR/CSP3/#directive-script-src), [MDN streaming compilation requirements](https://developer.mozilla.org/docs/WebAssembly/Reference/JavaScript_interface/instantiateStreaming_static), and [Vite static asset imports](https://vite.dev/guide/assets.html). ## Framework-neutral controlled use Vue, Svelte, Preact, and vanilla hosts can reuse the same controlled snapshot semantics through `@continuity-editor/editor/controller`. Attach before the element becomes ready, synchronize only complete engine snapshots, and dispose the controller when the host view releases the element: ```js import { attachContinuityEditor } from "@continuity-editor/editor/controller"; const element = document.createElement("continuity-editor"); const controller = attachContinuityEditor(element, { value: savedText, revision: savedEngineRevision, callbacks: { onChange: ({ snapshot }) => persistInHost(snapshot), }, }); mount.append(element); await controller.synchronize(reloadedText, reloadedEngineRevision); controller.dispose(); ``` `synchronize()` uses revision-checked `replaceValue` and rejects with `RevisionConflictError` rather than overwriting newer typing. `dispose()` only detaches controller listeners; the host still owns the element. The React adapter declaration is self-contained, so Preact consumers using `preact/compat` do not need `@types/react` solely to import it. Every change has `commitOrigin: "user" | "host"`. Persist only `"user"`; `"host"` acknowledges a host replacement and must not loop back into storage. `onHostReplacement` is the dedicated controller/React callback. The controller also forwards selection, reveal, scroll-state, and linear-memory APIs. Svelte hosts can use `/svelte`; Vue 3 hosts can use `/vue` (Vue is an optional peer). `/lazy` dynamically loads route-local editors. `/conformance` exports a disposable browser wiring harness, and `/commit-queue` provides an optional single-in-flight, newest-wins debounced save queue with a maximum-delay cap. ## Pipe tables GFM pipe tables render as bordered column grids in both the editor and ``. Columns size to their widest cell (floored at 3em, capped at 16em so long cells wrap) and shrink proportionally to fit the pane. Delimiter alignments (`:--`, `:-:`, `--:`) apply to the body cells, links and inline styles render inside cells, and the row under the caret shows its raw `| a | b |` source for editing while the rest of the table stays laid out. Cell borders follow `--continuity-border`; header cells are bold on a faint foreground tint. ## Plain text and static rendering Set `syntax="plain"` to retain the rope, selection, undo, multi-cursor, and host contracts while disabling Markdown projection. `` provides selectable, read-only Markdown or plain projection without an input textarea. ## React use The optional `@continuity-editor/editor/react` subpath supplies a controlled React adapter without adding React to non-React consumers. Initialize WASM once before mounting the application, then keep the complete Continuity snapshot in React state: ```tsx import { useState } from "react"; import { initialize } from "@continuity-editor/editor"; import { ContinuityEditor } from "@continuity-editor/editor/react"; await initialize(); export function NoteEditor({ initialText, persist }) { const [snapshot, setSnapshot] = useState({ text: initialText, revision: 0 }); return ( { setSnapshot(detail.snapshot); persist(detail.snapshot.text); }} /> ); } ``` `revision` is the Continuity engine revision corresponding exactly to `value`. It is not a database ETag, file mtime, or host optimistic-concurrency token. Hosts keep those persistence revisions separately. Unchanged React props never echo a replacement after local typing; a changed host snapshot is applied with `replaceValue(value, revision)`, and stale replacement attempts call `onRevisionConflict` instead of overwriting newer editor state. Use a stable resource key and remount with revision zero when switching to a different note unless the host persisted the previous Continuity revision. The component uses a semantic `