@quillmark/wasm 0.104.0 → 0.106.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.
@@ -24,17 +24,13 @@ export type PayloadItem =
24
24
  | { type: "comment"; text: string; inline?: boolean };
25
25
 
26
26
  /**
27
- * A single card block, as read back from a document: returned by
28
- * `Document.main` / `Document.cards` / `Document.removeCard` / `Quill.seedCard`
29
- * / `Document.makeCard`. To feed a card *into* a document use `CardInput`
30
- * (which `insertCard` accepts); every `Card` is a valid `CardInput`,
31
- * so a card read from one document pushes straight into another.
27
+ * A single card block, as read back from a document. Every `Card` is a valid
28
+ * `CardInput`, so a card read from one document pushes straight into another.
32
29
  *
33
30
  * `$` system entries are hoisted to named fields: `kind` (the `$kind`, empty
34
- * string when none), optional `quill` (the `$quill` `name@version`, main card
35
- * only), optional `ext` (`$ext`), and optional `seed`
36
- * (the `$seed` per-kind overlay map, main card only). `payloadItems` carries
37
- * user fields and comments in order.
31
+ * string when none), `quill` (`$quill` `name@version`, main card only), `ext`
32
+ * (`$ext`), and `seed` (the `$seed` per-kind overlay map, main card only).
33
+ * `payloadItems` carries user fields and comments in order.
38
34
  */
39
35
  export interface Card {
40
36
  kind: string;
@@ -43,21 +39,16 @@ export interface Card {
43
39
  seed?: Record<string, unknown>;
44
40
  payloadItems: PayloadItem[];
45
41
  /**
46
- * The card body as canonical `Content`: the source-of-truth content model.
47
- * Always this content shape on read, never a markdown string. For the markdown
48
- * projection call the codec `exportMarkdown(card.body)`. Write a body back
49
- * with `doc.overwrite(addr, rt)` / `doc.revise(addr, md)`, or via `CardInput.body`.
42
+ * The card body as canonical `Content`, never a markdown string. For the
43
+ * markdown projection call `exportMarkdown(card.body)`.
50
44
  */
51
45
  body: Content;
52
46
  }
53
47
 
54
48
  /**
55
- * A card written *into* a document: the input twin of `Card`, accepted by
56
- * `Document.insertCard`. Like `Card` but `body` also
57
- * takes a markdown `string` (imported to the content, so a markdown / LLM writer
58
- * needn't build the `Content` shape), and every field but `kind` is optional:
59
- * an absent field defaults (no payload items, an empty body). Write one inline
60
- * (`{ kind, body }`) or build it with `Document.makeCard`.
49
+ * A card written *into* a document, accepted by `Document.insertCard`. Like
50
+ * `Card`, but `body` also takes a markdown `string`, and every field but `kind`
51
+ * is optional (defaulting to no payload items and an empty body).
61
52
  */
62
53
  export interface CardInput {
63
54
  kind: string;
@@ -69,11 +60,10 @@ export interface CardInput {
69
60
  }
70
61
 
71
62
  /**
72
- * Canonical richtext content: the content model for a card body (and richtext
73
- * fields). One text sequence over a single coordinate space (Unicode scalar
74
- * values): `text` plus line attributes, anchored `marks`, and embedded
75
- * `islands`. Every edit is a splice; markdown is a projection, not the model.
76
- * Mirrors `quillmark_content::serial`'s canonical JSON encoding.
63
+ * Canonical richtext content: the model behind a card body and richtext fields.
64
+ * One text sequence over a single coordinate space (Unicode scalar values):
65
+ * `text` plus line attributes, anchored `marks`, and embedded `islands`. Every
66
+ * edit is a splice; markdown is a projection, not the model.
77
67
  */
78
68
  export interface Content {
79
69
  text: string;
@@ -82,19 +72,17 @@ export interface Content {
82
72
  islands: ContentIsland[];
83
73
  }
84
74
 
85
- /** One `\n`-separated segment of `Content.text`, in order. `kind` is an open set
86
- * (as on `ContentIsland` and `ContentMark`): a role this build does not know
87
- * round-trips with opaque `attrs` and renders as a paragraph, so a document
88
- * carrying a future block construct still opens. The open arm blocks discriminant
89
- * narrowing, so read `level`/`lang` behind a check of the arm you want. */
75
+ /** One `\n`-separated segment of `Content.text`, in order. `kind` is an open set:
76
+ * an unknown role round-trips with opaque `attrs` and renders as a paragraph.
77
+ * The open arm blocks discriminant narrowing, so read `level`/`lang` behind a
78
+ * check of the arm you want. */
90
79
  export type ContentLine = {
91
80
  containers: ContentContainer[];
92
81
  /** A within-block hard line break rather than a new block. Omitted (false) in the common case. */
93
82
  continues?: boolean;
94
83
  } & ContentLineKind;
95
84
 
96
- /** A line's block role, declared once for `ContentLine` and the `setKind` op:
97
- * a new role is one edit here, as for `ContentContainer`. */
85
+ /** A line's block role, shared by `ContentLine` and the `setKind` op. */
98
86
  export type ContentLineKind =
99
87
  | { kind: "para" }
100
88
  | { kind: "heading"; level: number }
@@ -112,13 +100,12 @@ export type ContentContainer =
112
100
  | { container: string; attrs: unknown };
113
101
 
114
102
  /** A mark over char range `[start, end)` into `Content.text`. The open `type`
115
- * arm blocks discriminant narrowing (as on `ContentIsland`), so read a
116
- * payload-carrying arm behind its guard: `isLinkMark` (`url`) / `isAnchorMark`
117
- * (`id`), from `@quillmark/wasm/runtime`; the bare arms carry no payload. An
118
- * `anchor`'s `id` is a caller-supplied, opaque handle, unique per `Content` and
119
- * invariant while the mark lives (positions rebase, the id never does); it has no
120
- * markdown projection and survives only through the edit lane. See DOCUMENT_STORAGE
121
- * § Anchor-id identity. */
103
+ * arm blocks discriminant narrowing, so read a payload-carrying arm behind its
104
+ * guard: `isLinkMark` (`url`) / `isAnchorMark` (`id`), from
105
+ * `@quillmark/wasm/runtime`. An `anchor`'s `id` is a caller-supplied opaque
106
+ * handle, unique per `Content` and invariant while the mark lives (positions
107
+ * rebase, the id never does); it has no markdown projection and survives only
108
+ * through the edit lane. */
122
109
  export type ContentMark = { start: number; end: number } & (
123
110
  | { type: "strong" | "emph" | "underline" | "strike" | "code" }
124
111
  | { type: "link"; url: string }
@@ -126,9 +113,8 @@ export type ContentMark = { start: number; end: number } & (
126
113
  | { type: string; attrs: unknown }
127
114
  );
128
115
 
129
- /** A cell in a `TableProps`: its plain `text` plus the `marks` over it. `marks`
130
- * rides the same wire shape as prose `ContentMark`, but each mark's `start`/`end`
131
- * are USV offsets into this cell's `text` (`0..text.length`), not into
116
+ /** A cell in a `TableProps`. `marks` rides the prose `ContentMark` shape, but
117
+ * each mark's `start`/`end` are USV offsets into this cell's `text`, not into
132
118
  * `Content.text`. */
133
119
  export interface TableCell {
134
120
  text: string;
@@ -150,17 +136,15 @@ export interface ImageProps {
150
136
  alt: string;
151
137
  }
152
138
 
153
- /** A structured object occupying one island slot in `Content.text`. `type` is an
154
- * open set: the engine pins `props` as `TableProps` for `table` and `ImageProps`
155
- * for `image`; an island of any other type round-trips with opaque `props`. Like
156
- * `ContentMark`, the open `type` arm means a discriminant check does not itself
157
- * narrow `props`: read `props` as the matching shape behind the `isTableIsland` /
158
- * `isImageIsland` guards (from `@quillmark/wasm/runtime`), which narrow it. */
159
- /** How faithfully the markdown projection can carry an island. Open like an
160
- * island `type`: a class this build does not know round-trips verbatim, and
161
- * reads as `unrepresentable`. */
139
+ /** How faithfully the markdown projection can carry an island. Open: an unknown
140
+ * class round-trips verbatim and reads as `unrepresentable`. */
162
141
  export type ContentLossClass = "lossless" | "degraded" | "unrepresentable" | (string & {});
163
142
 
143
+ /** A structured object occupying one island slot in `Content.text`. `type` is an
144
+ * open set: `props` is `TableProps` for `table` and `ImageProps` for `image`,
145
+ * and any other type round-trips with opaque `props`. The open arm blocks
146
+ * narrowing, so read `props` behind the `isTableIsland` / `isImageIsland`
147
+ * guards (from `@quillmark/wasm/runtime`). */
164
148
  export type ContentIsland = {
165
149
  id: string;
166
150
  loss: ContentLossClass;
@@ -178,14 +162,16 @@ export type ContentIsland = {
178
162
  * field: "intro" }` a card field.
179
163
  *
180
164
  * On the `Addr`-taking verbs a **bare string** is shorthand for `{ field: name }`
181
- * (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
182
- * rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
183
- * spelling), so no third navigation idiom re-fragments the surface.
165
+ * (`doc.storeField("qty", 3)`); a bare number is *not* an addr.
184
166
  *
185
167
  * `doc.pathFor(addr)` mints the address as its canonical `DocPath` string, the
186
168
  * anchor `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
187
- * take: a card path is kind-qualified, so building one by hand needs the card's
169
+ * take. A card path is kind-qualified, so a hand-built one needs the card's
188
170
  * `$kind`, and a wrong-kind path matches nothing silently.
171
+ *
172
+ * An `Addr` names a field, never a value inside one: every verb that takes one
173
+ * would then carry an element axis it cannot answer. The one read that reaches
174
+ * inside takes the path as its own argument, `reader.getContentAt(addr, path)`.
189
175
  */
190
176
  export interface Addr {
191
177
  card?: number;
@@ -193,10 +179,9 @@ export interface Addr {
193
179
  }
194
180
 
195
181
  /**
196
- * A card-only address: the axis the card-scoped verbs (`storeFields`,
197
- * `storeExt`, `getExt`, `commitFields`, …) take. An absent `card` targets the
198
- * main card. A present `field` throws: a card address takes only `card`, and a
199
- * would-be nested write is a bug the error names rather than silently ignores.
182
+ * A card-only address, taken by the card-scoped verbs (`storeFields`,
183
+ * `storeExt`, `getExt`, `commitFields`, …). An absent `card` targets the main
184
+ * card; a present `field` throws.
200
185
  */
201
186
  export interface CardAddr {
202
187
  card?: number;
@@ -204,8 +189,8 @@ export interface CardAddr {
204
189
 
205
190
  /**
206
191
  * A text-splice change set over the USV content (CodeMirror `ChangeSet`
207
- * semantics): plain, structured-clone-able data. Returned by `revise` and by
208
- * the `rebase` codec; map a stored position through it with `mapPos`.
192
+ * semantics), returned by `revise` and by the `rebase` codec. Map a stored
193
+ * position through it with `mapPos`.
209
194
  */
210
195
  export interface Delta {
211
196
  ops: ({ retain: number } | { insert: string } | { delete: number })[];
@@ -216,11 +201,9 @@ export type Assoc = "before" | "after";
216
201
 
217
202
  /**
218
203
  * A mark edit in final-text coordinates (post-delta, post-line-op). `add` /
219
- * `remove` carry the `ContentMark` vocabulary (`{ type, }`); `removeAnchor`
220
- * drops one identity anchor by id. An `add` of an `anchor` requires a non-empty
221
- * `id` not already live in the field: a collision or the empty id throws
222
- * (ids are caller-supplied and unique per `Content`; DOCUMENT_STORAGE
223
- * § Anchor-id identity).
204
+ * `remove` carry the `ContentMark` vocabulary; `removeAnchor` drops one identity
205
+ * anchor by id. An `add` of an `anchor` requires a non-empty `id` not already
206
+ * live in the field; a collision or the empty id throws.
224
207
  */
225
208
  export type MarkOp =
226
209
  | ({ op: "add" | "remove"; start: number; end: number } & (
@@ -232,12 +215,10 @@ export type MarkOp =
232
215
  | { op: "removeAnchor"; id: string };
233
216
 
234
217
  /**
235
- * A line/block edit. `split`/`join` splice `\n` in post-`delta`, post-`islandOps`
236
- * coordinates; `setKind`/`setContainers`/`setContinues` touch metadata.
237
- * `setContinues` sets/clears a line's within-block hard-break flag
238
- * (`ContentLine.continues`): the op-grained way to lower a Shift+Enter hard
239
- * break or a new code-fence interior line; `continues: true` on line 0 is
240
- * rejected (nothing precedes it to continue).
218
+ * A line/block edit. `split`/`join` splice `\n` in post-`delta`,
219
+ * post-`islandOps` coordinates; `setKind`/`setContainers`/`setContinues` touch
220
+ * metadata. `setContinues` sets or clears a line's within-block hard-break flag
221
+ * (`ContentLine.continues`); `continues: true` on line 0 is rejected.
241
222
  */
242
223
  export type LineOp =
243
224
  | { op: "split"; at: number }
@@ -248,34 +229,25 @@ export type LineOp =
248
229
 
249
230
  /**
250
231
  * An island edit: the only channel that reaches an island's payload, a table's
251
- * cells or an image's url.
252
- *
253
- * Both ops move one island entry and leave the field's text and marks alone, so
254
- * an island edit keeps every identity anchor in the field. That is why a table
255
- * edit lowers to `applyChange` rather than `overwrite`, which drops them all.
256
- *
257
- * `set` addresses an existing island by `id`; an `id` no island carries throws
258
- * rather than passing silently. `insert` places a new island's slot at `at`
259
- * together with its entry, so a slot never exists without an island behind it;
260
- * its `id` must be non-empty and unused. `at` is a position in the text the
261
- * `delta` and this bundle's earlier island ops left: each insert splices its
262
- * slot before the next op reads the text, so slots after `a` and `b` of `abc`
263
- * go in at 1 and 3. A stale frame misplaces slots and never throws.
232
+ * cells or an image's url. Both ops leave the field's text and marks alone, so
233
+ * an island edit keeps every identity anchor in the field.
264
234
  *
265
- * A `delta` insert string may not carry a slot, which would orphan. A producer
266
- * that computes one splice over the whole field text carries slots in it on any
267
- * paste of an island or undo of a deletion; that splice splits into the
268
- * slot-free `delta` plus one `insert` per slot.
235
+ * `set` addresses an existing island by `id`; an unknown `id` throws. `insert`
236
+ * places a new island's slot at `at` together with its entry, so a slot never
237
+ * exists without an island behind it; its `id` must be non-empty and unused.
238
+ * `at` is a position in the text the `delta` and this bundle's earlier island
239
+ * ops left, so slots after `a` and `b` of `abc` go in at 1 and 3. A stale frame
240
+ * misplaces slots and never throws. A `delta` insert string may not carry a
241
+ * slot, which would orphan: split such a splice into the slot-free `delta` plus
242
+ * one `insert` per slot.
269
243
  *
270
- * Deleting an island needs no op, and the drop is whole: a `delta` that removes
271
- * its slot drops the island from the store. Re-landing it is an `insert` of the
272
- * full island under its original id, and only the producer that deleted it
273
- * still holds that value. A pasted copy of a live island is new and mints fresh
274
- * (DOCUMENT_STORAGE § Island-id determinism). A block island's line demotes to
275
- * `para` when its slot goes, so re-landing one re-tags the line too.
244
+ * Deleting an island needs no op: a `delta` that removes its slot drops the
245
+ * island whole, and a block island's line demotes to `para`. Re-landing it is an
246
+ * `insert` of the full island under its original id; a pasted copy of a live
247
+ * island mints a fresh one.
276
248
  *
277
- * A `set` stores the `loss` it is given: nothing re-derives the class from the
278
- * new `props`, so a write that changes what markdown can carry must say so.
249
+ * A `set` stores the `loss` it is given; nothing re-derives the class from the
250
+ * new `props`.
279
251
  *
280
252
  * An island is *inline* (a slot inside a paragraph) unless its line says
281
253
  * otherwise. A **block** island is one bundle of all three channels, in the
@@ -288,13 +260,12 @@ export type IslandOp =
288
260
  | ({ op: "insert"; at: number } & ContentIsland);
289
261
 
290
262
  /**
291
- * A committed content edit bundle for `applyChange`: a text `delta` (default no
292
- * text change), then `islandOps`, then `lineOps`, then `markOps` (mark ranges
293
- * are in final-text coordinates: every earlier channel applied). Every field is
294
- * optional.
263
+ * A committed content edit bundle for `applyChange`, applied in order: a text
264
+ * `delta`, then `islandOps`, then `lineOps`, then `markOps` (mark ranges are in
265
+ * final-text coordinates). Every field is optional.
295
266
  *
296
- * Within each channel ops apply in sequence, each against the state the earlier
297
- * ones left: an island `insert`'s `at` counts earlier ops' slots, and `lineOps`
267
+ * Within each channel ops apply in sequence against the state the earlier ones
268
+ * left: an island `insert`'s `at` counts earlier ops' slots, and `lineOps`
298
269
  * positions and indices renumber through earlier `split`/`join`.
299
270
  */
300
271
  export interface ChangeBundle {
@@ -322,13 +293,9 @@ export type DocPathSeg =
322
293
 
323
294
 
324
295
  /**
325
- * Page dimensions in points (1 pt = 1/72 inch). Typst measures in Typst
326
- * points; pdfform measures in PDF points: the same unit.
327
- *
328
- * Report-only: the painter sizes the canvas itself based on
329
- * `PaintOptions`. `pageSize` is exposed for callers that need page
330
- * geometry up-front (e.g. to lay out a scrollable list of canvases
331
- * before any pixels are rendered).
296
+ * Page dimensions in points (1 pt = 1/72 inch). Report-only: the painter sizes
297
+ * the canvas itself from `PaintOptions`. `pageSize` is for callers that need
298
+ * page geometry up-front, e.g. to lay out a scrollable list of canvases.
332
299
  */
333
300
  export interface PageSize {
334
301
  widthPt: number;
@@ -336,25 +303,14 @@ export interface PageSize {
336
303
  }
337
304
 
338
305
  /**
339
- * Inputs to `LiveSession.paint`. Both fields are optional and default
340
- * to `1`.
341
- *
342
- * - `layoutScale` (layout-space pixels per point (Typst point / PDF
343
- * point) the same 1/72″ unit). For on-screen
344
- * canvases this is CSS pixels per pt; the page's layout-pixel size is
345
- * `widthPt * layoutScale × heightPt * layoutScale`. The painter
346
- * surfaces these dimensions as `layoutWidth` / `layoutHeight` so
347
- * consumers can drive `canvas.style.*` (or any layout system).
348
- * - `densityScale`: backing-store density multiplier. Fold
349
- * `window.devicePixelRatio`, in-app zoom, and `visualViewport.scale`
350
- * (pinch-zoom) into a single value here. Defaults to `1`, which
351
- * produces a non-retina backing store: pass `window.devicePixelRatio`
352
- * for crisp output on high-DPI displays.
306
+ * Inputs to `LiveSession.paint`. Both default to `1`, must be finite and `> 0`,
307
+ * and multiply to the effective rasterization scale.
353
308
  *
354
- * The effective rasterization scale is `layoutScale * densityScale`.
355
- * Both must be finite and `> 0`. For `OffscreenCanvasRenderingContext2D`
356
- * the two collapse to a single scalar; folding everything into
357
- * `densityScale` is the simplest convention.
309
+ * - `layoutScale`: layout-space pixels per point CSS pixels per pt for an
310
+ * on-screen canvas surfaced back as `layoutWidth` / `layoutHeight`.
311
+ * - `densityScale`: backing-store density. Fold `window.devicePixelRatio`,
312
+ * in-app zoom, and `visualViewport.scale` into this one value; the default
313
+ * `1` produces a non-retina backing store.
358
314
  */
359
315
  export interface PaintOptions {
360
316
  layoutScale?: number;
@@ -364,36 +320,21 @@ export interface PaintOptions {
364
320
  /**
365
321
  * Returned by `LiveSession.paint`.
366
322
  *
367
- * - `layoutWidth` / `layoutHeight`: layout-pixel dimensions of the
368
- * canvas's display box. For on-screen canvases this is CSS pixels:
369
- * set `canvas.style.width = layoutWidth + "px"` and
370
- * `canvas.style.height = layoutHeight + "px"` (or feed these into
371
- * your layout system). Independent of `densityScale`.
372
- * - `pixelWidth` / `pixelHeight`: integer backing-store pixel
373
- * dimensions the painter wrote to `canvas.width` / `canvas.height`.
374
- * Equal to `round(layoutWidth * densityScale)` ×
375
- * `round(layoutHeight * densityScale)` *unless* the requested backing
376
- * exceeded the painter's safe maximum (16384 px per side), in which
377
- * case `densityScale` was clamped to fit.
378
- * - `clamped`: `true` when that 16384-px clamp fired, so the page is
379
- * painted at fewer device pixels than requested and renders soft at the
380
- * same `canvas.style` size. Reads the clamp off the return value instead
381
- * of the `pixelWidth < round(layoutWidth * densityScale)` derivation.
382
- * - `effectiveDensityScale`, the `densityScale` actually applied: the
383
- * requested value unless `clamped`, then reduced proportionally.
384
- * `layoutScale * effectiveDensityScale` is the scale the backing store
385
- * was rasterized at.
323
+ * - `layoutWidth` / `layoutHeight`: the display box, in CSS pixels for an
324
+ * on-screen canvas, to drive `canvas.style.*`. Independent of `densityScale`.
325
+ * - `pixelWidth` / `pixelHeight`: the backing store the painter wrote to
326
+ * `canvas.width` / `canvas.height`, `round(layout * densityScale)` unless the
327
+ * request exceeded 16384 px per side and `densityScale` was clamped to fit.
328
+ * - `clamped`: `true` when that clamp fired, so the page renders soft at the
329
+ * same `canvas.style` size.
330
+ * - `effectiveDensityScale`: the `densityScale` actually applied.
386
331
  *
387
- * The painter owns `canvas.width` / `canvas.height`; consumers must not
388
- * write to them. The painter does **not** touch `canvas.style.*`;
389
- * consumers own layout. The write is a whole-backing-store `putImageData`,
390
- * which bypasses the 2D context transform, `globalAlpha`, and clip: give
391
- * each visible page its own `<canvas>`; you cannot composite two pages, a
392
- * sub-rect, or a context transform through `paint`.
393
- *
394
- * For `OffscreenCanvasRenderingContext2D` (Worker rasterization, no
395
- * DOM), `layoutWidth` / `layoutHeight` are informational: there's no
396
- * CSS layout box to apply them to.
332
+ * The painter owns `canvas.width` / `canvas.height` and never touches
333
+ * `canvas.style.*`. The write is a whole-backing-store `putImageData`, which
334
+ * bypasses the 2D context transform, `globalAlpha`, and clip: give each visible
335
+ * page its own `<canvas>`, since no compositing, sub-rect, or transform reaches
336
+ * through `paint`. Under `OffscreenCanvasRenderingContext2D` the layout
337
+ * dimensions are informational there is no CSS box to apply them to.
397
338
  */
398
339
  export interface PaintResult {
399
340
  layoutWidth: number;
@@ -407,14 +348,12 @@ export interface PaintResult {
407
348
 
408
349
 
409
350
  /** The commitment-ladder rung that produced a `ResolvedField.value`. */
410
- export type FieldSource = "authored" | "default" | "zero";
351
+ export type FieldSource = "authored" | "default" | "blank";
411
352
 
412
353
  /**
413
354
  * One resolved row: its `name`, the value the render projection would use, and
414
- * the `FieldSource` rung it came from. Rows are an ordered array: declaration
415
- * order is structural, not object-key order. The card body is a `body` sibling
416
- * on its card, never a row in `fields`. Diagnostics stay `Quill.validate`'s;
417
- * schema guidance (`example:`, labels) reads from `Quill.schema`.
355
+ * the `FieldSource` rung it came from. Rows are an ordered array, so declaration
356
+ * order is structural rather than object-key order.
418
357
  */
419
358
  export interface ResolvedField {
420
359
  name: string;
@@ -444,9 +383,8 @@ export interface ResolvedCard {
444
383
  }
445
384
 
446
385
  /**
447
- * The resolved-value view (`Quill.resolve`): the main card and every
448
- * composable card. Value and provenance only: completeness and errors stay
449
- * `Quill.validate`.
386
+ * The resolved-value view (`Quill.resolve`): the main card and every composable
387
+ * card. Value and provenance only; completeness stays `Quill.validate`'s.
450
388
  */
451
389
  export interface Resolved {
452
390
  main: ResolvedMain;
@@ -455,20 +393,21 @@ export interface Resolved {
455
393
 
456
394
 
457
395
 
458
- /** UI layout hints for a single field. Field display order is not a hint:
459
- * key order in the schema's `fields`/`properties` objects is declaration
460
- * order, the ordering contract. */
396
+ /** UI layout hints for a single field. Display order is not a hint: key order
397
+ * in the schema's `fields`/`properties` objects is the ordering contract. */
461
398
  export interface QuillFieldUi {
462
399
  title?: string;
463
400
  group?: string;
464
401
  compact?: boolean;
465
402
  multiline?: boolean;
403
+ /** Label for an `enum`'s blank option. Absent, the consumer supplies a
404
+ * conventional label of its own. */
405
+ blank_title?: string;
466
406
  }
467
407
 
468
408
  /** One entry in a card's `ui.groups` registry: a display-label override for the
469
- * group id (the map key). An empty object carries no override: the consumer
470
- * derives the label from the id (`memo_for` → "Memo For"), as it does a field
471
- * label from its key. */
409
+ * group id (the map key). An empty object carries no override, and the consumer
410
+ * derives the label from the id (`memo_for` → "Memo For"). */
472
411
  export interface QuillGroupUi {
473
412
  title?: string;
474
413
  }
@@ -476,16 +415,14 @@ export interface QuillGroupUi {
476
415
  /** UI layout hints for a card (main or named card kind). */
477
416
  export interface QuillCardUi {
478
417
  title?: string;
479
- /** The card's group registry: the ordered table of contents naming every
480
- * group a field's `ui.group` may reference. The map key is the group id, and
481
- * key order is declaration order: the display-order contract, the same one
482
- * `fields` key order carries. Absent when the card declares no groups (or
483
- * uses the deprecated implicit-group form). */
418
+ /** The groups a field's `ui.group` may reference, keyed by group id. Key
419
+ * order is the display-order contract, as with `fields`. Absent when the
420
+ * card declares no groups. */
484
421
  groups?: Record<string, QuillGroupUi>;
485
422
  }
486
423
 
487
- /** A block construct a body can hold. `paragraph` is absent on purpose: it is
488
- * the floor and cannot be declined. */
424
+ /** A block construct a body can hold. `paragraph` is the floor and cannot be
425
+ * declined, so it is absent. */
489
426
  export type QuillBlockConstruct =
490
427
  | "heading"
491
428
  | "rule"
@@ -501,40 +438,43 @@ export interface QuillCardBody {
501
438
  enabled?: boolean;
502
439
  /** Example body content embedded verbatim in the blueprint body region. Fallback is "Write <card> body here." */
503
440
  example?: string;
504
- /** Block constructs this quill's plate does not typeset in this body.
505
- *
506
- * Absent or empty means it declines nothing, which is the default. An
507
- * editor reads this to decline a gesture before the author makes it; a body
508
- * that holds one anyway draws a non-fatal `plate::unsupported_construct`
509
- * warning carrying the construct and a count. It is the quill's claim about
510
- * its own plate, and nothing verifies it: a construct absent from this list
511
- * is not a promise that the plate typesets it. */
441
+ /** Block constructs this quill's plate does not typeset in this body;
442
+ * absent or empty declines nothing. A body that holds one anyway draws a
443
+ * non-fatal `plate::unsupported_construct` warning. Nothing verifies the
444
+ * claim: absence from this list is not a promise the plate typesets it. */
512
445
  unsupported?: QuillBlockConstruct[];
513
446
  }
514
447
 
515
448
  /** Schema entry for a single field declared in a quill's `Quill.yaml`.
516
449
  *
517
- * A field's *cell* is determined by `default`: a field with a `default`
518
- * is **Endorsed** (the rendered value is shippable as-is), while a field
519
- * without a `default` is **Unendorsed** (the blueprint carries a
520
- * `!must_fill` marker; a marker left in the document yields the non-fatal
521
- * `validation::must_fill` warning from validate, and the render path
522
- * zero-fills the field). There is no separate `required` axis.
450
+ * Two independent axes, and no separate `required` one. `default` and
451
+ * `example` say what the cell holds; `must_fill` says whether a human must
452
+ * author it, deriving from `default`'s absence when left unset. An obliged
453
+ * field carries a `!must_fill` marker in the blueprint and warns
454
+ * `validation::must_fill` while the document leaves it unauthored. Neither
455
+ * axis gates render: an absent field blank-fills.
523
456
  */
524
457
  export interface QuillFieldSchema {
525
458
  type: "string" | "number" | "integer" | "boolean" | "array" | "object" | "date" | "datetime" | "richtext" | "plaintext" | "enum";
526
459
  description?: string;
527
460
  default?: unknown;
528
461
  example?: unknown;
529
- /** Required on `type: "enum"`, and valid nowhere else: the closed set of
530
- * allowed string values. */
462
+ /** The closed set of allowed values. Required on `type: "enum"`, and valid
463
+ * nowhere else. */
531
464
  values?: string[];
465
+ /** Per-member field sets on a card-level `type: "enum"` field, keyed by
466
+ * member: the fields that exist only where the discriminant holds that
467
+ * member. Declaring it makes the field rest as a container,
468
+ * `{value: <member>, …that member's fields}`, rather than a bare string. */
469
+ variants?: Record<string, Record<string, QuillFieldSchema>>;
470
+ /** Whether a human must author the field. Absent, it derives from
471
+ * `default`: a defaulted field is unobliged, a defaultless one obliged. */
472
+ must_fill?: boolean;
532
473
  ui?: QuillFieldUi;
533
474
  properties?: Record<string, QuillFieldSchema>;
534
475
  items?: QuillFieldSchema;
535
- /** Present (and `true`) on a `richtext` or `plaintext` field declared
536
- * `inline`: the single-paragraph, container-free, island-free constraint.
537
- * Core serializes `inline: true` into the schema JSON; absent otherwise. */
476
+ /** `true` on a `richtext` or `plaintext` field declared `inline`: the
477
+ * single-paragraph, container-free, island-free constraint. */
538
478
  inline?: boolean;
539
479
  }
540
480
 
@@ -547,10 +487,8 @@ export interface QuillCardSchema {
547
487
  }
548
488
 
549
489
  /**
550
- * Document schema returned by `Quill.schema`. Includes optional `ui` keys.
551
- *
552
- * Describes only the user-fillable fields. The quill reference
553
- * (constructed as `${metadata.name}@${metadata.version}`) and card-kind
490
+ * Document schema returned by `Quill.schema`: the user-fillable fields only.
491
+ * The quill reference (`${metadata.name}@${metadata.version}`) and card-kind
554
492
  * discriminators are document-level metadata, not schema fields.
555
493
  */
556
494
  export interface QuillSchema {
@@ -560,10 +498,9 @@ export interface QuillSchema {
560
498
  }
561
499
 
562
500
  /**
563
- * Identity snapshot mirroring the `quill:` section of `Quill.yaml`.
564
- * The schema lives on `Quill.schema`; the backend's output formats are a
565
- * resolved-backend capability read from the engine (`Quillmark.supportedFormats`),
566
- * not part of this pure-config snapshot.
501
+ * Identity snapshot mirroring the `quill:` section of `Quill.yaml`. The schema
502
+ * lives on `Quill.schema`; output formats are a resolved-backend capability read
503
+ * from `Quillmark.supportedFormats`, not part of this config snapshot.
567
504
  */
568
505
  export interface QuillMetadata {
569
506
  name: string;
@@ -575,74 +512,56 @@ export interface QuillMetadata {
575
512
 
576
513
 
577
514
  /**
578
- * A rendered field region: the quill schema field address plus its geometry on
579
- * the page. Emitted for schema-bound fields: span-tracked content (richtext
580
- * bodies, `richtext[]` elements, card content fields, direct scalar
581
- * references) and form-field widgets (pdfform AcroForm, Typst `form-field`).
582
- * Consumers use it to scroll to / highlight the focused field; for the
583
- * reverse click direction use `LiveSession.fieldAt`, which answers over any
584
- * placement. Geometry only: the raster is already complete, so a region is
585
- * never a compositing input.
586
- *
587
- * `field` is **not** unique: content fields surface one region **per segment**
588
- * (paragraph, heading, whole code fence) and per page each touches, a scalar
589
- * referenced at several plate sites surfaces each site, and tracked content
590
- * plus a `field:`-bound widget yields both. Group by `field`: every entry
591
- * routes to that field. The whole-field highlight is the **union of a page\'s
592
- * `span`-bearing segment rects**, so inter-paragraph whitespace stays
593
- * uncovered; `LiveSession.fieldBoxes(field)` owns that union so
594
- * consumers need not derive it. Later placements of one content value are not
595
- * enumerated; `fieldAt` / `positionAt` still resolve clicks on them.
515
+ * A resolved point → content position: the field a click landed in and the USV
516
+ * offset into its `Content`. The `LiveSession.positionAt` result, inverse of
517
+ * `locate`.
596
518
  */
597
- export interface FieldRegion {
519
+ export interface ContentHit {
598
520
  /**
599
- * Canonical `DocPath` field address (e.g. `\"signature_block\"`,
600
- * `\"cards.indorsement[1].from\"`, `\"main.body\"`): the same grammar
601
- * `parseDocPath` reads and `Diagnostic.path` carries. The session resolves
602
- * the backend\'s plate-space per-kind ordinal to this absolute-index form,
603
- * so one parser routes every address. Feed it back to `fieldBoxes` /
604
- * `locate`; hit-test the click direction with `fieldAt` / `positionAt`.
521
+ * Canonical `DocPath` field address (same grammar as `FieldRegion.field`).
605
522
  */
606
523
  field: string;
607
524
  /**
608
- * 0-based page index.
609
- */
610
- page: number;
611
- /**
612
- * `[x0, y0, x1, y1]` in PDF points (1/72″), bottom-left origin.
525
+ * USV offset into the field\'s `Content`.
613
526
  */
614
- rect: [number, number, number, number];
527
+ pos: number;
615
528
  /**
616
- * The content slice this box covers: USV `[start, end)` into the field\'s
617
- * `Content` for content ink (one segment), `undefined` for a scalar
618
- * reference site or widget. Consumers key segment highlights on it;
619
- * `fieldBoxes(field)` unions same-page segments for the whole-field box.
529
+ * `undefined` when the backend does not report granularity.
620
530
  */
621
- span?: [number, number];
531
+ granularity?: HitGranularity;
622
532
  }
623
533
 
624
534
  /**
625
- * A resolved point content position: the field a click landed in and the USV
626
- * offset into its `Content`. The `LiveSession.positionAt` result, paired with
627
- * `locate` (content position → caret rect). `pos` is cluster-exact and degrades
628
- * to the containing segment\'s start on origin-less ink; `granularity` reports
629
- * which happened so a caret UI need not guess.
535
+ * A schema field address plus its geometry on the page, for scrolling to or
536
+ * highlighting a field; use `LiveSession.fieldAt` for the click direction.
537
+ *
538
+ * `field` is **not** unique: content fields surface one region per segment
539
+ * (paragraph, heading, whole code fence) and per page each touches, a scalar
540
+ * referenced at several plate sites surfaces each site, and tracked content
541
+ * plus a `field:`-bound widget yields both. Group by `field`. The whole-field
542
+ * highlight is the union of a page\'s `span`-bearing rects, so inter-paragraph
543
+ * whitespace stays uncovered; `LiveSession.fieldBoxes(field)` owns that union.
630
544
  */
631
- export interface ContentHit {
545
+ export interface FieldRegion {
632
546
  /**
633
- * Canonical `DocPath` field address (same grammar as `FieldRegion.field`).
547
+ * Canonical `DocPath` field address (e.g. `\"cards.indorsement[1].from\"`):
548
+ * the grammar `parseDocPath` reads and `Diagnostic.path` carries. Feed it
549
+ * back to `fieldBoxes` / `locate`.
634
550
  */
635
551
  field: string;
636
552
  /**
637
- * USV offset into the field\'s `Content`.
553
+ * 0-based page index.
638
554
  */
639
- pos: number;
555
+ page: number;
640
556
  /**
641
- * Whether `pos` is cluster-exact or floored to the segment start
642
- * (`HitGranularity`). `undefined` when the backend does not report it.
643
- * Additive-optional.
557
+ * `[x0, y0, x1, y1]` in PDF points (1/72″), bottom-left origin.
644
558
  */
645
- granularity?: HitGranularity;
559
+ rect: [number, number, number, number];
560
+ /**
561
+ * The slice this box covers: USV `[start, end)` into the field\'s `Content`
562
+ * for one content segment, `undefined` for a scalar site or widget.
563
+ */
564
+ span?: [number, number];
646
565
  }
647
566
 
648
567
  /**
@@ -654,31 +573,25 @@ export interface Diagnostic {
654
573
  message: string;
655
574
  location?: Location;
656
575
  /**
657
- * Document-model path anchor (e.g. `\"cards.indorsement[0].signature_block\"`).
658
- *
659
- * Set on schema validation diagnostics; `undefined` otherwise. See the
660
- * Rust `quillmark_core::error` module docs for the path grammar.
576
+ * Document-model path anchor (e.g. `\"cards.indorsement[0].signature_block\"`),
577
+ * set on schema validation diagnostics and `undefined` otherwise.
661
578
  */
662
579
  path?: string;
663
580
  hint?: string;
664
581
  /**
665
- * The facts `message` interpolates, keyed by name. With `code`, the
666
- * substitution unit needed to word this diagnostic in another language;
667
- * `prose/canon/ERROR.md` § \"Diagnostic args\" tabulates the keys per code.
582
+ * The facts `message` interpolates, keyed by name. With `code`, enough to
583
+ * word this diagnostic in another language.
668
584
  *
669
- * Declared optional explicitly because `tsify` does not read
670
- * `skip_serializing_if`: without this, a field the runtime omits is
671
- * declared required. `sourceChain` carries that mismatch.
585
+ * Declared optional explicitly: `tsify` does not read
586
+ * `skip_serializing_if`, so an omitted field would be declared required.
672
587
  */
673
588
  args?: Record<string, unknown>;
674
589
  sourceChain?: string[];
675
590
  }
676
591
 
677
592
  /**
678
- * How precisely a `ContentHit.pos` resolved: the marker a caret UI reads to
679
- * decide whether to trust the offset. Never sub-cluster: `cluster` is the
680
- * finest this API offers, `segment` the floor it degrades to on origin-less
681
- * ink.
593
+ * How precisely a `ContentHit.pos` resolved. Never sub-cluster: `cluster` is
594
+ * the finest this API offers, `segment` the floor it degrades to.
682
595
  */
683
596
  export type HitGranularity = "cluster" | "segment";
684
597
 
@@ -688,43 +601,30 @@ export type HitGranularity = "cluster" | "segment";
688
601
  export interface RenderOptions {
689
602
  format?: OutputFormat;
690
603
  /**
691
- * Pixels per inch for raster output formats (PNG).
692
- * Ignored for vector/document formats (PDF, SVG).
693
- * Defaults to 144.0 (2x at 72pt/inch) when omitted.
604
+ * Pixels per inch for PNG; ignored for PDF and SVG. Defaults to 144.0.
694
605
  */
695
606
  ppi?: number;
696
607
  /**
697
- * Optional 0-based page indices to render (e.g., `[0, 2]` for the
698
- * first and third pages). `undefined` renders all pages. Any index
699
- * `>= pageCount` throws with the `typst::page_index_out_of_bounds`
700
- * code: read `LiveSession.pageCount` first if validation is needed.
701
- * **Not supported for PDF output**: passing `pages` with
702
- * `format: \"pdf\"` throws with the
703
- * `typst::pdf_page_selection_not_supported` code.
608
+ * 0-based page indices to render; `undefined` renders all pages. An index
609
+ * `>= pageCount` throws `typst::page_index_out_of_bounds`. Not supported
610
+ * for PDF output: throws `typst::pdf_page_selection_not_supported`.
704
611
  */
705
612
  pages?: number[];
706
613
  /**
707
- * Override for the PDF `/Info` `/Producer` metadata string. Omit to use
708
- * the default (`Quillmark <version>`). Applies to PDF output only.
614
+ * PDF `/Info` `/Producer` override; defaults to `Quillmark <version>`.
709
615
  */
710
616
  producer?: string;
711
617
  /**
712
- * Populate `RenderResult.regions` with the schema-field geometry sidecar
713
- * (the same entries `LiveSession.regions()` serves), for consumers
714
- * without a live session; e.g. overlays over a one-shot SVG export.
715
- * Defaults to `false`: exports pay no introspection cost. The sidecar
716
- * always describes the whole document: page indices are document-space
717
- * even when `pages` selects a subset.
618
+ * Populate `RenderResult.regions` with schema-field geometry, for consumers
619
+ * without a live session. Defaults to `false`. Page indices are
620
+ * document-space even when `pages` selects a subset.
718
621
  */
719
622
  regions?: boolean;
720
623
  }
721
624
 
722
625
  /**
723
- * Output formats supported by backends.
724
- *
725
- * Gated behind the engine surface (`typst` or `pdfform`) so tsify omits
726
- * its `.d.ts` interface from the core bundle (`pkg/core/wasm.d.ts`), which
727
- * has no rendering surface.
626
+ * Output formats supported by backends. Gated behind the engine surface so
627
+ * tsify omits it from the core bundle, which has no rendering surface.
728
628
  */
729
629
  export type OutputFormat = "pdf" | "svg" | "png";
730
630
 
@@ -734,9 +634,7 @@ export type OutputFormat = "pdf" | "svg" | "png";
734
634
  export interface Artifact {
735
635
  format: OutputFormat;
736
636
  /**
737
- * Serialized via `serde_bytes` so `serde_wasm_bindgen` emits a real
738
- * `Uint8Array` at the boundary instead of a `number[]`. Without this
739
- * annotation, the declared `Uint8Array` type would silently lie.
637
+ * `serde_bytes` so the boundary emits a real `Uint8Array`, not `number[]`.
740
638
  */
741
639
  bytes: Uint8Array;
742
640
  mimeType: string;
@@ -751,19 +649,12 @@ export interface RenderResult {
751
649
  outputFormat: OutputFormat;
752
650
  renderTimeMs: number;
753
651
  /**
754
- * Schema-field geometry sidecar: populated only when
755
- * `RenderOptions.regions` requested it; empty otherwise. The same entries
756
- * `LiveSession.regions()` serves, for consumers without a live session.
757
- * Page indices are document-space even under a `pages` subset render.
652
+ * Schema-field geometry, populated only when `RenderOptions.regions` asked
653
+ * for it. Page indices are document-space even under a `pages` subset.
758
654
  */
759
655
  regions: FieldRegion[];
760
656
  }
761
657
 
762
- /**
763
- * Severity levels for diagnostics
764
- */
765
- export type Severity = "error" | "warning";
766
-
767
658
  /**
768
659
  * Source location for errors and warnings
769
660
  */
@@ -774,16 +665,17 @@ export interface Location {
774
665
  }
775
666
 
776
667
  /**
777
- * What a committed `LiveSession.update` changed. `dirtyPages` lists the pages
778
- * whose rendered content differs from the previous compile, including pages
779
- * the edit added; removed pages are implied by `pageCount`. A preview
780
- * repaints `dirty ∩ visible` and nothing else.
668
+ * What a committed `LiveSession.update` changed. `dirtyPages` lists pages whose
669
+ * content differs from the previous compile, including pages the edit added;
670
+ * removed pages are implied by `pageCount`.
781
671
  */
782
672
  export interface ChangeSet {
783
673
  pageCount: number;
784
674
  dirtyPages: number[];
785
675
  }
786
676
 
677
+ export type Severity = "error" | "warning";
678
+
787
679
 
788
680
  /**
789
681
  * Typed in-memory Quillmark document.
@@ -792,86 +684,69 @@ export class Document {
792
684
  free(): void;
793
685
  [Symbol.dispose](): void;
794
686
  /**
795
- * **Apply** a committed content edit `bundle`
796
- * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
797
- * splice: text delta first, then island ops, then line ops, then mark ops
798
- * (mark ranges in final-text coordinates), each all-or-nothing. An absent
799
- * `addr.field` targets the body, an absent `addr.card` the main card.
800
- *
801
- * The island channel keeps a table or image edit on the op path: it moves
802
- * the island alone, so the anchors elsewhere in the field survive an edit
687
+ * **Apply** a committed content edit `bundle` at `addr`, the editor splice:
688
+ * text delta first, then island ops, then line ops, then mark ops (mark
689
+ * ranges in final-text coordinates), all-or-nothing. An absent `addr.field`
690
+ * targets the body, an absent `addr.card` the main card. The island channel
691
+ * moves an island alone, so anchors elsewhere in the field survive an edit
803
692
  * `overwrite` would clear.
804
693
  *
805
694
  * Throws on an out-of-range card, a field that is not richtext, a malformed
806
- * bundle, or an op that applies out of bounds (the value is unchanged on a
807
- * failed apply).
695
+ * bundle, or an op that applies out of bounds; the value is unchanged on a
696
+ * failed apply.
808
697
  */
809
698
  applyChange(addr: Addr | string, bundle: ChangeBundle): void;
810
699
  /**
811
- * Authoring-ergonomics header introducing a blueprint to an LLM/MCP
812
- * consumer for the given `quillName`. Re-exposes core's canonical text for
813
- * JS consumers; any surface that draws from the same core source stays
814
- * uniform.
700
+ * Authoring-ergonomics header introducing a blueprint to an LLM/MCP consumer
701
+ * for the given `quillName`, re-exposed from core.
815
702
  */
816
703
  static blueprintInstruction(quill_name: string): string;
817
704
  /**
818
- * The **body** markdown projection (the main body, or a composable card's
819
- * body (`{ card }`)) the on-demand, lossy export (content-only marks do not
820
- * survive markdown). A body's type is a format fact, not a schema fact, so
821
- * this read stays quill-free; a body is never absent.
705
+ * The **body** markdown projection: an on-demand, lossy export (content-only
706
+ * marks do not survive markdown). A body's type is a format fact, not a
707
+ * schema fact, so this read stays quill-free, and a body is never absent.
822
708
  *
823
- * `addr` is an optional **card address** (`{ card }`, absent = main). A
824
- * present `field` throws: a field's markdown is read through the
825
- * schema-plane `quill.reader(doc).get(field)`, which interprets by declared
826
- * type. An out-of-range `addr.card` throws.
709
+ * `addr` is an optional card address (absent = main). A present `field`
710
+ * throws: read a field's markdown through `quill.reader(doc).get(field)`,
711
+ * which interprets by declared type. An out-of-range `addr.card` throws.
827
712
  */
828
713
  bodyMarkdown(addr?: CardAddr): string;
829
714
  /**
830
- * A single composable card by index: the whole `Card`, the card-indexed
831
- * twin of the [`main`](Self::main) getter, so reading one card need not
832
- * materialize every card via [`cards`](Self::cards). An out-of-range
833
- * `index` throws `edit::index_out_of_range`, matching the card write
834
- * verbs.
715
+ * A single composable card by index, so reading one need not materialize
716
+ * every card via [`cards`](Self::cards). An out-of-range `index` throws
717
+ * `edit::index_out_of_range`.
835
718
  */
836
719
  card(index: number): Card;
837
720
  /**
838
- * The composable card's own path, `cards.<kind>[index]`: the whole-card
839
- * root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
840
- * card rather than one of its fields. Total on the index axis for the same
841
- * reason, out of range renders `cards[index]`.
721
+ * The composable card's own path, `cards.<kind>[index]`: the root
722
+ * [`pathFor`](Self::path_for) extends, for anchoring the card rather than
723
+ * one of its fields. Total on the index axis; out of range renders
724
+ * `cards[index]`.
842
725
  */
843
726
  cardPath(index: number): string;
844
727
  clone(): Document;
845
728
  /**
846
- * Storage version this build writes via [`toJson`](Document::to_json).
847
- * Tracks the `Document` model version (not the running crate version):
848
- * the tag advances only when the wire format changes, not on every release.
729
+ * Storage version this build writes via [`toJson`](Document::to_json). The
730
+ * tag advances only when the wire format changes, not on every release.
849
731
  */
850
732
  static currentStorageVersion(): string;
851
733
  /**
852
- * Structural equality (parse-time `warnings` excluded). Use to debounce
853
- * upstream prop updates instead of re-parsing on every keystroke.
734
+ * Structural equality, excluding parse-time `warnings`.
854
735
  */
855
736
  equals(other: Document): boolean;
856
737
  /**
857
- * Render a Diagnostic as the canonical pretty-printed text (core's
858
- * `Diagnostic::fmt_pretty`). Single source of truth so a Diagnostic looks
859
- * identical no matter which consumer surfaces it.
738
+ * Render a Diagnostic as the canonical pretty-printed text, so it looks
739
+ * identical whichever consumer surfaces it.
860
740
  */
861
741
  static formatDiagnostic(diag: Diagnostic): string;
862
742
  /**
863
- * Authoring-format rules for the card-yaml markdown surface. The canonical
864
- * text is core's (`quillmark_core::document::FORMAT_RULES`), re-exposed
865
- * here for JS consumers so it matches any other surface that draws from the
866
- * same source. Read once at startup and cache; the value never changes
867
- * between calls.
743
+ * Authoring-format rules for the card-yaml markdown surface, re-exposed from
744
+ * core. Constant across calls; read once and cache.
868
745
  */
869
746
  static formatRules(): string;
870
747
  /**
871
- * Reconstruct a `Document` from a versioned storage DTO string produced
872
- * by [`toJson`](Document::to_json). Unknown `schema` tags are rejected.
873
- * The result carries no parse-time warnings (`.warnings` is always empty).
874
- *
748
+ * Reconstruct a `Document` from a versioned storage DTO string produced by
749
+ * [`toJson`](Document::to_json). The result carries no parse-time warnings.
875
750
  * Throws if `json` is not a valid storage DTO (malformed JSON, unknown
876
751
  * `schema`, missing fields, or unparseable quill reference).
877
752
  */
@@ -882,81 +757,66 @@ export class Document {
882
757
  static fromMarkdown(markdown: string): Document;
883
758
  /**
884
759
  * The whole `$ext` map at `addr` (a card address, absent `card` = main), or
885
- * `undefined` when the card carries none. The fine-grained `$ext` read:
886
- * your own state without serializing the whole card. Throws on a present
887
- * `field` (a card address takes only `card`) or an out-of-range card.
760
+ * `undefined` when the card carries none: the `$ext` read that avoids
761
+ * serializing the whole card. Throws on a present `field` or an
762
+ * out-of-range card.
888
763
  */
889
764
  getExt(addr?: CardAddr): Record<string, unknown> | undefined;
890
765
  /**
891
766
  * The value stored under `$ext[ns]` at `addr` (a card address, absent `card`
892
- * = main), or `undefined`. The namespace-scoped `$ext` read: your own slot
893
- * without a whole-card serialize, and non-destructive (unlike
894
- * `removeExtNamespace`). Throws on a present `field` or an out-of-range card.
767
+ * = main), or `undefined`. Throws on a present `field` or an out-of-range
768
+ * card.
895
769
  */
896
770
  getExtNamespace(addr: CardAddr, ns: string): unknown;
897
771
  /**
898
- * Read the **verbatim stored value** at `addr`: the raw payload value of a
899
- * field, or the **body content** when `addr.field` is absent. A bare
900
- * string is `Addr` shorthand for `{ field }`. Reads are total over the field
901
- * axis: an absent field is `undefined`; only an out-of-range `addr.card`
902
- * throws `edit::index_out_of_range`. Needs no schema, so it lives on
903
- * `Document`: the read echo of the verbatim `store*` write, distinct from
904
- * the interpreted schema-plane [`reader.get`](Self::reader_get). For the
905
- * markdown projection use [`bodyMarkdown`](Self::get_markdown) (body) or
906
- * `reader.get` (a field's declared type).
772
+ * Read the **verbatim stored value** at `addr`: a field's raw payload value,
773
+ * or the body content when `addr.field` is absent. A bare string is `Addr`
774
+ * shorthand for `{ field }`. Needs no schema: the read echo of the verbatim
775
+ * `store*` write, distinct from the interpreted
776
+ * [`reader.get`](Self::reader_get). Reads are total over the field axis — an
777
+ * absent field is `undefined` and only an out-of-range `addr.card` throws
778
+ * `edit::index_out_of_range`.
907
779
  *
908
- * **A content field at rest has one stored form per codec**: a `richtext`
909
- * field holds the canonical content object, a `plaintext` field its literal
910
- * string. A document that came through the bound door (`quill.parse` /
911
- * `quill.conform`) is at rest, so this read no longer depends on which lane
912
- * built it. A document that came through the transport door
913
- * (`Document.fromMarkdown`, a legacy stored row) may rest as authored until
914
- * it is conformed, and this read reports what is there. For the `Content`
915
- * either way, use the schema-plane `reader.getContent`, which decodes
916
- * through the codec the field's declared type names.
780
+ * A content field at rest has one stored form per codec: a `richtext` field
781
+ * holds the canonical content object, a `plaintext` field its literal
782
+ * string. A document from the bound door (`quill.parse` / `quill.conform`)
783
+ * is at rest; one from the transport door may rest as authored until it is
784
+ * conformed, and this read reports what is there. For the `Content` either
785
+ * way use `reader.getContent`.
917
786
  */
918
787
  getStored(addr: Addr | string): unknown;
919
788
  /**
920
- * Insert a card, the single insertion verb: `at` absent appends, a number
921
- * inserts at that index (must be in `0..=cards.length`). Accepts a
922
- * `CardInput`: a card read back (`cards` / `removeCard` / `quill.seedCard`),
923
- * a [`makeCard`](Document::make_card) result, or a bare `{ kind, body }`
924
- * (every returned `Card` is a valid `CardInput`). Throws if `card.kind` is
925
- * not a valid kind name, or if `at` is out of range.
789
+ * Insert a card: `at` absent appends, a number inserts at that index (in
790
+ * `0..=cards.length`). Accepts any `CardInput`, including a card read back
791
+ * out of a document. Throws if `card.kind` is not a valid kind name, or if
792
+ * `at` is out of range.
926
793
  */
927
794
  insertCard(card: CardInput, at?: number): void;
928
795
  /**
929
796
  * Whether the field at `addr` is marked `!must_fill`. A bare string is `Addr`
930
- * shorthand for `{ field }`. `false` for an absent field (truthful: it isn't
931
- * marked) and for a body address (a body is never a fill). Only an
932
- * out-of-range `addr.card` throws.
797
+ * shorthand for `{ field }`. `false` for an absent field and for a body
798
+ * address; only an out-of-range `addr.card` throws.
933
799
  */
934
800
  isFill(addr: Addr | string): boolean;
935
801
  /**
936
- * Replace this document's contents **in place** from a versioned storage
937
- * DTO string: the mutating twin of the static
938
- * [`fromJson`](Document::from_json) constructor. Parse-time `warnings` are
939
- * cleared. Throws (leaving the document unchanged) on an invalid DTO.
802
+ * Replace this document's contents **in place** from a versioned storage DTO
803
+ * string: the mutating twin of [`fromJson`](Document::from_json). Parse-time
804
+ * `warnings` are cleared. Throws on an invalid DTO, leaving the document
805
+ * unchanged.
940
806
  *
941
807
  * The cross-WASM-memory `Document` bridge: mutate a document on a
942
- * backend-memory clone, then write the mutated state back into the caller's
943
- * canonical document with this, the one way to update a live handle across
944
- * the linear-memory seam without the caller re-binding its variable.
808
+ * backend-memory clone, then write the state back into the caller's
809
+ * canonical document, without the caller re-binding its variable.
945
810
  */
946
811
  loadJson(json: string): void;
947
812
  /**
948
813
  * Build a fresh `Card` from a kind and a flat field map: the ergonomic
949
- * constructor for `insertCard`. `fields` is an optional
950
- * `Record<string, unknown>` (each entry becomes a card field, in
951
- * insertion order); `body` defaults to `""`.
814
+ * constructor for `insertCard`, which also takes any `Card` object
815
+ * directly. Each `fields` entry becomes a card field in insertion order;
816
+ * `body` defaults to `""`.
952
817
  *
953
- * Sugar, not a required step: `insertCard` takes any `Card` object, and
954
- * `removeCard` returns one, so a card round-trips without passing through
955
- * here.
956
- *
957
- * Checks only what a detached card can decide alone: field-name grammar
958
- * and value depth. Kind validity is positional (`main` is right for the
959
- * root, reserved for a composable card) so `insertCard` is its gate, and
818
+ * Checks only what a detached card can decide alone: field-name grammar and
819
+ * value depth. Kind validity is positional, so `insertCard` is its gate and
960
820
  * any kind string is accepted here.
961
821
  */
962
822
  static makeCard(kind: string, fields?: Record<string, unknown>, body?: string): Card;
@@ -965,66 +825,51 @@ export class Document {
965
825
  */
966
826
  moveCard(from: number, to: number): void;
967
827
  /**
968
- * `new Document(quillRef)`, a blank document: a main card carrying only
969
- * `$quill`, an empty body, and no composable cards. The programmatic
970
- * blank canvas: absent fields resolve at render time (`default`, else
971
- * type-empty zero), so nothing the caller did not set reaches the
972
- * output. For an example-filled starter use `Quill.seedDocument()`.
973
- * Throws on an invalid quill reference. Mirrors Python `Document(quill_ref)`.
828
+ * A blank document: a main card carrying only `$quill`, an empty body, and
829
+ * no composable cards. Absent fields resolve at render time (`default`, else
830
+ * the field's blank), so nothing the caller did not set reaches the output.
831
+ * For an example-filled starter use `Quill.seedDocument()`. Throws on an
832
+ * invalid quill reference.
974
833
  */
975
834
  constructor(quill_ref: string);
976
835
  /**
977
- * **Overwrite** the content value at `addr`: **value semantics**, content
978
- * only. Stores exactly `rt` (a canonical `Content` content object); the
979
- * identity anchors of any previous value are gone. The bottom rung of the
980
- * content lane's ladder by anchor fate: `overwrite` destroys,
981
- * [`revise`](Document::revise) rebases,
982
- * [`applyChange`](Document::apply_change) preserves. An absent `addr.field`
983
- * targets the body, an absent `addr.card` the main card. Cold-importing
984
- * markdown is spelled `overwrite(addr, importMarkdown(md))` at the call
985
- * site, where the anchor loss is visible.
836
+ * **Overwrite** the content value at `addr` with exactly `rt`: value
837
+ * semantics, so the identity anchors of any previous value are gone. By
838
+ * anchor fate `overwrite` destroys, [`revise`](Document::revise) rebases,
839
+ * and [`applyChange`](Document::apply_change) preserves. An absent
840
+ * `addr.field` targets the body, an absent `addr.card` the main card.
986
841
  *
987
842
  * Throws on an out-of-range card, a malformed field name, or an `rt` that is
988
843
  * not a canonical content object.
989
844
  */
990
845
  overwrite(addr: Addr | string, rt: Content): void;
991
846
  /**
992
- * `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
993
- * carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
994
- * `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
995
- * `Addr` mints one without restating the kind lookup, the `Addr` defaults
996
- * or the range guard.
847
+ * `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path` carries:
848
+ * `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
849
+ * `pathFor({card: 2})` `cards.<kind>[2].body`.
997
850
  *
998
- * The kind is the card's stored `$kind` verbatim, the quill-free rule the
999
- * addressed mutators anchor with and the geometry translation uses, not
1000
- * `validate`'s declared-kind filter: a `Document` holds a `$quill`
1001
- * reference and no schema. That is the one edge where this path and a
1002
- * `validate` diagnostic path differ for the same card.
851
+ * The kind is the card's stored `$kind` verbatim, not `validate`'s
852
+ * declared-kind filter, since a `Document` holds a `$quill` reference and no
853
+ * schema. That is the one edge where this path and a `validate` diagnostic
854
+ * path differ for the same card.
1003
855
  *
1004
- * **Total on the index axis**, unlike the `Addr` reads (`getStored`,
1005
- * `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
1006
- * a read. An out-of-range `{card: 7, field: "from"}` extends the
1007
- * unknown-kind root `edit::index_out_of_range` anchors at, rendering
1008
- * `cards[7].from`, which parses back and resolves to nothing rather than
1009
- * mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
1010
- * a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
1011
- * address throws.
856
+ * **Total on the index axis**, unlike the `Addr` reads, which throw there:
857
+ * an out-of-range `{card: 7, field: "from"}` renders `cards[7].from`, which
858
+ * parses back and resolves to nothing rather than mis-targeting. Only a
859
+ * malformed address throws.
1012
860
  */
1013
861
  pathFor(addr: Addr | string): string;
1014
862
  /**
1015
- * The canonical `$quill` reference grammar as author-facing text. Core is
1016
- * the single source of truth: drive schema `describe` and validation
1017
- * messages from this instead of re-stating the rule; it matches the
1018
- * `hint` on `parse::invalid_quill_reference`. Cache it; the value never
1019
- * changes.
863
+ * The canonical `$quill` reference grammar as author-facing text: the same
864
+ * text the `parse::invalid_quill_reference` hint carries. Drive validation
865
+ * messages from this instead of re-stating the rule.
1020
866
  */
1021
867
  static quillRefHint(): string;
1022
868
  removeCard(index: number): Card | undefined;
1023
869
  /**
1024
- * Remove the `$ext` map on the card `addr` targets *entirely*, returning the
1025
- * previous map or `undefined`: a blunt escape hatch that discards every
1026
- * namespace at once (prefer `removeExtNamespace`). `addr` is a card address
1027
- * (absent = main). Throws on a present `field` or an out-of-range card.
870
+ * Remove the `$ext` map on the card `addr` targets entirely, returning the
871
+ * previous map or `undefined`. Discards every namespace at once; prefer
872
+ * `removeExtNamespace`. Throws on a present `field` or an out-of-range card.
1028
873
  */
1029
874
  removeExt(addr?: CardAddr): Record<string, unknown> | undefined;
1030
875
  /**
@@ -1036,35 +881,31 @@ export class Document {
1036
881
  removeExtNamespace(addr: CardAddr, ns: string): any;
1037
882
  /**
1038
883
  * Remove a field at `addr`, returning the removed value or `undefined`. A
1039
- * bare string is `Addr` shorthand for `{ field }`. One `remove` verb serves
1040
- * every write lane. A body address throws; throws on an out-of-range card or
1041
- * a malformed name.
884
+ * bare string is `Addr` shorthand for `{ field }`. A body address throws, as
885
+ * does an out-of-range card or a malformed name.
1042
886
  */
1043
887
  removeField(addr: Addr | string): any;
1044
888
  /**
1045
- * Remove `cardKind` from the main card's `$seed` map, returning its
1046
- * overlay or `undefined`; drops `$seed` entirely once empty. Sibling kinds
1047
- * survive. `$seed` is main-only, so this takes no address.
889
+ * Remove `cardKind` from the main card's `$seed` map, returning its overlay
890
+ * or `undefined`; drops `$seed` entirely once empty. Sibling kinds survive.
1048
891
  */
1049
892
  removeSeedOverlay(card_kind: string): any;
1050
893
  /**
1051
- * **Revise** the richtext value at `addr` from a markdown string: **edit
1052
- * semantics**, the default write path, returning the text `Delta`. Imports
1053
- * the markdown, diffs it against the current value, rebases surviving
1054
- * identity anchors, and returns the change an editor bridge maps its own
1055
- * positions through (`mapPos`). An absent `addr.field` targets the body, an
1056
- * absent `addr.card` the main card; an absent field cold-imports from empty.
894
+ * **Revise** the richtext value at `addr` from a markdown string: the
895
+ * default write path. Imports the markdown, diffs it against the current
896
+ * value, rebases surviving identity anchors, and returns the text `Delta` an
897
+ * editor bridge maps its own positions through (`mapPos`). An absent
898
+ * `addr.field` targets the body, an absent `addr.card` the main card; an
899
+ * absent field cold-imports from empty.
1057
900
  *
1058
901
  * Throws on an out-of-range card, a malformed field name, a present
1059
902
  * non-content field value, or an over-nested markdown input.
1060
903
  */
1061
904
  revise(addr: Addr | string, markdown: string): Delta;
1062
905
  /**
1063
- * The main card's `$seed` overlay object for `kind` (the `$seed[kind]`
1064
- * entry), or `undefined` when absent. The cheap read that feeds
1065
- * `quill.seedCard(kind, overlay)` without serializing the whole main card
1066
- * via [`main`](Self::main) to fish out one key, and it keeps `seedCard`
1067
- * pure: the quill still never reads the document.
906
+ * The main card's `$seed[kind]` overlay object, or `undefined`. Feeds
907
+ * `quill.seedCard(kind, overlay)` without serializing the whole main card,
908
+ * and keeps `seedCard` pure: the quill never reads the document.
1068
909
  */
1069
910
  seedOverlay(kind: string): Record<string, unknown> | undefined;
1070
911
  /**
@@ -1078,78 +919,60 @@ export class Document {
1078
919
  */
1079
920
  setQuillRef(ref_str: string): void;
1080
921
  /**
1081
- * Read the storage version tag from a raw storage DTO string without a
1082
- * full parse, or `undefined`. Returns unknown future versions as-is:
1083
- * useful to distinguish "build too old" from "payload corrupt" when
1084
- * `fromJson` throws.
1085
- *
1086
- * The storage version, not a field schema ([`schema`](Quill::schema) is the
1087
- * quill's field declarations). The JSON key is spelled `"schema"`: it is
1088
- * the DTO's serde tag, and retagging it would break the version dispatch
1089
- * it drives.
922
+ * Read the storage version tag from a raw storage DTO string without a full
923
+ * parse, or `undefined`. Unknown future versions come back as-is, which
924
+ * distinguishes "build too old" from "payload corrupt" when `fromJson`
925
+ * throws. This is the storage version, not a field schema, though the JSON
926
+ * key is spelled `"schema"`: that is the DTO's serde tag.
1090
927
  */
1091
928
  static storageVersionOf(json: string): string | undefined;
1092
929
  /**
1093
- * Replace the opaque `$ext` map on the card `addr` targets (a card address,
1094
- * absent `card` = main). `value` must be a plain object. `$ext` carries
1095
- * out-of-band consumer state and never reaches the rendered output; pass
1096
- * `{}` for an explicit empty `$ext`. Quill-free and verbatim: an opaque
1097
- * `store` verb. Throws on a present `field` or an out-of-range card.
930
+ * Replace the opaque `$ext` map on the card `addr` targets (absent `card` =
931
+ * main). `value` must be a plain object. `$ext` carries out-of-band consumer
932
+ * state and never reaches the rendered output. Throws on a present `field`
933
+ * or an out-of-range card.
1098
934
  */
1099
935
  storeExt(addr: CardAddr, value: any): void;
1100
936
  /**
1101
937
  * Merge `value` into `$ext[ns]` on the card `addr` targets, preserving
1102
- * sibling namespaces: the recommended `$ext` write. `addr` is a card
1103
- * address (absent = main). Quill-free and verbatim: an opaque `store` verb.
1104
- * Throws on a present `field` or an out-of-range card.
938
+ * sibling namespaces: the recommended `$ext` write. Throws on a present
939
+ * `field` or an out-of-range card.
1105
940
  */
1106
941
  storeExtNamespace(addr: CardAddr, ns: string, value: any): void;
1107
942
  /**
1108
- * Store a field verbatim at `addr`: the opaque store (**store** = verbatim,
1109
- * coercion deferred to render; the typed write is
1110
- * [`commitField`](Document::commit_field)). A bare string is `Addr`
1111
- * shorthand for `{ field }`, so `doc.storeField("qty", 3)` reads as written;
1112
- * `{ card: 2, field: "qty" }` targets a composable card. Clears any
1113
- * `!must_fill` marker. A body address (no `field`) throws: a body is never
1114
- * opaque; write it with `revise` / `overwrite` / `writer.reviseBody`. Throws on
1115
- * an out-of-range card or a malformed name.
943
+ * Store a field verbatim at `addr`, deferring coercion to render; the typed
944
+ * write is [`commitField`](Document::commit_field). A bare string is `Addr`
945
+ * shorthand for `{ field }`; `{ card: 2, field: "qty" }` targets a
946
+ * composable card. Clears any `!must_fill` marker. A body address throws:
947
+ * write a body with `revise` / `overwrite`. Throws on an out-of-range card
948
+ * or a malformed name.
1116
949
  */
1117
950
  storeField(addr: Addr | string, value: any): void;
1118
951
  /**
1119
- * Store several fields verbatim and atomically on the card `addr` targets:
1120
- * the opaque store's batch. `addr` is a **card address** (`{ card }`, absent
1121
- * = main); a present `field` throws. The batch verb takes the address first
1122
- * and is never shape-overloaded, because `card` is a legal field name:
1123
- * `storeFields({}, fields)` is the main card, `storeFields({ card: 2 },
1124
- * fields)` a composable one, never ambiguous with "set field `card`".
1125
- * Nothing is applied on error; the thrown error's `diagnostics` carry one
1126
- * entry per offending field. Throws on an out-of-range card.
952
+ * Store several fields verbatim and atomically on the card `addr` targets.
953
+ * `addr` is a **card address** (`{ card }`, absent = main) and comes first
954
+ * because `card` is itself a legal field name; a present `field` throws.
955
+ * Nothing is applied on error, and the thrown error's `diagnostics` carry
956
+ * one entry per offending field. Throws on an out-of-range card.
1127
957
  */
1128
958
  storeFields(addr: CardAddr, fields: Record<string, unknown>): void;
1129
959
  /**
1130
- * Store a field verbatim at `addr` and mark it `!must_fill`: the opaque
1131
- * store's fill variant, card-capable (a bare string or `{ field }` for main,
1132
- * `{ card, field }` for a composable card). A body address throws. Same
1133
- * validation as [`storeField`](Document::store_field).
960
+ * Store a field verbatim at `addr` and mark it `!must_fill`. A body address
961
+ * throws; same validation as [`storeField`](Document::store_field).
1134
962
  */
1135
963
  storeFill(addr: Addr | string, value: any): void;
1136
964
  /**
1137
965
  * Merge a card-kind's seed `overlay` into the **main** card's `$seed` map
1138
- * under `cardKind`, preserving sibling kinds: `$seed` lives on the main
1139
- * card by model, so this takes no address. Sets the starting values new
1140
- * cards of that kind spawn with. Quill-free and verbatim: an opaque `store`
1141
- * verb. Throws if `overlay` cannot be serialized or nests too deep.
966
+ * under `cardKind`, preserving sibling kinds; `$seed` is main-only, so this
967
+ * takes no address. Sets the starting values new cards of that kind spawn
968
+ * with. Throws if `overlay` cannot be serialized or nests too deep.
1142
969
  */
1143
970
  storeSeedOverlay(card_kind: string, overlay: any): void;
1144
971
  /**
1145
- * Serialize this document to a versioned storage DTO string.
1146
- *
1147
- * Prefer this over `toMarkdown` for persistence across restarts or crate
1148
- * upgrades: the wire format is frozen per `schema` version. Parse-time
1149
- * `warnings` are excluded from the DTO.
1150
- *
1151
- * Output is **byte-deterministic** within a `schema` version: equal
1152
- * documents produce byte-equal output, safe for content-hash use cases.
972
+ * Serialize this document to a versioned storage DTO string. Prefer it over
973
+ * `toMarkdown` for persistence: the wire format is frozen per `schema`
974
+ * version and the output is byte-deterministic within one, so equal
975
+ * documents hash equal. Parse-time `warnings` are excluded.
1153
976
  */
1154
977
  toJson(): string;
1155
978
  /**
@@ -1158,80 +981,66 @@ export class Document {
1158
981
  */
1159
982
  toMarkdown(): string;
1160
983
  /**
1161
- * Like [`fromJson`](Document::from_json) but returns `undefined` instead
1162
- * of throwing when `json` is not a valid storage DTO: use to
1163
- * discriminate format without exceptions as control flow.
1164
- * `undefined` means "not a storage DTO"; `fromMarkdown` still throws on
1165
- * genuinely malformed markdown.
984
+ * Like [`fromJson`](Document::from_json) but returns `undefined` instead of
985
+ * throwing when `json` is not a valid storage DTO, to discriminate format
986
+ * without exceptions as control flow.
1166
987
  */
1167
988
  static tryFromJson(json: string): Document | undefined;
1168
989
  /**
1169
- * Number of composable cards (excludes the main card). O(1).
990
+ * Number of composable cards, excluding the main card.
1170
991
  */
1171
992
  readonly cardCount: number;
1172
993
  readonly cards: Card[];
1173
994
  /**
1174
- * The document's main (entry) card. Allocates and serializes on each
1175
- * call: cache locally if read in a hot loop.
995
+ * The document's main (entry) card. Allocates and serializes on each call.
1176
996
  */
1177
997
  readonly main: Card;
1178
998
  readonly quillRef: string;
1179
999
  /**
1180
1000
  * The non-fatal diagnostics of the load that produced this document: parse
1181
- * warnings, plus the `conform::*` warnings when it came through
1182
- * `quill.parse`. Session state, not document value: `equals` and the
1183
- * storage DTO exclude it, and `fromJson` / `loadJson` clear it.
1001
+ * warnings, plus `conform::*` warnings when it came through `quill.parse`.
1002
+ * Session state, not document value: `equals` and the storage DTO exclude
1003
+ * it, and `fromJson` / `loadJson` clear it.
1184
1004
  */
1185
1005
  readonly warnings: Diagnostic[];
1186
1006
  }
1187
1007
 
1188
1008
  /**
1189
- * Live render session: reads (`render`, `paint`, `pageSize`, `regions`,
1190
- * `fieldAt`, `positionAt`, `locate`) serve the current compile. `apply(doc)`
1191
- * recompiles a whole document in place, transactionally (on throw every read
1192
- * keeps serving the last-good compile). Geometry reads reflect the current
1193
- * compile; anchoring a caret across edits is the editor's job: re-read
1194
- * geometry after each committed `apply`.
1009
+ * Live render session: every read serves the current compile. `apply(doc)`
1010
+ * recompiles a whole document in place, transactionally — on throw the reads
1011
+ * keep serving the last-good compile. Geometry is per-compile, so re-read it
1012
+ * after each committed `apply`.
1195
1013
  *
1196
- * **Empty documents.** A zero-page document yields a valid session
1197
- * (`pageCount === 0`); `paint(ctx, 0)` or `pageSize(0)` throws with
1198
- * `"page index 0 out of range (pageCount=0)"`. Branch on `pageCount === 0`
1199
- * rather than catching the error.
1014
+ * A zero-page document yields a valid session (`pageCount === 0`) whose
1015
+ * `paint(ctx, 0)` and `pageSize(0)` throw; branch on `pageCount === 0` rather
1016
+ * than catching.
1200
1017
  */
1201
1018
  export class LiveSession {
1202
1019
  private constructor();
1203
1020
  free(): void;
1204
1021
  [Symbol.dispose](): void;
1205
1022
  /**
1206
- * The schema field whose content is under a point on `page`, the
1207
- * forward (click field) direction: hit-test a click against the
1208
- * compiled document and get back the `DocPath` field address to focus in
1209
- * the editor, or `undefined` off any field's ink. `x`/`y` are PDF points
1210
- * with a **bottom-left** origin, the same space as `FieldRegion.rect`,
1211
- * from a canvas click, invert the overlay transform documented on
1212
- * `FieldRegion`: `x = clickPx.x / renderScale`,
1213
- * `y = pageHeightPt - clickPx.y / renderScale`. Unlike `regions()`,
1214
- * *every* placement answers, not just the first.
1023
+ * The schema field whose content is under a point on `page`: the `DocPath`
1024
+ * address to focus in the editor, or `undefined` off any field's ink.
1025
+ * `x`/`y` are PDF points with a **bottom-left** origin, the same space as
1026
+ * `FieldRegion.rect`, so from a canvas click use
1027
+ * `x = clickPx.x / renderScale`, `y = pageHeightPt - clickPx.y / renderScale`.
1028
+ * Unlike `regions()`, *every* placement answers, not just the first.
1215
1029
  */
1216
1030
  fieldAt(page: number, x: number, y: number): string | undefined;
1217
1031
  /**
1218
- * The whole-field highlight boxes for `field`: one union rect per page,
1219
- * over the field's `span`-bearing content segments. The convenience that
1220
- * owns the union `regions()` leaves derived: it keeps `regions()` the
1221
- * low-level disjoint truth and folds the span-filter + per-page
1222
- * union here, so a "highlight the focused field" consumer stops
1223
- * reimplementing it. **Content only**: a field placed solely as a scalar
1224
- * reference or a bound widget carries no `span` and returns `[]`; its box
1225
- * is a single `regions()` rect. Reflects the current compile, like
1226
- * `regions()`.
1032
+ * The whole-field highlight boxes for `field`: one union rect per page over
1033
+ * the field's `span`-bearing content segments, the union `regions()` leaves
1034
+ * derived. **Content only**: a field placed solely as a scalar reference or
1035
+ * a bound widget carries no `span` and returns `[]`, its box being a single
1036
+ * `regions()` rect. Reflects the current compile.
1227
1037
  */
1228
1038
  fieldBoxes(field: string): FieldRegion[];
1229
1039
  /**
1230
- * A content position → **caret rect**, the reverse of `positionAt`: given
1231
- * a field and a USV offset into its `Content`, return the box (in the
1232
- * same bottom-left PDF-point space as `FieldRegion.rect`) to draw a caret
1233
- * at, its `span` collapsed to `[pos, pos]`; `undefined` when the field
1234
- * places no tracked content or the offset maps to no drawn glyph.
1040
+ * A content position → **caret rect**, the reverse of `positionAt`: the box
1041
+ * to draw a caret at, in the same bottom-left PDF-point space as
1042
+ * `FieldRegion.rect`, its `span` collapsed to `[pos, pos]`. `undefined` when
1043
+ * the field places no tracked content or the offset maps to no drawn glyph.
1235
1044
  */
1236
1045
  locate(field: string, pos: number): FieldRegion | undefined;
1237
1046
  /**
@@ -1243,54 +1052,45 @@ export class LiveSession {
1243
1052
  * Paint `page` into a `CanvasRenderingContext2D` or
1244
1053
  * `OffscreenCanvasRenderingContext2D`. The painter owns
1245
1054
  * `canvas.width`/`height` (no `clearRect` needed); consumers own
1246
- * `canvas.style.*`. If `layoutScale * densityScale` exceeds 16384 px
1247
- * per side, `densityScale` is clamped: `PaintResult.clamped` reports it and
1248
- * `PaintResult.effectiveDensityScale` carries the density actually applied.
1055
+ * `canvas.style.*`. If `layoutScale * densityScale` exceeds 16384 px per
1056
+ * side, `densityScale` is clamped and `PaintResult` reports it.
1249
1057
  *
1250
1058
  * `put_image_data` writes the whole backing store, bypassing the 2D
1251
- * context's transform, `globalAlpha`, and clip: the painter owns the entire
1252
- * canvas, so each visible page needs its own `<canvas>`; you cannot composite
1253
- * two pages, a sub-rect, or a context transform through this call.
1059
+ * context's transform, `globalAlpha`, and clip, so each visible page needs
1060
+ * its own `<canvas>`: no compositing, sub-rect, or transform reaches through
1061
+ * this call.
1254
1062
  *
1255
- * Throws if the backend has no canvas painter, `page` is out of range,
1256
- * `ctx` is the wrong type, or either scale is non-finite or `<= 0`.
1063
+ * Throws if the backend has no canvas painter, `page` is out of range, `ctx`
1064
+ * is the wrong type, or either scale is non-finite or `<= 0`.
1257
1065
  */
1258
1066
  paint(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, page: number, opts: PaintOptions | undefined): PaintResult;
1259
1067
  /**
1260
- * A point → **content position**, the fine-grained click direction:
1261
- * hit-test a point and get back the field *and* a USV offset into its
1262
- * `Content` (for placing a caret or mapping a selection into the content
1263
- * model), or `undefined` off all content ink. `x`/`y` are PDF points,
1264
- * bottom-left origin: the same space as `fieldAt`. The offset is
1265
- * cluster-exact and degrades to the containing segment's start on
1266
- * origin-less ink (list markers, a code fence's interior). See
1267
- * `ContentHit`.
1068
+ * A point → **content position**: the field *and* a USV offset into its
1069
+ * `Content`, for placing a caret or mapping a selection into the content
1070
+ * model, or `undefined` off all content ink. `x`/`y` are PDF points,
1071
+ * bottom-left origin, as in `fieldAt`. The offset is cluster-exact and
1072
+ * degrades to the containing segment's start on origin-less ink.
1268
1073
  */
1269
1074
  positionAt(page: number, x: number, y: number): ContentHit | undefined;
1270
1075
  /**
1271
1076
  * Schema-field geometry for this compiled session: each content field's
1272
1077
  * **first placement** (one region per page it touches) plus widget and
1273
- * scalar-reference-site regions, keyed on the canonical `DocPath` address
1274
- * (`parseDocPath`-routable; the session resolves the backend's plate-space
1275
- * per-kind ordinal to it); a field may still appear more than once (group
1276
- * by `field`, see `FieldRegion`). A session-level query: no render, no byte
1277
- * artifact. An interactive preview reads it to scroll to / highlight the
1278
- * focused field over a `paint`-ed canvas; the click direction is `fieldAt`.
1279
- * Empty for backends that place no schema fields.
1078
+ * scalar-reference-site regions, keyed on the canonical `DocPath` address. A
1079
+ * field may appear more than once, so group by `field` (see `FieldRegion`).
1080
+ * A session-level query: no render, no byte artifact. The click direction is
1081
+ * `fieldAt`. Empty for backends that place no schema fields.
1280
1082
  */
1281
1083
  regions(): FieldRegion[];
1282
1084
  render(opts?: RenderOptions | null): RenderResult;
1283
1085
  /**
1284
- * Recompile the session against `doc`: the edit verb of a live preview.
1285
- * The document is compiled through the same schema pipeline as `open`
1286
- * (same quill), then swapped in transactionally: on throw every read
1287
- * (`render`, `paint`, `pageSize`, `regions`, `fieldAt`) keeps serving the last-good
1288
- * compile, and the session recovers on the next successful `update`. On
1289
- * success reads serve the new compile; repaint `dirtyPages ∩ visible`.
1086
+ * Recompile the session against `doc`: the edit verb of a live preview. The
1087
+ * document compiles through the same pipeline as `open`, then swaps in
1088
+ * transactionally on throw every read keeps serving the last-good compile
1089
+ * and the session recovers on the next successful `update`. On success,
1090
+ * repaint `dirtyPages visible`.
1290
1091
  *
1291
- * Distinct from the content lane's [`applyChange`](Document::apply_change),
1292
- * which splices ops into a document: this one recompiles a whole document
1293
- * the caller already mutated.
1092
+ * Distinct from [`applyChange`](Document::apply_change), which splices ops
1093
+ * into a document; this recompiles a document the caller already mutated.
1294
1094
  */
1295
1095
  update(doc: Document): ChangeSet;
1296
1096
  /**
@@ -1299,16 +1099,13 @@ export class LiveSession {
1299
1099
  readonly backendId: string;
1300
1100
  readonly pageCount: number;
1301
1101
  /**
1302
- * `true` iff `paint` and `pageSize` will succeed for this session. Derived
1303
- * from the session's canvas seam, so it reflects exactly what `paint` will
1304
- * do: no separately captured flag.
1102
+ * `true` iff `paint` and `pageSize` will succeed for this session.
1305
1103
  */
1306
1104
  readonly supportsCanvas: boolean;
1307
1105
  /**
1308
- * Non-fatal diagnostics of the session's **current compile** (e.g. Typst
1309
- * font fallback): set at open and refreshed by each committed `apply`;
1310
- * a failed apply keeps the last-good compile's warnings. Also appended
1311
- * to `RenderResult.warnings` on each `render()` call.
1106
+ * Non-fatal diagnostics of the session's **current compile**, refreshed by
1107
+ * each committed `apply`; a failed apply keeps the last-good compile's.
1108
+ * Also appended to `RenderResult.warnings` on each `render()`.
1312
1109
  */
1313
1110
  readonly warnings: Diagnostic[];
1314
1111
  }
@@ -1319,132 +1116,100 @@ export class Quill {
1319
1116
  [Symbol.dispose](): void;
1320
1117
  /**
1321
1118
  * Land `doc`'s declared content fields at their canonical rest **in
1322
- * place**, returning the `conform::*` diagnostics for the values that would
1323
- * not commit (an empty array when everything rested).
1324
- *
1325
- * The read-repair verb: a document that arrived through the transport door
1326
- * (`fromMarkdown`, `fromJson`, a stored row) converges here, and is then
1327
- * eligible for rewrite under its current schema tag. Idempotent, and a
1328
- * no-op on an already-canonical document: an equal value is not rewritten,
1329
- * so YAML comments and stored bytes survive.
1119
+ * place**, returning the `conform::*` diagnostics for values that would not
1120
+ * commit. The read-repair verb for a document that arrived through the
1121
+ * transport door (`fromMarkdown`, `fromJson`, a stored row).
1330
1122
  *
1331
- * A `!must_fill` marker anywhere in a field's value skips that field (the
1332
- * marker is the state), and a value the strict write refuses stays as
1333
- * authored with a diagnostic. Throws when `doc` declares a different
1334
- * `$quill`, before any mutation.
1123
+ * Idempotent: an equal value is not rewritten, so YAML comments and stored
1124
+ * bytes survive. A `!must_fill` marker anywhere in a field's value skips
1125
+ * that field, and a value the strict write refuses stays as authored with a
1126
+ * diagnostic. Throws when `doc` declares a different `$quill`, before any
1127
+ * mutation.
1335
1128
  */
1336
1129
  conform(doc: Document): Diagnostic[];
1337
1130
  /**
1338
- * Build a quill from a file tree. Pure: no backend, no engine; the
1339
- * declared backend is resolved later, at render time.
1340
- *
1341
- * Accepts either a `Map<string, Uint8Array>` or a plain object
1342
- * (`Record<string, Uint8Array>`). Plain objects are walked via
1343
- * `Object.entries` at the boundary; the Rust side sees a single
1344
- * canonical shape.
1131
+ * Build a quill from a file tree. Pure: the declared backend is resolved
1132
+ * later, at render time. Accepts a `Map<string, Uint8Array>` or a plain
1133
+ * object.
1345
1134
  */
1346
1135
  static fromTree(tree: Map<string, Uint8Array>): Quill;
1347
1136
  /**
1348
- * Parse `markdown` and conform it against this quill: the **primary
1349
- * ingestion path**, and the bound twin of the schema-free
1350
- * `Document.fromMarkdown`. The returned document rests at its canonical
1351
- * form (a `richtext` field as a content object, a `plaintext` field as its
1352
- * literal string), so `getStored` answers "content object or string?" by the
1353
- * field's declared codec rather than by how the document was built.
1137
+ * Parse `markdown` and conform it against this quill: the primary ingestion
1138
+ * path, and the bound twin of the schema-free `Document.fromMarkdown`. The
1139
+ * returned document rests at its canonical form (a `richtext` field as a
1140
+ * content object, a `plaintext` field as its literal string), so `getStored`
1141
+ * answers by the field's declared codec, not by how the document was built.
1354
1142
  *
1355
1143
  * Parse warnings and the `conform::*` diagnostics both land on
1356
1144
  * `doc.warnings`. Throws on a parse failure, or when `markdown` declares a
1357
- * `$quill` this quill does not answer to: nothing conforms under the wrong
1358
- * schema. To open a document whose `$quill` is stale, use the transport
1359
- * door (`Document.fromMarkdown`, `setQuillRef`, then `quill.conform`).
1145
+ * `$quill` this quill does not answer to. To open a document whose `$quill`
1146
+ * is stale, use `Document.fromMarkdown`, `setQuillRef`, then `quill.conform`.
1360
1147
  */
1361
1148
  parse(markdown: string): Document;
1362
1149
  /**
1363
- * The resolved-value view of `doc` against this quill's schema: for every
1364
- * declared field the value the render projection would use and the
1365
- * `FieldSource` rung it came from (`"authored" | "default" | "zero"`), in
1366
- * one call. The card body is a `body` sibling on its card (row `name`
1367
- * `"body"`), never a row in `fields`: `null` when the kind enables no body.
1368
- *
1369
- * Value and provenance only: completeness and errors stay `validate`'s
1370
- * (a consumer merges it with its own diagnostic producers regardless), and
1371
- * schema guidance reads from `Quill.schema`.
1150
+ * The resolved-value view of `doc`: for every declared field, the value the
1151
+ * render projection would use and the `FieldSource` rung it came from
1152
+ * (`"authored" | "default" | "blank"`). The card body is a `body` sibling on
1153
+ * its card, never a row in `fields`, and `null` when the kind enables no
1154
+ * body. Value and provenance only; completeness stays `validate`'s.
1372
1155
  */
1373
1156
  resolve(doc: Document): Resolved;
1374
1157
  /**
1375
1158
  * Seed a starter composable `Card` of the given kind (carries `$kind`),
1376
- * layering an optional per-kind seed `overlay` over the schema-example
1377
- * base (`overlay › example › absent`). Returns `undefined` if `cardKind`
1378
- * is not declared in this quill's schema, else a `Card` that feeds
1379
- * straight into `Document.insertCard`.
1159
+ * layering an optional per-kind seed `overlay` over the schema-example base
1160
+ * (`overlay › example › absent`). `undefined` when `cardKind` is not
1161
+ * declared in this quill's schema.
1380
1162
  *
1381
1163
  * Pass `document.seedOverlay(cardKind)` as `overlay` so a card added to a
1382
1164
  * template-derived document inherits its curated starting values; omit it
1383
- * (or pass `undefined` / `null`) for the bare schema seed. `overlay` is a
1384
- * plain object: this reads the document, it does not mutate it.
1165
+ * for the bare schema seed.
1385
1166
  */
1386
1167
  seedCard(card_kind: string, overlay: Record<string, unknown> | undefined): Card | undefined;
1387
1168
  /**
1388
- * Seed a starter `Document` from the schema, the main card plus one
1389
- * instance of each composable card kind, each committing its fields'
1390
- * `example:` values and leaving every other field absent (interpolated at
1391
- * render: `default:`, else type-empty zero). Illustration-first: a field
1392
- * with both an `example` and a `default` renders its example. See
1393
- * `prose/canon/SCHEMAS.md` § "Document seeding".
1169
+ * Seed a starter `Document` from the schema: the main card plus one instance
1170
+ * of each composable card kind, each committing its fields' `example:`
1171
+ * values and leaving every other field absent (interpolated at render as
1172
+ * `default:`, else the field's blank). A field with both renders its example.
1394
1173
  */
1395
1174
  seedDocument(): Document;
1396
1175
  /**
1397
1176
  * Seed a starter main `Card` (carries `$quill`) from the schema: the
1398
- * `$kind: main` card of [`seedDocument`](Self::seed_document) in
1399
- * isolation, committing each field's `example:` value. Returns the same
1400
- * `Card` shape as the `Document.main` getter.
1177
+ * `$kind: main` card of [`seedDocument`](Self::seed_document) alone.
1401
1178
  */
1402
1179
  seedMain(): Card;
1403
1180
  /**
1404
- * Flatten this quill back into its canonical file tree: the inverse of
1405
- * [`fromTree`](Self::from_tree). Round-trips: `Quill.fromTree(q.toTree())`
1406
- * reproduces an equivalent quill.
1181
+ * Flatten this quill back into its canonical file tree, the inverse of
1182
+ * [`fromTree`](Self::from_tree). Keys are `"/"`-joined relative paths.
1407
1183
  *
1408
1184
  * This is how a quill crosses a WASM linear-memory boundary as data: a
1409
- * `Quill` built in one build (e.g. the Typst-less `@quillmark/wasm/core`)
1410
- * cannot be passed to an engine in another (separate linear memories), so
1185
+ * `Quill` built in one build cannot be passed to an engine in another, so
1411
1186
  * `@quillmark/wasm/runtime` re-feeds this tree to the backend build's
1412
- * `Quill.fromTree` on demand. Keys are `"/"`-joined relative paths,
1413
- * matching what `fromTree` accepts.
1187
+ * `Quill.fromTree` on demand.
1414
1188
  */
1415
1189
  toTree(): Map<string, Uint8Array>;
1416
1190
  /**
1417
1191
  * Validate `doc` against this quill's schema, returning every diagnostic
1418
- * (an empty array when the document is valid).
1419
- *
1420
- * Forwards the canonical `validation::*` diagnostics (same `code`,
1421
- * `path`, and `hint` the engine emits) including the non-fatal
1422
- * `validation::must_fill` warning for each `!must_fill` marker left in
1423
- * the document. Field values, defaults, and order are not part of this
1424
- * surface: read them from the `Document` payload and `Quill.schema`
1425
- * (schema key order is display order).
1192
+ * (empty when the document is valid). Forwards the canonical
1193
+ * `validation::*` diagnostics the engine emits, including the non-fatal
1194
+ * `validation::must_fill` warning per `!must_fill` marker left behind.
1426
1195
  */
1427
1196
  validate(doc: Document): Diagnostic[];
1428
1197
  /**
1429
- * The *declared* backend identifier (`config.backend`, e.g. `"typst"`).
1430
- * Intent, not a resolved capability: capability (`supportedFormats` /
1431
- * `supportsCanvas`) is read from the engine.
1198
+ * The *declared* backend identifier (e.g. `"typst"`): intent, not a
1199
+ * resolved capability. Capability is read from the engine.
1432
1200
  */
1433
1201
  readonly backendId: string;
1434
1202
  readonly blueprint: string;
1435
1203
  /**
1436
1204
  * Identity snapshot of the `quill:` section of `Quill.yaml` plus any extra
1437
- * `quill:` keys. Pure config: the backend's output formats are a
1438
- * resolved-backend capability read from the engine
1439
- * (`Quillmark.supportedFormats`), not part of this snapshot.
1205
+ * `quill:` keys. Pure config: output formats are a resolved-backend
1206
+ * capability read from `Quillmark.supportedFormats`, not part of this.
1440
1207
  */
1441
1208
  readonly metadata: QuillMetadata;
1442
1209
  /**
1443
- * Document schema for the quill: the user-fillable fields plus their
1444
- * `ui` hints (title / group / compact / multiline). The single
1445
- * field-metadata surface: drives form editors and LLM/MCP consumers
1446
- * alike. Key order in `fields`/`properties` is declaration order: the
1447
- * ordering contract. Returns the `QuillSchema` shape.
1210
+ * Document schema for the quill: the user-fillable fields plus their `ui`
1211
+ * hints. Key order in `fields`/`properties` is declaration order, the
1212
+ * ordering contract.
1448
1213
  */
1449
1214
  readonly schema: QuillSchema;
1450
1215
  }
@@ -1468,81 +1233,67 @@ export class Quillmark {
1468
1233
  */
1469
1234
  render(quill: Quill, doc: Document, opts?: RenderOptions | null): RenderResult;
1470
1235
  /**
1471
- * The output formats `quill`'s backend can emit. Static capability:
1472
- * resolves the backend but compiles nothing. Throws `engine::backend_not_found`
1473
- * if no registered backend matches the quill's declared backend.
1236
+ * The output formats `quill`'s backend can emit; resolves the backend but
1237
+ * compiles nothing. Throws `engine::backend_not_found` when no registered
1238
+ * backend matches the quill's declared one.
1474
1239
  */
1475
1240
  supportedFormats(quill: Quill): OutputFormat[];
1476
1241
  /**
1477
- * Pre-session hint: `true` iff `quill`'s backend can paint sessions to a
1478
- * canvas, derived from the backend's output formats; `false` when the
1479
- * backend is unsupported. Use as a cheap precondition probe before mounting
1480
- * a canvas-based preview UI; the authoritative answer is the session's
1481
- * `supportsCanvas` getter once `open()` has been called.
1242
+ * Whether `quill`'s backend can paint sessions to a canvas; `false` when the
1243
+ * backend is unsupported. A cheap probe before mounting a preview UI. The
1244
+ * authoritative answer is the session's `supportsCanvas` getter.
1482
1245
  */
1483
1246
  supportsCanvas(quill: Quill): boolean;
1484
1247
  }
1485
1248
 
1486
1249
  /**
1487
- * Export a canonical `Content` content to its markdown projection: the pure
1488
- * on-demand codec behind `exportMarkdown(card.body)`. Throws if `rt` is not a
1250
+ * Export canonical `Content` to its markdown projection. Throws if `rt` is not
1489
1251
  * canonical content.
1490
1252
  */
1491
1253
  export function exportMarkdown(rt: Content): string;
1492
1254
 
1493
1255
  /**
1494
1256
  * Serialize structured [`DocPathSeg`] segments back to the canonical path
1495
- * string: the inverse of `parseDocPath`, for a consumer that builds a path
1496
- * rather than reads one. Throws on a segment array the deserializer rejects,
1497
- * and on an empty segment array (symmetric with `parseDocPath("")`, which
1498
- * throws "empty path").
1257
+ * string: the inverse of `parseDocPath`. Throws on a segment array the
1258
+ * deserializer rejects, and on an empty one.
1499
1259
  */
1500
1260
  export function formatDocPath(segs: DocPathSeg[]): string;
1501
1261
 
1502
1262
  /**
1503
- * Import a markdown string to a canonical `Content` content: the pure,
1504
- * document-free codec. Pair with `overwrite(addr, importMarkdown(md))` to spell
1505
- * the cold (anchor-losing) write at the call site; prefer `revise` for edit
1506
- * semantics. Throws on an over-nested input.
1263
+ * Import a markdown string to canonical `Content`: the pure, document-free
1264
+ * codec. `overwrite(addr, importMarkdown(md))` spells the cold, anchor-losing
1265
+ * write; prefer `revise` for edit semantics. Throws on an over-nested input.
1507
1266
  */
1508
1267
  export function importMarkdown(markdown: string): Content;
1509
1268
 
1510
1269
  /**
1511
1270
  * Map a base content position (a USV index into `Content.text`, not a UTF-16
1512
- * offset) through a `delta` to its new USV position: the pure position-mapping
1513
- * codec an editor bridge composes to hold a caret stable across a `revise`.
1514
- * `assoc` decides the side of a same-position insertion (`"after"` moves past
1515
- * it). Throws on a malformed `delta`.
1271
+ * offset) through a `delta` to its new position, holding a caret stable across
1272
+ * a `revise`. `assoc` decides the side of a same-position insertion (`"after"`
1273
+ * moves past it). Throws on a malformed `delta`.
1516
1274
  */
1517
1275
  export function mapPos(delta: Delta, pos: number, assoc: Assoc): number;
1518
1276
 
1519
1277
  /**
1520
- * Parse a canonical document-model `Diagnostic.path`
1521
- * (`cards.<kind>[<i>].<field>`, `main.body`, `recipients[0].name`) into its
1522
- * structured [`DocPathSeg`] segments: the exported inverse of the engine's
1523
- * one path serializer, so a consumer routes on segments instead of regexing
1524
- * the string. Throws on a malformed path.
1278
+ * Parse a canonical document-model `Diagnostic.path` (`cards.<kind>[<i>].<field>`,
1279
+ * `main.body`, `recipients[0].name`) into structured [`DocPathSeg`] segments, so
1280
+ * a consumer routes on segments instead of regexing the string. Throws on a
1281
+ * malformed path.
1525
1282
  */
1526
1283
  export function parseDocPath(path: string): DocPathSeg[];
1527
1284
 
1528
1285
  /**
1529
- * Rebase `markdown` onto a `base` content, the pure, document-free twin of
1530
- * `revise`: cold-import + `diff_import`, returning the new `content` and the
1531
- * text `delta` (its offsets USV indices into `Content.text`, surviving anchors
1532
- * rebased). Use it to compute a revise without a document in hand; `revise(addr,
1533
- * md)` fuses this with the store for atomicity. Throws on an over-nested
1534
- * markdown input or a non-content `base`.
1286
+ * Rebase `markdown` onto a `base` content: the document-free twin of `revise`,
1287
+ * returning the new `content` and the text `delta` (offsets are USV indices into
1288
+ * `Content.text`, surviving anchors rebased). Throws on an over-nested markdown
1289
+ * input or a non-content `base`.
1535
1290
  */
1536
1291
  export function rebase(base: Content, markdown: string): { content: Content; delta: Delta };
1537
1292
 
1538
1293
  /**
1539
- * Runs at instantiation (the wasm-bindgen start section): installs the panic
1540
- * hook, so a Rust panic reaches the console as a stack trace rather than
1541
- * `unreachable`.
1542
- *
1543
- * Not the package's `init`. That name belongs to the hand-written runtime,
1544
- * which owns instantiation itself (`runtime/runtime.js`); this runs as part of
1545
- * the instantiation it awaits.
1294
+ * Runs at instantiation, so a Rust panic reaches the console as a stack trace
1295
+ * rather than `unreachable`. Not the package's `init` that name belongs to
1296
+ * the hand-written runtime, which owns instantiation itself.
1546
1297
  */
1547
1298
  export function start(): void;
1548
1299
 
@@ -1559,6 +1310,7 @@ export interface InitOutput {
1559
1310
  readonly document__commitFields: (a: number, b: number, c: number, d: number, e: number) => void;
1560
1311
  readonly document__readerGet: (a: number, b: number, c: number, d: number) => void;
1561
1312
  readonly document__readerGetContent: (a: number, b: number, c: number, d: number) => void;
1313
+ readonly document__readerGetContentAt: (a: number, b: number, c: number, d: number, e: number) => void;
1562
1314
  readonly document__reviseField: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
1563
1315
  readonly document_applyChange: (a: number, b: number, c: number, d: number) => void;
1564
1316
  readonly document_blueprintInstruction: (a: number, b: number, c: number) => void;