@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.
- package/CHANGELOG.md +303 -0
- package/LICENSE +13 -0
- package/README.md +63 -60
- package/backends/pdfform/wasm.d.ts +300 -143
- package/backends/pdfform/wasm_bg.js +101 -102
- package/backends/pdfform/wasm_bg.wasm +0 -0
- package/backends/typst/wasm.d.ts +300 -143
- package/backends/typst/wasm_bg.js +101 -102
- package/backends/typst/wasm_bg.wasm +0 -0
- package/core/wasm.d.ts +127 -93
- package/core/wasm_bg.js +84 -82
- package/core/wasm_bg.wasm +0 -0
- package/package.json +2 -2
- package/runtime/runtime.d.ts +157 -79
- package/runtime/runtime.js +375 -95
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.
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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)
|
|
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
|
|
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`)
|
|
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
|
|
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
|
|
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`
|
|
281
|
-
* point
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
-
|
|
684
|
+
/**
|
|
685
|
+
* Severity levels for diagnostics
|
|
686
|
+
*/
|
|
687
|
+
export type Severity = "error" | "warning";
|
|
555
688
|
|
|
556
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
655
|
-
* 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 `""`.
|
|
724
|
-
*
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
824
|
-
* 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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1100
|
-
* `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
|
|
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
|
|
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
|
|
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
|
|
1125
|
-
* 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1196
|
-
* 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
|
|
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
|
|
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
|
|
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,
|