Commit Graph

3 Commits

Author SHA1 Message Date
xarmian f0c65fe08c chore(web): adopt Tiptap 3.31.4 and regenerate the materializer corpus (TASK-3421) (#1811)
* chore(web): adopt Tiptap 3.31.4 and regenerate the materializer corpus (TASK-3421)

3.31.4's TableCell/TableHeader renderHTML stop rendering a default
colspan="1" / rowspan="1". parseHTML is unchanged, so a stored body
carrying them parses to the same document. Replaying all 50 old corpus
op-logs through the 3.31.4 bundle reproduces the old output exactly once
those attributes are removed (and fails on 28 cases without removing them).

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS

* test(web): pin that a pre-3.31.4 table body still dedupes on open (TASK-3421)

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS
2026-10-05 15:52:54 -04:00
xarmian 1e16d2228b fix(web): link text with markdown/HTML-significant characters survives a save (BUG-3315 U1) (#1686)
A wiki link's display text was mangled on its way through the editor, and
the first save of any item linking such a title pinned the mangled text as
a display override, with no rename involved (a census found 76 stored
overrides of this shape among 107 that differ from their target's title).

Load: escapeMarkdownLinkText escaped only brackets and backslashes, so the
html-enabled parser read the title as markdown. `*real*` became emphasis,
`<topic>` was dropped as a tag, `&gt;` was decoded. It now backslash-escapes
\ [ ] * _ ~ ` < > &, all ASCII punctuation CommonMark lets a backslash
escape.

Save: unescapeMarkdownLinkText undid only bracket and backslash escapes,
while the serializer also backslash-escapes other punctuation and writes
< > & as entities. It now undoes both, in one pass.

One residue is intrinsic and pinned by a test: the serializer writes a
literal `&gt;` and a literal `>` as the same bytes, so a title containing
entity-shaped text still becomes an override (0 of 9,620 live titles do).

The materializer corpus: two expectations change (a backtick and `<b>` in
link text, both this fix), taken from the goja bundle's output. A full
regeneration was not used because the generator is nondeterministic: with
unchanged code it rewrites all 50 cases' rows and 1 expected value.

Claude-Session: https://claude.ai/code/session_01H63zaWhkb5pAafx2WGjrVC
2026-09-30 07:19:04 -04:00
xarmian fa2755e183 feat(materialize): headless op-log materializer bundle, goja runner and worker (TASK-2198 U2) (#1678)
* feat(materialize): headless op-log materializer bundle, goja runner and worker (TASK-2198 U2)

Builds the editor's own JS (Yjs -> y-tiptap -> Tiptap schema -> tiptap-markdown
-> the tab's flush pipeline) into one IIFE, embeds it, and runs it in goja. Not
wired into the server yet (U3 supervisor, U4 write path).

- web/src/lib/collab/materializer/: bundle entry (extension list mirrors
  Editor.svelte's collab branch via the U1 shared modules), op-log replay
  mirroring wsProvider's MESSAGE_SYNC arm, linkedom DOM shim and polyfills
  from the spike, and a vendored patch of prosemirror-markdown
  MarkdownSerializerState.atBlank (quadratic under goja; equivalent).
- web/scripts/build-materializer.mjs (esbuild) -> web/build-materializer/,
  run by `npm run build`; embedded as pad.MaterializerJS.
- internal/materialize: Runner (Go-native atob/btoa/TextEncoder/TextDecoder/
  getRandomValues, schema-version check, ctx interrupt with a clean VM after),
  and RunWorker's length-prefixed JSON protocol behind the hidden
  `pad __materialize-worker` command.
- Parity: vitest drives two real Editor.svelte mounts and compares
  materialize() with the tab's flush on 50 seeded cases; the same cases are
  committed as testdata/corpus.json and replayed in goja (TestCorpusParity).
- CI Go jobs, release tests, Docker and Nix produce the bundle; linkedom and
  esbuild are new devDependencies.

Claude-Session: https://claude.ai/code/session_01H63zaWhkb5pAafx2WGjrVC

* test(materialize): pin the atBlank patch's equivalence under V8 too (TASK-2198 U2, codex r1)

Codex r1 claimed upstream's /(^|\n)$/ is true for a trailing CR in JS. It is
not (checked in V8: false for "\r" and "a\u2028", as the patch returns),
but the only equivalence test ran under goja and the patch header cited a
V8-side test that did not exist. This adds it, with the line-terminator edge
cases, and it fails when the patch checks CR instead of LF.

Claude-Session: https://claude.ai/code/session_01H63zaWhkb5pAafx2WGjrVC

* build(nix): vendorHash for goja (TASK-2198 U2)

Taken from the Nix job's recompute on c7fa1931 (specified sha256-iEqv…,
got sha256-P1bQ…), so main does not depend on the heal job after merge.

Claude-Session: https://claude.ai/code/session_01H63zaWhkb5pAafx2WGjrVC
2026-09-30 02:50:10 -04:00