@quillmark/wasm 0.92.0 → 0.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,64 @@ export class Document {
19
19
  const ptr = this.__destroy_into_raw();
20
20
  wasm.__wbg_document_free(ptr, 0);
21
21
  }
22
+ /**
23
+ * Build a composable card of `kind`, typed-commit `fields` onto it, set its
24
+ * body from optional markdown, and append it — the ABI under
25
+ * `writer.addCard`. Fuses `makeCard` + typed commit + `pushCard`
26
+ * transactionally: the card is committed in full before it joins the
27
+ * document, so a rejected field (or an invalid kind or body) leaves the
28
+ * document untouched. Field errors throw the same per-field diagnostic
29
+ * bundle as [`commitFields`](Self::commit_fields), including an
30
+ * `[EditError::UnknownField]` per undeclared name; an invalid kind or body
31
+ * throws a single-entry bundle keyed `$kind` / `$body`.
32
+ * @param {Quill} quill
33
+ * @param {string} kind
34
+ * @param {Record<string, unknown>} [fields]
35
+ * @param {string} [body]
36
+ */
37
+ addCard(quill, kind, fields, body) {
38
+ try {
39
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
40
+ _assertClass(quill, Quill);
41
+ const ptr0 = passStringToWasm0(kind, wasm.__wbindgen_export, wasm.__wbindgen_export2);
42
+ const len0 = WASM_VECTOR_LEN;
43
+ var ptr1 = isLikeNone(body) ? 0 : passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
44
+ var len1 = WASM_VECTOR_LEN;
45
+ wasm.document_addCard(retptr, this.__wbg_ptr, quill.__wbg_ptr, ptr0, len0, isLikeNone(fields) ? 0 : addHeapObject(fields), ptr1, len1);
46
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
47
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
48
+ if (r1) {
49
+ throw takeObject(r0);
50
+ }
51
+ } finally {
52
+ wasm.__wbindgen_add_to_stack_pointer(16);
53
+ }
54
+ }
55
+ /**
56
+ * **Apply** a committed corpus edit `bundle` (`{ delta?, lineOps?, markOps? }`)
57
+ * at `addr` — the editor splice: text delta first, then line ops, then mark
58
+ * ops (mark ranges in post-delta coordinates), each all-or-nothing. An absent
59
+ * `addr.field` targets the body, an absent `addr.card` the main card.
60
+ *
61
+ * Throws on an out-of-range card, a field that is not richtext, a malformed
62
+ * bundle, or an op that applies out of bounds (the value is unchanged on a
63
+ * failed apply).
64
+ * @param {Addr} addr
65
+ * @param {ChangeBundle} bundle
66
+ */
67
+ applyChange(addr, bundle) {
68
+ try {
69
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
70
+ wasm.document_applyChange(retptr, this.__wbg_ptr, addHeapObject(addr), addHeapObject(bundle));
71
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
72
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
73
+ if (r1) {
74
+ throw takeObject(r0);
75
+ }
76
+ } finally {
77
+ wasm.__wbindgen_add_to_stack_pointer(16);
78
+ }
79
+ }
22
80
  /**
23
81
  * Authoring-ergonomics header introducing a blueprint to an LLM/MCP
24
82
  * consumer for the given `quillName`. Re-exposes core's canonical text for
@@ -78,6 +136,128 @@ export class Document {
78
136
  const ret = wasm.document_clone(this.__wbg_ptr);
79
137
  return Document.__wrap(ret);
80
138
  }
139
+ /**
140
+ * Typed field write on the composable card at `index` — the card-indexed
141
+ * twin of [`commitField`](Document::commit_field). Resolves the field's
142
+ * type from the card's `$kind` schema in `quill` and strict-commits it.
143
+ *
144
+ * Throws `[EditError::IndexOutOfRange]` when `index` is out of range, and
145
+ * the same typed-mismatch / name errors as `commitField` — including
146
+ * `[EditError::UnknownField]` for a field the card-kind schema does not
147
+ * declare (an unknown `$kind` has no schema, so every field is undeclared).
148
+ * @param {Quill} quill
149
+ * @param {number} index
150
+ * @param {string} name
151
+ * @param {any} value
152
+ */
153
+ commitCardField(quill, index, name, value) {
154
+ try {
155
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
156
+ _assertClass(quill, Quill);
157
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
158
+ const len0 = WASM_VECTOR_LEN;
159
+ wasm.document_commitCardField(retptr, this.__wbg_ptr, quill.__wbg_ptr, index, ptr0, len0, addHeapObject(value));
160
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
161
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
162
+ if (r1) {
163
+ throw takeObject(r0);
164
+ }
165
+ } finally {
166
+ wasm.__wbindgen_add_to_stack_pointer(16);
167
+ }
168
+ }
169
+ /**
170
+ * Batched twin of [`commitCardField`](Document::commit_card_field):
171
+ * typed-commit several fields on the card at `index` atomically, resolving
172
+ * each field's type from the card's `$kind` schema in `quill`. All-or-nothing
173
+ * with the same per-field-diagnostic contract as
174
+ * [`commitFields`](Document::commit_fields), including an
175
+ * `[EditError::UnknownField]` diagnostic per undeclared name. Throws
176
+ * `[EditError::IndexOutOfRange]` when `index` is out of range.
177
+ * @param {Quill} quill
178
+ * @param {number} index
179
+ * @param {Record<string, unknown>} fields
180
+ */
181
+ commitCardFields(quill, index, fields) {
182
+ try {
183
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
184
+ _assertClass(quill, Quill);
185
+ wasm.document_commitCardFields(retptr, this.__wbg_ptr, quill.__wbg_ptr, index, addHeapObject(fields));
186
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
187
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
188
+ if (r1) {
189
+ throw takeObject(r0);
190
+ }
191
+ } finally {
192
+ wasm.__wbindgen_add_to_stack_pointer(16);
193
+ }
194
+ }
195
+ /**
196
+ * Typed field write on the main card, resolving the field's schema `type`
197
+ * from `quill` — the one write verb for **every** field type (richtext,
198
+ * scalar, array, object). The schema carries the `inline` constraint, so no
199
+ * type token or flag is passed. A richtext-typed field stores the canonical
200
+ * corpus, so identity marks (anchors, island ids) and corpus-only marks
201
+ * (e.g. `underline`) live on it and survive compiles and the storage DTO.
202
+ * Values use the encoding the seam already speaks: a corpus object
203
+ * or markdown string for richtext, a scalar/array/object otherwise.
204
+ *
205
+ * A field declared in the schema is strict-committed — a mismatch throws
206
+ * now, not at render. A name the schema does not declare throws
207
+ * `[EditError::UnknownField]` rather than falling to the opaque store: on
208
+ * the typed path it is a typo. Use [`setField`](Document::set_field) when
209
+ * opaque storage is the intent. Also throws `[EditError::FieldConform]` /
210
+ * `[EditError::FieldRichtextDecode]` / `[EditError::FieldRichtextNotInline]`
211
+ * on a typed mismatch and `[EditError::InvalidFieldName]` on a malformed
212
+ * name.
213
+ *
214
+ * The `quill` handle is passed per call because a `Document` carries only a
215
+ * `$quill` reference, not the resolved schema.
216
+ * @param {Quill} quill
217
+ * @param {string} name
218
+ * @param {any} value
219
+ */
220
+ commitField(quill, name, value) {
221
+ try {
222
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
223
+ _assertClass(quill, Quill);
224
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
225
+ const len0 = WASM_VECTOR_LEN;
226
+ wasm.document_commitField(retptr, this.__wbg_ptr, quill.__wbg_ptr, ptr0, len0, addHeapObject(value));
227
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
228
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
229
+ if (r1) {
230
+ throw takeObject(r0);
231
+ }
232
+ } finally {
233
+ wasm.__wbindgen_add_to_stack_pointer(16);
234
+ }
235
+ }
236
+ /**
237
+ * Batched twin of [`commitField`](Document::commit_field): typed-commit
238
+ * several main-card fields atomically, resolving each field's schema `type`
239
+ * from `quill`. All-or-nothing with the same per-field-diagnostic error
240
+ * contract as [`setFields`](Document::set_fields) — nothing is applied on
241
+ * error and the thrown error's `diagnostics` carry one entry per offending
242
+ * field, including an `[EditError::UnknownField]` for any name the schema
243
+ * does not declare, so a whole-form submit sees every typo in one pass.
244
+ * @param {Quill} quill
245
+ * @param {Record<string, unknown>} fields
246
+ */
247
+ commitFields(quill, fields) {
248
+ try {
249
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
250
+ _assertClass(quill, Quill);
251
+ wasm.document_commitFields(retptr, this.__wbg_ptr, quill.__wbg_ptr, addHeapObject(fields));
252
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
253
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
254
+ if (r1) {
255
+ throw takeObject(r0);
256
+ }
257
+ } finally {
258
+ wasm.__wbindgen_add_to_stack_pointer(16);
259
+ }
260
+ }
81
261
  /**
82
262
  * Schema version this build writes via [`toJson`](Document::to_json).
83
263
  * Tracks the `Document` model version (not the running crate version):
@@ -207,11 +387,65 @@ export class Document {
207
387
  wasm.__wbindgen_add_to_stack_pointer(16);
208
388
  }
209
389
  }
390
+ /**
391
+ * Read a main-card field's stored value — the raw payload value (a corpus
392
+ * object for a richtext field, a scalar/array/object otherwise), or
393
+ * `undefined` when the field is absent. The quill-free read: reads need no
394
+ * schema, so they live on `Document`, not the typed writer. For the markdown
395
+ * projection of a richtext value use [`getMarkdown`](Self::get_markdown).
396
+ * @param {string} name
397
+ * @returns {any}
398
+ */
399
+ get(name) {
400
+ try {
401
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
402
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
403
+ const len0 = WASM_VECTOR_LEN;
404
+ wasm.document_get(retptr, this.__wbg_ptr, ptr0, len0);
405
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
406
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
407
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
408
+ if (r2) {
409
+ throw takeObject(r1);
410
+ }
411
+ return takeObject(r0);
412
+ } finally {
413
+ wasm.__wbindgen_add_to_stack_pointer(16);
414
+ }
415
+ }
416
+ /**
417
+ * The markdown projection of a main-card field (`name` given) or the main
418
+ * body (`name` omitted) — the on-demand, lossy export (corpus-only marks do
419
+ * not survive markdown), returning `""` for an absent field. Re-coins,
420
+ * lazily and by name, the projection the eager `fieldMarkdown` /
421
+ * `bodyMarkdown` getters dropped in #925; call it only when markdown is what
422
+ * you need out.
423
+ * @param {string} [name]
424
+ * @returns {string}
425
+ */
426
+ getMarkdown(name) {
427
+ let deferred2_0;
428
+ let deferred2_1;
429
+ try {
430
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
431
+ var ptr0 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
432
+ var len0 = WASM_VECTOR_LEN;
433
+ wasm.document_getMarkdown(retptr, this.__wbg_ptr, ptr0, len0);
434
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
435
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
436
+ deferred2_0 = r0;
437
+ deferred2_1 = r1;
438
+ return getStringFromWasm0(r0, r1);
439
+ } finally {
440
+ wasm.__wbindgen_add_to_stack_pointer(16);
441
+ wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
442
+ }
443
+ }
210
444
  /**
211
445
  * Insert a card at `index` (must be in `0..=cards.length`). Accepts a
212
- * `Card` (see [`pushCard`](Self::push_card)).
446
+ * `CardInput` (see [`pushCard`](Self::push_card)).
213
447
  * @param {number} index
214
- * @param {Card} card
448
+ * @param {CardInput} card
215
449
  */
216
450
  insertCard(index, card) {
217
451
  try {
@@ -226,6 +460,60 @@ export class Document {
226
460
  wasm.__wbindgen_add_to_stack_pointer(16);
227
461
  }
228
462
  }
463
+ /**
464
+ * **Install** a richtext value at `addr` — **value semantics**, corpus only.
465
+ * Stores exactly `rt` (a canonical `RichText` corpus object); the identity
466
+ * anchors of any previous value are gone. An absent `addr.field` targets the
467
+ * body, an absent `addr.card` the main card. For "here's new markdown," use
468
+ * [`revise`](Document::revise); the cold-import path is spelled at the call
469
+ * site as `install(addr, importMarkdown(md))`, so anchor loss is visible in
470
+ * source.
471
+ *
472
+ * Throws on an out-of-range card, a malformed field name, or an `rt` that is
473
+ * not a canonical corpus object.
474
+ * @param {Addr} addr
475
+ * @param {RichText} rt
476
+ */
477
+ install(addr, rt) {
478
+ try {
479
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
480
+ wasm.document_install(retptr, this.__wbg_ptr, addHeapObject(addr), addHeapObject(rt));
481
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
482
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
483
+ if (r1) {
484
+ throw takeObject(r0);
485
+ }
486
+ } finally {
487
+ wasm.__wbindgen_add_to_stack_pointer(16);
488
+ }
489
+ }
490
+ /**
491
+ * Replace this document's contents **in place** from a versioned storage
492
+ * DTO string — the mutating twin of the static
493
+ * [`fromJson`](Document::from_json) constructor. Parse-time `warnings` are
494
+ * cleared. Throws (leaving the document unchanged) on an invalid DTO.
495
+ *
496
+ * The cross-WASM-memory `Document` bridge: mutate a document on a
497
+ * backend-memory clone, then write the mutated state back into the caller's
498
+ * canonical document with this — the one way to update a live handle across
499
+ * the linear-memory seam without the caller re-binding its variable.
500
+ * @param {string} json
501
+ */
502
+ loadJson(json) {
503
+ try {
504
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
505
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
506
+ const len0 = WASM_VECTOR_LEN;
507
+ wasm.document_loadJson(retptr, this.__wbg_ptr, ptr0, len0);
508
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
509
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
510
+ if (r1) {
511
+ throw takeObject(r0);
512
+ }
513
+ } finally {
514
+ wasm.__wbindgen_add_to_stack_pointer(16);
515
+ }
516
+ }
229
517
  /**
230
518
  * The document's main (entry) card. Allocates and serializes on each
231
519
  * call — cache locally if read in a hot loop.
@@ -295,11 +583,40 @@ export class Document {
295
583
  }
296
584
  }
297
585
  /**
298
- * Append a card to the end of the card list. Accepts a `Card` (the shape
299
- * returned by `cards` / `removeCard` / `quill.seedCard`); build a fresh
300
- * one with [`Document.makeCard`](Document::make_card). Throws if
301
- * `card.kind` is not a valid kind name.
302
- * @param {Card} card
586
+ * `new Document(quillRef)` a blank document: a main card carrying only
587
+ * `$quill`, an empty body, and no composable cards. The programmatic
588
+ * blank canvas: absent fields resolve at render time (`default`, else
589
+ * type-empty zero), so nothing the caller did not set reaches the
590
+ * output. For an example-filled starter use `Quill.seedDocument()`.
591
+ * Throws on an invalid quill reference. Mirrors Python `Document(quill_ref)`.
592
+ * @param {string} quill_ref
593
+ */
594
+ constructor(quill_ref) {
595
+ try {
596
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
597
+ const ptr0 = passStringToWasm0(quill_ref, wasm.__wbindgen_export, wasm.__wbindgen_export2);
598
+ const len0 = WASM_VECTOR_LEN;
599
+ wasm.document_new(retptr, ptr0, len0);
600
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
601
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
602
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
603
+ if (r2) {
604
+ throw takeObject(r1);
605
+ }
606
+ this.__wbg_ptr = r0 >>> 0;
607
+ DocumentFinalization.register(this, this.__wbg_ptr, this);
608
+ return this;
609
+ } finally {
610
+ wasm.__wbindgen_add_to_stack_pointer(16);
611
+ }
612
+ }
613
+ /**
614
+ * Append a card to the end of the card list. Accepts a `CardInput` — a card
615
+ * read back (`cards` / `removeCard` / `quill.seedCard`), a
616
+ * [`makeCard`](Document::make_card) result, or a bare `{ kind, body }`
617
+ * (every returned `Card` is a valid `CardInput`). Throws if `card.kind` is
618
+ * not a valid kind name.
619
+ * @param {CardInput} card
303
620
  */
304
621
  pushCard(card) {
305
622
  try {
@@ -496,7 +813,7 @@ export class Document {
496
813
  }
497
814
  /**
498
815
  * Remove a payload field on the main card, returning the removed value or
499
- * `undefined`. Throws if `name` does not match `[a-z_][a-z0-9_]*`.
816
+ * `undefined`. Throws if `name` does not match `[A-Za-z_][A-Za-z0-9_]*`.
500
817
  * @param {string} name
501
818
  * @returns {any}
502
819
  */
@@ -542,12 +859,57 @@ export class Document {
542
859
  }
543
860
  }
544
861
  /**
862
+ * **Deprecated** — alias for `revise({}, markdown)`, kept one release cycle.
863
+ * Revise the main card's body from a markdown string (edit semantics: a
864
+ * `diff_import` that rebases surviving anchors). Discards the text delta;
865
+ * call [`revise`](Document::revise) to receive it.
545
866
  * @param {string} body
546
867
  */
547
868
  replaceBody(body) {
548
- const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
549
- const len0 = WASM_VECTOR_LEN;
550
- wasm.document_replaceBody(this.__wbg_ptr, ptr0, len0);
869
+ try {
870
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
871
+ const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
872
+ const len0 = WASM_VECTOR_LEN;
873
+ wasm.document_replaceBody(retptr, this.__wbg_ptr, ptr0, len0);
874
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
875
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
876
+ if (r1) {
877
+ throw takeObject(r0);
878
+ }
879
+ } finally {
880
+ wasm.__wbindgen_add_to_stack_pointer(16);
881
+ }
882
+ }
883
+ /**
884
+ * **Revise** the richtext value at `addr` from a markdown string — **edit
885
+ * semantics**, the default write path, returning the text [`Delta`]. Imports
886
+ * the markdown, diffs it against the current value, rebases surviving
887
+ * identity anchors, and returns the change an editor bridge maps its own
888
+ * positions through (`mapPos`). An absent `addr.field` targets the body, an
889
+ * absent `addr.card` the main card; an absent field cold-imports from empty.
890
+ *
891
+ * Throws on an out-of-range card, a malformed field name, a present
892
+ * non-corpus field value, or an over-nested markdown input.
893
+ * @param {Addr} addr
894
+ * @param {string} markdown
895
+ * @returns {Delta}
896
+ */
897
+ revise(addr, markdown) {
898
+ try {
899
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
900
+ const ptr0 = passStringToWasm0(markdown, wasm.__wbindgen_export, wasm.__wbindgen_export2);
901
+ const len0 = WASM_VECTOR_LEN;
902
+ wasm.document_revise(retptr, this.__wbg_ptr, addHeapObject(addr), ptr0, len0);
903
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
904
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
905
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
906
+ if (r2) {
907
+ throw takeObject(r1);
908
+ }
909
+ return takeObject(r0);
910
+ } finally {
911
+ wasm.__wbindgen_add_to_stack_pointer(16);
912
+ }
551
913
  }
552
914
  /**
553
915
  * Read the `schema` version tag from a raw storage DTO string without a
@@ -618,6 +980,50 @@ export class Document {
618
980
  wasm.__wbindgen_add_to_stack_pointer(16);
619
981
  }
620
982
  }
983
+ /**
984
+ * Set a field on the card at `index` — the card-indexed twin of
985
+ * [`setField`](Document::set_field). Stores the value opaquely.
986
+ * Throws if `index` is out of range, `name` is reserved or invalid.
987
+ * @param {number} index
988
+ * @param {string} name
989
+ * @param {any} value
990
+ */
991
+ setCardField(index, name, value) {
992
+ try {
993
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
994
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
995
+ const len0 = WASM_VECTOR_LEN;
996
+ wasm.document_setCardField(retptr, this.__wbg_ptr, index, ptr0, len0, addHeapObject(value));
997
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
998
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
999
+ if (r1) {
1000
+ throw takeObject(r0);
1001
+ }
1002
+ } finally {
1003
+ wasm.__wbindgen_add_to_stack_pointer(16);
1004
+ }
1005
+ }
1006
+ /**
1007
+ * Batched twin of [`setCardField`](Document::set_card_field): set
1008
+ * several fields on the card at `index` atomically. Same all-or-nothing,
1009
+ * one-diagnostic-per-field contract as [`setFields`](Document::set_fields).
1010
+ * Throws if `index` is out of range.
1011
+ * @param {number} index
1012
+ * @param {Record<string, unknown>} fields
1013
+ */
1014
+ setCardFields(index, fields) {
1015
+ try {
1016
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1017
+ wasm.document_setCardFields(retptr, this.__wbg_ptr, index, addHeapObject(fields));
1018
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1019
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1020
+ if (r1) {
1021
+ throw takeObject(r0);
1022
+ }
1023
+ } finally {
1024
+ wasm.__wbindgen_add_to_stack_pointer(16);
1025
+ }
1026
+ }
621
1027
  /**
622
1028
  * Replace the kind of the card at `index`. Payload and body are untouched;
623
1029
  * schema-aware migration is the caller's responsibility.
@@ -663,7 +1069,7 @@ export class Document {
663
1069
  /**
664
1070
  * Merge `value` into the main card's `$ext` map under `namespace`, creating
665
1071
  * the map when absent and replacing any existing value at that key. Sibling
666
- * namespaces are preserved, so independent consumers (`$ext.presentation`,
1072
+ * namespaces are preserved, so independent consumers (`$ext.editor`,
667
1073
  * `$ext.agent`, …) don't clobber each other.
668
1074
  * @param {string} namespace
669
1075
  * @param {any} value
@@ -686,7 +1092,7 @@ export class Document {
686
1092
  /**
687
1093
  * Update a payload field on the main card. Clears any existing `!must_fill` marker.
688
1094
  *
689
- * Throws if `name` does not match `[a-z_][a-z0-9_]*`.
1095
+ * Throws if `name` does not match `[A-Za-z_][A-Za-z0-9_]*`.
690
1096
  * @param {string} name
691
1097
  * @param {any} value
692
1098
  */
@@ -705,6 +1111,28 @@ export class Document {
705
1111
  wasm.__wbindgen_add_to_stack_pointer(16);
706
1112
  }
707
1113
  }
1114
+ /**
1115
+ * Set several main-card payload fields atomically from a plain object,
1116
+ * clearing any `!must_fill` marker on each key. Nothing is applied on
1117
+ * error; the thrown error's `diagnostics` array carries one entry per
1118
+ * offending field (`path` = field name), so externally-sourced names
1119
+ * (database columns, form keys) surface every violation in one pass.
1120
+ * Mirrors Python `set_fields`.
1121
+ * @param {Record<string, unknown>} fields
1122
+ */
1123
+ setFields(fields) {
1124
+ try {
1125
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1126
+ wasm.document_setFields(retptr, this.__wbg_ptr, addHeapObject(fields));
1127
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1128
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1129
+ if (r1) {
1130
+ throw takeObject(r0);
1131
+ }
1132
+ } finally {
1133
+ wasm.__wbindgen_add_to_stack_pointer(16);
1134
+ }
1135
+ }
708
1136
  /**
709
1137
  * Update a payload field on the main card and mark it as `!must_fill`.
710
1138
  * Throws on invalid name (see [`setField`](Document::set_field)).
@@ -779,107 +1207,380 @@ export class Document {
779
1207
  * documents produce byte-equal output, safe for content-hash use cases.
780
1208
  * @returns {string}
781
1209
  */
782
- toJson() {
783
- let deferred1_0;
784
- let deferred1_1;
1210
+ toJson() {
1211
+ let deferred1_0;
1212
+ let deferred1_1;
1213
+ try {
1214
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1215
+ wasm.document_toJson(retptr, this.__wbg_ptr);
1216
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1217
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1218
+ deferred1_0 = r0;
1219
+ deferred1_1 = r1;
1220
+ return getStringFromWasm0(r0, r1);
1221
+ } finally {
1222
+ wasm.__wbindgen_add_to_stack_pointer(16);
1223
+ wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
1224
+ }
1225
+ }
1226
+ /**
1227
+ * Emit canonical Quillmark Markdown. Round-trip safe: re-parsing the
1228
+ * result produces a `Document` equal to `self` by value and by type.
1229
+ * @returns {string}
1230
+ */
1231
+ toMarkdown() {
1232
+ let deferred1_0;
1233
+ let deferred1_1;
1234
+ try {
1235
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1236
+ wasm.document_toMarkdown(retptr, this.__wbg_ptr);
1237
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1238
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1239
+ deferred1_0 = r0;
1240
+ deferred1_1 = r1;
1241
+ return getStringFromWasm0(r0, r1);
1242
+ } finally {
1243
+ wasm.__wbindgen_add_to_stack_pointer(16);
1244
+ wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
1245
+ }
1246
+ }
1247
+ /**
1248
+ * Like [`fromJson`](Document::from_json) but returns `undefined` instead
1249
+ * of throwing when `json` is not a valid storage DTO — use to
1250
+ * discriminate format without exceptions as control flow.
1251
+ * `undefined` means "not a storage DTO"; `fromMarkdown` still throws on
1252
+ * genuinely malformed markdown.
1253
+ * @param {string} json
1254
+ * @returns {Document | undefined}
1255
+ */
1256
+ static tryFromJson(json) {
1257
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
1258
+ const len0 = WASM_VECTOR_LEN;
1259
+ const ret = wasm.document_tryFromJson(ptr0, len0);
1260
+ return ret === 0 ? undefined : Document.__wrap(ret);
1261
+ }
1262
+ /**
1263
+ * @returns {Diagnostic[]}
1264
+ */
1265
+ get warnings() {
1266
+ try {
1267
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1268
+ wasm.document_warnings(retptr, this.__wbg_ptr);
1269
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1270
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1271
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1272
+ if (r2) {
1273
+ throw takeObject(r1);
1274
+ }
1275
+ return takeObject(r0);
1276
+ } finally {
1277
+ wasm.__wbindgen_add_to_stack_pointer(16);
1278
+ }
1279
+ }
1280
+ }
1281
+ if (Symbol.dispose) Document.prototype[Symbol.dispose] = Document.prototype.free;
1282
+
1283
+ /**
1284
+ * Live render session: reads (`render`, `paint`, `pageSize`, `regions`,
1285
+ * `fieldAt`, `positionAt`, `locate`) serve the current compile. `apply(doc)`
1286
+ * recompiles a whole document in place, transactionally (on throw every read
1287
+ * keeps serving the last-good compile). Geometry reads reflect the current
1288
+ * compile; anchoring a caret across edits is the editor's job — re-read
1289
+ * geometry after each committed `apply`.
1290
+ *
1291
+ * **Empty documents.** A zero-page document yields a valid session
1292
+ * (`pageCount === 0`); `paint(ctx, 0)` or `pageSize(0)` throws with
1293
+ * `"page index 0 out of range (pageCount=0)"`. Branch on `pageCount === 0`
1294
+ * rather than catching the error.
1295
+ */
1296
+ export class LiveSession {
1297
+ static __wrap(ptr) {
1298
+ ptr = ptr >>> 0;
1299
+ const obj = Object.create(LiveSession.prototype);
1300
+ obj.__wbg_ptr = ptr;
1301
+ LiveSessionFinalization.register(obj, obj.__wbg_ptr, obj);
1302
+ return obj;
1303
+ }
1304
+ __destroy_into_raw() {
1305
+ const ptr = this.__wbg_ptr;
1306
+ this.__wbg_ptr = 0;
1307
+ LiveSessionFinalization.unregister(this);
1308
+ return ptr;
1309
+ }
1310
+ free() {
1311
+ const ptr = this.__destroy_into_raw();
1312
+ wasm.__wbg_livesession_free(ptr, 0);
1313
+ }
1314
+ /**
1315
+ * Recompile the session against `doc` — the edit verb of a live preview.
1316
+ * The document is compiled through the same schema pipeline as `open`
1317
+ * (same quill), then applied transactionally: on throw every read
1318
+ * (`render`, `paint`, `pageSize`, `regions`, `fieldAt`) keeps serving the last-good
1319
+ * compile, and the session recovers on the next successful `apply`. On
1320
+ * success reads serve the new compile; repaint `dirtyPages ∩ visible`.
1321
+ * @param {Document} doc
1322
+ * @returns {ChangeSet}
1323
+ */
1324
+ apply(doc) {
1325
+ try {
1326
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1327
+ _assertClass(doc, Document);
1328
+ wasm.livesession_apply(retptr, this.__wbg_ptr, doc.__wbg_ptr);
1329
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1330
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1331
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1332
+ if (r2) {
1333
+ throw takeObject(r1);
1334
+ }
1335
+ return takeObject(r0);
1336
+ } finally {
1337
+ wasm.__wbindgen_add_to_stack_pointer(16);
1338
+ }
1339
+ }
1340
+ /**
1341
+ * The backend that produced this session (e.g. `"typst"`).
1342
+ * @returns {string}
1343
+ */
1344
+ get backendId() {
1345
+ let deferred1_0;
1346
+ let deferred1_1;
1347
+ try {
1348
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1349
+ wasm.livesession_backendId(retptr, this.__wbg_ptr);
1350
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1351
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1352
+ deferred1_0 = r0;
1353
+ deferred1_1 = r1;
1354
+ return getStringFromWasm0(r0, r1);
1355
+ } finally {
1356
+ wasm.__wbindgen_add_to_stack_pointer(16);
1357
+ wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
1358
+ }
1359
+ }
1360
+ /**
1361
+ * The schema field whose content is under a point on `page` — the
1362
+ * forward (click → field) direction: hit-test a click against the
1363
+ * compiled document and get back the field address to focus in the
1364
+ * editor, or `undefined` off any field's ink. `x`/`y` are PDF points
1365
+ * with a **bottom-left** origin, the same space as `FieldRegion.rect` —
1366
+ * from a canvas click, invert the overlay transform documented on
1367
+ * `FieldRegion`: `x = clickPx.x / renderScale`,
1368
+ * `y = pageHeightPt - clickPx.y / renderScale`. Unlike `regions()`,
1369
+ * *every* placement answers, not just the first.
1370
+ * @param {number} page
1371
+ * @param {number} x
1372
+ * @param {number} y
1373
+ * @returns {string | undefined}
1374
+ */
1375
+ fieldAt(page, x, y) {
1376
+ try {
1377
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1378
+ wasm.livesession_fieldAt(retptr, this.__wbg_ptr, page, x, y);
1379
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1380
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1381
+ let v1;
1382
+ if (r0 !== 0) {
1383
+ v1 = getStringFromWasm0(r0, r1).slice();
1384
+ wasm.__wbindgen_export4(r0, r1 * 1, 1);
1385
+ }
1386
+ return v1;
1387
+ } finally {
1388
+ wasm.__wbindgen_add_to_stack_pointer(16);
1389
+ }
1390
+ }
1391
+ /**
1392
+ * The whole-field highlight boxes for `field` — one union rect per page,
1393
+ * over the field's `span`-bearing content segments. The convenience that
1394
+ * owns the union `regions()` leaves derived: it keeps `regions()` the
1395
+ * low-level disjoint truth (#829) and folds the span-filter + per-page
1396
+ * union here, so a "highlight the focused field" consumer stops
1397
+ * reimplementing it. **Content only** — a field placed solely as a scalar
1398
+ * reference or a bound widget carries no `span` and returns `[]`; its box
1399
+ * is a single `regions()` rect. Reflects the current compile, like
1400
+ * `regions()`.
1401
+ * @param {string} field
1402
+ * @returns {FieldRegion[]}
1403
+ */
1404
+ fieldBoxes(field) {
1405
+ try {
1406
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1407
+ const ptr0 = passStringToWasm0(field, wasm.__wbindgen_export, wasm.__wbindgen_export2);
1408
+ const len0 = WASM_VECTOR_LEN;
1409
+ wasm.livesession_fieldBoxes(retptr, this.__wbg_ptr, ptr0, len0);
1410
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1411
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1412
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1413
+ if (r2) {
1414
+ throw takeObject(r1);
1415
+ }
1416
+ return takeObject(r0);
1417
+ } finally {
1418
+ wasm.__wbindgen_add_to_stack_pointer(16);
1419
+ }
1420
+ }
1421
+ /**
1422
+ * A corpus position → **caret rect** — the reverse of `positionAt`: given
1423
+ * a field and a USV offset into its `RichText`, return the box (in the
1424
+ * same bottom-left PDF-point space as `FieldRegion.rect`) to draw a caret
1425
+ * at, its `span` collapsed to `[pos, pos]`; `undefined` when the field
1426
+ * places no tracked content or the offset maps to no drawn glyph.
1427
+ * @param {string} field
1428
+ * @param {number} pos
1429
+ * @returns {FieldRegion | undefined}
1430
+ */
1431
+ locate(field, pos) {
1432
+ const ptr0 = passStringToWasm0(field, wasm.__wbindgen_export, wasm.__wbindgen_export2);
1433
+ const len0 = WASM_VECTOR_LEN;
1434
+ const ret = wasm.livesession_locate(this.__wbg_ptr, ptr0, len0, pos);
1435
+ return takeObject(ret);
1436
+ }
1437
+ /**
1438
+ * @returns {number}
1439
+ */
1440
+ get pageCount() {
1441
+ const ret = wasm.livesession_pageCount(this.__wbg_ptr);
1442
+ return ret >>> 0;
1443
+ }
1444
+ /**
1445
+ * Page dimensions in points (1 pt = 1/72 inch).
1446
+ * Throws if the backend has no canvas painter or `page` is out of range.
1447
+ * @param {number} page
1448
+ * @returns {PageSize}
1449
+ */
1450
+ pageSize(page) {
785
1451
  try {
786
1452
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
787
- wasm.document_toJson(retptr, this.__wbg_ptr);
1453
+ wasm.livesession_pageSize(retptr, this.__wbg_ptr, page);
788
1454
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
789
1455
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
790
- deferred1_0 = r0;
791
- deferred1_1 = r1;
792
- return getStringFromWasm0(r0, r1);
1456
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1457
+ if (r2) {
1458
+ throw takeObject(r1);
1459
+ }
1460
+ return takeObject(r0);
793
1461
  } finally {
794
1462
  wasm.__wbindgen_add_to_stack_pointer(16);
795
- wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
796
1463
  }
797
1464
  }
798
1465
  /**
799
- * Emit canonical Quillmark Markdown. Round-trip safe: re-parsing the
800
- * result produces a `Document` equal to `self` by value and by type.
801
- * @returns {string}
1466
+ * Paint `page` into a `CanvasRenderingContext2D` or
1467
+ * `OffscreenCanvasRenderingContext2D`. The painter owns
1468
+ * `canvas.width`/`height` (no `clearRect` needed); consumers own
1469
+ * `canvas.style.*`. If `layoutScale * densityScale` exceeds 16384 px
1470
+ * per side, `densityScale` is clamped — `PaintResult.clamped` reports it and
1471
+ * `PaintResult.effectiveDensityScale` carries the density actually applied.
1472
+ *
1473
+ * `put_image_data` writes the whole backing store, bypassing the 2D
1474
+ * context's transform, `globalAlpha`, and clip: the painter owns the entire
1475
+ * canvas, so each visible page needs its own `` — you cannot composite
1476
+ * two pages, a sub-rect, or a context transform through this call.
1477
+ *
1478
+ * Throws if the backend has no canvas painter, `page` is out of range,
1479
+ * `ctx` is the wrong type, or either scale is non-finite or `<= 0`.
1480
+ * @param {CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D} ctx
1481
+ * @param {number} page
1482
+ * @param {PaintOptions | undefined} opts
1483
+ * @returns {PaintResult}
802
1484
  */
803
- toMarkdown() {
804
- let deferred1_0;
805
- let deferred1_1;
1485
+ paint(ctx, page, opts) {
806
1486
  try {
807
1487
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
808
- wasm.document_toMarkdown(retptr, this.__wbg_ptr);
1488
+ wasm.livesession_paint(retptr, this.__wbg_ptr, addHeapObject(ctx), page, addHeapObject(opts));
809
1489
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
810
1490
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
811
- deferred1_0 = r0;
812
- deferred1_1 = r1;
813
- return getStringFromWasm0(r0, r1);
1491
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1492
+ if (r2) {
1493
+ throw takeObject(r1);
1494
+ }
1495
+ return takeObject(r0);
814
1496
  } finally {
815
1497
  wasm.__wbindgen_add_to_stack_pointer(16);
816
- wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
817
1498
  }
818
1499
  }
819
1500
  /**
820
- * Like [`fromJson`](Document::from_json) but returns `undefined` instead
821
- * of throwing when `json` is not a valid storage DTO use to
822
- * discriminate format without exceptions as control flow.
823
- * `undefined` means "not a storage DTO"; `fromMarkdown` still throws on
824
- * genuinely malformed markdown.
825
- * @param {string} json
826
- * @returns {Document | undefined}
1501
+ * A point **corpus position** — the fine-grained click direction:
1502
+ * hit-test a point and get back the field *and* a USV offset into its
1503
+ * `RichText` (for placing a caret or mapping a selection into the content
1504
+ * model), or `undefined` off all content ink. `x`/`y` are PDF points,
1505
+ * bottom-left origin — the same space as `fieldAt`. The offset is
1506
+ * cluster-exact and degrades to the containing segment's start on
1507
+ * origin-less ink (list markers, a code fence's interior). See
1508
+ * `CorpusHit`.
1509
+ * @param {number} page
1510
+ * @param {number} x
1511
+ * @param {number} y
1512
+ * @returns {CorpusHit | undefined}
827
1513
  */
828
- static tryFromJson(json) {
829
- const ptr0 = passStringToWasm0(json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
830
- const len0 = WASM_VECTOR_LEN;
831
- const ret = wasm.document_tryFromJson(ptr0, len0);
832
- return ret === 0 ? undefined : Document.__wrap(ret);
1514
+ positionAt(page, x, y) {
1515
+ const ret = wasm.livesession_positionAt(this.__wbg_ptr, page, x, y);
1516
+ return takeObject(ret);
833
1517
  }
834
1518
  /**
835
- * Replace the body of the card at `index`. Throws if out of range.
836
- * @param {number} index
837
- * @param {string} body
1519
+ * Schema-field geometry for this compiled session each content field's
1520
+ * **first placement** (one region per page it touches) plus widget and
1521
+ * scalar-reference-site regions, keyed on the quill schema field path; a
1522
+ * field may still appear more than once (group by `field`, see
1523
+ * `FieldRegion`). A session-level query: no render, no byte artifact. An
1524
+ * interactive preview reads it to scroll to / highlight the focused
1525
+ * field over a `paint`-ed canvas; the click direction is `fieldAt`.
1526
+ * Empty for backends that place no schema fields.
1527
+ * @returns {FieldRegion[]}
838
1528
  */
839
- updateCardBody(index, body) {
1529
+ regions() {
840
1530
  try {
841
1531
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
842
- const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
843
- const len0 = WASM_VECTOR_LEN;
844
- wasm.document_updateCardBody(retptr, this.__wbg_ptr, index, ptr0, len0);
1532
+ wasm.livesession_regions(retptr, this.__wbg_ptr);
845
1533
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
846
1534
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
847
- if (r1) {
848
- throw takeObject(r0);
1535
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1536
+ if (r2) {
1537
+ throw takeObject(r1);
849
1538
  }
1539
+ return takeObject(r0);
850
1540
  } finally {
851
1541
  wasm.__wbindgen_add_to_stack_pointer(16);
852
1542
  }
853
1543
  }
854
1544
  /**
855
- * Update a field on the card at `index`.
856
- * Throws if `index` is out of range, `name` is reserved or invalid.
857
- * @param {number} index
858
- * @param {string} name
859
- * @param {any} value
1545
+ * @param {RenderOptions | null} [opts]
1546
+ * @returns {RenderResult}
860
1547
  */
861
- updateCardField(index, name, value) {
1548
+ render(opts) {
862
1549
  try {
863
1550
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
864
- const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
865
- const len0 = WASM_VECTOR_LEN;
866
- wasm.document_updateCardField(retptr, this.__wbg_ptr, index, ptr0, len0, addHeapObject(value));
1551
+ wasm.livesession_render(retptr, this.__wbg_ptr, isLikeNone(opts) ? 0 : addHeapObject(opts));
867
1552
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
868
1553
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
869
- if (r1) {
870
- throw takeObject(r0);
1554
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1555
+ if (r2) {
1556
+ throw takeObject(r1);
871
1557
  }
1558
+ return takeObject(r0);
872
1559
  } finally {
873
1560
  wasm.__wbindgen_add_to_stack_pointer(16);
874
1561
  }
875
1562
  }
876
1563
  /**
1564
+ * `true` iff `paint` and `pageSize` will succeed for this session. Derived
1565
+ * from the session's canvas seam, so it reflects exactly what `paint` will
1566
+ * do — no separately captured flag.
1567
+ * @returns {boolean}
1568
+ */
1569
+ get supportsCanvas() {
1570
+ const ret = wasm.livesession_supportsCanvas(this.__wbg_ptr);
1571
+ return ret !== 0;
1572
+ }
1573
+ /**
1574
+ * Non-fatal diagnostics of the session's **current compile** (e.g. Typst
1575
+ * font fallback) — set at open and refreshed by each committed `apply`;
1576
+ * a failed apply keeps the last-good compile's warnings. Also appended
1577
+ * to `RenderResult.warnings` on each `render()` call.
877
1578
  * @returns {Diagnostic[]}
878
1579
  */
879
1580
  get warnings() {
880
1581
  try {
881
1582
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
882
- wasm.document_warnings(retptr, this.__wbg_ptr);
1583
+ wasm.livesession_warnings(retptr, this.__wbg_ptr);
883
1584
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
884
1585
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
885
1586
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -892,7 +1593,7 @@ export class Document {
892
1593
  }
893
1594
  }
894
1595
  }
895
- if (Symbol.dispose) Document.prototype[Symbol.dispose] = Document.prototype.free;
1596
+ if (Symbol.dispose) LiveSession.prototype[Symbol.dispose] = LiveSession.prototype.free;
896
1597
 
897
1598
  export class Quill {
898
1599
  static __wrap(ptr) {
@@ -1003,9 +1704,10 @@ export class Quill {
1003
1704
  }
1004
1705
  /**
1005
1706
  * Document schema for the quill: the user-fillable fields plus their
1006
- * `ui` hints (group / order / showWhen). The single field-metadata
1007
- * surface — drives form editors and LLM/MCP consumers alike. Returns the
1008
- * `QuillSchema` shape.
1707
+ * `ui` hints (title / group / compact / multiline). The single
1708
+ * field-metadata surface — drives form editors and LLM/MCP consumers
1709
+ * alike. Key order in `fields`/`properties` is declaration order — the
1710
+ * ordering contract. Returns the `QuillSchema` shape.
1009
1711
  * @returns {QuillSchema}
1010
1712
  */
1011
1713
  get schema() {
@@ -1113,10 +1815,10 @@ export class Quill {
1113
1815
  *
1114
1816
  * Forwards the canonical `validation::*` diagnostics — same `code`,
1115
1817
  * `path`, and `hint` the engine emits — including the non-fatal
1116
- * `validation::field_absent` completeness signal that `render` demotes.
1117
- * Field values, defaults, and order are not part of this surface: read
1118
- * them from the `Document` payload and `Quill.schema` (fields carry
1119
- * `ui.order`).
1818
+ * `validation::must_fill` warning for each `!must_fill` marker left in
1819
+ * the document. Field values, defaults, and order are not part of this
1820
+ * surface: read them from the `Document` payload and `Quill.schema`
1821
+ * (schema key order is display order).
1120
1822
  * @param {Document} doc
1121
1823
  * @returns {Diagnostic[]}
1122
1824
  */
@@ -1161,10 +1863,10 @@ export class Quillmark {
1161
1863
  return this;
1162
1864
  }
1163
1865
  /**
1164
- * Open an iterative render session for `doc` against `quill`'s backend.
1866
+ * Open a live render session for `doc` against `quill`'s backend.
1165
1867
  * @param {Quill} quill
1166
1868
  * @param {Document} doc
1167
- * @returns {RenderSession}
1869
+ * @returns {LiveSession}
1168
1870
  */
1169
1871
  open(quill, doc) {
1170
1872
  try {
@@ -1178,14 +1880,14 @@ export class Quillmark {
1178
1880
  if (r2) {
1179
1881
  throw takeObject(r1);
1180
1882
  }
1181
- return RenderSession.__wrap(r0);
1883
+ return LiveSession.__wrap(r0);
1182
1884
  } finally {
1183
1885
  wasm.__wbindgen_add_to_stack_pointer(16);
1184
1886
  }
1185
1887
  }
1186
1888
  /**
1187
1889
  * Render `doc` against `quill` in one shot. Convenience over `open` +
1188
- * `RenderSession.render`: an unset `output_format` falls back to the
1890
+ * `LiveSession.render`: an unset `output_format` falls back to the
1189
1891
  * backend's first supported format.
1190
1892
  * @param {Quill} quill
1191
1893
  * @param {Document} doc
@@ -1211,7 +1913,7 @@ export class Quillmark {
1211
1913
  }
1212
1914
  /**
1213
1915
  * The output formats `quill`'s backend can emit. Static capability —
1214
- * resolves the backend but compiles nothing. Throws `UnsupportedBackend`
1916
+ * resolves the backend but compiles nothing. Throws `engine::backend_not_found`
1215
1917
  * if no registered backend matches the quill's declared backend.
1216
1918
  * @param {Quill} quill
1217
1919
  * @returns {OutputFormat[]}
@@ -1233,9 +1935,11 @@ export class Quillmark {
1233
1935
  }
1234
1936
  }
1235
1937
  /**
1236
- * `true` iff `quill`'s backend can paint sessions to a canvas. Asked of
1237
- * the real backend; `false` when the backend is unsupported or non-canvas.
1238
- * Use as a precondition probe before mounting a canvas-based preview UI.
1938
+ * Pre-session hint: `true` iff `quill`'s backend can paint sessions to a
1939
+ * canvas, derived from the backend's output formats; `false` when the
1940
+ * backend is unsupported. Use as a cheap precondition probe before mounting
1941
+ * a canvas-based preview UI; the authoritative answer is the session's
1942
+ * `supportsCanvas` getter once `open()` has been called.
1239
1943
  * @param {Quill} quill
1240
1944
  * @returns {boolean}
1241
1945
  */
@@ -1248,158 +1952,62 @@ export class Quillmark {
1248
1952
  if (Symbol.dispose) Quillmark.prototype[Symbol.dispose] = Quillmark.prototype.free;
1249
1953
 
1250
1954
  /**
1251
- * Iterative render handle backed by an immutable compiled snapshot.
1252
- *
1253
- * **Empty documents.** A zero-page document yields a valid session
1254
- * (`pageCount === 0`); `paint(ctx, 0)` or `pageSize(0)` throws with
1255
- * `"page index 0 out of range (pageCount=0)"`. Branch on `pageCount === 0`
1256
- * rather than catching the error.
1955
+ * Export a canonical `RichText` corpus to its markdown projection — the pure
1956
+ * codec that replaces the eager `bodyMarkdown` / `fieldMarkdown` precomputes
1957
+ * (`exportMarkdown(card.body)`). Throws if `rt` is not a canonical corpus.
1958
+ * @param {RichText} rt
1959
+ * @returns {string}
1257
1960
  */
1258
- export class RenderSession {
1259
- static __wrap(ptr) {
1260
- ptr = ptr >>> 0;
1261
- const obj = Object.create(RenderSession.prototype);
1262
- obj.__wbg_ptr = ptr;
1263
- RenderSessionFinalization.register(obj, obj.__wbg_ptr, obj);
1264
- return obj;
1265
- }
1266
- __destroy_into_raw() {
1267
- const ptr = this.__wbg_ptr;
1268
- this.__wbg_ptr = 0;
1269
- RenderSessionFinalization.unregister(this);
1270
- return ptr;
1271
- }
1272
- free() {
1273
- const ptr = this.__destroy_into_raw();
1274
- wasm.__wbg_rendersession_free(ptr, 0);
1275
- }
1276
- /**
1277
- * The backend that produced this session (e.g. `"typst"`).
1278
- * @returns {string}
1279
- */
1280
- get backendId() {
1281
- let deferred1_0;
1282
- let deferred1_1;
1283
- try {
1284
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1285
- wasm.rendersession_backendId(retptr, this.__wbg_ptr);
1286
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1287
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1288
- deferred1_0 = r0;
1289
- deferred1_1 = r1;
1290
- return getStringFromWasm0(r0, r1);
1291
- } finally {
1292
- wasm.__wbindgen_add_to_stack_pointer(16);
1293
- wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
1294
- }
1295
- }
1296
- /**
1297
- * @returns {number}
1298
- */
1299
- get pageCount() {
1300
- const ret = wasm.rendersession_pageCount(this.__wbg_ptr);
1301
- return ret >>> 0;
1302
- }
1303
- /**
1304
- * Page dimensions in Typst points (1 pt = 1/72 inch).
1305
- * Throws if the backend has no canvas painter or `page` is out of range.
1306
- * @param {number} page
1307
- * @returns {PageSize}
1308
- */
1309
- pageSize(page) {
1310
- try {
1311
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1312
- wasm.rendersession_pageSize(retptr, this.__wbg_ptr, page);
1313
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1314
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1315
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1316
- if (r2) {
1317
- throw takeObject(r1);
1318
- }
1319
- return takeObject(r0);
1320
- } finally {
1321
- wasm.__wbindgen_add_to_stack_pointer(16);
1322
- }
1323
- }
1324
- /**
1325
- * Paint `page` into a `CanvasRenderingContext2D` or
1326
- * `OffscreenCanvasRenderingContext2D`. The painter owns
1327
- * `canvas.width`/`height` (no `clearRect` needed); consumers own
1328
- * `canvas.style.*`. If `layoutScale * densityScale` exceeds 16384 px
1329
- * per side, `densityScale` is clamped — detect via `PaintResult.pixelWidth`.
1330
- *
1331
- * Throws if the backend has no canvas painter, `page` is out of range,
1332
- * `ctx` is the wrong type, or either scale is non-finite or `<= 0`.
1333
- * @param {CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D} ctx
1334
- * @param {number} page
1335
- * @param {PaintOptions | undefined} opts
1336
- * @returns {PaintResult}
1337
- */
1338
- paint(ctx, page, opts) {
1339
- try {
1340
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1341
- wasm.rendersession_paint(retptr, this.__wbg_ptr, addHeapObject(ctx), page, addHeapObject(opts));
1342
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1343
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1344
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1345
- if (r2) {
1346
- throw takeObject(r1);
1347
- }
1348
- return takeObject(r0);
1349
- } finally {
1350
- wasm.__wbindgen_add_to_stack_pointer(16);
1351
- }
1352
- }
1353
- /**
1354
- * @param {RenderOptions | null} [opts]
1355
- * @returns {RenderResult}
1356
- */
1357
- render(opts) {
1358
- try {
1359
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1360
- wasm.rendersession_render(retptr, this.__wbg_ptr, isLikeNone(opts) ? 0 : addHeapObject(opts));
1361
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1362
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1363
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1364
- if (r2) {
1365
- throw takeObject(r1);
1366
- }
1367
- return takeObject(r0);
1368
- } finally {
1369
- wasm.__wbindgen_add_to_stack_pointer(16);
1961
+ export function exportMarkdown(rt) {
1962
+ let deferred2_0;
1963
+ let deferred2_1;
1964
+ try {
1965
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1966
+ wasm.exportMarkdown(retptr, addHeapObject(rt));
1967
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1968
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1969
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1970
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1971
+ var ptr1 = r0;
1972
+ var len1 = r1;
1973
+ if (r3) {
1974
+ ptr1 = 0; len1 = 0;
1975
+ throw takeObject(r2);
1370
1976
  }
1977
+ deferred2_0 = ptr1;
1978
+ deferred2_1 = len1;
1979
+ return getStringFromWasm0(ptr1, len1);
1980
+ } finally {
1981
+ wasm.__wbindgen_add_to_stack_pointer(16);
1982
+ wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
1371
1983
  }
1372
- /**
1373
- * `true` iff `paint` and `pageSize` will succeed for this session. The
1374
- * backend's canvas capability, captured at open time.
1375
- * @returns {boolean}
1376
- */
1377
- get supportsCanvas() {
1378
- const ret = wasm.rendersession_supportsCanvas(this.__wbg_ptr);
1379
- return ret !== 0;
1380
- }
1381
- /**
1382
- * Non-fatal diagnostics emitted when opening the session. Also appended
1383
- * to `RenderResult.warnings` on each `render()` call.
1384
- * @returns {Diagnostic[]}
1385
- */
1386
- get warnings() {
1387
- try {
1388
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1389
- wasm.rendersession_warnings(retptr, this.__wbg_ptr);
1390
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1391
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1392
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1393
- if (r2) {
1394
- throw takeObject(r1);
1395
- }
1396
- return takeObject(r0);
1397
- } finally {
1398
- wasm.__wbindgen_add_to_stack_pointer(16);
1984
+ }
1985
+
1986
+ /**
1987
+ * Import a markdown string to a canonical `RichText` corpus — the pure,
1988
+ * document-free codec. Pair with `install(addr, importMarkdown(md))` to spell
1989
+ * the cold (anchor-losing) write at the call site; prefer `revise` for edit
1990
+ * semantics. Throws on an over-nested input.
1991
+ * @param {string} markdown
1992
+ * @returns {RichText}
1993
+ */
1994
+ export function importMarkdown(markdown) {
1995
+ try {
1996
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1997
+ const ptr0 = passStringToWasm0(markdown, wasm.__wbindgen_export, wasm.__wbindgen_export2);
1998
+ const len0 = WASM_VECTOR_LEN;
1999
+ wasm.importMarkdown(retptr, ptr0, len0);
2000
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
2001
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
2002
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
2003
+ if (r2) {
2004
+ throw takeObject(r1);
1399
2005
  }
2006
+ return takeObject(r0);
2007
+ } finally {
2008
+ wasm.__wbindgen_add_to_stack_pointer(16);
1400
2009
  }
1401
2010
  }
1402
- if (Symbol.dispose) RenderSession.prototype[Symbol.dispose] = RenderSession.prototype.free;
1403
2011
 
1404
2012
  /**
1405
2013
  * Initialize the WASM module with panic hooks for better error messages
@@ -1407,10 +2015,68 @@ if (Symbol.dispose) RenderSession.prototype[Symbol.dispose] = RenderSession.prot
1407
2015
  export function init() {
1408
2016
  wasm.init();
1409
2017
  }
2018
+
2019
+ /**
2020
+ * Map a base corpus position through a `delta` to its new position — the pure
2021
+ * position-mapping codec an editor bridge composes to hold a caret stable
2022
+ * across a `revise`. `assoc` decides the side of a same-position insertion
2023
+ * (`"after"` moves past it). Throws on a malformed `delta`.
2024
+ * @param {Delta} delta
2025
+ * @param {number} pos
2026
+ * @param {Assoc} assoc
2027
+ * @returns {number}
2028
+ */
2029
+ export function mapPos(delta, pos, assoc) {
2030
+ try {
2031
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
2032
+ wasm.mapPos(retptr, addHeapObject(delta), pos, addHeapObject(assoc));
2033
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
2034
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
2035
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
2036
+ if (r2) {
2037
+ throw takeObject(r1);
2038
+ }
2039
+ return r0 >>> 0;
2040
+ } finally {
2041
+ wasm.__wbindgen_add_to_stack_pointer(16);
2042
+ }
2043
+ }
2044
+
2045
+ /**
2046
+ * Rebase `markdown` onto a `base` corpus — the pure, document-free twin of
2047
+ * `revise`: cold-import + `diff_import`, returning the new `corpus` and the
2048
+ * text `delta` (surviving anchors rebased). Use it to compute a revise without
2049
+ * a document in hand; `revise(addr, md)` fuses this with the store for
2050
+ * atomicity. Throws on an over-nested markdown input or a non-corpus `base`.
2051
+ * @param {RichText} base
2052
+ * @param {string} markdown
2053
+ * @returns {{ corpus: RichText; delta: Delta }}
2054
+ */
2055
+ export function rebase(base, markdown) {
2056
+ try {
2057
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
2058
+ const ptr0 = passStringToWasm0(markdown, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2059
+ const len0 = WASM_VECTOR_LEN;
2060
+ wasm.rebase(retptr, addHeapObject(base), ptr0, len0);
2061
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
2062
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
2063
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
2064
+ if (r2) {
2065
+ throw takeObject(r1);
2066
+ }
2067
+ return takeObject(r0);
2068
+ } finally {
2069
+ wasm.__wbindgen_add_to_stack_pointer(16);
2070
+ }
2071
+ }
1410
2072
  export function __wbg_Error_960c155d3d49e4c2(arg0, arg1) {
1411
2073
  const ret = Error(getStringFromWasm0(arg0, arg1));
1412
2074
  return addHeapObject(ret);
1413
2075
  }
2076
+ export function __wbg_Number_32bf70a599af1d4b(arg0) {
2077
+ const ret = Number(getObject(arg0));
2078
+ return ret;
2079
+ }
1414
2080
  export function __wbg_String_8564e559799eccda(arg0, arg1) {
1415
2081
  const ret = String(getObject(arg1));
1416
2082
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
@@ -1795,15 +2461,15 @@ export function __wbindgen_object_drop_ref(arg0) {
1795
2461
  const DocumentFinalization = (typeof FinalizationRegistry === 'undefined')
1796
2462
  ? { register: () => {}, unregister: () => {} }
1797
2463
  : new FinalizationRegistry(ptr => wasm.__wbg_document_free(ptr >>> 0, 1));
2464
+ const LiveSessionFinalization = (typeof FinalizationRegistry === 'undefined')
2465
+ ? { register: () => {}, unregister: () => {} }
2466
+ : new FinalizationRegistry(ptr => wasm.__wbg_livesession_free(ptr >>> 0, 1));
1798
2467
  const QuillFinalization = (typeof FinalizationRegistry === 'undefined')
1799
2468
  ? { register: () => {}, unregister: () => {} }
1800
2469
  : new FinalizationRegistry(ptr => wasm.__wbg_quill_free(ptr >>> 0, 1));
1801
2470
  const QuillmarkFinalization = (typeof FinalizationRegistry === 'undefined')
1802
2471
  ? { register: () => {}, unregister: () => {} }
1803
2472
  : new FinalizationRegistry(ptr => wasm.__wbg_quillmark_free(ptr >>> 0, 1));
1804
- const RenderSessionFinalization = (typeof FinalizationRegistry === 'undefined')
1805
- ? { register: () => {}, unregister: () => {} }
1806
- : new FinalizationRegistry(ptr => wasm.__wbg_rendersession_free(ptr >>> 0, 1));
1807
2473
 
1808
2474
  function addHeapObject(obj) {
1809
2475
  if (heap_next === heap.length) heap.push(heap.length + 1);