@quillmark/wasm 0.103.0 → 0.104.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 +120 -26
- package/README.md +4 -4
- package/backends/pdfform/wasm.d.ts +60 -6
- package/backends/pdfform/wasm.js +72 -0
- package/backends/pdfform/wasm_bg.wasm +0 -0
- package/backends/pdfform/wasm_bg.wasm.d.ts +2 -0
- package/backends/typst/wasm.d.ts +60 -6
- package/backends/typst/wasm.js +72 -0
- package/backends/typst/wasm_bg.wasm +0 -0
- package/backends/typst/wasm_bg.wasm.d.ts +2 -0
- package/core/wasm.d.ts +59 -5
- package/core/wasm.js +72 -0
- package/core/wasm_bg.wasm +0 -0
- package/core/wasm_bg.wasm.d.ts +2 -0
- package/package.json +2 -2
- package/runtime/runtime.d.ts +4 -1
- package/runtime/runtime.js +21 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,125 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.104.0 - 2026-08-13
|
|
4
|
+
|
|
5
|
+
- feat(core,wasm): a quill declares, per body, the block constructs its plate
|
|
6
|
+
does not typeset (`main.body.unsupported`, `card_kinds.<k>.body.unsupported`;
|
|
7
|
+
names from `heading`, `rule`, `code`, `list`, `quote`, `table`, `image`).
|
|
8
|
+
A body holding one anyway draws the non-fatal `plate::unsupported_construct`,
|
|
9
|
+
a fifth warning family, on the pre-render walk `Quill::parse` runs beside
|
|
10
|
+
`conform`: one diagnostic per (body, construct) carrying the count in `args`
|
|
11
|
+
and the body's path, so occurrences collapse rather than scatter. The
|
|
12
|
+
declaration also rides `QuillConfig::schema()` to the editor, which is the
|
|
13
|
+
half a render-time warning could not serve: it answers before the gesture.
|
|
14
|
+
Nothing verifies a declaration — a plate that drops an undeclared construct
|
|
15
|
+
stays as silent as before. `usaf_memo` declares `rule`; empty everywhere
|
|
16
|
+
else, so no existing quill's schema or warnings change.
|
|
17
|
+
- fix(fixtures): `usaf_memo`'s `render-body` drained its heading buffer in the
|
|
18
|
+
three shapes that used to discard it. A heading with nothing after it (the
|
|
19
|
+
buffer died with the loop, taking a list item's bullet with it), a heading
|
|
20
|
+
whose next element opened a *different* list item (its text was delivered
|
|
21
|
+
into that item), and a heading following a heading (the assignment overwrote
|
|
22
|
+
the earlier one) each lost their text with nothing in the render to say so.
|
|
23
|
+
The run-in style is unchanged where it was right: a heading joins the next
|
|
24
|
+
block of its own item, or the next paragraph at top level.
|
|
25
|
+
- fix(content)!: `to_markdown` writes `***` for a thematic break, not `---`.
|
|
26
|
+
`- ` + `---` is four dashes separated by spaces, which re-imports as a
|
|
27
|
+
top-level break, so a rule as a bullet item's first block lost its item on
|
|
28
|
+
every markdown round-trip. The canonical spelling is now the one with the
|
|
29
|
+
fewest other readings (`---` is also a setext underline and the root-block
|
|
30
|
+
front-matter opener). Exported markdown changes for documents holding a
|
|
31
|
+
rule; the content model, wire data and rendered output do not.
|
|
32
|
+
- refactor(core,pdfform,cli,wasm)!: the `enum:` modifier on `type: string`
|
|
33
|
+
retires. `type: enum` with a `values:` list is the one spelling of a finite
|
|
34
|
+
string domain; `enum:` on any type is now `quill::field_parse_error`, whose
|
|
35
|
+
message names the replacement — it is the only diagnostic a quill written
|
|
36
|
+
against the modifier ever received, since the deprecation shipped in 0.94
|
|
37
|
+
with no warning code behind it. `QuillConfig::schema()` re-emits every
|
|
38
|
+
domain as `values:`, so a consumer reading `enum:` off the schema echo (the
|
|
39
|
+
wasm `QuillFieldSchema.enum`, dropped here) reads `values:` instead. The
|
|
40
|
+
`usaf_memo` and `sample_form` fixtures migrate; wire data and rendered
|
|
41
|
+
output are unchanged, the projections being domain-keyed already.
|
|
42
|
+
- fix(core): `build_transform_schema` keys a field's finite domain on the
|
|
43
|
+
domain itself rather than the `Enum` token, joining the render floor, the
|
|
44
|
+
pdfform widget kind and the blueprint annotation. Under the retired
|
|
45
|
+
spelling every `usaf_memo` enum — `classification`, `format`, `action` —
|
|
46
|
+
projected as a bare `{"type":"string"}`, so a consumer building a
|
|
47
|
+
JSON-Schema validator from the transform schema accepted
|
|
48
|
+
`classification: "banana"` while pdfform drew the six-option dropdown for
|
|
49
|
+
the same field and `QuillConfig` rejected the value at coercion (#1237)
|
|
50
|
+
- fix(core)!: geometry addresses parse segment-wise, so `locate` and
|
|
51
|
+
`fieldBoxes` answer for an address deeper than one segment. The translation
|
|
52
|
+
boundary folded a plate address's whole tail into one `Field`, so
|
|
53
|
+
`references.0` minted `main.references.0` — a string that reparses as a field
|
|
54
|
+
literally named `0`, and that the reverse direction refused outright. Both
|
|
55
|
+
spellings returned `None`, leaving caret placement and whole-field highlight
|
|
56
|
+
dead for **every** `array<richtext>` element (the flagship memo's
|
|
57
|
+
`references` among them) and for every nested key a pdfform widget binds
|
|
58
|
+
(`address.city`). `region.rs` now reads and renders a plate tail one segment
|
|
59
|
+
at a time: an all-digit segment is an array index, `$body` the body terminal,
|
|
60
|
+
anything else a field or map key.
|
|
61
|
+
- change(wasm, python)!: `RenderedRegion.field`, `FieldRegion.field` and
|
|
62
|
+
`ContentHit.field` spell an array element bracketed — `main.references.0`
|
|
63
|
+
becomes `main.references[0]` — on `regions()`, `fieldAt`, `positionAt` and
|
|
64
|
+
`RenderResult.regions`. This is the spelling schema validation already emits,
|
|
65
|
+
so a `Diagnostic.path` and the geometry address for one place are now the same
|
|
66
|
+
string. A consumer finding an address's children by prefix (`startsWith(`${field}.`)`)
|
|
67
|
+
needs the `[` opener too, and any heuristic reading a trailing all-digit field
|
|
68
|
+
name as a lost index is dead.
|
|
69
|
+
- feat(wasm): `doc.pathFor(addr)` mints an `Addr` as the canonical `DocPath`
|
|
70
|
+
string `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
|
|
71
|
+
take; `doc.cardPath(i)` is the card's own root. `Document` computed the
|
|
72
|
+
kind-qualified root for every addressed write and did not hand it out, so a
|
|
73
|
+
consumer building a path restated the kind lookup, the `Addr` defaults and the
|
|
74
|
+
range guard — and a wrong-kind path is compared as a string, matching nothing
|
|
75
|
+
and drawing no highlight without throwing. Both are quill-free (the stored
|
|
76
|
+
`$kind` verbatim) and total on the index axis: a path is an anchor, not a
|
|
77
|
+
read, so a per-keystroke call needs no `try` (#1225)
|
|
78
|
+
- change(wasm)!: `@quillmark/wasm` declares `engines: { node: ">=24" }`, the
|
|
79
|
+
tier CI builds and tests the bindings on and the one both devcontainers hand a
|
|
80
|
+
contributor. Nothing in the package requires it at runtime, so a Node 22
|
|
81
|
+
install fails `engines` checking without failing at import.
|
|
82
|
+
- docs: `docs/migrations/0.103-to-0.104.md` carries the four breaks — the
|
|
83
|
+
retired `enum:` modifier, the bracketed index spelling, the `***` thematic
|
|
84
|
+
break and the Node floor — with the prefix-match, trailing-digit and stored
|
|
85
|
+
-markdown shapes a consumer has to fix, and the two additive surfaces
|
|
86
|
+
(`pathFor` / `cardPath`, and the `plate::unsupported_construct` family a
|
|
87
|
+
code-routing consumer gains an arm for).
|
|
88
|
+
- test(core): three characterization tests pin the render floor's two
|
|
89
|
+
type-domain edges (a defaultless enum, top-level and nested in a typed
|
|
90
|
+
dictionary) and an authored empty `date` beside an empty `string`, so the
|
|
91
|
+
coercion difference between the two is one test's diff. Every shipped quill
|
|
92
|
+
declares a `default:` on every enum and none authors an empty `date`, so the
|
|
93
|
+
fixture suite reached neither path. A fourth carries a `!must_fill` tag on two
|
|
94
|
+
example-seeded cells through seed → store → load → conform. Refs #1234
|
|
95
|
+
|
|
96
|
+
<!-- seed: commits since v0.103.0, confirm the entries above cover them, then delete this comment
|
|
97
|
+
- Carry the thematic-break and unsupported-construct work into the guide
|
|
98
|
+
- Dense-prose pass over the new comments and docs
|
|
99
|
+
- Let a quill declare the constructs its plate does not typeset
|
|
100
|
+
- Drain the memo's heading buffer instead of dropping it
|
|
101
|
+
- Canonicalize a thematic break to `***`
|
|
102
|
+
- Close the 0.104 release gaps: the migration guide, and four changelog entries
|
|
103
|
+
- Retire the enum: modifier; project a field's domain by capability
|
|
104
|
+
- Pin the render floor's two type-domain edges and the seeded fill tag
|
|
105
|
+
- Raise the Node floor to 24
|
|
106
|
+
- dense-prose pass over the added prose
|
|
107
|
+
- docs: dense-prose pass on the text-type sections
|
|
108
|
+
- docs: give the text-type choice a decision procedure
|
|
109
|
+
- docs: state the backend seam's scope and reserve its namespaces
|
|
110
|
+
- docs: drop the private intra-doc link from pathFor
|
|
111
|
+
- fix(core): state the unspellable-tail conditions instead of linking a private fn
|
|
112
|
+
- chore(wasm): density pass, and gate a core-build dead function
|
|
113
|
+
- docs: dense-prose pass over the geometry-address translation
|
|
114
|
+
- docs: dense-prose pass over the pathFor / cardPath prose
|
|
115
|
+
- test(wasm): execute the static-export exemption instead of listing it
|
|
116
|
+
- feat(wasm): mint a DocPath from an Addr (#1225)
|
|
117
|
+
- fix(core)!: parse geometry addresses segment-wise (#1223)
|
|
118
|
+
- docs: carry the 0.103 CLI break, and the init gate into the quickstart (#1222)
|
|
119
|
+
- SCHEMAS.md: a declared type change rewrites stored values (#1221)
|
|
120
|
+
-->
|
|
121
|
+
|
|
122
|
+
|
|
3
123
|
## v0.103.0 - 2026-08-09
|
|
4
124
|
|
|
5
125
|
- docs: `docs/integration/operations.md`, carrying what the other integration
|
|
@@ -50,32 +170,6 @@
|
|
|
50
170
|
documents and stored blobs are unaffected. See
|
|
51
171
|
`docs/migrations/0.102-to-0.103.md`
|
|
52
172
|
|
|
53
|
-
<!-- seed: commits since v0.102.0, confirm the entries above cover them, then delete this comment
|
|
54
|
-
- ci: tag the merge commit, and serialize a release against itself
|
|
55
|
-
- ci: drop the tagger GitHub App from the release workflows
|
|
56
|
-
- Cut SECURITY.md, and operations.md down to what only it can say
|
|
57
|
-
- Drop the audit gate; keep the reachability finding in ci.yml's note
|
|
58
|
-
- Fix two wrong claims, a dead property, and the stdout bug the review found
|
|
59
|
-
- dense-prose pass over the added prose, and read the fixture once
|
|
60
|
-
- Close four production-readiness gaps: audit gate, ops docs, CLI tests, PDF fuzzing
|
|
61
|
-
- Drop the README's claim about the deleted sentinel patch
|
|
62
|
-
- dense-prose pass: cut the restatement the change introduced
|
|
63
|
-
- docs: the 0.102 → 0.103 step, and correct the surface it describes
|
|
64
|
-
- The gate is the only door to the core surface
|
|
65
|
-
- docs(migration): a span guide for 0.92 → 0.102
|
|
66
|
-
- Cut over-specified style rules; author preference wins
|
|
67
|
-
- dense-prose: remove the em-dash ban
|
|
68
|
-
- dense-prose: drop the line-budget clause
|
|
69
|
-
- dense-prose: wrong is worse than missing; relax em-dash ban
|
|
70
|
-
- docs: dense-prose pass over the conform-scope and date-grammar prose
|
|
71
|
-
- docs: migration guides are era-stamped, not immutable
|
|
72
|
-
- docs(migrations): give the datetime split its corpus audit step
|
|
73
|
-
- docs: scope conform to content fields, state the date corpus precondition
|
|
74
|
-
- Tighten the failure-delivery prose
|
|
75
|
-
- Deliver init's conflict as a rejection, not a synchronous throw
|
|
76
|
-
-->
|
|
77
|
-
|
|
78
|
-
|
|
79
173
|
## v0.102.0 - 2026-08-04
|
|
80
174
|
|
|
81
175
|
The pre-1.0 vocabulary reset. Verbs, diagnostic codes, and two words that meant
|
package/README.md
CHANGED
|
@@ -604,11 +604,11 @@ call returns: `try { return engine.render(quill, doc); } finally
|
|
|
604
604
|
{ doc.free(); }`: is safe even on the first render, while the backend
|
|
605
605
|
binary is still loading.
|
|
606
606
|
|
|
607
|
-
The package floor is Node
|
|
607
|
+
The package floor is Node 24+ (`engines: { node: ">=24" }`) and current
|
|
608
608
|
evergreen browsers; `--weak-refs` itself only needs Node 14.6+. The `using`
|
|
609
|
-
sugar ([explicit resource management][erm])
|
|
610
|
-
|
|
611
|
-
|
|
609
|
+
sugar ([explicit resource management][erm]) is on that floor and optional;
|
|
610
|
+
an explicit `try` / `finally` is the equivalent, and the form that also runs
|
|
611
|
+
in a browser that hasn't shipped it:
|
|
612
612
|
|
|
613
613
|
```ts
|
|
614
614
|
const session = await engine.open(quill, doc);
|
|
@@ -181,6 +181,11 @@ export type ContentIsland = {
|
|
|
181
181
|
* (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
|
|
182
182
|
* rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
|
|
183
183
|
* spelling), so no third navigation idiom re-fragments the surface.
|
|
184
|
+
*
|
|
185
|
+
* `doc.pathFor(addr)` mints the address as its canonical `DocPath` string, the
|
|
186
|
+
* anchor `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
|
|
187
|
+
* take: a card path is kind-qualified, so building one by hand needs the card's
|
|
188
|
+
* `$kind`, and a wrong-kind path matches nothing silently.
|
|
184
189
|
*/
|
|
185
190
|
export interface Addr {
|
|
186
191
|
card?: number;
|
|
@@ -479,12 +484,32 @@ export interface QuillCardUi {
|
|
|
479
484
|
groups?: Record<string, QuillGroupUi>;
|
|
480
485
|
}
|
|
481
486
|
|
|
487
|
+
/** A block construct a body can hold. `paragraph` is absent on purpose: it is
|
|
488
|
+
* the floor and cannot be declined. */
|
|
489
|
+
export type QuillBlockConstruct =
|
|
490
|
+
| "heading"
|
|
491
|
+
| "rule"
|
|
492
|
+
| "code"
|
|
493
|
+
| "list"
|
|
494
|
+
| "quote"
|
|
495
|
+
| "table"
|
|
496
|
+
| "image";
|
|
497
|
+
|
|
482
498
|
/** Body namespace for a card (main or named card kind). */
|
|
483
499
|
export interface QuillCardBody {
|
|
484
500
|
/** When false, consumers must not accept or store body content for this card kind. Defaults to true. */
|
|
485
501
|
enabled?: boolean;
|
|
486
502
|
/** Example body content embedded verbatim in the blueprint body region. Fallback is "Write <card> body here." */
|
|
487
503
|
example?: string;
|
|
504
|
+
/** Block constructs this quill's plate does not typeset in this body.
|
|
505
|
+
*
|
|
506
|
+
* Absent or empty means it declines nothing, which is the default. An
|
|
507
|
+
* editor reads this to decline a gesture before the author makes it; a body
|
|
508
|
+
* that holds one anyway draws a non-fatal `plate::unsupported_construct`
|
|
509
|
+
* warning carrying the construct and a count. It is the quill's claim about
|
|
510
|
+
* its own plate, and nothing verifies it: a construct absent from this list
|
|
511
|
+
* is not a promise that the plate typesets it. */
|
|
512
|
+
unsupported?: QuillBlockConstruct[];
|
|
488
513
|
}
|
|
489
514
|
|
|
490
515
|
/** Schema entry for a single field declared in a quill's `Quill.yaml`.
|
|
@@ -501,11 +526,8 @@ export interface QuillFieldSchema {
|
|
|
501
526
|
description?: string;
|
|
502
527
|
default?: unknown;
|
|
503
528
|
example?: unknown;
|
|
504
|
-
/**
|
|
505
|
-
*
|
|
506
|
-
* release. Both round-trip through this field. */
|
|
507
|
-
enum?: string[];
|
|
508
|
-
/** Required on `type: "enum"`: the closed set of allowed string values. */
|
|
529
|
+
/** Required on `type: "enum"`, and valid nowhere else: the closed set of
|
|
530
|
+
* allowed string values. */
|
|
509
531
|
values?: string[];
|
|
510
532
|
ui?: QuillFieldUi;
|
|
511
533
|
properties?: Record<string, QuillFieldSchema>;
|
|
@@ -752,7 +774,7 @@ export interface Location {
|
|
|
752
774
|
}
|
|
753
775
|
|
|
754
776
|
/**
|
|
755
|
-
* What a committed `LiveSession.
|
|
777
|
+
* What a committed `LiveSession.update` changed. `dirtyPages` lists the pages
|
|
756
778
|
* whose rendered content differs from the previous compile, including pages
|
|
757
779
|
* the edit added; removed pages are implied by `pageCount`. A preview
|
|
758
780
|
* repaints `dirty ∩ visible` and nothing else.
|
|
@@ -812,6 +834,13 @@ export class Document {
|
|
|
812
834
|
* verbs.
|
|
813
835
|
*/
|
|
814
836
|
card(index: number): Card;
|
|
837
|
+
/**
|
|
838
|
+
* The composable card's own path, `cards.<kind>[index]`: the whole-card
|
|
839
|
+
* root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
|
|
840
|
+
* card rather than one of its fields. Total on the index axis for the same
|
|
841
|
+
* reason, out of range renders `cards[index]`.
|
|
842
|
+
*/
|
|
843
|
+
cardPath(index: number): string;
|
|
815
844
|
clone(): Document;
|
|
816
845
|
/**
|
|
817
846
|
* Storage version this build writes via [`toJson`](Document::to_json).
|
|
@@ -959,6 +988,29 @@ export class Document {
|
|
|
959
988
|
* not a canonical content object.
|
|
960
989
|
*/
|
|
961
990
|
overwrite(addr: Addr | string, rt: Content): void;
|
|
991
|
+
/**
|
|
992
|
+
* `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
|
|
993
|
+
* carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
|
|
994
|
+
* `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
|
|
995
|
+
* `Addr` mints one without restating the kind lookup, the `Addr` defaults
|
|
996
|
+
* or the range guard.
|
|
997
|
+
*
|
|
998
|
+
* The kind is the card's stored `$kind` verbatim, the quill-free rule the
|
|
999
|
+
* addressed mutators anchor with and the geometry translation uses, not
|
|
1000
|
+
* `validate`'s declared-kind filter: a `Document` holds a `$quill`
|
|
1001
|
+
* reference and no schema. That is the one edge where this path and a
|
|
1002
|
+
* `validate` diagnostic path differ for the same card.
|
|
1003
|
+
*
|
|
1004
|
+
* **Total on the index axis**, unlike the `Addr` reads (`getStored`,
|
|
1005
|
+
* `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
|
|
1006
|
+
* a read. An out-of-range `{card: 7, field: "from"}` extends the
|
|
1007
|
+
* unknown-kind root `edit::index_out_of_range` anchors at, rendering
|
|
1008
|
+
* `cards[7].from`, which parses back and resolves to nothing rather than
|
|
1009
|
+
* mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
|
|
1010
|
+
* a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
|
|
1011
|
+
* address throws.
|
|
1012
|
+
*/
|
|
1013
|
+
pathFor(addr: Addr | string): string;
|
|
962
1014
|
/**
|
|
963
1015
|
* The canonical `$quill` reference grammar as author-facing text. Core is
|
|
964
1016
|
* the single source of truth: drive schema `describe` and validation
|
|
@@ -1513,6 +1565,7 @@ export interface InitOutput {
|
|
|
1513
1565
|
readonly document_bodyMarkdown: (a: number, b: number, c: number) => void;
|
|
1514
1566
|
readonly document_card: (a: number, b: number, c: number) => void;
|
|
1515
1567
|
readonly document_cardCount: (a: number) => number;
|
|
1568
|
+
readonly document_cardPath: (a: number, b: number, c: number) => void;
|
|
1516
1569
|
readonly document_cards: (a: number, b: number) => void;
|
|
1517
1570
|
readonly document_clone: (a: number) => number;
|
|
1518
1571
|
readonly document_currentStorageVersion: (a: number) => void;
|
|
@@ -1532,6 +1585,7 @@ export interface InitOutput {
|
|
|
1532
1585
|
readonly document_moveCard: (a: number, b: number, c: number, d: number) => void;
|
|
1533
1586
|
readonly document_new: (a: number, b: number, c: number) => void;
|
|
1534
1587
|
readonly document_overwrite: (a: number, b: number, c: number, d: number) => void;
|
|
1588
|
+
readonly document_pathFor: (a: number, b: number, c: number) => void;
|
|
1535
1589
|
readonly document_quillRef: (a: number, b: number) => void;
|
|
1536
1590
|
readonly document_quillRefHint: (a: number) => void;
|
|
1537
1591
|
readonly document_removeCard: (a: number, b: number, c: number) => void;
|
package/backends/pdfform/wasm.js
CHANGED
|
@@ -368,6 +368,30 @@ export class Document {
|
|
|
368
368
|
const ret = wasm.document_cardCount(this.__wbg_ptr);
|
|
369
369
|
return ret >>> 0;
|
|
370
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* The composable card's own path, `cards.<kind>[index]`: the whole-card
|
|
373
|
+
* root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
|
|
374
|
+
* card rather than one of its fields. Total on the index axis for the same
|
|
375
|
+
* reason, out of range renders `cards[index]`.
|
|
376
|
+
* @param {number} index
|
|
377
|
+
* @returns {string}
|
|
378
|
+
*/
|
|
379
|
+
cardPath(index) {
|
|
380
|
+
let deferred1_0;
|
|
381
|
+
let deferred1_1;
|
|
382
|
+
try {
|
|
383
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
384
|
+
wasm.document_cardPath(retptr, this.__wbg_ptr, index);
|
|
385
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
386
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
387
|
+
deferred1_0 = r0;
|
|
388
|
+
deferred1_1 = r1;
|
|
389
|
+
return getStringFromWasm0(r0, r1);
|
|
390
|
+
} finally {
|
|
391
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
392
|
+
wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
371
395
|
/**
|
|
372
396
|
* @returns {Card[]}
|
|
373
397
|
*/
|
|
@@ -815,6 +839,54 @@ export class Document {
|
|
|
815
839
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
816
840
|
}
|
|
817
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
|
|
844
|
+
* carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
|
|
845
|
+
* `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
|
|
846
|
+
* `Addr` mints one without restating the kind lookup, the `Addr` defaults
|
|
847
|
+
* or the range guard.
|
|
848
|
+
*
|
|
849
|
+
* The kind is the card's stored `$kind` verbatim, the quill-free rule the
|
|
850
|
+
* addressed mutators anchor with and the geometry translation uses, not
|
|
851
|
+
* `validate`'s declared-kind filter: a `Document` holds a `$quill`
|
|
852
|
+
* reference and no schema. That is the one edge where this path and a
|
|
853
|
+
* `validate` diagnostic path differ for the same card.
|
|
854
|
+
*
|
|
855
|
+
* **Total on the index axis**, unlike the `Addr` reads (`getStored`,
|
|
856
|
+
* `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
|
|
857
|
+
* a read. An out-of-range `{card: 7, field: "from"}` extends the
|
|
858
|
+
* unknown-kind root `edit::index_out_of_range` anchors at, rendering
|
|
859
|
+
* `cards[7].from`, which parses back and resolves to nothing rather than
|
|
860
|
+
* mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
|
|
861
|
+
* a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
|
|
862
|
+
* address throws.
|
|
863
|
+
* @param {Addr | string} addr
|
|
864
|
+
* @returns {string}
|
|
865
|
+
*/
|
|
866
|
+
pathFor(addr) {
|
|
867
|
+
let deferred2_0;
|
|
868
|
+
let deferred2_1;
|
|
869
|
+
try {
|
|
870
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
871
|
+
wasm.document_pathFor(retptr, this.__wbg_ptr, addHeapObject(addr));
|
|
872
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
873
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
874
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
875
|
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
|
876
|
+
var ptr1 = r0;
|
|
877
|
+
var len1 = r1;
|
|
878
|
+
if (r3) {
|
|
879
|
+
ptr1 = 0; len1 = 0;
|
|
880
|
+
throw takeObject(r2);
|
|
881
|
+
}
|
|
882
|
+
deferred2_0 = ptr1;
|
|
883
|
+
deferred2_1 = len1;
|
|
884
|
+
return getStringFromWasm0(ptr1, len1);
|
|
885
|
+
} finally {
|
|
886
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
887
|
+
wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
818
890
|
/**
|
|
819
891
|
* @returns {string}
|
|
820
892
|
*/
|
|
Binary file
|
|
@@ -16,6 +16,7 @@ export const document_blueprintInstruction: (a: number, b: number, c: number) =>
|
|
|
16
16
|
export const document_bodyMarkdown: (a: number, b: number, c: number) => void;
|
|
17
17
|
export const document_card: (a: number, b: number, c: number) => void;
|
|
18
18
|
export const document_cardCount: (a: number) => number;
|
|
19
|
+
export const document_cardPath: (a: number, b: number, c: number) => void;
|
|
19
20
|
export const document_cards: (a: number, b: number) => void;
|
|
20
21
|
export const document_clone: (a: number) => number;
|
|
21
22
|
export const document_currentStorageVersion: (a: number) => void;
|
|
@@ -35,6 +36,7 @@ export const document_makeCard: (a: number, b: number, c: number, d: number, e:
|
|
|
35
36
|
export const document_moveCard: (a: number, b: number, c: number, d: number) => void;
|
|
36
37
|
export const document_new: (a: number, b: number, c: number) => void;
|
|
37
38
|
export const document_overwrite: (a: number, b: number, c: number, d: number) => void;
|
|
39
|
+
export const document_pathFor: (a: number, b: number, c: number) => void;
|
|
38
40
|
export const document_quillRef: (a: number, b: number) => void;
|
|
39
41
|
export const document_quillRefHint: (a: number) => void;
|
|
40
42
|
export const document_removeCard: (a: number, b: number, c: number) => void;
|
package/backends/typst/wasm.d.ts
CHANGED
|
@@ -181,6 +181,11 @@ export type ContentIsland = {
|
|
|
181
181
|
* (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
|
|
182
182
|
* rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
|
|
183
183
|
* spelling), so no third navigation idiom re-fragments the surface.
|
|
184
|
+
*
|
|
185
|
+
* `doc.pathFor(addr)` mints the address as its canonical `DocPath` string, the
|
|
186
|
+
* anchor `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
|
|
187
|
+
* take: a card path is kind-qualified, so building one by hand needs the card's
|
|
188
|
+
* `$kind`, and a wrong-kind path matches nothing silently.
|
|
184
189
|
*/
|
|
185
190
|
export interface Addr {
|
|
186
191
|
card?: number;
|
|
@@ -479,12 +484,32 @@ export interface QuillCardUi {
|
|
|
479
484
|
groups?: Record<string, QuillGroupUi>;
|
|
480
485
|
}
|
|
481
486
|
|
|
487
|
+
/** A block construct a body can hold. `paragraph` is absent on purpose: it is
|
|
488
|
+
* the floor and cannot be declined. */
|
|
489
|
+
export type QuillBlockConstruct =
|
|
490
|
+
| "heading"
|
|
491
|
+
| "rule"
|
|
492
|
+
| "code"
|
|
493
|
+
| "list"
|
|
494
|
+
| "quote"
|
|
495
|
+
| "table"
|
|
496
|
+
| "image";
|
|
497
|
+
|
|
482
498
|
/** Body namespace for a card (main or named card kind). */
|
|
483
499
|
export interface QuillCardBody {
|
|
484
500
|
/** When false, consumers must not accept or store body content for this card kind. Defaults to true. */
|
|
485
501
|
enabled?: boolean;
|
|
486
502
|
/** Example body content embedded verbatim in the blueprint body region. Fallback is "Write <card> body here." */
|
|
487
503
|
example?: string;
|
|
504
|
+
/** Block constructs this quill's plate does not typeset in this body.
|
|
505
|
+
*
|
|
506
|
+
* Absent or empty means it declines nothing, which is the default. An
|
|
507
|
+
* editor reads this to decline a gesture before the author makes it; a body
|
|
508
|
+
* that holds one anyway draws a non-fatal `plate::unsupported_construct`
|
|
509
|
+
* warning carrying the construct and a count. It is the quill's claim about
|
|
510
|
+
* its own plate, and nothing verifies it: a construct absent from this list
|
|
511
|
+
* is not a promise that the plate typesets it. */
|
|
512
|
+
unsupported?: QuillBlockConstruct[];
|
|
488
513
|
}
|
|
489
514
|
|
|
490
515
|
/** Schema entry for a single field declared in a quill's `Quill.yaml`.
|
|
@@ -501,11 +526,8 @@ export interface QuillFieldSchema {
|
|
|
501
526
|
description?: string;
|
|
502
527
|
default?: unknown;
|
|
503
528
|
example?: unknown;
|
|
504
|
-
/**
|
|
505
|
-
*
|
|
506
|
-
* release. Both round-trip through this field. */
|
|
507
|
-
enum?: string[];
|
|
508
|
-
/** Required on `type: "enum"`: the closed set of allowed string values. */
|
|
529
|
+
/** Required on `type: "enum"`, and valid nowhere else: the closed set of
|
|
530
|
+
* allowed string values. */
|
|
509
531
|
values?: string[];
|
|
510
532
|
ui?: QuillFieldUi;
|
|
511
533
|
properties?: Record<string, QuillFieldSchema>;
|
|
@@ -752,7 +774,7 @@ export interface Location {
|
|
|
752
774
|
}
|
|
753
775
|
|
|
754
776
|
/**
|
|
755
|
-
* What a committed `LiveSession.
|
|
777
|
+
* What a committed `LiveSession.update` changed. `dirtyPages` lists the pages
|
|
756
778
|
* whose rendered content differs from the previous compile, including pages
|
|
757
779
|
* the edit added; removed pages are implied by `pageCount`. A preview
|
|
758
780
|
* repaints `dirty ∩ visible` and nothing else.
|
|
@@ -812,6 +834,13 @@ export class Document {
|
|
|
812
834
|
* verbs.
|
|
813
835
|
*/
|
|
814
836
|
card(index: number): Card;
|
|
837
|
+
/**
|
|
838
|
+
* The composable card's own path, `cards.<kind>[index]`: the whole-card
|
|
839
|
+
* root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
|
|
840
|
+
* card rather than one of its fields. Total on the index axis for the same
|
|
841
|
+
* reason, out of range renders `cards[index]`.
|
|
842
|
+
*/
|
|
843
|
+
cardPath(index: number): string;
|
|
815
844
|
clone(): Document;
|
|
816
845
|
/**
|
|
817
846
|
* Storage version this build writes via [`toJson`](Document::to_json).
|
|
@@ -959,6 +988,29 @@ export class Document {
|
|
|
959
988
|
* not a canonical content object.
|
|
960
989
|
*/
|
|
961
990
|
overwrite(addr: Addr | string, rt: Content): void;
|
|
991
|
+
/**
|
|
992
|
+
* `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
|
|
993
|
+
* carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
|
|
994
|
+
* `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
|
|
995
|
+
* `Addr` mints one without restating the kind lookup, the `Addr` defaults
|
|
996
|
+
* or the range guard.
|
|
997
|
+
*
|
|
998
|
+
* The kind is the card's stored `$kind` verbatim, the quill-free rule the
|
|
999
|
+
* addressed mutators anchor with and the geometry translation uses, not
|
|
1000
|
+
* `validate`'s declared-kind filter: a `Document` holds a `$quill`
|
|
1001
|
+
* reference and no schema. That is the one edge where this path and a
|
|
1002
|
+
* `validate` diagnostic path differ for the same card.
|
|
1003
|
+
*
|
|
1004
|
+
* **Total on the index axis**, unlike the `Addr` reads (`getStored`,
|
|
1005
|
+
* `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
|
|
1006
|
+
* a read. An out-of-range `{card: 7, field: "from"}` extends the
|
|
1007
|
+
* unknown-kind root `edit::index_out_of_range` anchors at, rendering
|
|
1008
|
+
* `cards[7].from`, which parses back and resolves to nothing rather than
|
|
1009
|
+
* mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
|
|
1010
|
+
* a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
|
|
1011
|
+
* address throws.
|
|
1012
|
+
*/
|
|
1013
|
+
pathFor(addr: Addr | string): string;
|
|
962
1014
|
/**
|
|
963
1015
|
* The canonical `$quill` reference grammar as author-facing text. Core is
|
|
964
1016
|
* the single source of truth: drive schema `describe` and validation
|
|
@@ -1513,6 +1565,7 @@ export interface InitOutput {
|
|
|
1513
1565
|
readonly document_bodyMarkdown: (a: number, b: number, c: number) => void;
|
|
1514
1566
|
readonly document_card: (a: number, b: number, c: number) => void;
|
|
1515
1567
|
readonly document_cardCount: (a: number) => number;
|
|
1568
|
+
readonly document_cardPath: (a: number, b: number, c: number) => void;
|
|
1516
1569
|
readonly document_cards: (a: number, b: number) => void;
|
|
1517
1570
|
readonly document_clone: (a: number) => number;
|
|
1518
1571
|
readonly document_currentStorageVersion: (a: number) => void;
|
|
@@ -1532,6 +1585,7 @@ export interface InitOutput {
|
|
|
1532
1585
|
readonly document_moveCard: (a: number, b: number, c: number, d: number) => void;
|
|
1533
1586
|
readonly document_new: (a: number, b: number, c: number) => void;
|
|
1534
1587
|
readonly document_overwrite: (a: number, b: number, c: number, d: number) => void;
|
|
1588
|
+
readonly document_pathFor: (a: number, b: number, c: number) => void;
|
|
1535
1589
|
readonly document_quillRef: (a: number, b: number) => void;
|
|
1536
1590
|
readonly document_quillRefHint: (a: number) => void;
|
|
1537
1591
|
readonly document_removeCard: (a: number, b: number, c: number) => void;
|
package/backends/typst/wasm.js
CHANGED
|
@@ -368,6 +368,30 @@ export class Document {
|
|
|
368
368
|
const ret = wasm.document_cardCount(this.__wbg_ptr);
|
|
369
369
|
return ret >>> 0;
|
|
370
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* The composable card's own path, `cards.<kind>[index]`: the whole-card
|
|
373
|
+
* root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
|
|
374
|
+
* card rather than one of its fields. Total on the index axis for the same
|
|
375
|
+
* reason, out of range renders `cards[index]`.
|
|
376
|
+
* @param {number} index
|
|
377
|
+
* @returns {string}
|
|
378
|
+
*/
|
|
379
|
+
cardPath(index) {
|
|
380
|
+
let deferred1_0;
|
|
381
|
+
let deferred1_1;
|
|
382
|
+
try {
|
|
383
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
384
|
+
wasm.document_cardPath(retptr, this.__wbg_ptr, index);
|
|
385
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
386
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
387
|
+
deferred1_0 = r0;
|
|
388
|
+
deferred1_1 = r1;
|
|
389
|
+
return getStringFromWasm0(r0, r1);
|
|
390
|
+
} finally {
|
|
391
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
392
|
+
wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
371
395
|
/**
|
|
372
396
|
* @returns {Card[]}
|
|
373
397
|
*/
|
|
@@ -815,6 +839,54 @@ export class Document {
|
|
|
815
839
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
816
840
|
}
|
|
817
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
|
|
844
|
+
* carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
|
|
845
|
+
* `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
|
|
846
|
+
* `Addr` mints one without restating the kind lookup, the `Addr` defaults
|
|
847
|
+
* or the range guard.
|
|
848
|
+
*
|
|
849
|
+
* The kind is the card's stored `$kind` verbatim, the quill-free rule the
|
|
850
|
+
* addressed mutators anchor with and the geometry translation uses, not
|
|
851
|
+
* `validate`'s declared-kind filter: a `Document` holds a `$quill`
|
|
852
|
+
* reference and no schema. That is the one edge where this path and a
|
|
853
|
+
* `validate` diagnostic path differ for the same card.
|
|
854
|
+
*
|
|
855
|
+
* **Total on the index axis**, unlike the `Addr` reads (`getStored`,
|
|
856
|
+
* `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
|
|
857
|
+
* a read. An out-of-range `{card: 7, field: "from"}` extends the
|
|
858
|
+
* unknown-kind root `edit::index_out_of_range` anchors at, rendering
|
|
859
|
+
* `cards[7].from`, which parses back and resolves to nothing rather than
|
|
860
|
+
* mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
|
|
861
|
+
* a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
|
|
862
|
+
* address throws.
|
|
863
|
+
* @param {Addr | string} addr
|
|
864
|
+
* @returns {string}
|
|
865
|
+
*/
|
|
866
|
+
pathFor(addr) {
|
|
867
|
+
let deferred2_0;
|
|
868
|
+
let deferred2_1;
|
|
869
|
+
try {
|
|
870
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
871
|
+
wasm.document_pathFor(retptr, this.__wbg_ptr, addHeapObject(addr));
|
|
872
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
873
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
874
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
875
|
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
|
876
|
+
var ptr1 = r0;
|
|
877
|
+
var len1 = r1;
|
|
878
|
+
if (r3) {
|
|
879
|
+
ptr1 = 0; len1 = 0;
|
|
880
|
+
throw takeObject(r2);
|
|
881
|
+
}
|
|
882
|
+
deferred2_0 = ptr1;
|
|
883
|
+
deferred2_1 = len1;
|
|
884
|
+
return getStringFromWasm0(ptr1, len1);
|
|
885
|
+
} finally {
|
|
886
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
887
|
+
wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
818
890
|
/**
|
|
819
891
|
* @returns {string}
|
|
820
892
|
*/
|
|
Binary file
|
|
@@ -16,6 +16,7 @@ export const document_blueprintInstruction: (a: number, b: number, c: number) =>
|
|
|
16
16
|
export const document_bodyMarkdown: (a: number, b: number, c: number) => void;
|
|
17
17
|
export const document_card: (a: number, b: number, c: number) => void;
|
|
18
18
|
export const document_cardCount: (a: number) => number;
|
|
19
|
+
export const document_cardPath: (a: number, b: number, c: number) => void;
|
|
19
20
|
export const document_cards: (a: number, b: number) => void;
|
|
20
21
|
export const document_clone: (a: number) => number;
|
|
21
22
|
export const document_currentStorageVersion: (a: number) => void;
|
|
@@ -35,6 +36,7 @@ export const document_makeCard: (a: number, b: number, c: number, d: number, e:
|
|
|
35
36
|
export const document_moveCard: (a: number, b: number, c: number, d: number) => void;
|
|
36
37
|
export const document_new: (a: number, b: number, c: number) => void;
|
|
37
38
|
export const document_overwrite: (a: number, b: number, c: number, d: number) => void;
|
|
39
|
+
export const document_pathFor: (a: number, b: number, c: number) => void;
|
|
38
40
|
export const document_quillRef: (a: number, b: number) => void;
|
|
39
41
|
export const document_quillRefHint: (a: number) => void;
|
|
40
42
|
export const document_removeCard: (a: number, b: number, c: number) => void;
|
package/core/wasm.d.ts
CHANGED
|
@@ -181,6 +181,11 @@ export type ContentIsland = {
|
|
|
181
181
|
* (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
|
|
182
182
|
* rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
|
|
183
183
|
* spelling), so no third navigation idiom re-fragments the surface.
|
|
184
|
+
*
|
|
185
|
+
* `doc.pathFor(addr)` mints the address as its canonical `DocPath` string, the
|
|
186
|
+
* anchor `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
|
|
187
|
+
* take: a card path is kind-qualified, so building one by hand needs the card's
|
|
188
|
+
* `$kind`, and a wrong-kind path matches nothing silently.
|
|
184
189
|
*/
|
|
185
190
|
export interface Addr {
|
|
186
191
|
card?: number;
|
|
@@ -394,12 +399,32 @@ export interface QuillCardUi {
|
|
|
394
399
|
groups?: Record<string, QuillGroupUi>;
|
|
395
400
|
}
|
|
396
401
|
|
|
402
|
+
/** A block construct a body can hold. `paragraph` is absent on purpose: it is
|
|
403
|
+
* the floor and cannot be declined. */
|
|
404
|
+
export type QuillBlockConstruct =
|
|
405
|
+
| "heading"
|
|
406
|
+
| "rule"
|
|
407
|
+
| "code"
|
|
408
|
+
| "list"
|
|
409
|
+
| "quote"
|
|
410
|
+
| "table"
|
|
411
|
+
| "image";
|
|
412
|
+
|
|
397
413
|
/** Body namespace for a card (main or named card kind). */
|
|
398
414
|
export interface QuillCardBody {
|
|
399
415
|
/** When false, consumers must not accept or store body content for this card kind. Defaults to true. */
|
|
400
416
|
enabled?: boolean;
|
|
401
417
|
/** Example body content embedded verbatim in the blueprint body region. Fallback is "Write <card> body here." */
|
|
402
418
|
example?: string;
|
|
419
|
+
/** Block constructs this quill's plate does not typeset in this body.
|
|
420
|
+
*
|
|
421
|
+
* Absent or empty means it declines nothing, which is the default. An
|
|
422
|
+
* editor reads this to decline a gesture before the author makes it; a body
|
|
423
|
+
* that holds one anyway draws a non-fatal `plate::unsupported_construct`
|
|
424
|
+
* warning carrying the construct and a count. It is the quill's claim about
|
|
425
|
+
* its own plate, and nothing verifies it: a construct absent from this list
|
|
426
|
+
* is not a promise that the plate typesets it. */
|
|
427
|
+
unsupported?: QuillBlockConstruct[];
|
|
403
428
|
}
|
|
404
429
|
|
|
405
430
|
/** Schema entry for a single field declared in a quill's `Quill.yaml`.
|
|
@@ -416,11 +441,8 @@ export interface QuillFieldSchema {
|
|
|
416
441
|
description?: string;
|
|
417
442
|
default?: unknown;
|
|
418
443
|
example?: unknown;
|
|
419
|
-
/**
|
|
420
|
-
*
|
|
421
|
-
* release. Both round-trip through this field. */
|
|
422
|
-
enum?: string[];
|
|
423
|
-
/** Required on `type: "enum"`: the closed set of allowed string values. */
|
|
444
|
+
/** Required on `type: "enum"`, and valid nowhere else: the closed set of
|
|
445
|
+
* allowed string values. */
|
|
424
446
|
values?: string[];
|
|
425
447
|
ui?: QuillFieldUi;
|
|
426
448
|
properties?: Record<string, QuillFieldSchema>;
|
|
@@ -560,6 +582,13 @@ export class Document {
|
|
|
560
582
|
* verbs.
|
|
561
583
|
*/
|
|
562
584
|
card(index: number): Card;
|
|
585
|
+
/**
|
|
586
|
+
* The composable card's own path, `cards.<kind>[index]`: the whole-card
|
|
587
|
+
* root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
|
|
588
|
+
* card rather than one of its fields. Total on the index axis for the same
|
|
589
|
+
* reason, out of range renders `cards[index]`.
|
|
590
|
+
*/
|
|
591
|
+
cardPath(index: number): string;
|
|
563
592
|
clone(): Document;
|
|
564
593
|
/**
|
|
565
594
|
* Storage version this build writes via [`toJson`](Document::to_json).
|
|
@@ -707,6 +736,29 @@ export class Document {
|
|
|
707
736
|
* not a canonical content object.
|
|
708
737
|
*/
|
|
709
738
|
overwrite(addr: Addr | string, rt: Content): void;
|
|
739
|
+
/**
|
|
740
|
+
* `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
|
|
741
|
+
* carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
|
|
742
|
+
* `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
|
|
743
|
+
* `Addr` mints one without restating the kind lookup, the `Addr` defaults
|
|
744
|
+
* or the range guard.
|
|
745
|
+
*
|
|
746
|
+
* The kind is the card's stored `$kind` verbatim, the quill-free rule the
|
|
747
|
+
* addressed mutators anchor with and the geometry translation uses, not
|
|
748
|
+
* `validate`'s declared-kind filter: a `Document` holds a `$quill`
|
|
749
|
+
* reference and no schema. That is the one edge where this path and a
|
|
750
|
+
* `validate` diagnostic path differ for the same card.
|
|
751
|
+
*
|
|
752
|
+
* **Total on the index axis**, unlike the `Addr` reads (`getStored`,
|
|
753
|
+
* `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
|
|
754
|
+
* a read. An out-of-range `{card: 7, field: "from"}` extends the
|
|
755
|
+
* unknown-kind root `edit::index_out_of_range` anchors at, rendering
|
|
756
|
+
* `cards[7].from`, which parses back and resolves to nothing rather than
|
|
757
|
+
* mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
|
|
758
|
+
* a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
|
|
759
|
+
* address throws.
|
|
760
|
+
*/
|
|
761
|
+
pathFor(addr: Addr | string): string;
|
|
710
762
|
/**
|
|
711
763
|
* The canonical `$quill` reference grammar as author-facing text. Core is
|
|
712
764
|
* the single source of truth: drive schema `describe` and validation
|
|
@@ -1097,6 +1149,7 @@ export interface InitOutput {
|
|
|
1097
1149
|
readonly document_bodyMarkdown: (a: number, b: number, c: number) => void;
|
|
1098
1150
|
readonly document_card: (a: number, b: number, c: number) => void;
|
|
1099
1151
|
readonly document_cardCount: (a: number) => number;
|
|
1152
|
+
readonly document_cardPath: (a: number, b: number, c: number) => void;
|
|
1100
1153
|
readonly document_cards: (a: number, b: number) => void;
|
|
1101
1154
|
readonly document_clone: (a: number) => number;
|
|
1102
1155
|
readonly document_currentStorageVersion: (a: number) => void;
|
|
@@ -1116,6 +1169,7 @@ export interface InitOutput {
|
|
|
1116
1169
|
readonly document_moveCard: (a: number, b: number, c: number, d: number) => void;
|
|
1117
1170
|
readonly document_new: (a: number, b: number, c: number) => void;
|
|
1118
1171
|
readonly document_overwrite: (a: number, b: number, c: number, d: number) => void;
|
|
1172
|
+
readonly document_pathFor: (a: number, b: number, c: number) => void;
|
|
1119
1173
|
readonly document_quillRef: (a: number, b: number) => void;
|
|
1120
1174
|
readonly document_quillRefHint: (a: number) => void;
|
|
1121
1175
|
readonly document_removeCard: (a: number, b: number, c: number) => void;
|
package/core/wasm.js
CHANGED
|
@@ -368,6 +368,30 @@ export class Document {
|
|
|
368
368
|
const ret = wasm.document_cardCount(this.__wbg_ptr);
|
|
369
369
|
return ret >>> 0;
|
|
370
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* The composable card's own path, `cards.<kind>[index]`: the whole-card
|
|
373
|
+
* root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
|
|
374
|
+
* card rather than one of its fields. Total on the index axis for the same
|
|
375
|
+
* reason, out of range renders `cards[index]`.
|
|
376
|
+
* @param {number} index
|
|
377
|
+
* @returns {string}
|
|
378
|
+
*/
|
|
379
|
+
cardPath(index) {
|
|
380
|
+
let deferred1_0;
|
|
381
|
+
let deferred1_1;
|
|
382
|
+
try {
|
|
383
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
384
|
+
wasm.document_cardPath(retptr, this.__wbg_ptr, index);
|
|
385
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
386
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
387
|
+
deferred1_0 = r0;
|
|
388
|
+
deferred1_1 = r1;
|
|
389
|
+
return getStringFromWasm0(r0, r1);
|
|
390
|
+
} finally {
|
|
391
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
392
|
+
wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
371
395
|
/**
|
|
372
396
|
* @returns {Card[]}
|
|
373
397
|
*/
|
|
@@ -815,6 +839,54 @@ export class Document {
|
|
|
815
839
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
816
840
|
}
|
|
817
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
|
|
844
|
+
* carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
|
|
845
|
+
* `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
|
|
846
|
+
* `Addr` mints one without restating the kind lookup, the `Addr` defaults
|
|
847
|
+
* or the range guard.
|
|
848
|
+
*
|
|
849
|
+
* The kind is the card's stored `$kind` verbatim, the quill-free rule the
|
|
850
|
+
* addressed mutators anchor with and the geometry translation uses, not
|
|
851
|
+
* `validate`'s declared-kind filter: a `Document` holds a `$quill`
|
|
852
|
+
* reference and no schema. That is the one edge where this path and a
|
|
853
|
+
* `validate` diagnostic path differ for the same card.
|
|
854
|
+
*
|
|
855
|
+
* **Total on the index axis**, unlike the `Addr` reads (`getStored`,
|
|
856
|
+
* `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
|
|
857
|
+
* a read. An out-of-range `{card: 7, field: "from"}` extends the
|
|
858
|
+
* unknown-kind root `edit::index_out_of_range` anchors at, rendering
|
|
859
|
+
* `cards[7].from`, which parses back and resolves to nothing rather than
|
|
860
|
+
* mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
|
|
861
|
+
* a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
|
|
862
|
+
* address throws.
|
|
863
|
+
* @param {Addr | string} addr
|
|
864
|
+
* @returns {string}
|
|
865
|
+
*/
|
|
866
|
+
pathFor(addr) {
|
|
867
|
+
let deferred2_0;
|
|
868
|
+
let deferred2_1;
|
|
869
|
+
try {
|
|
870
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
871
|
+
wasm.document_pathFor(retptr, this.__wbg_ptr, addHeapObject(addr));
|
|
872
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
873
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
874
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
875
|
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
|
876
|
+
var ptr1 = r0;
|
|
877
|
+
var len1 = r1;
|
|
878
|
+
if (r3) {
|
|
879
|
+
ptr1 = 0; len1 = 0;
|
|
880
|
+
throw takeObject(r2);
|
|
881
|
+
}
|
|
882
|
+
deferred2_0 = ptr1;
|
|
883
|
+
deferred2_1 = len1;
|
|
884
|
+
return getStringFromWasm0(ptr1, len1);
|
|
885
|
+
} finally {
|
|
886
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
887
|
+
wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
818
890
|
/**
|
|
819
891
|
* @returns {string}
|
|
820
892
|
*/
|
package/core/wasm_bg.wasm
CHANGED
|
Binary file
|
package/core/wasm_bg.wasm.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export const document_blueprintInstruction: (a: number, b: number, c: number) =>
|
|
|
14
14
|
export const document_bodyMarkdown: (a: number, b: number, c: number) => void;
|
|
15
15
|
export const document_card: (a: number, b: number, c: number) => void;
|
|
16
16
|
export const document_cardCount: (a: number) => number;
|
|
17
|
+
export const document_cardPath: (a: number, b: number, c: number) => void;
|
|
17
18
|
export const document_cards: (a: number, b: number) => void;
|
|
18
19
|
export const document_clone: (a: number) => number;
|
|
19
20
|
export const document_currentStorageVersion: (a: number) => void;
|
|
@@ -33,6 +34,7 @@ export const document_makeCard: (a: number, b: number, c: number, d: number, e:
|
|
|
33
34
|
export const document_moveCard: (a: number, b: number, c: number, d: number) => void;
|
|
34
35
|
export const document_new: (a: number, b: number, c: number) => void;
|
|
35
36
|
export const document_overwrite: (a: number, b: number, c: number, d: number) => void;
|
|
37
|
+
export const document_pathFor: (a: number, b: number, c: number) => void;
|
|
36
38
|
export const document_quillRef: (a: number, b: number) => void;
|
|
37
39
|
export const document_quillRefHint: (a: number) => void;
|
|
38
40
|
export const document_removeCard: (a: number, b: number, c: number) => void;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quillmark/wasm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.104.0",
|
|
4
4
|
"description": "WebAssembly bindings for Quillmark, a schema-driven document engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=24"
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
package/runtime/runtime.d.ts
CHANGED
|
@@ -398,7 +398,10 @@ export interface FieldRegion {
|
|
|
398
398
|
* The field's canonical `DocPath` address (`parseDocPath`-routable), not a
|
|
399
399
|
* backend widget name: `main.signature_block` for a main field,
|
|
400
400
|
* `cards.<kind>[<i>].signature_block` for a card field (`cards[<i>].…` when the
|
|
401
|
-
* card's kind is unknown).
|
|
401
|
+
* card's kind is unknown). Nested addresses spell out in full, an array
|
|
402
|
+
* element bracketed and a key dotted — `main.references[0]`,
|
|
403
|
+
* `cards.<kind>[<i>].addr.city` — the same spelling `Diagnostic.path` uses,
|
|
404
|
+
* so the two join on string equality.
|
|
402
405
|
*/
|
|
403
406
|
field: string;
|
|
404
407
|
/** 0-based page index. */
|
package/runtime/runtime.js
CHANGED
|
@@ -90,19 +90,25 @@ import { parseDocPath, formatDocPath } from '../core/wasm.js';
|
|
|
90
90
|
// so there is no subpath around the gate either.
|
|
91
91
|
//
|
|
92
92
|
// The gate is the shape the lazy-backend idiom (§ DEFAULT_BACKENDS) takes when
|
|
93
|
-
// the surface it guards cannot be async: `Quill.fromTree` and
|
|
94
|
-
//
|
|
93
|
+
// the surface it guards cannot be async: `Quill.fromTree` and
|
|
94
|
+
// `quill.seedDocument` return synchronously, so there is nowhere to hide an
|
|
95
|
+
// await except in front.
|
|
95
96
|
//
|
|
96
|
-
// WHAT STAYS STATIC is what needs no instance. `MAIN_CARD_ADDR`, the
|
|
97
|
-
// guards and `isQuillmarkError` are pure JS over plain objects; gating
|
|
98
|
-
// would cost a consumer of one an await it has no use for.
|
|
97
|
+
// WHAT STAYS A STATIC EXPORT is what needs no instance. `MAIN_CARD_ADDR`, the
|
|
98
|
+
// open-set guards and `isQuillmarkError` are pure JS over plain objects; gating
|
|
99
|
+
// them would cost a consumer of one an await it has no use for.
|
|
99
100
|
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
101
|
+
// `Engine`, `LiveSession` and the four writer/reader classes stay static too,
|
|
102
|
+
// gated by their ARGUMENTS rather than by the door. Every `Engine` verb takes a
|
|
103
|
+
// `Quill` first (`#backendOf` is the single reader) and the writer/reader
|
|
104
|
+
// constructors take both handles, so a caller who has not awaited cannot
|
|
105
|
+
// produce an argument to call them with. The two constructors taking no handle
|
|
106
|
+
// reach no wasm: `new Engine()` validates a descriptor map, and a `LiveSession`
|
|
107
|
+
// forwards to the backend session `engine.open` is the sole source of. None of
|
|
108
|
+
// the six carries a static method, the one member shape an argument cannot
|
|
109
|
+
// gate. `gate.test.js` is the executable guard, driving the whole static
|
|
110
|
+
// surface before `init`. Holding them out of the gate keeps them tree-shakable,
|
|
111
|
+
// so the editor path drops the dispatcher it never calls.
|
|
106
112
|
//
|
|
107
113
|
// FAILURE DELIVERY follows the FUNCTION kind, not the failure kind: a sync verb
|
|
108
114
|
// throws, a promise-returning verb rejects, and nothing does both. A
|
|
@@ -510,9 +516,10 @@ export function isListItemContainer(container) {
|
|
|
510
516
|
// A predicate rather than an exported name list, because the known tables below
|
|
511
517
|
// are upstream's business. They are pinned against the Rust source
|
|
512
518
|
// (`Content::RESERVED_*` and `KnownIslandType`) by the
|
|
513
|
-
// `
|
|
514
|
-
// `crates/
|
|
515
|
-
// the TS unions in `crates/bindings/wasm/src/engine.rs`
|
|
519
|
+
// `js_known_name_tables_match_the_rust_open_sets` drift-guard test in
|
|
520
|
+
// `crates/bindings/wasm/tests/known_names_drift.rs`: adding a built-in means
|
|
521
|
+
// editing there, here, and the TS unions in `crates/bindings/wasm/src/engine.rs`
|
|
522
|
+
// in one commit.
|
|
516
523
|
//
|
|
517
524
|
// These classify unknown *tags*, not unknown *payloads on known tags*. A future
|
|
518
525
|
// `kind: "footnote"` with a sibling `ref` loses `ref` at a consumer that predates
|