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