@quillmark/wasm 0.97.0 → 0.99.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.
@@ -44,7 +44,7 @@ export interface Card {
44
44
  seed?: Record<string, unknown>;
45
45
  payloadItems: PayloadItem[];
46
46
  /**
47
- * The card body as canonical `Content` the source-of-truth content model.
47
+ * The card body as canonical `Content`: the source-of-truth content model.
48
48
  * Always this content shape on read, never a markdown string. For the markdown
49
49
  * projection call the codec `exportMarkdown(card.body)`. Write a body back
50
50
  * with `doc.install(addr, rt)` / `doc.revise(addr, md)`, or via `CardInput.body`.
@@ -53,10 +53,10 @@ export interface Card {
53
53
  }
54
54
 
55
55
  /**
56
- * A card written *into* a document the input twin of `Card`, accepted by
56
+ * A card written *into* a document: the input twin of `Card`, accepted by
57
57
  * `Document.insertCard`. Like `Card` but `body` also
58
58
  * takes a markdown `string` (imported to the content, so a markdown / LLM writer
59
- * needn't build the `Content` shape), and every field but `kind` is optional
59
+ * needn't build the `Content` shape), and every field but `kind` is optional:
60
60
  * an absent field defaults (no payload items, an empty body). Write one inline
61
61
  * (`{ kind, body }`) or build it with `Document.makeCard`.
62
62
  */
@@ -71,7 +71,7 @@ export interface CardInput {
71
71
  }
72
72
 
73
73
  /**
74
- * Canonical richtext content the content model for a card body (and richtext
74
+ * Canonical richtext content: the content model for a card body (and richtext
75
75
  * fields). One text sequence over a single coordinate space (Unicode scalar
76
76
  * values): `text` plus line attributes, anchored `marks`, and embedded
77
77
  * `islands`. Every edit is a splice; markdown is a projection, not the model.
@@ -84,27 +84,38 @@ export interface Content {
84
84
  islands: ContentIsland[];
85
85
  }
86
86
 
87
- /** One `\n`-separated segment of `Content.text`, in order. */
87
+ /** One `\n`-separated segment of `Content.text`, in order. `kind` is an open set
88
+ * (as on `ContentIsland` and `ContentMark`): a role this build does not know
89
+ * round-trips with opaque `attrs` and renders as a paragraph, so a document
90
+ * carrying a future block construct still opens. The open arm blocks discriminant
91
+ * narrowing, so read `level`/`lang` behind a check of the arm you want. */
88
92
  export type ContentLine = {
89
93
  containers: ContentContainer[];
90
94
  /** A within-block hard line break rather than a new block. Omitted (false) in the common case. */
91
95
  continues?: boolean;
92
- } & (
96
+ } & ContentLineKind;
97
+
98
+ /** A line's block role, declared once for `ContentLine` and the `setKind` op:
99
+ * a new role is one edit here, as for `ContentContainer`. */
100
+ export type ContentLineKind =
93
101
  | { kind: "para" }
94
102
  | { kind: "heading"; level: number }
95
103
  | { kind: "code"; lang?: string }
96
104
  | { kind: "island" }
97
105
  | { kind: "rule" }
98
- );
106
+ | { kind: string; attrs: unknown };
99
107
 
100
- /** An ancestor block a line nests inside, outermost first. */
108
+ /** An ancestor block a line nests inside, outermost first. Open like
109
+ * `ContentLine.kind`: an unrecognized container round-trips with opaque `attrs`
110
+ * and renders transparently (its lines sit at the enclosing level). */
101
111
  export type ContentContainer =
102
112
  | { container: "list_item"; ordered: boolean; start: number; ordinal: number }
103
- | { container: "quote" };
113
+ | { container: "quote" }
114
+ | { container: string; attrs: unknown };
104
115
 
105
116
  /** A mark over char range `[start, end)` into `Content.text`. The open `type`
106
117
  * arm blocks discriminant narrowing (as on `ContentIsland`), so read a
107
- * payload-carrying arm behind its guard `isLinkMark` (`url`) / `isAnchorMark`
118
+ * payload-carrying arm behind its guard: `isLinkMark` (`url`) / `isAnchorMark`
108
119
  * (`id`), from `@quillmark/wasm/runtime`; the bare arms carry no payload. An
109
120
  * `anchor`'s `id` is a caller-supplied, opaque handle, unique per `Content` and
110
121
  * invariant while the mark lives (positions rebase, the id never does); it has no
@@ -117,7 +128,7 @@ export type ContentMark = { start: number; end: number } & (
117
128
  | { type: string; attrs: unknown }
118
129
  );
119
130
 
120
- /** A cell in a `TableProps` its plain `text` plus the `marks` over it. `marks`
131
+ /** A cell in a `TableProps`: its plain `text` plus the `marks` over it. `marks`
121
132
  * rides the same wire shape as prose `ContentMark`, but each mark's `start`/`end`
122
133
  * are USV offsets into this cell's `text` (`0..text.length`), not into
123
134
  * `Content.text`. */
@@ -145,12 +156,16 @@ export interface ImageProps {
145
156
  * open set: the engine pins `props` as `TableProps` for `table` and `ImageProps`
146
157
  * for `image`; an island of any other type round-trips with opaque `props`. Like
147
158
  * `ContentMark`, the open `type` arm means a discriminant check does not itself
148
- * narrow `props` read `props` as the matching shape behind the `isTableIsland` /
159
+ * narrow `props`: read `props` as the matching shape behind the `isTableIsland` /
149
160
  * `isImageIsland` guards (from `@quillmark/wasm/runtime`), which narrow it. */
161
+ /** How faithfully the markdown projection can carry an island. Open like an
162
+ * island `type`: a class this build does not know round-trips verbatim, and
163
+ * reads as `unrepresentable`. */
164
+ export type ContentLossClass = "lossless" | "degraded" | "unrepresentable" | (string & {});
165
+
150
166
  export type ContentIsland = {
151
167
  id: string;
152
- /** How faithfully the markdown projection can carry this island. */
153
- loss: "lossless" | "degraded" | "unrepresentable";
168
+ loss: ContentLossClass;
154
169
  } & (
155
170
  | { type: "table"; props: TableProps }
156
171
  | { type: "image"; props: ImageProps }
@@ -158,14 +173,14 @@ export type ContentIsland = {
158
173
  );
159
174
 
160
175
  /**
161
- * A write address one navigation concept for the whole `Document` surface. An
176
+ * A write address: one navigation concept for the whole `Document` surface. An
162
177
  * absent `field` targets the card body; an absent `card` targets the main card.
163
178
  * `{}` is the main-card body; `{ card: 2 }` the body of the composable card at
164
179
  * index 2; `{ field: "intro" }` the main card's `intro` field; `{ card: 2,
165
180
  * field: "intro" }` a card field.
166
181
  *
167
182
  * On the `Addr`-taking verbs a **bare string** is shorthand for `{ field: name }`
168
- * `doc.storeField("qty", 3)`, `doc.revise("intro", md)` the one coercion
183
+ * (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
169
184
  * rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
170
185
  * spelling), so no third navigation idiom re-fragments the surface.
171
186
  */
@@ -175,7 +190,7 @@ export interface Addr {
175
190
  }
176
191
 
177
192
  /**
178
- * A card-only address the axis the card-scoped verbs (`storeFields`,
193
+ * A card-only address: the axis the card-scoped verbs (`storeFields`,
179
194
  * `storeExt`, `getExt`, `commitFields`, …) take. An absent `card` targets the
180
195
  * main card. A present `field` throws: a card address takes only `card`, and a
181
196
  * would-be nested write is a bug the error names rather than silently ignores.
@@ -186,7 +201,7 @@ export interface CardAddr {
186
201
 
187
202
  /**
188
203
  * A text-splice change set over the USV content (CodeMirror `ChangeSet`
189
- * semantics) plain, structured-clone-able data. Returned by `revise` and by
204
+ * semantics): plain, structured-clone-able data. Returned by `revise` and by
190
205
  * the `rebase` codec; map a stored position through it with `mapPos`.
191
206
  */
192
207
  export interface Delta {
@@ -200,7 +215,7 @@ export type Assoc = "before" | "after";
200
215
  * A mark edit in final-text coordinates (post-delta, post-line-op). `add` /
201
216
  * `remove` carry the `ContentMark` vocabulary (`{ type, … }`); `removeAnchor`
202
217
  * drops one identity anchor by id. An `add` of an `anchor` requires a non-empty
203
- * `id` not already live in the field a collision or the empty id throws
218
+ * `id` not already live in the field: a collision or the empty id throws
204
219
  * (ids are caller-supplied and unique per `Content`; DOCUMENT_STORAGE
205
220
  * § Anchor-id identity).
206
221
  */
@@ -216,18 +231,14 @@ export type MarkOp =
216
231
  /**
217
232
  * A line/block edit. `split`/`join` splice `\n`; `setKind`/`setContainers`/
218
233
  * `setContinues` touch metadata. `setContinues` sets/clears a line's within-block
219
- * hard-break flag (`ContentLine.continues`) the op-grained way to lower a
234
+ * hard-break flag (`ContentLine.continues`): the op-grained way to lower a
220
235
  * Shift+Enter hard break or a new code-fence interior line; `continues: true` on
221
236
  * line 0 is rejected (nothing precedes it to continue).
222
237
  */
223
238
  export type LineOp =
224
239
  | { op: "split"; at: number }
225
240
  | { op: "join"; line: number }
226
- | ({ op: "setKind"; line: number } & (
227
- | { kind: "para" | "island" | "rule" }
228
- | { kind: "heading"; level: number }
229
- | { kind: "code"; lang?: string }
230
- ))
241
+ | ({ op: "setKind"; line: number } & ContentLineKind)
231
242
  | { op: "setContainers"; line: number; containers: ContentContainer[] }
232
243
  | { op: "setContinues"; line: number; continues: boolean };
233
244
 
@@ -246,7 +257,7 @@ export interface ChangeBundle {
246
257
 
247
258
  /**
248
259
  * One segment of a parsed `Diagnostic.path` (see `parseDocPath`). The head
249
- * carries the document-model root `main` (only before `body`), a `card`
260
+ * carries the document-model root: `main` (only before `body`), a `card`
250
261
  * (`kind: null` is the unknown-kind `cards[i]` form), or a `field`; the tail is
251
262
  * `field` / `index` / a terminal `body`.
252
263
  */
@@ -261,7 +272,7 @@ export type DocPathSeg =
261
272
 
262
273
  /**
263
274
  * Page dimensions in points (1 pt = 1/72 inch). Typst measures in Typst
264
- * points; pdfform measures in PDF points the same unit.
275
+ * points; pdfform measures in PDF points: the same unit.
265
276
  *
266
277
  * Report-only: the painter sizes the canvas itself based on
267
278
  * `PaintOptions`. `pageSize` is exposed for callers that need page
@@ -277,16 +288,16 @@ export interface PageSize {
277
288
  * Inputs to `LiveSession.paint`. Both fields are optional and default
278
289
  * to `1`.
279
290
  *
280
- * - `layoutScale` layout-space pixels per point (Typst point / PDF
281
- * point the same 1/72″ unit). For on-screen
291
+ * - `layoutScale` (layout-space pixels per point (Typst point / PDF
292
+ * point) the same 1/72″ unit). For on-screen
282
293
  * canvases this is CSS pixels per pt; the page's layout-pixel size is
283
294
  * `widthPt * layoutScale × heightPt * layoutScale`. The painter
284
295
  * surfaces these dimensions as `layoutWidth` / `layoutHeight` so
285
296
  * consumers can drive `canvas.style.*` (or any layout system).
286
- * - `densityScale` backing-store density multiplier. Fold
297
+ * - `densityScale`: backing-store density multiplier. Fold
287
298
  * `window.devicePixelRatio`, in-app zoom, and `visualViewport.scale`
288
299
  * (pinch-zoom) into a single value here. Defaults to `1`, which
289
- * produces a non-retina backing store pass `window.devicePixelRatio`
300
+ * produces a non-retina backing store: pass `window.devicePixelRatio`
290
301
  * for crisp output on high-DPI displays.
291
302
  *
292
303
  * The effective rasterization scale is `layoutScale * densityScale`.
@@ -302,22 +313,22 @@ export interface PaintOptions {
302
313
  /**
303
314
  * Returned by `LiveSession.paint`.
304
315
  *
305
- * - `layoutWidth` / `layoutHeight` layout-pixel dimensions of the
316
+ * - `layoutWidth` / `layoutHeight`: layout-pixel dimensions of the
306
317
  * canvas's display box. For on-screen canvases this is CSS pixels:
307
318
  * set `canvas.style.width = layoutWidth + "px"` and
308
319
  * `canvas.style.height = layoutHeight + "px"` (or feed these into
309
320
  * your layout system). Independent of `densityScale`.
310
- * - `pixelWidth` / `pixelHeight` integer backing-store pixel
321
+ * - `pixelWidth` / `pixelHeight`: integer backing-store pixel
311
322
  * dimensions the painter wrote to `canvas.width` / `canvas.height`.
312
323
  * Equal to `round(layoutWidth * densityScale)` ×
313
324
  * `round(layoutHeight * densityScale)` *unless* the requested backing
314
325
  * exceeded the painter's safe maximum (16384 px per side), in which
315
326
  * case `densityScale` was clamped to fit.
316
- * - `clamped` `true` when that 16384-px clamp fired, so the page is
327
+ * - `clamped`: `true` when that 16384-px clamp fired, so the page is
317
328
  * painted at fewer device pixels than requested and renders soft at the
318
329
  * same `canvas.style` size. Reads the clamp off the return value instead
319
330
  * of the `pixelWidth < round(layoutWidth * densityScale)` derivation.
320
- * - `effectiveDensityScale` the `densityScale` actually applied: the
331
+ * - `effectiveDensityScale`, the `densityScale` actually applied: the
321
332
  * requested value unless `clamped`, then reduced proportionally.
322
333
  * `layoutScale * effectiveDensityScale` is the scale the backing store
323
334
  * was rasterized at.
@@ -326,11 +337,11 @@ export interface PaintOptions {
326
337
  * write to them. The painter does **not** touch `canvas.style.*`;
327
338
  * consumers own layout. The write is a whole-backing-store `putImageData`,
328
339
  * which bypasses the 2D context transform, `globalAlpha`, and clip: give
329
- * each visible page its own `` you cannot composite two pages, a
340
+ * each visible page its own `<canvas>`; you cannot composite two pages, a
330
341
  * sub-rect, or a context transform through `paint`.
331
342
  *
332
343
  * For `OffscreenCanvasRenderingContext2D` (Worker rasterization, no
333
- * DOM), `layoutWidth` / `layoutHeight` are informational there's no
344
+ * DOM), `layoutWidth` / `layoutHeight` are informational: there's no
334
345
  * CSS layout box to apply them to.
335
346
  */
336
347
  export interface PaintResult {
@@ -349,7 +360,7 @@ export type FieldSource = "authored" | "default" | "zero";
349
360
 
350
361
  /**
351
362
  * One resolved row: its `name`, the value the render projection would use, and
352
- * the `FieldSource` rung it came from. Rows are an ordered array declaration
363
+ * the `FieldSource` rung it came from. Rows are an ordered array: declaration
353
364
  * order is structural, not object-key order. The card body is a `body` sibling
354
365
  * on its card, never a row in `fields`. Diagnostics stay `Quill.validate`'s;
355
366
  * schema guidance (`example:`, labels) reads from `Quill.schema`.
@@ -361,7 +372,7 @@ export interface ResolvedField {
361
372
  }
362
373
 
363
374
  /**
364
- * The main card's resolved rows in declaration order, plus its body row
375
+ * The main card's resolved rows in declaration order, plus its body row:
365
376
  * `null` when the main enables no body.
366
377
  */
367
378
  export interface ResolvedMain {
@@ -372,7 +383,7 @@ export interface ResolvedMain {
372
383
  /**
373
384
  * One composable card's resolved rows in declaration order, with its authored
374
385
  * `kind` (`null` for an unknown-kind card), its document-array `index`, and its
375
- * body row `null` when the kind enables no body.
386
+ * body row: `null` when the kind enables no body.
376
387
  */
377
388
  export interface ResolvedCard {
378
389
  kind: string | null;
@@ -383,7 +394,7 @@ export interface ResolvedCard {
383
394
 
384
395
  /**
385
396
  * The resolved-value view (`Quill.resolve`): the main card and every
386
- * composable card. Value and provenance only completeness and errors stay
397
+ * composable card. Value and provenance only: completeness and errors stay
387
398
  * `Quill.validate`.
388
399
  */
389
400
  export interface Resolved {
@@ -404,7 +415,7 @@ export interface QuillFieldUi {
404
415
  }
405
416
 
406
417
  /** One entry in a card's `ui.groups` registry: a display-label override for the
407
- * group id (the map key). An empty object carries no override the consumer
418
+ * group id (the map key). An empty object carries no override: the consumer
408
419
  * derives the label from the id (`memo_for` → "Memo For"), as it does a field
409
420
  * label from its key. */
410
421
  export interface QuillGroupUi {
@@ -416,7 +427,7 @@ export interface QuillCardUi {
416
427
  title?: string;
417
428
  /** The card's group registry: the ordered table of contents naming every
418
429
  * group a field's `ui.group` may reference. The map key is the group id, and
419
- * key order is declaration order the display-order contract, the same one
430
+ * key order is declaration order: the display-order contract, the same one
420
431
  * `fields` key order carries. Absent when the card declares no groups (or
421
432
  * uses the deprecated implicit-group form). */
422
433
  groups?: Record<string, QuillGroupUi>;
@@ -454,7 +465,7 @@ export interface QuillFieldSchema {
454
465
  properties?: Record<string, QuillFieldSchema>;
455
466
  items?: QuillFieldSchema;
456
467
  /** Present (and `true`) on a `richtext` or `plaintext` field declared
457
- * `inline` the single-paragraph, container-free, island-free constraint.
468
+ * `inline`: the single-paragraph, container-free, island-free constraint.
458
469
  * Core serializes `inline: true` into the schema JSON; absent otherwise. */
459
470
  inline?: boolean;
460
471
  }
@@ -495,67 +506,205 @@ export interface QuillMetadata {
495
506
  }
496
507
 
497
508
 
498
- export interface Artifact {
499
- format: OutputFormat;
500
- bytes: Uint8Array;
501
- mimeType: string;
502
- }
503
-
504
- export interface ChangeSet {
505
- pageCount: number;
506
- dirtyPages: number[];
509
+ /**
510
+ * A rendered field region: the quill schema field address plus its geometry on
511
+ * the page. Emitted for schema-bound fields: span-tracked content (richtext
512
+ * bodies, `richtext[]` elements, card content fields, direct scalar
513
+ * references) and form-field widgets (pdfform AcroForm, Typst `form-field`).
514
+ * Consumers use it to scroll to / highlight the focused field; for the
515
+ * reverse click direction use `LiveSession.fieldAt`, which answers over any
516
+ * placement. Geometry only: the raster is already complete, so a region is
517
+ * never a compositing input.
518
+ *
519
+ * `field` is **not** unique: content fields surface one region **per segment**
520
+ * (paragraph, heading, whole code fence) and per page each touches, a scalar
521
+ * referenced at several plate sites surfaces each site, and tracked content
522
+ * plus a `field:`-bound widget yields both. Group by `field`: every entry
523
+ * routes to that field. The whole-field highlight is the **union of a page\'s
524
+ * `span`-bearing segment rects**, so inter-paragraph whitespace stays
525
+ * uncovered; `LiveSession.fieldBoxes(field)` owns that union so
526
+ * consumers need not derive it. Later placements of one content value are not
527
+ * enumerated; `fieldAt` / `positionAt` still resolve clicks on them.
528
+ */
529
+ export interface FieldRegion {
530
+ /**
531
+ * Canonical `DocPath` field address (e.g. `\"signature_block\"`,
532
+ * `\"cards.indorsement[1].from\"`, `\"main.body\"`): the same grammar
533
+ * `parseDocPath` reads and `Diagnostic.path` carries. The session resolves
534
+ * the backend\'s plate-space per-kind ordinal to this absolute-index form,
535
+ * so one parser routes every address. Feed it back to `fieldBoxes` /
536
+ * `locate`; hit-test the click direction with `fieldAt` / `positionAt`.
537
+ */
538
+ field: string;
539
+ /**
540
+ * 0-based page index.
541
+ */
542
+ page: number;
543
+ /**
544
+ * `[x0, y0, x1, y1]` in PDF points (1/72″), bottom-left origin.
545
+ */
546
+ rect: [number, number, number, number];
547
+ /**
548
+ * The content slice this box covers: USV `[start, end)` into the field\'s
549
+ * `Content` for content ink (one segment), `undefined` for a scalar
550
+ * reference site or widget. Consumers key segment highlights on it;
551
+ * `fieldBoxes(field)` unions same-page segments for the whole-field box.
552
+ */
553
+ span?: [number, number];
507
554
  }
508
555
 
556
+ /**
557
+ * A resolved point → content position: the field a click landed in and the USV
558
+ * offset into its `Content`. The `LiveSession.positionAt` result, paired with
559
+ * `locate` (content position → caret rect). `pos` is cluster-exact and degrades
560
+ * to the containing segment\'s start on origin-less ink; `granularity` reports
561
+ * which happened so a caret UI need not guess.
562
+ */
509
563
  export interface ContentHit {
564
+ /**
565
+ * Canonical `DocPath` field address (same grammar as `FieldRegion.field`).
566
+ */
510
567
  field: string;
568
+ /**
569
+ * USV offset into the field\'s `Content`.
570
+ */
511
571
  pos: number;
572
+ /**
573
+ * Whether `pos` is cluster-exact or floored to the segment start
574
+ * (`HitGranularity`). `undefined` when the backend does not report it.
575
+ * Additive-optional.
576
+ */
512
577
  granularity?: HitGranularity;
513
578
  }
514
579
 
580
+ /**
581
+ * Diagnostic message (error or warning)
582
+ */
515
583
  export interface Diagnostic {
516
584
  severity: Severity;
517
585
  code?: string;
518
586
  message: string;
519
587
  location?: Location;
588
+ /**
589
+ * Document-model path anchor (e.g. `\"cards.indorsement[0].signature_block\"`).
590
+ *
591
+ * Set on schema validation diagnostics; `undefined` otherwise. See the
592
+ * Rust `quillmark_core::error` module docs for the path grammar.
593
+ */
520
594
  path?: string;
521
595
  hint?: string;
522
596
  sourceChain?: string[];
523
597
  }
524
598
 
525
- export interface FieldRegion {
526
- field: string;
527
- page: number;
528
- rect: [number, number, number, number];
529
- span?: [number, number];
530
- }
531
-
532
- export interface Location {
533
- file: string;
534
- line: number;
535
- column: number;
536
- }
599
+ /**
600
+ * How precisely a `ContentHit.pos` resolved: the marker a caret UI reads to
601
+ * decide whether to trust the offset. Never sub-cluster: `cluster` is the
602
+ * finest this API offers, `segment` the floor it degrades to on origin-less
603
+ * ink.
604
+ */
605
+ export type HitGranularity = "cluster" | "segment";
537
606
 
607
+ /**
608
+ * Options for rendering.
609
+ */
538
610
  export interface RenderOptions {
539
611
  format?: OutputFormat;
612
+ /**
613
+ * Pixels per inch for raster output formats (PNG).
614
+ * Ignored for vector/document formats (PDF, SVG).
615
+ * Defaults to 144.0 (2x at 72pt/inch) when omitted.
616
+ */
540
617
  ppi?: number;
618
+ /**
619
+ * Optional 0-based page indices to render (e.g., `[0, 2]` for the
620
+ * first and third pages). `undefined` renders all pages. Any index
621
+ * `>= pageCount` throws with the `typst::page_index_out_of_bounds`
622
+ * code: read `LiveSession.pageCount` first if validation is needed.
623
+ * **Not supported for PDF output**: passing `pages` with
624
+ * `format: \"pdf\"` throws with the
625
+ * `typst::pdf_page_selection_not_supported` code.
626
+ */
541
627
  pages?: number[];
628
+ /**
629
+ * Override for the PDF `/Info` `/Producer` metadata string. Omit to use
630
+ * the default (`Quillmark <version>`). Applies to PDF output only.
631
+ */
542
632
  producer?: string;
633
+ /**
634
+ * Populate `RenderResult.regions` with the schema-field geometry sidecar
635
+ * (the same entries `LiveSession.regions()` serves), for consumers
636
+ * without a live session; e.g. overlays over a one-shot SVG export.
637
+ * Defaults to `false`: exports pay no introspection cost. The sidecar
638
+ * always describes the whole document: page indices are document-space
639
+ * even when `pages` selects a subset.
640
+ */
543
641
  regions?: boolean;
544
642
  }
545
643
 
644
+ /**
645
+ * Output formats supported by backends.
646
+ *
647
+ * Gated behind the engine surface (`typst` or `pdfform`) so tsify omits
648
+ * its `.d.ts` interface from the core bundle (`pkg/core/wasm.d.ts`), which
649
+ * has no rendering surface.
650
+ */
651
+ export type OutputFormat = "pdf" | "svg" | "png";
652
+
653
+ /**
654
+ * Rendered artifact (PDF, SVG, etc.).
655
+ */
656
+ export interface Artifact {
657
+ format: OutputFormat;
658
+ /**
659
+ * Serialized via `serde_bytes` so `serde_wasm_bindgen` emits a real
660
+ * `Uint8Array` at the boundary instead of a `number[]`. Without this
661
+ * annotation, the declared `Uint8Array` type would silently lie.
662
+ */
663
+ bytes: Uint8Array;
664
+ mimeType: string;
665
+ }
666
+
667
+ /**
668
+ * Result of a render operation.
669
+ */
546
670
  export interface RenderResult {
547
671
  artifacts: Artifact[];
548
672
  warnings: Diagnostic[];
549
673
  outputFormat: OutputFormat;
550
674
  renderTimeMs: number;
675
+ /**
676
+ * Schema-field geometry sidecar: populated only when
677
+ * `RenderOptions.regions` requested it; empty otherwise. The same entries
678
+ * `LiveSession.regions()` serves, for consumers without a live session.
679
+ * Page indices are document-space even under a `pages` subset render.
680
+ */
551
681
  regions: FieldRegion[];
552
682
  }
553
683
 
554
- export type HitGranularity = "cluster" | "segment";
684
+ /**
685
+ * Severity levels for diagnostics
686
+ */
687
+ export type Severity = "error" | "warning";
555
688
 
556
- export type OutputFormat = "pdf" | "svg" | "txt" | "png";
689
+ /**
690
+ * Source location for errors and warnings
691
+ */
692
+ export interface Location {
693
+ file: string;
694
+ line: number;
695
+ column: number;
696
+ }
557
697
 
558
- export type Severity = "error" | "warning";
698
+ /**
699
+ * What a committed `LiveSession.apply` changed. `dirtyPages` lists the pages
700
+ * whose rendered content differs from the previous compile, including pages
701
+ * the edit added; removed pages are implied by `pageCount`. A preview
702
+ * repaints `dirty ∩ visible` and nothing else.
703
+ */
704
+ export interface ChangeSet {
705
+ pageCount: number;
706
+ dirtyPages: number[];
707
+ }
559
708
 
560
709
 
561
710
  /**
@@ -566,7 +715,7 @@ export class Document {
566
715
  [Symbol.dispose](): void;
567
716
  /**
568
717
  * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
569
- * at `addr` the editor splice: text delta first, then line ops, then mark
718
+ * at `addr`, the editor splice: text delta first, then line ops, then mark
570
719
  * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
571
720
  * `addr.field` targets the body, an absent `addr.card` the main card.
572
721
  *
@@ -583,7 +732,7 @@ export class Document {
583
732
  */
584
733
  static blueprintInstruction(quill_name: string): string;
585
734
  /**
586
- * A single composable card by index the whole `Card`, the card-indexed
735
+ * A single composable card by index: the whole `Card`, the card-indexed
587
736
  * twin of the [`main`](Self::main) getter, so reading one card need not
588
737
  * materialize every card via [`cards`](Self::cards). An out-of-range
589
738
  * `index` throws `edit::index_out_of_range`, matching the card write
@@ -638,54 +787,54 @@ export class Document {
638
787
  static fromMarkdown(markdown: string): Document;
639
788
  /**
640
789
  * The whole `$ext` map at `addr` (a card address, absent `card` = main), or
641
- * `undefined` when the card carries none. The fine-grained `$ext` read
790
+ * `undefined` when the card carries none. The fine-grained `$ext` read:
642
791
  * your own state without serializing the whole card. Throws on a present
643
792
  * `field` (a card address takes only `card`) or an out-of-range card.
644
793
  */
645
794
  getExt(addr?: CardAddr): Record<string, unknown> | undefined;
646
795
  /**
647
796
  * The value stored under `$ext[ns]` at `addr` (a card address, absent `card`
648
- * = main), or `undefined`. The namespace-scoped `$ext` read your own slot
797
+ * = main), or `undefined`. The namespace-scoped `$ext` read: your own slot
649
798
  * without a whole-card serialize, and non-destructive (unlike
650
799
  * `removeExtNamespace`). Throws on a present `field` or an out-of-range card.
651
800
  */
652
801
  getExtNamespace(addr: CardAddr, ns: string): unknown;
653
802
  /**
654
- * The **body** markdown projection the main body, or a composable card's
655
- * body (`{ card }`) the on-demand, lossy export (content-only marks do not
803
+ * The **body** markdown projection (the main body, or a composable card's
804
+ * body (`{ card }`)) the on-demand, lossy export (content-only marks do not
656
805
  * survive markdown). A body's type is a format fact, not a schema fact, so
657
806
  * this read stays quill-free; a body is never absent.
658
807
  *
659
808
  * `addr` is an optional **card address** (`{ card }`, absent = main). A
660
- * present `field` throws a field's markdown is read through the
809
+ * present `field` throws: a field's markdown is read through the
661
810
  * schema-plane `quill.reader(doc).get(field)`, which interprets by declared
662
- * type (#978). An out-of-range `addr.card` throws.
811
+ * type. An out-of-range `addr.card` throws.
663
812
  */
664
813
  getMarkdown(addr?: CardAddr): string;
665
814
  /**
666
- * Read the **verbatim stored value** at `addr` the raw payload value of a
815
+ * Read the **verbatim stored value** at `addr`: the raw payload value of a
667
816
  * field (a content object for a richtext field, a scalar/array/object
668
817
  * otherwise), or the **body content** when `addr.field` is absent. A bare
669
818
  * string is `Addr` shorthand for `{ field }`. Reads are total over the field
670
819
  * axis: an absent field is `undefined`; only an out-of-range `addr.card`
671
820
  * throws `edit::index_out_of_range`. Needs no schema, so it lives on
672
- * `Document` the read echo of the verbatim `store*` write, distinct from
821
+ * `Document`: the read echo of the verbatim `store*` write, distinct from
673
822
  * the interpreted schema-plane [`reader.get`](Self::reader_get). For the
674
823
  * markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
675
824
  * `reader.get` (a field's declared type).
676
825
  */
677
826
  getStored(addr: Addr | string): unknown;
678
827
  /**
679
- * Insert a card the single insertion verb: `at` absent appends, a number
828
+ * Insert a card, the single insertion verb: `at` absent appends, a number
680
829
  * inserts at that index (must be in `0..=cards.length`). Accepts a
681
- * `CardInput` a card read back (`cards` / `removeCard` / `quill.seedCard`),
830
+ * `CardInput`: a card read back (`cards` / `removeCard` / `quill.seedCard`),
682
831
  * a [`makeCard`](Document::make_card) result, or a bare `{ kind, body }`
683
832
  * (every returned `Card` is a valid `CardInput`). Throws if `card.kind` is
684
833
  * not a valid kind name, or if `at` is out of range.
685
834
  */
686
835
  insertCard(card: CardInput, at?: number): void;
687
836
  /**
688
- * **Install** a richtext value at `addr` **value semantics**, content only.
837
+ * **Install** a richtext value at `addr`: **value semantics**, content only.
689
838
  * Stores exactly `rt` (a canonical `Content` content object); the identity
690
839
  * anchors of any previous value are gone. An absent `addr.field` targets the
691
840
  * body, an absent `addr.card` the main card. For "here's new markdown," use
@@ -699,29 +848,37 @@ export class Document {
699
848
  install(addr: Addr | string, rt: Content): void;
700
849
  /**
701
850
  * Whether the field at `addr` is marked `!must_fill`. A bare string is `Addr`
702
- * shorthand for `{ field }`. `false` for an absent field (truthful it isn't
851
+ * shorthand for `{ field }`. `false` for an absent field (truthful: it isn't
703
852
  * marked) and for a body address (a body is never a fill). Only an
704
853
  * out-of-range `addr.card` throws.
705
854
  */
706
855
  isFill(addr: Addr | string): boolean;
707
856
  /**
708
857
  * Replace this document's contents **in place** from a versioned storage
709
- * DTO string the mutating twin of the static
858
+ * DTO string: the mutating twin of the static
710
859
  * [`fromJson`](Document::from_json) constructor. Parse-time `warnings` are
711
860
  * cleared. Throws (leaving the document unchanged) on an invalid DTO.
712
861
  *
713
862
  * The cross-WASM-memory `Document` bridge: mutate a document on a
714
863
  * backend-memory clone, then write the mutated state back into the caller's
715
- * canonical document with this the one way to update a live handle across
864
+ * canonical document with this, the one way to update a live handle across
716
865
  * the linear-memory seam without the caller re-binding its variable.
717
866
  */
718
867
  loadJson(json: string): void;
719
868
  /**
720
- * Build a fresh `Card` from a kind and a flat field map the ergonomic
869
+ * Build a fresh `Card` from a kind and a flat field map: the ergonomic
721
870
  * constructor for `insertCard`. `fields` is an optional
722
871
  * `Record<string, unknown>` (each entry becomes a card field, in
723
- * insertion order); `body` defaults to `""`. Kind validity is checked by
724
- * `insertCard`, not here.
872
+ * insertion order); `body` defaults to `""`.
873
+ *
874
+ * Sugar, not a required step: `insertCard` takes any `Card` object, and
875
+ * `removeCard` returns one, so a card round-trips without passing through
876
+ * here.
877
+ *
878
+ * Checks only what a detached card can decide alone: field-name grammar
879
+ * and value depth. Kind validity is positional (`main` is right for the
880
+ * root, reserved for a composable card) so `insertCard` is its gate, and
881
+ * any kind string is accepted here.
725
882
  */
726
883
  static makeCard(kind: string, fields?: Record<string, unknown>, body?: string): Card;
727
884
  /**
@@ -729,7 +886,7 @@ export class Document {
729
886
  */
730
887
  moveCard(from: number, to: number): void;
731
888
  /**
732
- * `new Document(quillRef)` a blank document: a main card carrying only
889
+ * `new Document(quillRef)`, a blank document: a main card carrying only
733
890
  * `$quill`, an empty body, and no composable cards. The programmatic
734
891
  * blank canvas: absent fields resolve at render time (`default`, else
735
892
  * type-empty zero), so nothing the caller did not set reaches the
@@ -740,7 +897,7 @@ export class Document {
740
897
  /**
741
898
  * The canonical `$quill` reference grammar as author-facing text. Core is
742
899
  * the single source of truth: drive schema `describe` and validation
743
- * messages from this instead of re-stating the rule it matches the
900
+ * messages from this instead of re-stating the rule; it matches the
744
901
  * `hint` on `parse::invalid_quill_reference`. Cache it; the value never
745
902
  * changes.
746
903
  */
@@ -748,7 +905,7 @@ export class Document {
748
905
  removeCard(index: number): Card | undefined;
749
906
  /**
750
907
  * Remove the `$ext` map on the card `addr` targets *entirely*, returning the
751
- * previous map or `undefined` a blunt escape hatch that discards every
908
+ * previous map or `undefined`: a blunt escape hatch that discards every
752
909
  * namespace at once (prefer `removeExtNamespace`). `addr` is a card address
753
910
  * (absent = main). Throws on a present `field` or an out-of-range card.
754
911
  */
@@ -774,7 +931,7 @@ export class Document {
774
931
  */
775
932
  removeSeedNamespace(card_kind: string): any;
776
933
  /**
777
- * **Revise** the richtext value at `addr` from a markdown string **edit
934
+ * **Revise** the richtext value at `addr` from a markdown string: **edit
778
935
  * semantics**, the default write path, returning the text `Delta`. Imports
779
936
  * the markdown, diffs it against the current value, rebases surviving
780
937
  * identity anchors, and returns the change an editor bridge maps its own
@@ -787,7 +944,7 @@ export class Document {
787
944
  revise(addr: Addr | string, markdown: string): Delta;
788
945
  /**
789
946
  * Read the `schema` version tag from a raw storage DTO string without a
790
- * full parse, or `undefined`. Returns unknown future versions as-is
947
+ * full parse, or `undefined`. Returns unknown future versions as-is:
791
948
  * useful to distinguish "build too old" from "payload corrupt" when
792
949
  * `fromJson` throws.
793
950
  */
@@ -796,7 +953,7 @@ export class Document {
796
953
  * The main card's `$seed` overlay object for `kind` (the `$seed[kind]`
797
954
  * entry), or `undefined` when absent. The cheap read that feeds
798
955
  * `quill.seedCard(kind, overlay)` without serializing the whole main card
799
- * via [`main`](Self::main) to fish out one key and it keeps `seedCard`
956
+ * via [`main`](Self::main) to fish out one key, and it keeps `seedCard`
800
957
  * pure: the quill still never reads the document.
801
958
  */
802
959
  seedOverlay(kind: string): Record<string, unknown> | undefined;
@@ -814,41 +971,41 @@ export class Document {
814
971
  * Replace the opaque `$ext` map on the card `addr` targets (a card address,
815
972
  * absent `card` = main). `value` must be a plain object. `$ext` carries
816
973
  * out-of-band consumer state and never reaches the rendered output; pass
817
- * `{}` for an explicit empty `$ext`. Quill-free and verbatim an opaque
974
+ * `{}` for an explicit empty `$ext`. Quill-free and verbatim: an opaque
818
975
  * `store` verb. Throws on a present `field` or an out-of-range card.
819
976
  */
820
977
  storeExt(addr: CardAddr, value: any): void;
821
978
  /**
822
979
  * Merge `value` into `$ext[ns]` on the card `addr` targets, preserving
823
- * sibling namespaces the recommended `$ext` write. `addr` is a card
824
- * address (absent = main). Quill-free and verbatim an opaque `store` verb.
980
+ * sibling namespaces: the recommended `$ext` write. `addr` is a card
981
+ * address (absent = main). Quill-free and verbatim: an opaque `store` verb.
825
982
  * Throws on a present `field` or an out-of-range card.
826
983
  */
827
984
  storeExtNamespace(addr: CardAddr, ns: string, value: any): void;
828
985
  /**
829
- * Store a field verbatim at `addr` the opaque store (**store** = verbatim,
986
+ * Store a field verbatim at `addr`: the opaque store (**store** = verbatim,
830
987
  * coercion deferred to render; the typed write is
831
988
  * [`commitField`](Document::commit_field)). A bare string is `Addr`
832
989
  * shorthand for `{ field }`, so `doc.storeField("qty", 3)` reads as written;
833
990
  * `{ card: 2, field: "qty" }` targets a composable card. Clears any
834
- * `!must_fill` marker. A body address (no `field`) throws a body is never
991
+ * `!must_fill` marker. A body address (no `field`) throws: a body is never
835
992
  * opaque; write it with `revise` / `install` / `writer.setBody`. Throws on
836
993
  * an out-of-range card or a malformed name.
837
994
  */
838
995
  storeField(addr: Addr | string, value: any): void;
839
996
  /**
840
- * Store several fields verbatim and atomically on the card `addr` targets
997
+ * Store several fields verbatim and atomically on the card `addr` targets:
841
998
  * the opaque store's batch. `addr` is a **card address** (`{ card }`, absent
842
999
  * = main); a present `field` throws. The batch verb takes the address first
843
1000
  * and is never shape-overloaded, because `card` is a legal field name:
844
1001
  * `storeFields({}, fields)` is the main card, `storeFields({ card: 2 },
845
- * fields)` a composable one never ambiguous with "set field `card`".
1002
+ * fields)` a composable one, never ambiguous with "set field `card`".
846
1003
  * Nothing is applied on error; the thrown error's `diagnostics` carry one
847
1004
  * entry per offending field. Throws on an out-of-range card.
848
1005
  */
849
1006
  storeFields(addr: CardAddr, fields: Record<string, unknown>): void;
850
1007
  /**
851
- * Store a field verbatim at `addr` and mark it `!must_fill` the opaque
1008
+ * Store a field verbatim at `addr` and mark it `!must_fill`: the opaque
852
1009
  * store's fill variant, card-capable (a bare string or `{ field }` for main,
853
1010
  * `{ card, field }` for a composable card). A body address throws. Same
854
1011
  * validation as [`storeField`](Document::store_field).
@@ -856,9 +1013,9 @@ export class Document {
856
1013
  storeFill(addr: Addr | string, value: any): void;
857
1014
  /**
858
1015
  * Merge a card-kind's seed `overlay` into the **main** card's `$seed` map
859
- * under `cardKind`, preserving sibling kinds `$seed` lives on the main
1016
+ * under `cardKind`, preserving sibling kinds: `$seed` lives on the main
860
1017
  * card by model, so this takes no address. Sets the starting values new
861
- * cards of that kind spawn with. Quill-free and verbatim an opaque `store`
1018
+ * cards of that kind spawn with. Quill-free and verbatim: an opaque `store`
862
1019
  * verb. Throws if `overlay` cannot be serialized or nests too deep.
863
1020
  */
864
1021
  storeSeedNamespace(card_kind: string, overlay: any): void;
@@ -866,7 +1023,7 @@ export class Document {
866
1023
  * Serialize this document to a versioned storage DTO string.
867
1024
  *
868
1025
  * Prefer this over `toMarkdown` for persistence across restarts or crate
869
- * upgrades the wire format is frozen per `schema` version. Parse-time
1026
+ * upgrades: the wire format is frozen per `schema` version. Parse-time
870
1027
  * `warnings` are excluded from the DTO.
871
1028
  *
872
1029
  * Output is **byte-deterministic** within a `schema` version: equal
@@ -880,7 +1037,7 @@ export class Document {
880
1037
  toMarkdown(): string;
881
1038
  /**
882
1039
  * Like [`fromJson`](Document::from_json) but returns `undefined` instead
883
- * of throwing when `json` is not a valid storage DTO use to
1040
+ * of throwing when `json` is not a valid storage DTO: use to
884
1041
  * discriminate format without exceptions as control flow.
885
1042
  * `undefined` means "not a storage DTO"; `fromMarkdown` still throws on
886
1043
  * genuinely malformed markdown.
@@ -893,7 +1050,7 @@ export class Document {
893
1050
  readonly cards: Card[];
894
1051
  /**
895
1052
  * The document's main (entry) card. Allocates and serializes on each
896
- * call cache locally if read in a hot loop.
1053
+ * call: cache locally if read in a hot loop.
897
1054
  */
898
1055
  readonly main: Card;
899
1056
  readonly quillRef: string;
@@ -905,7 +1062,7 @@ export class Document {
905
1062
  * `fieldAt`, `positionAt`, `locate`) serve the current compile. `apply(doc)`
906
1063
  * recompiles a whole document in place, transactionally (on throw every read
907
1064
  * keeps serving the last-good compile). Geometry reads reflect the current
908
- * compile; anchoring a caret across edits is the editor's job re-read
1065
+ * compile; anchoring a caret across edits is the editor's job: re-read
909
1066
  * geometry after each committed `apply`.
910
1067
  *
911
1068
  * **Empty documents.** A zero-page document yields a valid session
@@ -918,7 +1075,7 @@ export class LiveSession {
918
1075
  free(): void;
919
1076
  [Symbol.dispose](): void;
920
1077
  /**
921
- * Recompile the session against `doc` the edit verb of a live preview.
1078
+ * Recompile the session against `doc`: the edit verb of a live preview.
922
1079
  * The document is compiled through the same schema pipeline as `open`
923
1080
  * (same quill), then applied transactionally: on throw every read
924
1081
  * (`render`, `paint`, `pageSize`, `regions`, `fieldAt`) keeps serving the last-good
@@ -927,11 +1084,11 @@ export class LiveSession {
927
1084
  */
928
1085
  apply(doc: Document): ChangeSet;
929
1086
  /**
930
- * The schema field whose content is under a point on `page` the
1087
+ * The schema field whose content is under a point on `page`, the
931
1088
  * forward (click → field) direction: hit-test a click against the
932
1089
  * compiled document and get back the `DocPath` field address to focus in
933
1090
  * the editor, or `undefined` off any field's ink. `x`/`y` are PDF points
934
- * with a **bottom-left** origin, the same space as `FieldRegion.rect` —
1091
+ * with a **bottom-left** origin, the same space as `FieldRegion.rect`,
935
1092
  * from a canvas click, invert the overlay transform documented on
936
1093
  * `FieldRegion`: `x = clickPx.x / renderScale`,
937
1094
  * `y = pageHeightPt - clickPx.y / renderScale`. Unlike `regions()`,
@@ -939,19 +1096,19 @@ export class LiveSession {
939
1096
  */
940
1097
  fieldAt(page: number, x: number, y: number): string | undefined;
941
1098
  /**
942
- * The whole-field highlight boxes for `field` one union rect per page,
1099
+ * The whole-field highlight boxes for `field`: one union rect per page,
943
1100
  * over the field's `span`-bearing content segments. The convenience that
944
1101
  * owns the union `regions()` leaves derived: it keeps `regions()` the
945
- * low-level disjoint truth (#829) and folds the span-filter + per-page
1102
+ * low-level disjoint truth and folds the span-filter + per-page
946
1103
  * union here, so a "highlight the focused field" consumer stops
947
- * reimplementing it. **Content only** a field placed solely as a scalar
1104
+ * reimplementing it. **Content only**: a field placed solely as a scalar
948
1105
  * reference or a bound widget carries no `span` and returns `[]`; its box
949
1106
  * is a single `regions()` rect. Reflects the current compile, like
950
1107
  * `regions()`.
951
1108
  */
952
1109
  fieldBoxes(field: string): FieldRegion[];
953
1110
  /**
954
- * A content position → **caret rect** the reverse of `positionAt`: given
1111
+ * A content position → **caret rect**, the reverse of `positionAt`: given
955
1112
  * a field and a USV offset into its `Content`, return the box (in the
956
1113
  * same bottom-left PDF-point space as `FieldRegion.rect`) to draw a caret
957
1114
  * at, its `span` collapsed to `[pos, pos]`; `undefined` when the field
@@ -968,12 +1125,12 @@ export class LiveSession {
968
1125
  * `OffscreenCanvasRenderingContext2D`. The painter owns
969
1126
  * `canvas.width`/`height` (no `clearRect` needed); consumers own
970
1127
  * `canvas.style.*`. If `layoutScale * densityScale` exceeds 16384 px
971
- * per side, `densityScale` is clamped `PaintResult.clamped` reports it and
1128
+ * per side, `densityScale` is clamped: `PaintResult.clamped` reports it and
972
1129
  * `PaintResult.effectiveDensityScale` carries the density actually applied.
973
1130
  *
974
1131
  * `put_image_data` writes the whole backing store, bypassing the 2D
975
1132
  * context's transform, `globalAlpha`, and clip: the painter owns the entire
976
- * canvas, so each visible page needs its own `` you cannot composite
1133
+ * canvas, so each visible page needs its own `<canvas>`; you cannot composite
977
1134
  * two pages, a sub-rect, or a context transform through this call.
978
1135
  *
979
1136
  * Throws if the backend has no canvas painter, `page` is out of range,
@@ -981,18 +1138,18 @@ export class LiveSession {
981
1138
  */
982
1139
  paint(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, page: number, opts: PaintOptions | undefined): PaintResult;
983
1140
  /**
984
- * A point → **content position** the fine-grained click direction:
1141
+ * A point → **content position**, the fine-grained click direction:
985
1142
  * hit-test a point and get back the field *and* a USV offset into its
986
1143
  * `Content` (for placing a caret or mapping a selection into the content
987
1144
  * model), or `undefined` off all content ink. `x`/`y` are PDF points,
988
- * bottom-left origin the same space as `fieldAt`. The offset is
1145
+ * bottom-left origin: the same space as `fieldAt`. The offset is
989
1146
  * cluster-exact and degrades to the containing segment's start on
990
1147
  * origin-less ink (list markers, a code fence's interior). See
991
1148
  * `ContentHit`.
992
1149
  */
993
1150
  positionAt(page: number, x: number, y: number): ContentHit | undefined;
994
1151
  /**
995
- * Schema-field geometry for this compiled session each content field's
1152
+ * Schema-field geometry for this compiled session: each content field's
996
1153
  * **first placement** (one region per page it touches) plus widget and
997
1154
  * scalar-reference-site regions, keyed on the canonical `DocPath` address
998
1155
  * (`parseDocPath`-routable; the session resolves the backend's plate-space
@@ -1012,12 +1169,12 @@ export class LiveSession {
1012
1169
  /**
1013
1170
  * `true` iff `paint` and `pageSize` will succeed for this session. Derived
1014
1171
  * from the session's canvas seam, so it reflects exactly what `paint` will
1015
- * do no separately captured flag.
1172
+ * do: no separately captured flag.
1016
1173
  */
1017
1174
  readonly supportsCanvas: boolean;
1018
1175
  /**
1019
1176
  * Non-fatal diagnostics of the session's **current compile** (e.g. Typst
1020
- * font fallback) set at open and refreshed by each committed `apply`;
1177
+ * font fallback): set at open and refreshed by each committed `apply`;
1021
1178
  * a failed apply keeps the last-good compile's warnings. Also appended
1022
1179
  * to `RenderResult.warnings` on each `render()` call.
1023
1180
  */
@@ -1029,7 +1186,7 @@ export class Quill {
1029
1186
  free(): void;
1030
1187
  [Symbol.dispose](): void;
1031
1188
  /**
1032
- * Build a quill from a file tree. Pure no backend, no engine; the
1189
+ * Build a quill from a file tree. Pure: no backend, no engine; the
1033
1190
  * declared backend is resolved later, at render time.
1034
1191
  *
1035
1192
  * Accepts either a `Map<string, Uint8Array>` or a plain object
@@ -1039,11 +1196,11 @@ export class Quill {
1039
1196
  */
1040
1197
  static fromTree(tree: Map<string, Uint8Array>): Quill;
1041
1198
  /**
1042
- * The resolved-value view of `doc` against this quill's schema for every
1199
+ * The resolved-value view of `doc` against this quill's schema: for every
1043
1200
  * declared field the value the render projection would use and the
1044
1201
  * `FieldSource` rung it came from (`"authored" | "default" | "zero"`), in
1045
1202
  * one call. The card body is a `body` sibling on its card (row `name`
1046
- * `"body"`), never a row in `fields` `null` when the kind enables no body.
1203
+ * `"body"`), never a row in `fields`: `null` when the kind enables no body.
1047
1204
  *
1048
1205
  * Value and provenance only: completeness and errors stay `validate`'s
1049
1206
  * (a consumer merges it with its own diagnostic producers regardless), and
@@ -1060,11 +1217,11 @@ export class Quill {
1060
1217
  * Pass `document.seedOverlay(cardKind)` as `overlay` so a card added to a
1061
1218
  * template-derived document inherits its curated starting values; omit it
1062
1219
  * (or pass `undefined` / `null`) for the bare schema seed. `overlay` is a
1063
- * plain object this reads the document, it does not mutate it.
1220
+ * plain object: this reads the document, it does not mutate it.
1064
1221
  */
1065
1222
  seedCard(card_kind: string, overlay: Record<string, unknown> | undefined): Card | undefined;
1066
1223
  /**
1067
- * Seed a starter `Document` from the schema the main card plus one
1224
+ * Seed a starter `Document` from the schema, the main card plus one
1068
1225
  * instance of each composable card kind, each committing its fields'
1069
1226
  * `example:` values and leaving every other field absent (interpolated at
1070
1227
  * render: `default:`, else type-empty zero). Illustration-first: a field
@@ -1073,14 +1230,14 @@ export class Quill {
1073
1230
  */
1074
1231
  seedDocument(): Document;
1075
1232
  /**
1076
- * Seed a starter main `Card` (carries `$quill`) from the schema the
1233
+ * Seed a starter main `Card` (carries `$quill`) from the schema: the
1077
1234
  * `$kind: main` card of [`seedDocument`](Self::seed_document) in
1078
1235
  * isolation, committing each field's `example:` value. Returns the same
1079
1236
  * `Card` shape as the `Document.main` getter.
1080
1237
  */
1081
1238
  seedMain(): Card;
1082
1239
  /**
1083
- * Flatten this quill back into its canonical file tree the inverse of
1240
+ * Flatten this quill back into its canonical file tree: the inverse of
1084
1241
  * [`fromTree`](Self::from_tree). Round-trips: `Quill.fromTree(q.toTree())`
1085
1242
  * reproduces an equivalent quill.
1086
1243
  *
@@ -1096,8 +1253,8 @@ export class Quill {
1096
1253
  * Validate `doc` against this quill's schema, returning every diagnostic
1097
1254
  * (an empty array when the document is valid).
1098
1255
  *
1099
- * Forwards the canonical `validation::*` diagnostics same `code`,
1100
- * `path`, and `hint` the engine emits including the non-fatal
1256
+ * Forwards the canonical `validation::*` diagnostics (same `code`,
1257
+ * `path`, and `hint` the engine emits) including the non-fatal
1101
1258
  * `validation::must_fill` warning for each `!must_fill` marker left in
1102
1259
  * the document. Field values, defaults, and order are not part of this
1103
1260
  * surface: read them from the `Document` payload and `Quill.schema`
@@ -1106,14 +1263,14 @@ export class Quill {
1106
1263
  validate(doc: Document): Diagnostic[];
1107
1264
  /**
1108
1265
  * The *declared* backend identifier (`config.backend`, e.g. `"typst"`).
1109
- * Intent, not a resolved capability capability (`supportedFormats` /
1266
+ * Intent, not a resolved capability: capability (`supportedFormats` /
1110
1267
  * `supportsCanvas`) is read from the engine.
1111
1268
  */
1112
1269
  readonly backendId: string;
1113
1270
  readonly blueprint: string;
1114
1271
  /**
1115
1272
  * Identity snapshot of the `quill:` section of `Quill.yaml` plus any extra
1116
- * `quill:` keys. Pure config the backend's output formats are a
1273
+ * `quill:` keys. Pure config: the backend's output formats are a
1117
1274
  * resolved-backend capability read from the engine
1118
1275
  * (`Quillmark.supportedFormats`), not part of this snapshot.
1119
1276
  */
@@ -1121,15 +1278,15 @@ export class Quill {
1121
1278
  /**
1122
1279
  * Document schema for the quill: the user-fillable fields plus their
1123
1280
  * `ui` hints (title / group / compact / multiline). The single
1124
- * field-metadata surface drives form editors and LLM/MCP consumers
1125
- * alike. Key order in `fields`/`properties` is declaration order the
1281
+ * field-metadata surface: drives form editors and LLM/MCP consumers
1282
+ * alike. Key order in `fields`/`properties` is declaration order: the
1126
1283
  * ordering contract. Returns the `QuillSchema` shape.
1127
1284
  */
1128
1285
  readonly schema: QuillSchema;
1129
1286
  }
1130
1287
 
1131
1288
  /**
1132
- * Render engine: a backend registry and render dispatcher. Render build only
1289
+ * Render engine: a backend registry and render dispatcher. Render build only:
1133
1290
  * the core build constructs and validates quills without it.
1134
1291
  */
1135
1292
  export class Quillmark {
@@ -1147,7 +1304,7 @@ export class Quillmark {
1147
1304
  */
1148
1305
  render(quill: Quill, doc: Document, opts?: RenderOptions | null): RenderResult;
1149
1306
  /**
1150
- * The output formats `quill`'s backend can emit. Static capability
1307
+ * The output formats `quill`'s backend can emit. Static capability:
1151
1308
  * resolves the backend but compiles nothing. Throws `engine::backend_not_found`
1152
1309
  * if no registered backend matches the quill's declared backend.
1153
1310
  */
@@ -1163,7 +1320,7 @@ export class Quillmark {
1163
1320
  }
1164
1321
 
1165
1322
  /**
1166
- * Export a canonical `Content` content to its markdown projection the pure
1323
+ * Export a canonical `Content` content to its markdown projection: the pure
1167
1324
  * on-demand codec behind `exportMarkdown(card.body)`. Throws if `rt` is not a
1168
1325
  * canonical content.
1169
1326
  */
@@ -1171,7 +1328,7 @@ export function exportMarkdown(rt: Content): string;
1171
1328
 
1172
1329
  /**
1173
1330
  * Serialize structured [`DocPathSeg`] segments back to the canonical path
1174
- * string the inverse of `parseDocPath`, for a consumer that builds a path
1331
+ * string: the inverse of `parseDocPath`, for a consumer that builds a path
1175
1332
  * rather than reads one. Throws on a segment array the deserializer rejects,
1176
1333
  * and on an empty segment array (symmetric with `parseDocPath("")`, which
1177
1334
  * throws "empty path").
@@ -1179,7 +1336,7 @@ export function exportMarkdown(rt: Content): string;
1179
1336
  export function formatDocPath(segs: DocPathSeg[]): string;
1180
1337
 
1181
1338
  /**
1182
- * Import a markdown string to a canonical `Content` content the pure,
1339
+ * Import a markdown string to a canonical `Content` content: the pure,
1183
1340
  * document-free codec. Pair with `install(addr, importMarkdown(md))` to spell
1184
1341
  * the cold (anchor-losing) write at the call site; prefer `revise` for edit
1185
1342
  * semantics. Throws on an over-nested input.
@@ -1192,8 +1349,8 @@ export function importMarkdown(markdown: string): Content;
1192
1349
  export function init(): void;
1193
1350
 
1194
1351
  /**
1195
- * Map a base content position a USV index into `Content.text`, not a UTF-16
1196
- * offset through a `delta` to its new USV position: the pure position-mapping
1352
+ * Map a base content position (a USV index into `Content.text`, not a UTF-16
1353
+ * offset) through a `delta` to its new USV position: the pure position-mapping
1197
1354
  * codec an editor bridge composes to hold a caret stable across a `revise`.
1198
1355
  * `assoc` decides the side of a same-position insertion (`"after"` moves past
1199
1356
  * it). Throws on a malformed `delta`.
@@ -1203,14 +1360,14 @@ export function mapPos(delta: Delta, pos: number, assoc: Assoc): number;
1203
1360
  /**
1204
1361
  * Parse a canonical document-model `Diagnostic.path`
1205
1362
  * (`cards.<kind>[<i>].<field>`, `main.body`, `recipients[0].name`) into its
1206
- * structured [`DocPathSeg`] segments the exported inverse of the engine's
1363
+ * structured [`DocPathSeg`] segments: the exported inverse of the engine's
1207
1364
  * one path serializer, so a consumer routes on segments instead of regexing
1208
1365
  * the string. Throws on a malformed path.
1209
1366
  */
1210
1367
  export function parseDocPath(path: string): DocPathSeg[];
1211
1368
 
1212
1369
  /**
1213
- * Rebase `markdown` onto a `base` content the pure, document-free twin of
1370
+ * Rebase `markdown` onto a `base` content, the pure, document-free twin of
1214
1371
  * `revise`: cold-import + `diff_import`, returning the new `content` and the
1215
1372
  * text `delta` (its offsets USV indices into `Content.text`, surviving anchors
1216
1373
  * rebased). Use it to compute a revise without a document in hand; `revise(addr,