@quillmark/wasm 0.96.0 → 0.98.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 +99 -0
- package/README.md +3 -2
- package/backends/pdfform/wasm.d.ts +71 -40
- package/backends/pdfform/wasm_bg.js +56 -43
- package/backends/pdfform/wasm_bg.wasm +0 -0
- package/backends/pdfform/wasm_bg.wasm.d.ts +1 -1
- package/backends/typst/wasm.d.ts +71 -40
- package/backends/typst/wasm_bg.js +56 -43
- package/backends/typst/wasm_bg.wasm +0 -0
- package/backends/typst/wasm_bg.wasm.d.ts +1 -1
- package/core/wasm.d.ts +70 -39
- package/core/wasm_bg.js +56 -43
- package/core/wasm_bg.wasm +0 -0
- package/core/wasm_bg.wasm.d.ts +1 -1
- package/package.json +1 -1
- package/runtime/runtime.d.ts +65 -4
- package/runtime/runtime.js +72 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,104 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.98.0 - 2026-07-28
|
|
4
|
+
|
|
5
|
+
Five breaking changes, all covered by `docs/migrations/0.97-to-0.98.md`.
|
|
6
|
+
Stored documents are unaffected: a `0.97` blob loads byte-identically and
|
|
7
|
+
`0.98` writes the same bytes for the same content.
|
|
8
|
+
|
|
9
|
+
- feat(core,content,wasm)!: the block vocabulary opens. A line's `kind` and a
|
|
10
|
+
container's name join the mark `type` and island `type` as open sets — an
|
|
11
|
+
unrecognized value round-trips opaque and renders as its nearest safe
|
|
12
|
+
neighbor instead of failing the load, so adding a block construct is no
|
|
13
|
+
longer a document schema-version event. `LineKind` and `Container` each gain
|
|
14
|
+
an `Unknown { tag, attrs }` variant (exhaustive matches need an arm) and
|
|
15
|
+
`Line` / `LineKind` / `Container` drop their `Eq` derive, matching `MarkKind`;
|
|
16
|
+
`Invariant` gains `ReservedUnknownLineKind` / `ReservedUnknownContainer`, so
|
|
17
|
+
an unknown may not reuse a built-in name. `ContentLine.kind` and
|
|
18
|
+
`ContentContainer.container` gain an open TS arm, so a bare discriminant check
|
|
19
|
+
no longer narrows — `isHeadingLine` / `isCodeLine` / `isListItemContainer`
|
|
20
|
+
join the existing guards in `@quillmark/wasm/runtime`. `Loss` describes
|
|
21
|
+
fidelity; it does not gate export (#1054). See
|
|
22
|
+
`docs/migrations/0.97-to-0.98.md`
|
|
23
|
+
- refactor(core,wasm,python,cli)!: `OutputFormat::Txt` is removed — the Rust
|
|
24
|
+
variant, Python's `OutputFormat.TXT`, the TS `'txt'` arm. No backend listed it
|
|
25
|
+
in `SUPPORTED_FORMATS`, so every path reaching it failed at render time;
|
|
26
|
+
`--format txt` and `from_str("txt")` now fail at the argument instead, and
|
|
27
|
+
there is no replacement format (#1058). See
|
|
28
|
+
`docs/migrations/0.97-to-0.98.md`
|
|
29
|
+
- refactor(typst,pdfform)!: `format_not_supported` was three codes for one
|
|
30
|
+
condition. Both backends now emit `backend::format_not_supported`, alongside
|
|
31
|
+
the sibling `backend::apply_unsupported` — route on the namespaced code
|
|
32
|
+
(#1057). See `docs/migrations/0.97-to-0.98.md`
|
|
33
|
+
- refactor(core)!: dead public surface is removed — `ReadValue::as_text` /
|
|
34
|
+
`as_value` (match the variants), `Quill::list_files` / `list_subdirectories`
|
|
35
|
+
(`quill.files()` owns the walk), and `QuillValue`'s eight `Deref`-shadowed
|
|
36
|
+
accessors (`QuillValue: Deref<Target = serde_json::Value>` resolves each call
|
|
37
|
+
unchanged — no action). `prescan`'s helpers and `reader::err` drop to
|
|
38
|
+
`pub(crate)` (#1066, #1064). See `docs/migrations/0.97-to-0.98.md`
|
|
39
|
+
- fix(python)!: rendered regions cross the boundary as `DocPath`. Python
|
|
40
|
+
returned plate-space addresses no document API accepts; the plate→`DocPath`
|
|
41
|
+
translation now lives in core as `regions_to_doc_path` and both bindings call
|
|
42
|
+
it, so `RenderResult.regions[].field` reads `main.body` /
|
|
43
|
+
`cards.<kind>[<i>].<field>` as WASM already did (#1063). See
|
|
44
|
+
`docs/migrations/0.97-to-0.98.md`
|
|
45
|
+
- fix(content): three codec holes close. A mark spanning an island slot no
|
|
46
|
+
longer swallows it; a `LineKind` that disagrees with its segment is caught
|
|
47
|
+
(`Invariant::LineKindMismatch`, carrying a `LineKindMismatch` reason); and
|
|
48
|
+
decode is bounded — `MAX_NESTING_DEPTH` is enforced at the door, and a wire
|
|
49
|
+
position is read checked rather than `as usize`, which on wasm32 landed
|
|
50
|
+
`2^32 + 5` at position `5` (#1051)
|
|
51
|
+
- fix(content): export's verify-and-drop safety net is bounded per line rather
|
|
52
|
+
than per mark; `CONVERT.md` states the import↔export coupling the net implies
|
|
53
|
+
(#1052)
|
|
54
|
+
- fix(content): markdown import keeps a literal `*` that abuts strong or
|
|
55
|
+
emphasis — `a***a**` imports as `a`, `*`, strong `a`, where the deleted fixup
|
|
56
|
+
dropped the typed star. Removing it also fixes a backslash escape or entity in
|
|
57
|
+
such a span re-entering the content as literal source bytes (#1053)
|
|
58
|
+
- feat(core): `FileTreeNode`, `QuillIgnore`, `QuillConfig`, the schema types,
|
|
59
|
+
and `ValidationError` are nameable from `quillmark` and from `quillmark_core`'s
|
|
60
|
+
root, so in-memory quill construction and schema reading need no direct core
|
|
61
|
+
dependency (#1055)
|
|
62
|
+
- refactor(core,pdfform): `From<PdfError> for RenderError` replaces two
|
|
63
|
+
byte-identical `map_pdf_err` copies; `lopdf`, `js-sys` and `wasm-bindgen`
|
|
64
|
+
hoist into `[workspace.dependencies]`, the no-op `default-features = false`
|
|
65
|
+
pins drop, and `publish` is explicit on every crate (#1070, #1064)
|
|
66
|
+
- docs(core): the card-kind validation line is documented where it lives —
|
|
67
|
+
construction (`Document::make_card`, `TryFrom<CardWire>`) is permissive
|
|
68
|
+
data-shaping and insertion is the gate, returning `edit::invalid_kind_name`
|
|
69
|
+
- docs(canon): `ERROR.md` stops documenting a `fmt_pretty_with_source()` that
|
|
70
|
+
does not exist and states what carries the source chain: serialization to
|
|
71
|
+
both bindings, no Rust formatter. `error.rs`'s divergent path-grammar copy
|
|
72
|
+
gives way to a pointer at `path.rs` and the canon anchor table (#1061, #1069)
|
|
73
|
+
- docs(canon): prune — canon stops re-documenting what `docs/` owns and states
|
|
74
|
+
each fact once; the lint checks truth rather than shape, and the CI job table
|
|
75
|
+
lists every job
|
|
76
|
+
- test: test clusters go table-driven, wrong-altitude binding tests move down to
|
|
77
|
+
core, tests that pin foreign behavior or assert nothing are dropped, and one
|
|
78
|
+
walker and one quill builder replace the per-suite copies (#1060, #1056,
|
|
79
|
+
#1065, #1062, #1067)
|
|
80
|
+
- ci: the zero-backend configuration is built and tested — `--workspace
|
|
81
|
+
--all-features` forces `typst` on, so that branch never compiled (#1068)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
## v0.97.0 - 2026-07-24
|
|
85
|
+
|
|
86
|
+
- core: one take_item primitive behind the three payload removers
|
|
87
|
+
- core: fold the incoming-card guard shared by push_card/insert_card
|
|
88
|
+
- tests: dense-prose fix on a muddy reinstatement comment
|
|
89
|
+
- canon/docs: §Card-id identity — the third twin; wasm surface follows
|
|
90
|
+
- core: card $id is the durable handle — unique per document, guarded
|
|
91
|
+
- wasm: add island/mark discriminant guards; USV docs on mapPos/rebase
|
|
92
|
+
- ci: lint the wasm binding's rustdoc to catch intra-doc breakage
|
|
93
|
+
- Canonize anchor-id policy: caller-supplied, unique, invariant
|
|
94
|
+
- Fix stale resolve() docs: body is a sibling, not a `$body` row
|
|
95
|
+
- docs: prune per pruning pass — archive old migrations, cut duplication
|
|
96
|
+
- docs: public integration pages for the high/medium doc gaps
|
|
97
|
+
- docs: dense-prose sweep and accuracy fixes in docs/ and canon
|
|
98
|
+
- docs(wasm): fix broken [`Delta`] intra-doc links (#1034)
|
|
99
|
+
- wasm: rename Document.get → getStored so the verbatim read carries its lane
|
|
100
|
+
|
|
101
|
+
|
|
3
102
|
## v0.96.0 - 2026-07-23
|
|
4
103
|
|
|
5
104
|
- docs(spec): keep plate JSON out of the markdown spec
|
package/README.md
CHANGED
|
@@ -255,9 +255,10 @@ Build a fresh card from a flat field map with
|
|
|
255
255
|
`{ card?, field? }`, absent `card` = main, absent `field` = body — and a bare
|
|
256
256
|
string is shorthand for `{ field }`. So `doc.storeField("qty", 3)` targets the
|
|
257
257
|
main card's `qty`, `doc.storeField({ card: 2, field: "qty" }, 3)` a composable
|
|
258
|
-
card's. Reads are total over the field axis (`
|
|
258
|
+
card's. Reads are total over the field axis (`getStored` → `undefined`, `isFill` → `false` for
|
|
259
259
|
an absent field; only an out-of-range card throws); field writes throw on a body
|
|
260
|
-
address. `
|
|
260
|
+
address. `getStored` is the verbatim transport read, distinct from the interpreted
|
|
261
|
+
`quill.reader(doc).get`; `getMarkdown` is the body markdown read (a `CardAddr`; a field's
|
|
261
262
|
markdown is read through `quill.reader(doc).get(field)`). Card-scoped verbs take a
|
|
262
263
|
`CardAddr` (`{ card? }`) first: `doc.getExt({ card: 2 })`, and the batch below.
|
|
263
264
|
|
|
@@ -84,25 +84,43 @@ export interface Content {
|
|
|
84
84
|
islands: ContentIsland[];
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
/** One `\n`-separated segment of `Content.text`, in order.
|
|
87
|
+
/** One `\n`-separated segment of `Content.text`, in order. `kind` is an open set
|
|
88
|
+
* (as on `ContentIsland` and `ContentMark`): a role this build does not know
|
|
89
|
+
* round-trips with opaque `attrs` and renders as a paragraph, so a document
|
|
90
|
+
* carrying a future block construct still opens. The open arm blocks discriminant
|
|
91
|
+
* narrowing, so read `level`/`lang` behind a check of the arm you want. */
|
|
88
92
|
export type ContentLine = {
|
|
89
93
|
containers: ContentContainer[];
|
|
90
94
|
/** A within-block hard line break rather than a new block. Omitted (false) in the common case. */
|
|
91
95
|
continues?: boolean;
|
|
92
|
-
} &
|
|
96
|
+
} & ContentLineKind;
|
|
97
|
+
|
|
98
|
+
/** A line's block role, declared once for `ContentLine` and the `setKind` op —
|
|
99
|
+
* a new role is one edit here, as for `ContentContainer`. */
|
|
100
|
+
export type ContentLineKind =
|
|
93
101
|
| { kind: "para" }
|
|
94
102
|
| { kind: "heading"; level: number }
|
|
95
103
|
| { kind: "code"; lang?: string }
|
|
96
104
|
| { kind: "island" }
|
|
97
105
|
| { kind: "rule" }
|
|
98
|
-
|
|
106
|
+
| { kind: string; attrs: unknown };
|
|
99
107
|
|
|
100
|
-
/** An ancestor block a line nests inside, outermost first.
|
|
108
|
+
/** An ancestor block a line nests inside, outermost first. Open like
|
|
109
|
+
* `ContentLine.kind`: an unrecognized container round-trips with opaque `attrs`
|
|
110
|
+
* and renders transparently (its lines sit at the enclosing level). */
|
|
101
111
|
export type ContentContainer =
|
|
102
112
|
| { container: "list_item"; ordered: boolean; start: number; ordinal: number }
|
|
103
|
-
| { container: "quote" }
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
| { container: "quote" }
|
|
114
|
+
| { container: string; attrs: unknown };
|
|
115
|
+
|
|
116
|
+
/** A mark over char range `[start, end)` into `Content.text`. The open `type`
|
|
117
|
+
* arm blocks discriminant narrowing (as on `ContentIsland`), so read a
|
|
118
|
+
* payload-carrying arm behind its guard — `isLinkMark` (`url`) / `isAnchorMark`
|
|
119
|
+
* (`id`), from `@quillmark/wasm/runtime`; the bare arms carry no payload. An
|
|
120
|
+
* `anchor`'s `id` is a caller-supplied, opaque handle, unique per `Content` and
|
|
121
|
+
* invariant while the mark lives (positions rebase, the id never does); it has no
|
|
122
|
+
* markdown projection and survives only through the edit lane. See DOCUMENT_STORAGE
|
|
123
|
+
* § Anchor-id identity. */
|
|
106
124
|
export type ContentMark = { start: number; end: number } & (
|
|
107
125
|
| { type: "strong" | "emph" | "underline" | "strike" | "code" }
|
|
108
126
|
| { type: "link"; url: string }
|
|
@@ -138,7 +156,8 @@ export interface ImageProps {
|
|
|
138
156
|
* open set: the engine pins `props` as `TableProps` for `table` and `ImageProps`
|
|
139
157
|
* for `image`; an island of any other type round-trips with opaque `props`. Like
|
|
140
158
|
* `ContentMark`, the open `type` arm means a discriminant check does not itself
|
|
141
|
-
* narrow `props` —
|
|
159
|
+
* narrow `props` — read `props` as the matching shape behind the `isTableIsland` /
|
|
160
|
+
* `isImageIsland` guards (from `@quillmark/wasm/runtime`), which narrow it. */
|
|
142
161
|
export type ContentIsland = {
|
|
143
162
|
id: string;
|
|
144
163
|
/** How faithfully the markdown projection can carry this island. */
|
|
@@ -191,7 +210,10 @@ export type Assoc = "before" | "after";
|
|
|
191
210
|
/**
|
|
192
211
|
* A mark edit in final-text coordinates (post-delta, post-line-op). `add` /
|
|
193
212
|
* `remove` carry the `ContentMark` vocabulary (`{ type, … }`); `removeAnchor`
|
|
194
|
-
* drops one identity anchor by id.
|
|
213
|
+
* drops one identity anchor by id. An `add` of an `anchor` requires a non-empty
|
|
214
|
+
* `id` not already live in the field — a collision or the empty id throws
|
|
215
|
+
* (ids are caller-supplied and unique per `Content`; DOCUMENT_STORAGE
|
|
216
|
+
* § Anchor-id identity).
|
|
195
217
|
*/
|
|
196
218
|
export type MarkOp =
|
|
197
219
|
| ({ op: "add" | "remove"; start: number; end: number } & (
|
|
@@ -212,11 +234,7 @@ export type MarkOp =
|
|
|
212
234
|
export type LineOp =
|
|
213
235
|
| { op: "split"; at: number }
|
|
214
236
|
| { op: "join"; line: number }
|
|
215
|
-
| ({ op: "setKind"; line: number } &
|
|
216
|
-
| { kind: "para" | "island" | "rule" }
|
|
217
|
-
| { kind: "heading"; level: number }
|
|
218
|
-
| { kind: "code"; lang?: string }
|
|
219
|
-
))
|
|
237
|
+
| ({ op: "setKind"; line: number } & ContentLineKind)
|
|
220
238
|
| { op: "setContainers"; line: number; containers: ContentContainer[] }
|
|
221
239
|
| { op: "setContinues"; line: number; continues: boolean };
|
|
222
240
|
|
|
@@ -542,7 +560,7 @@ export interface RenderResult {
|
|
|
542
560
|
|
|
543
561
|
export type HitGranularity = "cluster" | "segment";
|
|
544
562
|
|
|
545
|
-
export type OutputFormat = "pdf" | "svg" | "
|
|
563
|
+
export type OutputFormat = "pdf" | "svg" | "png";
|
|
546
564
|
|
|
547
565
|
export type Severity = "error" | "warning";
|
|
548
566
|
|
|
@@ -580,10 +598,10 @@ export class Document {
|
|
|
580
598
|
*/
|
|
581
599
|
card(index: number): Card;
|
|
582
600
|
/**
|
|
583
|
-
* The index of the
|
|
584
|
-
* `undefined` when none carries it. Resolves the
|
|
601
|
+
* The index of the composable card whose `$id` equals `id`, or
|
|
602
|
+
* `undefined` when none carries it. Resolves the durable card handle
|
|
585
603
|
* without a hand-rolled scan over [`cards`](Self::cards); `$id` is
|
|
586
|
-
*
|
|
604
|
+
* unique per document, so at most one card matches.
|
|
587
605
|
*/
|
|
588
606
|
cardIndexById(id: string): number | undefined;
|
|
589
607
|
clone(): Document;
|
|
@@ -625,17 +643,6 @@ export class Document {
|
|
|
625
643
|
* Parse markdown into a typed Document. Throws on parse errors.
|
|
626
644
|
*/
|
|
627
645
|
static fromMarkdown(markdown: string): Document;
|
|
628
|
-
/**
|
|
629
|
-
* Read the value at `addr` — the raw stored payload value of a field (a
|
|
630
|
-
* content object for a richtext field, a scalar/array/object otherwise), or
|
|
631
|
-
* the **body content** when `addr.field` is absent. A bare string is `Addr`
|
|
632
|
-
* shorthand for `{ field }`. Reads are total over the field axis: an absent
|
|
633
|
-
* field is `undefined`; only an out-of-range `addr.card` throws
|
|
634
|
-
* `edit::index_out_of_range`. Reads need no schema, so they live on
|
|
635
|
-
* `Document`, not the typed writer; for the markdown projection of a
|
|
636
|
-
* richtext value use [`getMarkdown`](Self::get_markdown).
|
|
637
|
-
*/
|
|
638
|
-
get(addr: Addr | string): unknown;
|
|
639
646
|
/**
|
|
640
647
|
* The whole `$ext` map at `addr` (a card address, absent `card` = main), or
|
|
641
648
|
* `undefined` when the card carries none. The fine-grained `$ext` read —
|
|
@@ -662,6 +669,19 @@ export class Document {
|
|
|
662
669
|
* type (#978). An out-of-range `addr.card` throws.
|
|
663
670
|
*/
|
|
664
671
|
getMarkdown(addr?: CardAddr): string;
|
|
672
|
+
/**
|
|
673
|
+
* Read the **verbatim stored value** at `addr` — the raw payload value of a
|
|
674
|
+
* field (a content object for a richtext field, a scalar/array/object
|
|
675
|
+
* otherwise), or the **body content** when `addr.field` is absent. A bare
|
|
676
|
+
* string is `Addr` shorthand for `{ field }`. Reads are total over the field
|
|
677
|
+
* axis: an absent field is `undefined`; only an out-of-range `addr.card`
|
|
678
|
+
* throws `edit::index_out_of_range`. Needs no schema, so it lives on
|
|
679
|
+
* `Document` — the read echo of the verbatim `store*` write, distinct from
|
|
680
|
+
* the interpreted schema-plane [`reader.get`](Self::reader_get). For the
|
|
681
|
+
* markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
|
|
682
|
+
* `reader.get` (a field's declared type).
|
|
683
|
+
*/
|
|
684
|
+
getStored(addr: Addr | string): unknown;
|
|
665
685
|
/**
|
|
666
686
|
* Insert a card — the single insertion verb: `at` absent appends, a number
|
|
667
687
|
* inserts at that index (must be in `0..=cards.length`). Accepts a
|
|
@@ -707,8 +727,16 @@ export class Document {
|
|
|
707
727
|
* Build a fresh `Card` from a kind and a flat field map — the ergonomic
|
|
708
728
|
* constructor for `insertCard`. `fields` is an optional
|
|
709
729
|
* `Record<string, unknown>` (each entry becomes a card field, in
|
|
710
|
-
* insertion order); `body` defaults to `""`.
|
|
711
|
-
*
|
|
730
|
+
* insertion order); `body` defaults to `""`.
|
|
731
|
+
*
|
|
732
|
+
* Sugar, not a required step: `insertCard` takes any `Card` object, and
|
|
733
|
+
* `removeCard` returns one, so a card round-trips without passing through
|
|
734
|
+
* here.
|
|
735
|
+
*
|
|
736
|
+
* Checks only what a detached card can decide alone: field-name grammar
|
|
737
|
+
* and value depth. Kind validity is positional — `main` is right for the
|
|
738
|
+
* root, reserved for a composable card — so `insertCard` is its gate, and
|
|
739
|
+
* any kind string is accepted here.
|
|
712
740
|
*/
|
|
713
741
|
static makeCard(kind: string, fields?: Record<string, unknown>, body?: string): Card;
|
|
714
742
|
/**
|
|
@@ -762,7 +790,7 @@ export class Document {
|
|
|
762
790
|
removeSeedNamespace(card_kind: string): any;
|
|
763
791
|
/**
|
|
764
792
|
* **Revise** the richtext value at `addr` from a markdown string — **edit
|
|
765
|
-
* semantics**, the default write path, returning the text
|
|
793
|
+
* semantics**, the default write path, returning the text `Delta`. Imports
|
|
766
794
|
* the markdown, diffs it against the current value, rebases surviving
|
|
767
795
|
* identity anchors, and returns the change an editor bridge maps its own
|
|
768
796
|
* positions through (`mapPos`). An absent `addr.field` targets the body, an
|
|
@@ -1029,7 +1057,8 @@ export class Quill {
|
|
|
1029
1057
|
* The resolved-value view of `doc` against this quill's schema — for every
|
|
1030
1058
|
* declared field the value the render projection would use and the
|
|
1031
1059
|
* `FieldSource` rung it came from (`"authored" | "default" | "zero"`), in
|
|
1032
|
-
* one call. The card body
|
|
1060
|
+
* one call. The card body is a `body` sibling on its card (row `name`
|
|
1061
|
+
* `"body"`), never a row in `fields` — `null` when the kind enables no body.
|
|
1033
1062
|
*
|
|
1034
1063
|
* Value and provenance only: completeness and errors stay `validate`'s
|
|
1035
1064
|
* (a consumer merges it with its own diagnostic producers regardless), and
|
|
@@ -1178,10 +1207,11 @@ export function importMarkdown(markdown: string): Content;
|
|
|
1178
1207
|
export function init(): void;
|
|
1179
1208
|
|
|
1180
1209
|
/**
|
|
1181
|
-
* Map a base content position
|
|
1182
|
-
*
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1210
|
+
* Map a base content position — a USV index into `Content.text`, not a UTF-16
|
|
1211
|
+
* offset — through a `delta` to its new USV position: the pure position-mapping
|
|
1212
|
+
* codec an editor bridge composes to hold a caret stable across a `revise`.
|
|
1213
|
+
* `assoc` decides the side of a same-position insertion (`"after"` moves past
|
|
1214
|
+
* it). Throws on a malformed `delta`.
|
|
1185
1215
|
*/
|
|
1186
1216
|
export function mapPos(delta: Delta, pos: number, assoc: Assoc): number;
|
|
1187
1217
|
|
|
@@ -1197,8 +1227,9 @@ export function parseDocPath(path: string): DocPathSeg[];
|
|
|
1197
1227
|
/**
|
|
1198
1228
|
* Rebase `markdown` onto a `base` content — the pure, document-free twin of
|
|
1199
1229
|
* `revise`: cold-import + `diff_import`, returning the new `content` and the
|
|
1200
|
-
* text `delta` (
|
|
1201
|
-
* a document in hand; `revise(addr,
|
|
1202
|
-
* atomicity. Throws on an over-nested
|
|
1230
|
+
* text `delta` (its offsets USV indices into `Content.text`, surviving anchors
|
|
1231
|
+
* rebased). Use it to compute a revise without a document in hand; `revise(addr,
|
|
1232
|
+
* md)` fuses this with the store for atomicity. Throws on an over-nested
|
|
1233
|
+
* markdown input or a non-content `base`.
|
|
1203
1234
|
*/
|
|
1204
1235
|
export function rebase(base: Content, markdown: string): { content: Content; delta: Delta };
|
|
@@ -131,7 +131,7 @@ export class Document {
|
|
|
131
131
|
/**
|
|
132
132
|
* Interpreted read at `addr`, resolving the field's declared `type` from
|
|
133
133
|
* `quill` — the stable ABI under the runtime `reader.get` / `reader.card(i).get`.
|
|
134
|
-
* The schema-plane twin of the quill-free [`
|
|
134
|
+
* The schema-plane twin of the quill-free [`getStored`](Self::get_stored): a `richtext`
|
|
135
135
|
* field returns its markdown projection, every other declared type its
|
|
136
136
|
* canonical value verbatim, so a consumer holding the quill reads by field
|
|
137
137
|
* meaning rather than by wire shape.
|
|
@@ -176,7 +176,7 @@ export class Document {
|
|
|
176
176
|
* surviving anchors rebase (as [`revise`](Self::revise)), then the diffed
|
|
177
177
|
* result is schema-conformed, so a `richtext(inline)` field rejects a
|
|
178
178
|
* multi-block result with `edit::field_richtext_not_inline`. Returns the
|
|
179
|
-
* text
|
|
179
|
+
* text `Delta`.
|
|
180
180
|
*
|
|
181
181
|
* `addr` must name a field (a bare string is `{ field }`); a body address
|
|
182
182
|
* throws (a body carries no field schema — use [`revise`](Self::revise)). A
|
|
@@ -290,10 +290,10 @@ export class Document {
|
|
|
290
290
|
return ret >>> 0;
|
|
291
291
|
}
|
|
292
292
|
/**
|
|
293
|
-
* The index of the
|
|
294
|
-
* `undefined` when none carries it. Resolves the
|
|
293
|
+
* The index of the composable card whose `$id` equals `id`, or
|
|
294
|
+
* `undefined` when none carries it. Resolves the durable card handle
|
|
295
295
|
* without a hand-rolled scan over [`cards`](Self::cards); `$id` is
|
|
296
|
-
*
|
|
296
|
+
* unique per document, so at most one card matches.
|
|
297
297
|
* @param {string} id
|
|
298
298
|
* @returns {number | undefined}
|
|
299
299
|
*/
|
|
@@ -457,33 +457,6 @@ export class Document {
|
|
|
457
457
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
|
-
/**
|
|
461
|
-
* Read the value at `addr` — the raw stored payload value of a field (a
|
|
462
|
-
* content object for a richtext field, a scalar/array/object otherwise), or
|
|
463
|
-
* the **body content** when `addr.field` is absent. A bare string is `Addr`
|
|
464
|
-
* shorthand for `{ field }`. Reads are total over the field axis: an absent
|
|
465
|
-
* field is `undefined`; only an out-of-range `addr.card` throws
|
|
466
|
-
* `edit::index_out_of_range`. Reads need no schema, so they live on
|
|
467
|
-
* `Document`, not the typed writer; for the markdown projection of a
|
|
468
|
-
* richtext value use [`getMarkdown`](Self::get_markdown).
|
|
469
|
-
* @param {Addr | string} addr
|
|
470
|
-
* @returns {unknown}
|
|
471
|
-
*/
|
|
472
|
-
get(addr) {
|
|
473
|
-
try {
|
|
474
|
-
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
475
|
-
wasm.document_get(retptr, this.__wbg_ptr, addHeapObject(addr));
|
|
476
|
-
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
477
|
-
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
478
|
-
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
479
|
-
if (r2) {
|
|
480
|
-
throw takeObject(r1);
|
|
481
|
-
}
|
|
482
|
-
return takeObject(r0);
|
|
483
|
-
} finally {
|
|
484
|
-
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
460
|
/**
|
|
488
461
|
* The whole `$ext` map at `addr` (a card address, absent `card` = main), or
|
|
489
462
|
* `undefined` when the card carries none. The fine-grained `$ext` read —
|
|
@@ -561,6 +534,35 @@ export class Document {
|
|
|
561
534
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
562
535
|
}
|
|
563
536
|
}
|
|
537
|
+
/**
|
|
538
|
+
* Read the **verbatim stored value** at `addr` — the raw payload value of a
|
|
539
|
+
* field (a content object for a richtext field, a scalar/array/object
|
|
540
|
+
* otherwise), or the **body content** when `addr.field` is absent. A bare
|
|
541
|
+
* string is `Addr` shorthand for `{ field }`. Reads are total over the field
|
|
542
|
+
* axis: an absent field is `undefined`; only an out-of-range `addr.card`
|
|
543
|
+
* throws `edit::index_out_of_range`. Needs no schema, so it lives on
|
|
544
|
+
* `Document` — the read echo of the verbatim `store*` write, distinct from
|
|
545
|
+
* the interpreted schema-plane [`reader.get`](Self::reader_get). For the
|
|
546
|
+
* markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
|
|
547
|
+
* `reader.get` (a field's declared type).
|
|
548
|
+
* @param {Addr | string} addr
|
|
549
|
+
* @returns {unknown}
|
|
550
|
+
*/
|
|
551
|
+
getStored(addr) {
|
|
552
|
+
try {
|
|
553
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
554
|
+
wasm.document_getStored(retptr, this.__wbg_ptr, addHeapObject(addr));
|
|
555
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
556
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
557
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
558
|
+
if (r2) {
|
|
559
|
+
throw takeObject(r1);
|
|
560
|
+
}
|
|
561
|
+
return takeObject(r0);
|
|
562
|
+
} finally {
|
|
563
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
564
566
|
/**
|
|
565
567
|
* Insert a card — the single insertion verb: `at` absent appends, a number
|
|
566
568
|
* inserts at that index (must be in `0..=cards.length`). Accepts a
|
|
@@ -685,8 +687,16 @@ export class Document {
|
|
|
685
687
|
* Build a fresh `Card` from a kind and a flat field map — the ergonomic
|
|
686
688
|
* constructor for `insertCard`. `fields` is an optional
|
|
687
689
|
* `Record<string, unknown>` (each entry becomes a card field, in
|
|
688
|
-
* insertion order); `body` defaults to `""`.
|
|
689
|
-
*
|
|
690
|
+
* insertion order); `body` defaults to `""`.
|
|
691
|
+
*
|
|
692
|
+
* Sugar, not a required step: `insertCard` takes any `Card` object, and
|
|
693
|
+
* `removeCard` returns one, so a card round-trips without passing through
|
|
694
|
+
* here.
|
|
695
|
+
*
|
|
696
|
+
* Checks only what a detached card can decide alone: field-name grammar
|
|
697
|
+
* and value depth. Kind validity is positional — `main` is right for the
|
|
698
|
+
* root, reserved for a composable card — so `insertCard` is its gate, and
|
|
699
|
+
* any kind string is accepted here.
|
|
690
700
|
* @param {string} kind
|
|
691
701
|
* @param {Record<string, unknown>} [fields]
|
|
692
702
|
* @param {string} [body]
|
|
@@ -917,7 +927,7 @@ export class Document {
|
|
|
917
927
|
}
|
|
918
928
|
/**
|
|
919
929
|
* **Revise** the richtext value at `addr` from a markdown string — **edit
|
|
920
|
-
* semantics**, the default write path, returning the text
|
|
930
|
+
* semantics**, the default write path, returning the text `Delta`. Imports
|
|
921
931
|
* the markdown, diffs it against the current value, rebases surviving
|
|
922
932
|
* identity anchors, and returns the change an editor bridge maps its own
|
|
923
933
|
* positions through (`mapPos`). An absent `addr.field` targets the body, an
|
|
@@ -1691,7 +1701,8 @@ export class Quill {
|
|
|
1691
1701
|
* The resolved-value view of `doc` against this quill's schema — for every
|
|
1692
1702
|
* declared field the value the render projection would use and the
|
|
1693
1703
|
* `FieldSource` rung it came from (`"authored" | "default" | "zero"`), in
|
|
1694
|
-
* one call. The card body
|
|
1704
|
+
* one call. The card body is a `body` sibling on its card (row `name`
|
|
1705
|
+
* `"body"`), never a row in `fields` — `null` when the kind enables no body.
|
|
1695
1706
|
*
|
|
1696
1707
|
* Value and provenance only: completeness and errors stay `validate`'s
|
|
1697
1708
|
* (a consumer merges it with its own diagnostic producers regardless), and
|
|
@@ -2064,10 +2075,11 @@ export function init() {
|
|
|
2064
2075
|
}
|
|
2065
2076
|
|
|
2066
2077
|
/**
|
|
2067
|
-
* Map a base content position
|
|
2068
|
-
*
|
|
2069
|
-
*
|
|
2070
|
-
*
|
|
2078
|
+
* Map a base content position — a USV index into `Content.text`, not a UTF-16
|
|
2079
|
+
* offset — through a `delta` to its new USV position: the pure position-mapping
|
|
2080
|
+
* codec an editor bridge composes to hold a caret stable across a `revise`.
|
|
2081
|
+
* `assoc` decides the side of a same-position insertion (`"after"` moves past
|
|
2082
|
+
* it). Throws on a malformed `delta`.
|
|
2071
2083
|
* @param {Delta} delta
|
|
2072
2084
|
* @param {number} pos
|
|
2073
2085
|
* @param {Assoc} assoc
|
|
@@ -2119,9 +2131,10 @@ export function parseDocPath(path) {
|
|
|
2119
2131
|
/**
|
|
2120
2132
|
* Rebase `markdown` onto a `base` content — the pure, document-free twin of
|
|
2121
2133
|
* `revise`: cold-import + `diff_import`, returning the new `content` and the
|
|
2122
|
-
* text `delta` (
|
|
2123
|
-
* a document in hand; `revise(addr,
|
|
2124
|
-
* atomicity. Throws on an over-nested
|
|
2134
|
+
* text `delta` (its offsets USV indices into `Content.text`, surviving anchors
|
|
2135
|
+
* rebased). Use it to compute a revise without a document in hand; `revise(addr,
|
|
2136
|
+
* md)` fuses this with the store for atomicity. Throws on an over-nested
|
|
2137
|
+
* markdown input or a non-content `base`.
|
|
2125
2138
|
* @param {Content} base
|
|
2126
2139
|
* @param {string} markdown
|
|
2127
2140
|
* @returns {{ content: Content; delta: Delta }}
|
|
Binary file
|
|
@@ -23,10 +23,10 @@ export const document_formatDiagnostic: (a: number, b: number) => void;
|
|
|
23
23
|
export const document_formatRules: (a: number) => void;
|
|
24
24
|
export const document_fromJson: (a: number, b: number, c: number) => void;
|
|
25
25
|
export const document_fromMarkdown: (a: number, b: number, c: number) => void;
|
|
26
|
-
export const document_get: (a: number, b: number, c: number) => void;
|
|
27
26
|
export const document_getExt: (a: number, b: number, c: number) => void;
|
|
28
27
|
export const document_getExtNamespace: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
29
28
|
export const document_getMarkdown: (a: number, b: number, c: number) => void;
|
|
29
|
+
export const document_getStored: (a: number, b: number, c: number) => void;
|
|
30
30
|
export const document_insertCard: (a: number, b: number, c: number, d: number) => void;
|
|
31
31
|
export const document_install: (a: number, b: number, c: number, d: number) => void;
|
|
32
32
|
export const document_isFill: (a: number, b: number, c: number) => void;
|