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