@quillmark/wasm 0.99.0 → 0.100.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 +89 -104
- package/README.md +54 -5
- package/backends/pdfform/wasm.d.ts +60 -12
- package/backends/pdfform/wasm_bg.js +130 -20
- package/backends/pdfform/wasm_bg.wasm +0 -0
- package/backends/pdfform/wasm_bg.wasm.d.ts +3 -1
- package/backends/typst/wasm.d.ts +60 -12
- package/backends/typst/wasm_bg.js +130 -20
- package/backends/typst/wasm_bg.wasm +0 -0
- package/backends/typst/wasm_bg.wasm.d.ts +3 -1
- package/core/wasm.d.ts +60 -12
- package/core/wasm_bg.js +130 -20
- package/core/wasm_bg.wasm +0 -0
- package/core/wasm_bg.wasm.d.ts +3 -1
- package/package.json +1 -1
- package/runtime/runtime.d.ts +35 -9
- package/runtime/runtime.js +43 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.100.0 - 2026-08-03
|
|
4
|
+
|
|
5
|
+
A content field gets one resting form, and the last reserved `$` key with no
|
|
6
|
+
reader is removed. All breaking changes are covered by
|
|
7
|
+
`docs/migrations/0.99-to-0.100.md`. Stored documents load unchanged, but a row
|
|
8
|
+
read through the bound door converges once: read-repair, not a schema-version
|
|
9
|
+
event. One ordering matters, and the guide's "Legacy data" section states it —
|
|
10
|
+
conform a stored population before exporting markdown from it.
|
|
11
|
+
|
|
12
|
+
- refactor(core,wasm,python)!: content fields have one resting form, enforced at
|
|
13
|
+
load. `Quill::conform(&mut doc)` is the primitive and `Quill::parse(md)`
|
|
14
|
+
(parse, then conform) the convenience — the documented primary ingestion path,
|
|
15
|
+
`quill.parse` / `quill.conform` on both bindings. A `richtext` field rests as
|
|
16
|
+
the canonical content object, a `plaintext` field as its **literal string**, so
|
|
17
|
+
the stored shape is a property of the codec instead of the construction lane:
|
|
18
|
+
`equals` and content hashes stop separating semantically identical documents.
|
|
19
|
+
The typed writer commits `plaintext` as a string, and `revise_field` diffs it
|
|
20
|
+
through the literal codec (a byte-identical revise of `a \*b\*` used to commit
|
|
21
|
+
`a *b*`). `Document::parse` / `Document.fromMarkdown` stay exactly as they
|
|
22
|
+
were, demoted to the transport/repair door. Conform is idempotent, a byte no-op
|
|
23
|
+
on an already-canonical document, and reports a `conform::*` warning where the
|
|
24
|
+
strict write refuses rather than retyping or rejecting; a `$quill` naming
|
|
25
|
+
another quill errors before any mutation (#1160, #1162). See
|
|
26
|
+
`docs/migrations/0.99-to-0.100.md`
|
|
27
|
+
- fix(core)!: markdown exported from a `plaintext` field resting as a content
|
|
28
|
+
object is markdown-escaped. Emit is schema-free and cannot tell a `plaintext`
|
|
29
|
+
content from a `richtext` one, so `a *literal* line` leaves as
|
|
30
|
+
`a \*literal\* line` and re-parses with the backslashes as characters — one
|
|
31
|
+
more layer per save cycle. Only the typed writer produced that rest, and the
|
|
32
|
+
string rest above deletes it rather than managing it: load, conform, and
|
|
33
|
+
re-store a population before exporting markdown from it. Markdown already
|
|
34
|
+
exported under ≤0.99 is corrupt at rest, its escapes indistinguishable from
|
|
35
|
+
authored ones, so re-export it from the conformed rows (#1159). See
|
|
36
|
+
`docs/migrations/0.99-to-0.100.md`
|
|
37
|
+
- fix(core,wasm,python)!: a `plaintext` field resting as a string reads through
|
|
38
|
+
the **literal** codec, not markdown — `note: 'a *literal* line'` read back as
|
|
39
|
+
`a literal line` while render and validation kept the asterisks. Only the
|
|
40
|
+
string lane was wrong; the committed-object lane always decoded correctly, so
|
|
41
|
+
a consumer that pre-escaped a `plaintext` field to survive the read drops the
|
|
42
|
+
escaping. Alongside it, `reader.get_content` / `reader.getContent` returns a
|
|
43
|
+
content field's `Content` corpus whichever lane stored it, so a consumer
|
|
44
|
+
holding a corpus editor stops branching on the wire shape. `EditError` gains
|
|
45
|
+
`FieldNotContent` (`edit::field_not_content`) for a declared type that is not a
|
|
46
|
+
content leaf; core adds `Card::field_plaintext_content` (#1154). See
|
|
47
|
+
`docs/migrations/0.99-to-0.100.md`
|
|
48
|
+
- refactor(core,wasm,python)!: card `$id` is removed — the reserved key, its
|
|
49
|
+
resolver (`Document::find_card` / `doc.cardIndexById` / `doc.card_index_by_id`),
|
|
50
|
+
the uniqueness contract (`EditError::CardIdCollision` / `EmptyCardId`, the
|
|
51
|
+
`parse::card_id_*` warnings, the storage rejection), `Card::id` /
|
|
52
|
+
`Payload::{id, set_id, take_id}` / `Document::{set_card_id, remove_card_id}`,
|
|
53
|
+
the `PayloadItem::Id` and `CardWire.id` wire members, and the projected `id` on
|
|
54
|
+
both bindings' card shape. Nothing in the engine read it and it never reached a
|
|
55
|
+
backend, so what is left after removing the machinery that served the resolver
|
|
56
|
+
is `$ext` with a reserved name. A block declaring `$id` no longer parses and a
|
|
57
|
+
blob carrying an `id` payload item no longer loads: a hard cutover, no
|
|
58
|
+
tolerate-and-ignore window. Per-card consumer keys move to `$ext` under a
|
|
59
|
+
namespace you own, with no uniqueness, no collision check, and no repair
|
|
60
|
+
(#1151). See `docs/migrations/0.99-to-0.100.md`
|
|
61
|
+
- refactor(content)!: `Content`, `Line`, `Mark`, and `Island` take
|
|
62
|
+
`#[non_exhaustive]` — the four public structs the 0.99 sweep missed, that pass
|
|
63
|
+
having run as two issues split by crate. Their literals give way to `new` plus
|
|
64
|
+
the `with_*` setters on the same terms as the rest of the API; every field stays
|
|
65
|
+
`pub`, so reading and assigning are unchanged. `Delta`, `Segment`, and
|
|
66
|
+
`BaseLengthMismatch` stay open deliberately and now say so in their rustdoc.
|
|
67
|
+
A Rust source break only: nothing about the wire, the canonical bytes, or the
|
|
68
|
+
bindings moves (#1146). See `docs/migrations/0.99-to-0.100.md`
|
|
69
|
+
- feat(core,wasm,python): `Diagnostic.args` — the facts `message` interpolates,
|
|
70
|
+
keyed by name, so a consumer with its own string table selects a sentence by
|
|
71
|
+
`code` and fills it itself. Values keep their JSON shape (a list arrives as a
|
|
72
|
+
list, a count as a number), engine prose never rides under a key, and a
|
|
73
|
+
formatter missing a key falls back to `message` wholesale. `prose/canon/ERROR.md`
|
|
74
|
+
§ "Diagnostic args" tabulates the keys per code and a test fails when code and
|
|
75
|
+
canon disagree (#1130)
|
|
76
|
+
- fix(core): the `$quill` mismatch message and hint name the pairing rather than
|
|
77
|
+
the verb. `check_quill_reference` gates every schema-bound door now, not the
|
|
78
|
+
render path alone, so a `quill.parse` failure no longer reads "was rendered
|
|
79
|
+
with". The codes (`quill::name_mismatch` / `quill::version_mismatch`) are
|
|
80
|
+
unchanged
|
|
81
|
+
- test(fuzz): the resting-form invariant gains a target, stated as three
|
|
82
|
+
properties — conform is a fixed point, parse-then-conform equals typed-write
|
|
83
|
+
per content field, and a document through the markdown surface and back settles
|
|
84
|
+
after one pass (exactly, for `plaintext`, whose codec is lossless both ways)
|
|
85
|
+
- docs: the cycle's stale pages are repaired. Both binding READMEs gain the bound
|
|
86
|
+
door and the corpus read, `revise_field` is documented per declared type on all
|
|
87
|
+
four surfaces instead of as a markdown-only richtext verb, and four canon claims
|
|
88
|
+
that outran the tree are corrected
|
|
89
|
+
|
|
90
|
+
|
|
3
91
|
## v0.99.0 - 2026-08-01
|
|
4
92
|
|
|
5
93
|
The 1.0.0 API freeze lands ahead of the tag, and the content codec closes its
|
|
@@ -119,109 +207,6 @@ loads byte-identically and `0.99` writes the same bytes for the same content.
|
|
|
119
207
|
`serde_saphyr` types stay out of `quillmark-core`'s public API (see the YAML
|
|
120
208
|
engine entry above), so nothing downstream moves
|
|
121
209
|
|
|
122
|
-
<!-- seed: commits since v0.98.0, confirm the entries above cover them, then delete this comment
|
|
123
|
-
- chore(core): move the time format descriptions to parse_borrowed::<3>
|
|
124
|
-
- build(deps): bump lopdf from 0.42.0 to 0.44.0
|
|
125
|
-
- build(deps): bump thiserror in the cargo group across 1 directory
|
|
126
|
-
- build(deps): bump taiki-e/install-action
|
|
127
|
-
- chore(core): bump serde-saphyr to 1.0
|
|
128
|
-
- Split lint back out of test
|
|
129
|
-
- Link every shipped artifact in CI, and carry v0.99.0's notes forward
|
|
130
|
-
- dense-prose pass over the CI scope
|
|
131
|
-
- Cut CI to one job per shipped surface
|
|
132
|
-
- Stop the release from pushing to a branch that takes only PRs
|
|
133
|
-
- Fix three claims the independent review falsified
|
|
134
|
-
- Correct the release notes' exhaustive-type count
|
|
135
|
-
- dense-prose pass over the review's scope
|
|
136
|
-
- Close the two payload doors the depth guard missed
|
|
137
|
-
- Ship the license the workspace actually grants
|
|
138
|
-
- Correct the release docs against the tree they describe
|
|
139
|
-
- CLAUDE.md: tighten the Tests section to house voice
|
|
140
|
-
- CLAUDE.md: drop `uv run` from the Python binding flow
|
|
141
|
-
- CLAUDE.md: gate local binding builds, name the cheap profiles
|
|
142
|
-
- chore(release): v0.99.0
|
|
143
|
-
- Split serial.rs's fixed-point claim into the two it conflated
|
|
144
|
-
- Make Fidelity the one place a loss class is spelled
|
|
145
|
-
- Make an island's loss class injective instead of guarded
|
|
146
|
-
- dense-prose and simplify passes over the handle-check work
|
|
147
|
-
- Keep the colon out of embedded YAML values
|
|
148
|
-
- Sweep the em-dash out of comments and prose
|
|
149
|
-
- Refuse a core handle from a second copy, everywhere
|
|
150
|
-
- Replace the em-dash ban with the rule the exemplars follow
|
|
151
|
-
- dense-prose pass over the foreign-handle prose
|
|
152
|
-
- Extend the policy to the writer/reader lane, and draw the read/write line
|
|
153
|
-
- Keep the patched method names, and stop over-claiming in the warning
|
|
154
|
-
- Tolerate foreign core handles on the by-reference methods
|
|
155
|
-
- Correct the quill file-size cap doc and MiB units
|
|
156
|
-
- Collapse the rustdoc gate onto --workspace
|
|
157
|
-
- dense-prose pass over the release-readiness fixes
|
|
158
|
-
- Close the release-readiness gaps found against v0.98.0
|
|
159
|
-
- Drop the semver job
|
|
160
|
-
- Trim the Python typing work to its load-bearing parts
|
|
161
|
-
- Revert "Record KnownIslandType::ALL's slice shape in the 0.99 guide"
|
|
162
|
-
- Record KnownIslandType::ALL's slice shape in the 0.99 guide
|
|
163
|
-
- Close the Python Tier-1 gaps: single-card reads and a typed surface
|
|
164
|
-
- Drop the top-level-await plugin the vite 8 test config cannot load
|
|
165
|
-
- Shape the reserved-name lists as slices
|
|
166
|
-
- Shape the island ALL as a slice; list the 0.99 guide as published
|
|
167
|
-
- Prune rottable duplication from CLAUDE.md
|
|
168
|
-
- Adopt the editor's dense-prose rewrite; compress CLAUDE.md
|
|
169
|
-
- build(deps): bump the cargo group across 1 directory with 12 updates
|
|
170
|
-
- build(deps): bump the actions group across 1 directory with 11 updates
|
|
171
|
-
- build(deps): bump tsify from 0.4.5 to 0.5.6
|
|
172
|
-
- build(deps): bump toml from 0.8.23 to 1.1.3+spec-1.1.0
|
|
173
|
-
- build(deps): bump similar from 2.7.0 to 3.1.1
|
|
174
|
-
- build(deps): bump serde-saphyr from 0.0.23 to 0.0.29
|
|
175
|
-
- Run the semver job on release PRs, not on every one
|
|
176
|
-
- Drop the dead check-cfg rustflag that crashed the semver job
|
|
177
|
-
- docs: dense-prose pass over the new test comments
|
|
178
|
-
- dense-prose pass over the branch
|
|
179
|
-
- Gate the compatibility promise mechanically, and write it down
|
|
180
|
-
- test(bindings): cover the WASM and Python exports nothing exercised
|
|
181
|
-
- Close the struct half of the 1.0.0 non_exhaustive sweep, and seal Backend
|
|
182
|
-
- test(pdfform): drive unbound text/checkbox/choice through the fixture
|
|
183
|
-
- Move the workspace to edition 2024
|
|
184
|
-
- build(deps-dev): bump vitest in /crates/bindings/wasm
|
|
185
|
-
- build(deps-dev): bump typescript in /crates/bindings/wasm
|
|
186
|
-
- prose: drop the readiness proposal and SECURITY.md
|
|
187
|
-
- ci: drop the Windows matrix from the test job
|
|
188
|
-
- Finish the coerce_value_strict cleanup in the fuzz crate
|
|
189
|
-
- dense-prose pass across the code and docs
|
|
190
|
-
- Revert the wasm job to `npm install`
|
|
191
|
-
- Trim CI to the checks v1.0.0 actually needs
|
|
192
|
-
- Cut the two CI costs that buy nothing
|
|
193
|
-
- Clear the RUSTSEC vulnerabilities the audit job actually found
|
|
194
|
-
- Pin the tree to LF so the Windows runner reads what the test wrote
|
|
195
|
-
- Cleanup pass: cut the machinery the fix did not need
|
|
196
|
-
- prose: record what landed against the v1.0.0 readiness findings
|
|
197
|
-
- fuzz: cover the four JSON decode lanes the bindings expose
|
|
198
|
-
- Declare and hold an MSRV
|
|
199
|
-
- Ship the license text, verify the packages, scan the dependencies
|
|
200
|
-
- Open the engine crates' public enums ahead of the 1.0.0 freeze
|
|
201
|
-
- Hide the workspace-internal seams from the published surface
|
|
202
|
-
- typst: quill-load defects become session warnings, not stderr
|
|
203
|
-
- core: own the YAML boundary error, and budget the third entry point
|
|
204
|
-
- prose: index the v1.0.0 readiness findings against their issues
|
|
205
|
-
- prose: v1.0.0 production-readiness review
|
|
206
|
-
- Drop issue markers; dense-prose the unreleased 0.99 guide
|
|
207
|
-
- dense-prose pass over the PR 1097 scope
|
|
208
|
-
- docs: record the op-wire key-order change in the unreleased guide
|
|
209
|
-
- content: carry the `<u>` bit on the event, not in a shared set
|
|
210
|
-
- content: one key sorter for the canonical form
|
|
211
|
-
- content: bound opaque JSON payload depth on the Value lane
|
|
212
|
-
- content: make a vocabulary promotion carry its own legacy form
|
|
213
|
-
- content: simplify pass over the codec-gap changes
|
|
214
|
-
- content: house voice on the codec-gap comments
|
|
215
|
-
- content: close the three v1.0.0 codec gaps before the freeze
|
|
216
|
-
- content: cut the enumerated halves of the two open-set tests
|
|
217
|
-
- content: prune tests that assert what a neighbour already pins
|
|
218
|
-
- content: fold the authored-lane scan into the shared cell walk
|
|
219
|
-
- content: split the wire lanes on reserved-name reuse (#1084, #1085, #1086)
|
|
220
|
-
- docs: trim the migration index to a routing table; drop duplicate links
|
|
221
|
-
- refactor(typst): re-export span_scan/extract instead of forwarding
|
|
222
|
-
-->
|
|
223
|
-
|
|
224
|
-
|
|
225
210
|
## v0.98.0 - 2026-07-28
|
|
226
211
|
|
|
227
212
|
Five breaking changes, all covered by `docs/migrations/0.97-to-0.98.md`.
|
|
@@ -370,7 +355,7 @@ Stored documents are unaffected: a `0.97` blob loads byte-identically and
|
|
|
370
355
|
- **breaking** core,wasm,python: a schema-bound read view — `Quill::view(&doc)` / `quill.view(doc)`, the read twin of `quill.writer(doc)`. `view.get(addr)` interprets each field by its declared type (a `richtext` field → markdown, a `plaintext` field → its literal text via the plaintext codec, every other type → its canonical value verbatim), returns absent as `undefined` / `None`, and — the authority the quill-free `getMarkdown` lacks — throws `UnknownField` for a name the schema does not declare and `FieldRichtextDecode` for a content field holding an undecodable value. Core `TypedReader::get` returns a `ReadValue` (`Markdown`/`Plaintext`/`Value`); `view.card(i)` is the card cursor; core adds `Card::field_plaintext` (the `to_plaintext` twin of `field_markdown`). **`getMarkdown`'s field half retires**: `getMarkdown` / `get_markdown` / `get_card_markdown` are now body-only (WASM `getMarkdown` takes a `CardAddr`, a present `field` throws; Python drops the `name` parameter) — a field's markdown is read through `view.get`. The quill-free body projection stays on `Document` (#978)
|
|
371
356
|
- **breaking** content: one delta-application contract — implicit trailing retain is `try_apply`'s semantics (a short delta retains the untouched remainder; the error is over-consumption only), `apply` panics on an over-long delta instead of clamping (clamping is silent corruption), and `extend_to_base` is removed. `split_line` / `join_line` rebase marks through their one-char `\n` splice with `map_pos` — the same mapping the text-delta channel uses — so marks no longer drift across line ops and `apply_field_change` canonicalizes once (a single terminal normalize instead of one per stage); line sync rebuilds in one forward pass instead of per-`\n` `Vec` splices. Mark ops are specified in final-text coordinates (post-delta, post-line-op — the frame they validate against) (#926, #987)
|
|
372
357
|
- **breaking** core: storage blobs tagged `@0.81.0` / `@0.82.0` fail as an unknown schema version — the read-only `V0_81_0` / `V0_82_0` DTO trees and their forward migrations are retired (nothing persisted on this lineage predates `@0.92.0`; `0.82.0` was yanked). `V0_92_0` stays the oldest shape read, and its payload types back the current write path. DOCUMENT_STORAGE.md records variant retirement as the policy when no stored population remains (#929)
|
|
373
|
-
- **breaking** core,wasm,python: the markdown projection stops appending a trailing newline — `to_markdown` projects a *value*, not a file, so `field_markdown` / `body_markdown` (WASM `getMarkdown` / `exportMarkdown`, Python `export_markdown` / `get_markdown`) no longer grow a `\n`; `writer.set("subject", "Hello")` reads back as `"Hello"`, not `"Hello\n"`.
|
|
358
|
+
- **breaking** core,wasm,python: the markdown projection stops appending a trailing newline — `to_markdown` projects a *value*, not a file, so `field_markdown` / `body_markdown` (WASM `getMarkdown` / `exportMarkdown`, Python `export_markdown` / `get_markdown`) no longer grow a `\n`; `writer.set("subject", "Hello")` reads back as `"Hello"`, not `"Hello\n"`. The content fixed point is unchanged (import is newline-insensitive) (#965)
|
|
374
359
|
- **breaking** all: rename the content genus off its codec's name — crate `quillmark-richtext` → `quillmark-content`, type `RichText` → `Content` (and `RichTextLine`/`RichTextContainer`/`RichTextMark`/`RichTextIsland` → `ContentLine`/…), const `RICHTEXT_MEDIA_TYPE` → `CONTENT_MEDIA_TYPE` and its wire string `application/quillmark-richtext+json` → `application/quillmark-content+json`, `#[serde(skip)]` companion caches `FieldSchema::{default,example}_corpus` → `_content`, `SegmentMap.corpus: Range<usize>` → `.content`, Typst-emitter `EmittedContent` → `Emission` (it is markup + source map, not a Typst `content` value). Schema tokens `richtext` / `plaintext`, `FieldType::{RichText,PlainText}` variants, and the codec-specific `field_richtext` / `FieldRichtext*` / `apply_field_richtext_change` / `richtext(inline)` surface are unchanged — those name codecs, not the model. Canonical body JSON is nameless, so stored documents don't migrate; `contentMediaType` consumers pin to the new spelling. Retires the informal "corpus" noun to end the code/prose split (#976)
|
|
375
360
|
- **breaking** core,wasm,python: `getMarkdown` / `get_markdown` / `get_card_markdown` stop conflating an absent field with a present-but-not-richtext one — a present field that does not decode as richtext (a scalar/array/object a `storeField` wrote) now throws `FieldRichtextDecode` instead of reading back `undefined` / `""`; absence still returns the absent shape. Core `Card::field_markdown` becomes `Option<Result<String, RichtextDecodeError>>` (the projection twin of `field_richtext`). Rule: absence returns, mismatch raises; read the raw value with `get` (#968)
|
|
376
361
|
- feat(core,wasm): typed, anchor-preserving field revise — `TypedWriter::revise_field` / `CardWriter::revise_field` and `writer.reviseField` / `writer.card(i).reviseField` wrap core `Card::revise_field_checked` (diff-rebase surviving anchors, then schema-conform the result); the schema-bound verb lives on the writer, where the schema is (#957, #966)
|
package/README.md
CHANGED
|
@@ -94,10 +94,37 @@ For an example-filled starter use `quill.seedDocument()`. Throws on an
|
|
|
94
94
|
invalid quill reference.
|
|
95
95
|
|
|
96
96
|
### `Document.fromMarkdown(markdown)`
|
|
97
|
-
Parse markdown to a parsed document
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
Parse markdown to a parsed document, quill-free: the **transport door**
|
|
98
|
+
(migrations, `$ext` stamping, a quill that will not load, opening a document to
|
|
99
|
+
fix its `$quill`). Throws a JS `Error` (with `.diagnostics` attached, see
|
|
100
|
+
[Errors](#errors)) on any parse failure, including a missing root `$quill`
|
|
101
|
+
metadata line, malformed YAML, and inputs over the 10 MiB
|
|
102
|
+
`parse::input_too_large` limit. A content field rests as authored; `quill.parse`
|
|
103
|
+
below is the bound door that lands it at its canonical rest.
|
|
104
|
+
|
|
105
|
+
### `quill.parse(markdown)` / `quill.conform(doc)`
|
|
106
|
+
The **bound door**, and the primary ingestion path. `quill.parse` is
|
|
107
|
+
`Document.fromMarkdown` followed by `conform`: the returned document's declared
|
|
108
|
+
content fields rest at one form per codec (a `richtext` field as the canonical
|
|
109
|
+
content object, a `plaintext` field as its literal string), so `getStored`
|
|
110
|
+
answers "corpus or string?" by the field's declared codec rather than by how the
|
|
111
|
+
document was built. Parse warnings and the `conform::*` warnings both ride
|
|
112
|
+
`doc.warnings`.
|
|
113
|
+
|
|
114
|
+
`quill.conform(doc)` is the same walk in place on a document that arrived any
|
|
115
|
+
other way (`fromJson`, a stored row), returning the `conform::*` `Diagnostic[]`
|
|
116
|
+
(`[]` when everything rested). It is idempotent and a byte no-op on an
|
|
117
|
+
already-canonical document, YAML comments included, so calling it on every load
|
|
118
|
+
is safe. A `!must_fill` marker anywhere in a field's value skips that field; a
|
|
119
|
+
value the strict write refuses stays as authored under a warning. Both throw
|
|
120
|
+
when the document declares a `$quill` this quill does not answer to, before any
|
|
121
|
+
mutation.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
const doc = quill.parse(markdown); // rests canonical
|
|
125
|
+
const stale = Document.fromJson(row);
|
|
126
|
+
const diags = quill.conform(stale); // converges in place
|
|
127
|
+
```
|
|
101
128
|
|
|
102
129
|
### `doc.toMarkdown()`
|
|
103
130
|
Emit canonical Quillmark Markdown. Type-fidelity round-trip safe:
|
|
@@ -259,7 +286,11 @@ card's. Reads are total over the field axis (`getStored` → `undefined`, `isFil
|
|
|
259
286
|
an absent field; only an out-of-range card throws); field writes throw on a body
|
|
260
287
|
address. `getStored` is the verbatim transport read, distinct from the interpreted
|
|
261
288
|
`quill.reader(doc).get`; `getMarkdown` is the body markdown read (a `CardAddr`; a field's
|
|
262
|
-
markdown is read through `quill.reader(doc).get(field)`).
|
|
289
|
+
markdown is read through `quill.reader(doc).get(field)`). A content field's stored
|
|
290
|
+
form follows how the document was built (a canonical content object when the
|
|
291
|
+
typed writer committed it, the authored string when a markdown parse produced
|
|
292
|
+
it), so for the corpus either way read `quill.reader(doc).getContent(addr)`, which
|
|
293
|
+
decodes through the codec the field's declared type names. Card-scoped verbs take a
|
|
263
294
|
`CardAddr` (`{ card? }`) first: `doc.getExt({ card: 2 })`, and the batch below.
|
|
264
295
|
|
|
265
296
|
Batch mutation: `doc.storeFields({}, {...})` / `doc.storeFields({ card: index }, {...})`
|
|
@@ -324,6 +355,24 @@ ed.card(2).set("body", "**note**"); // composable card, resolved
|
|
|
324
355
|
is lazy: it never throws; an out-of-range index throws `IndexOutOfRange` at the
|
|
325
356
|
write.
|
|
326
357
|
|
|
358
|
+
#### `DocumentReader` / `CardReader`: the read twin
|
|
359
|
+
|
|
360
|
+
`quill.reader(doc)` carries the writer's ephemerality and its schema authority:
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
const v = quill.reader(doc);
|
|
364
|
+
v.get("subject"); // by declared type: richtext → markdown, plaintext → literal text
|
|
365
|
+
v.getContent("subject"); // the same read as a Content corpus, whichever lane stored it
|
|
366
|
+
v.getBody(); // the main body markdown (quill-free)
|
|
367
|
+
v.card(0).get("body"); // a card field, resolved by its $kind
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
`get` projects and `getContent` returns the corpus; both decode through the codec
|
|
371
|
+
the field's **declared type** names, which is why they bind the quill and the
|
|
372
|
+
verbatim `doc.getStored` does not. An undeclared name throws `UnknownField`, a
|
|
373
|
+
type that is not a content leaf throws `FieldNotContent`, and an undecodable
|
|
374
|
+
value throws `FieldRichtextDecode`; an absent field reads back `undefined`.
|
|
375
|
+
|
|
327
376
|
### `engine.render(quill, parsed, opts?)` vs. `engine.open(quill, parsed)`
|
|
328
377
|
|
|
329
378
|
Use **`engine.render`** for one-shot exports (PDF/SVG/PNG): compiles, emits
|
|
@@ -32,14 +32,13 @@ export type PayloadItem =
|
|
|
32
32
|
*
|
|
33
33
|
* `$` system entries are hoisted to named fields: `kind` (the `$kind`, empty
|
|
34
34
|
* string when none), optional `quill` (the `$quill` `name@version`, main card
|
|
35
|
-
* only), optional `
|
|
35
|
+
* only), optional `ext` (`$ext`), and optional `seed`
|
|
36
36
|
* (the `$seed` per-kind overlay map, main card only). `payloadItems` carries
|
|
37
37
|
* user fields and comments in order.
|
|
38
38
|
*/
|
|
39
39
|
export interface Card {
|
|
40
40
|
kind: string;
|
|
41
41
|
quill?: string;
|
|
42
|
-
id?: string;
|
|
43
42
|
ext?: Record<string, unknown>;
|
|
44
43
|
seed?: Record<string, unknown>;
|
|
45
44
|
payloadItems: PayloadItem[];
|
|
@@ -63,7 +62,6 @@ export interface Card {
|
|
|
63
62
|
export interface CardInput {
|
|
64
63
|
kind: string;
|
|
65
64
|
quill?: string;
|
|
66
|
-
id?: string;
|
|
67
65
|
ext?: Record<string, unknown>;
|
|
68
66
|
seed?: Record<string, unknown>;
|
|
69
67
|
payloadItems?: PayloadItem[];
|
|
@@ -593,6 +591,16 @@ export interface Diagnostic {
|
|
|
593
591
|
*/
|
|
594
592
|
path?: string;
|
|
595
593
|
hint?: string;
|
|
594
|
+
/**
|
|
595
|
+
* The facts `message` interpolates, keyed by name. With `code`, the
|
|
596
|
+
* substitution unit needed to word this diagnostic in another language;
|
|
597
|
+
* `prose/canon/ERROR.md` § \"Diagnostic args\" tabulates the keys per code.
|
|
598
|
+
*
|
|
599
|
+
* Declared optional explicitly because `tsify` does not read
|
|
600
|
+
* `skip_serializing_if`: without this, a field the runtime omits is
|
|
601
|
+
* declared required. `sourceChain` carries that mismatch.
|
|
602
|
+
*/
|
|
603
|
+
args?: Record<string, unknown>;
|
|
596
604
|
sourceChain?: string[];
|
|
597
605
|
}
|
|
598
606
|
|
|
@@ -739,13 +747,6 @@ export class Document {
|
|
|
739
747
|
* verbs.
|
|
740
748
|
*/
|
|
741
749
|
card(index: number): Card;
|
|
742
|
-
/**
|
|
743
|
-
* The index of the composable card whose `$id` equals `id`, or
|
|
744
|
-
* `undefined` when none carries it. Resolves the durable card handle
|
|
745
|
-
* without a hand-rolled scan over [`cards`](Self::cards); `$id` is
|
|
746
|
-
* unique per document, so at most one card matches.
|
|
747
|
-
*/
|
|
748
|
-
cardIndexById(id: string): number | undefined;
|
|
749
750
|
clone(): Document;
|
|
750
751
|
/**
|
|
751
752
|
* Schema version this build writes via [`toJson`](Document::to_json).
|
|
@@ -813,8 +814,7 @@ export class Document {
|
|
|
813
814
|
getMarkdown(addr?: CardAddr): string;
|
|
814
815
|
/**
|
|
815
816
|
* Read the **verbatim stored value** at `addr`: the raw payload value of a
|
|
816
|
-
* field
|
|
817
|
-
* otherwise), or the **body content** when `addr.field` is absent. A bare
|
|
817
|
+
* field, or the **body content** when `addr.field` is absent. A bare
|
|
818
818
|
* string is `Addr` shorthand for `{ field }`. Reads are total over the field
|
|
819
819
|
* axis: an absent field is `undefined`; only an out-of-range `addr.card`
|
|
820
820
|
* throws `edit::index_out_of_range`. Needs no schema, so it lives on
|
|
@@ -822,6 +822,16 @@ export class Document {
|
|
|
822
822
|
* the interpreted schema-plane [`reader.get`](Self::reader_get). For the
|
|
823
823
|
* markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
|
|
824
824
|
* `reader.get` (a field's declared type).
|
|
825
|
+
*
|
|
826
|
+
* **A content field at rest has one stored form per codec**: a `richtext`
|
|
827
|
+
* field holds the canonical content object, a `plaintext` field its literal
|
|
828
|
+
* string. A document that came through the bound door (`quill.parse` /
|
|
829
|
+
* `quill.conform`) is at rest, so this read no longer depends on which lane
|
|
830
|
+
* built it. A document that came through the transport door
|
|
831
|
+
* (`Document.fromMarkdown`, a legacy stored row) may rest as authored until
|
|
832
|
+
* it is conformed, and this read reports what is there. For the corpus
|
|
833
|
+
* either way, use the schema-plane `reader.getContent`, which decodes
|
|
834
|
+
* through the codec the field's declared type names.
|
|
825
835
|
*/
|
|
826
836
|
getStored(addr: Addr | string): unknown;
|
|
827
837
|
/**
|
|
@@ -1054,6 +1064,12 @@ export class Document {
|
|
|
1054
1064
|
*/
|
|
1055
1065
|
readonly main: Card;
|
|
1056
1066
|
readonly quillRef: string;
|
|
1067
|
+
/**
|
|
1068
|
+
* The non-fatal diagnostics of the load that produced this document: parse
|
|
1069
|
+
* warnings, plus the `conform::*` warnings when it came through
|
|
1070
|
+
* `quill.parse`. Session state, not document value: `equals` and the
|
|
1071
|
+
* storage DTO exclude it, and `fromJson` / `loadJson` clear it.
|
|
1072
|
+
*/
|
|
1057
1073
|
readonly warnings: Diagnostic[];
|
|
1058
1074
|
}
|
|
1059
1075
|
|
|
@@ -1185,6 +1201,23 @@ export class Quill {
|
|
|
1185
1201
|
private constructor();
|
|
1186
1202
|
free(): void;
|
|
1187
1203
|
[Symbol.dispose](): void;
|
|
1204
|
+
/**
|
|
1205
|
+
* Land `doc`'s declared content fields at their canonical rest **in
|
|
1206
|
+
* place**, returning the `conform::*` diagnostics for the values that would
|
|
1207
|
+
* not commit (an empty array when everything rested).
|
|
1208
|
+
*
|
|
1209
|
+
* The read-repair verb: a document that arrived through the transport door
|
|
1210
|
+
* (`fromMarkdown`, `fromJson`, a stored row) converges here, and is then
|
|
1211
|
+
* eligible for rewrite under its current schema tag. Idempotent, and a
|
|
1212
|
+
* no-op on an already-canonical document: an equal value is not rewritten,
|
|
1213
|
+
* so YAML comments and stored bytes survive.
|
|
1214
|
+
*
|
|
1215
|
+
* A `!must_fill` marker anywhere in a field's value skips that field (the
|
|
1216
|
+
* marker is the state), and a value the strict write refuses stays as
|
|
1217
|
+
* authored with a diagnostic. Throws when `doc` declares a different
|
|
1218
|
+
* `$quill`, before any mutation.
|
|
1219
|
+
*/
|
|
1220
|
+
conform(doc: Document): Diagnostic[];
|
|
1188
1221
|
/**
|
|
1189
1222
|
* Build a quill from a file tree. Pure: no backend, no engine; the
|
|
1190
1223
|
* declared backend is resolved later, at render time.
|
|
@@ -1195,6 +1228,21 @@ export class Quill {
|
|
|
1195
1228
|
* canonical shape.
|
|
1196
1229
|
*/
|
|
1197
1230
|
static fromTree(tree: Map<string, Uint8Array>): Quill;
|
|
1231
|
+
/**
|
|
1232
|
+
* Parse `markdown` and conform it against this quill: the **primary
|
|
1233
|
+
* ingestion path**, and the bound twin of the schema-free
|
|
1234
|
+
* `Document.fromMarkdown`. The returned document rests at its canonical
|
|
1235
|
+
* form (a `richtext` field as a content object, a `plaintext` field as its
|
|
1236
|
+
* literal string), so `getStored` no longer answers "corpus or string?"
|
|
1237
|
+
* with "depends how this document was built".
|
|
1238
|
+
*
|
|
1239
|
+
* Parse warnings and the `conform::*` diagnostics both land on
|
|
1240
|
+
* `doc.warnings`. Throws on a parse failure, or when `markdown` declares a
|
|
1241
|
+
* `$quill` this quill does not answer to: nothing conforms under the wrong
|
|
1242
|
+
* schema. To open a document whose `$quill` is stale, use the transport
|
|
1243
|
+
* door (`Document.fromMarkdown`, `setQuillRef`, then `quill.conform`).
|
|
1244
|
+
*/
|
|
1245
|
+
parse(markdown: string): Document;
|
|
1198
1246
|
/**
|
|
1199
1247
|
* The resolved-value view of `doc` against this quill's schema: for every
|
|
1200
1248
|
* declared field the value the render projection would use and the
|
|
@@ -169,7 +169,48 @@ export class Document {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
/**
|
|
172
|
-
*
|
|
172
|
+
* Interpreted **corpus** read at `addr`: the stable ABI under the runtime
|
|
173
|
+
* `reader.getContent` / `reader.card(i).getContent`. The corpus twin of
|
|
174
|
+
* [`reader.get`](Self::reader_get), which projects; this decodes the stored
|
|
175
|
+
* value through the codec the field's declared type names (`richtext` as
|
|
176
|
+
* markdown, `plaintext` as literal text) and returns the canonical `Content`.
|
|
177
|
+
*
|
|
178
|
+
* Total over the storage form: a committed field holds a content object and
|
|
179
|
+
* a parsed one holds the authored string, and both read back as a corpus
|
|
180
|
+
* here, so a consumer mounting a corpus editor stops branching on how the
|
|
181
|
+
* document was built.
|
|
182
|
+
*
|
|
183
|
+
* A bare string is `Addr` shorthand for `{ field }`; `{ card, field }`
|
|
184
|
+
* targets a composable card. Returns `undefined` for an **absent** field. An
|
|
185
|
+
* absent `addr.field` reads the **body** corpus, quill-free, mirroring
|
|
186
|
+
* [`getStored`](Self::get_stored). Throws `edit::unknown_field` for a name
|
|
187
|
+
* the schema does not declare, `edit::field_not_content` for a declared type
|
|
188
|
+
* that is not a content leaf (`array<richtext>` carries content and still has
|
|
189
|
+
* no one corpus), `edit::field_richtext_decode` for a stored value
|
|
190
|
+
* that decodes under neither encoding, and `edit::index_out_of_range` for a
|
|
191
|
+
* bad `addr.card`.
|
|
192
|
+
* @param {Quill} quill
|
|
193
|
+
* @param {Addr | string} addr
|
|
194
|
+
* @returns {Content | undefined}
|
|
195
|
+
*/
|
|
196
|
+
_readerGetContent(quill, addr) {
|
|
197
|
+
try {
|
|
198
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
199
|
+
_assertClass(quill, Quill);
|
|
200
|
+
wasm.document__readerGetContent(retptr, this.__wbg_ptr, quill.__wbg_ptr, addHeapObject(addr));
|
|
201
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
202
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
203
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
204
|
+
if (r2) {
|
|
205
|
+
throw takeObject(r1);
|
|
206
|
+
}
|
|
207
|
+
return takeObject(r0);
|
|
208
|
+
} finally {
|
|
209
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Revise the content field at `addr` from authored text, typed *and*
|
|
173
214
|
* anchor-preserving: the ABI under `writer.reviseField`. Resolves the
|
|
174
215
|
* field's schema from `quill` (main card, or the addressed card's `$kind`)
|
|
175
216
|
* and defers to [`TypedWriter::revise_field`](quillmark_core::TypedWriter::revise_field):
|
|
@@ -178,6 +219,9 @@ export class Document {
|
|
|
178
219
|
* multi-block result with `edit::field_richtext_not_inline`. Returns the
|
|
179
220
|
* text `Delta`.
|
|
180
221
|
*
|
|
222
|
+
* The codec is the declared type's: `richtext` diffs markdown, `plaintext`
|
|
223
|
+
* the literal text.
|
|
224
|
+
*
|
|
181
225
|
* `addr` must name a field (a bare string is `{ field }`); a body address
|
|
182
226
|
* throws (a body carries no field schema: use [`revise`](Self::revise)). A
|
|
183
227
|
* name the schema does not declare throws `edit::unknown_field`. Throws
|
|
@@ -185,14 +229,14 @@ export class Document {
|
|
|
185
229
|
* `writer.reviseField` in the runtime layer.
|
|
186
230
|
* @param {Quill} quill
|
|
187
231
|
* @param {Addr | string} addr
|
|
188
|
-
* @param {string}
|
|
232
|
+
* @param {string} text
|
|
189
233
|
* @returns {Delta}
|
|
190
234
|
*/
|
|
191
|
-
_reviseField(quill, addr,
|
|
235
|
+
_reviseField(quill, addr, text) {
|
|
192
236
|
try {
|
|
193
237
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
194
238
|
_assertClass(quill, Quill);
|
|
195
|
-
const ptr0 = passStringToWasm0(
|
|
239
|
+
const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
196
240
|
const len0 = WASM_VECTOR_LEN;
|
|
197
241
|
wasm.document__reviseField(retptr, this.__wbg_ptr, quill.__wbg_ptr, addHeapObject(addr), ptr0, len0);
|
|
198
242
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
@@ -289,20 +333,6 @@ export class Document {
|
|
|
289
333
|
const ret = wasm.document_cardCount(this.__wbg_ptr);
|
|
290
334
|
return ret >>> 0;
|
|
291
335
|
}
|
|
292
|
-
/**
|
|
293
|
-
* The index of the composable card whose `$id` equals `id`, or
|
|
294
|
-
* `undefined` when none carries it. Resolves the durable card handle
|
|
295
|
-
* without a hand-rolled scan over [`cards`](Self::cards); `$id` is
|
|
296
|
-
* unique per document, so at most one card matches.
|
|
297
|
-
* @param {string} id
|
|
298
|
-
* @returns {number | undefined}
|
|
299
|
-
*/
|
|
300
|
-
cardIndexById(id) {
|
|
301
|
-
const ptr0 = passStringToWasm0(id, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
302
|
-
const len0 = WASM_VECTOR_LEN;
|
|
303
|
-
const ret = wasm.document_cardIndexById(this.__wbg_ptr, ptr0, len0);
|
|
304
|
-
return takeObject(ret);
|
|
305
|
-
}
|
|
306
336
|
/**
|
|
307
337
|
* @returns {Card[]}
|
|
308
338
|
*/
|
|
@@ -536,8 +566,7 @@ export class Document {
|
|
|
536
566
|
}
|
|
537
567
|
/**
|
|
538
568
|
* Read the **verbatim stored value** at `addr`: the raw payload value of a
|
|
539
|
-
* field
|
|
540
|
-
* otherwise), or the **body content** when `addr.field` is absent. A bare
|
|
569
|
+
* field, or the **body content** when `addr.field` is absent. A bare
|
|
541
570
|
* string is `Addr` shorthand for `{ field }`. Reads are total over the field
|
|
542
571
|
* axis: an absent field is `undefined`; only an out-of-range `addr.card`
|
|
543
572
|
* throws `edit::index_out_of_range`. Needs no schema, so it lives on
|
|
@@ -545,6 +574,16 @@ export class Document {
|
|
|
545
574
|
* the interpreted schema-plane [`reader.get`](Self::reader_get). For the
|
|
546
575
|
* markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
|
|
547
576
|
* `reader.get` (a field's declared type).
|
|
577
|
+
*
|
|
578
|
+
* **A content field at rest has one stored form per codec**: a `richtext`
|
|
579
|
+
* field holds the canonical content object, a `plaintext` field its literal
|
|
580
|
+
* string. A document that came through the bound door (`quill.parse` /
|
|
581
|
+
* `quill.conform`) is at rest, so this read no longer depends on which lane
|
|
582
|
+
* built it. A document that came through the transport door
|
|
583
|
+
* (`Document.fromMarkdown`, a legacy stored row) may rest as authored until
|
|
584
|
+
* it is conformed, and this read reports what is there. For the corpus
|
|
585
|
+
* either way, use the schema-plane `reader.getContent`, which decodes
|
|
586
|
+
* through the codec the field's declared type names.
|
|
548
587
|
* @param {Addr | string} addr
|
|
549
588
|
* @returns {unknown}
|
|
550
589
|
*/
|
|
@@ -1254,6 +1293,10 @@ export class Document {
|
|
|
1254
1293
|
return ret === 0 ? undefined : Document.__wrap(ret);
|
|
1255
1294
|
}
|
|
1256
1295
|
/**
|
|
1296
|
+
* The non-fatal diagnostics of the load that produced this document: parse
|
|
1297
|
+
* warnings, plus the `conform::*` warnings when it came through
|
|
1298
|
+
* `quill.parse`. Session state, not document value: `equals` and the
|
|
1299
|
+
* storage DTO exclude it, and `fromJson` / `loadJson` clear it.
|
|
1257
1300
|
* @returns {Diagnostic[]}
|
|
1258
1301
|
*/
|
|
1259
1302
|
get warnings() {
|
|
@@ -1649,6 +1692,40 @@ export class Quill {
|
|
|
1649
1692
|
wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
|
|
1650
1693
|
}
|
|
1651
1694
|
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Land `doc`'s declared content fields at their canonical rest **in
|
|
1697
|
+
* place**, returning the `conform::*` diagnostics for the values that would
|
|
1698
|
+
* not commit (an empty array when everything rested).
|
|
1699
|
+
*
|
|
1700
|
+
* The read-repair verb: a document that arrived through the transport door
|
|
1701
|
+
* (`fromMarkdown`, `fromJson`, a stored row) converges here, and is then
|
|
1702
|
+
* eligible for rewrite under its current schema tag. Idempotent, and a
|
|
1703
|
+
* no-op on an already-canonical document: an equal value is not rewritten,
|
|
1704
|
+
* so YAML comments and stored bytes survive.
|
|
1705
|
+
*
|
|
1706
|
+
* A `!must_fill` marker anywhere in a field's value skips that field (the
|
|
1707
|
+
* marker is the state), and a value the strict write refuses stays as
|
|
1708
|
+
* authored with a diagnostic. Throws when `doc` declares a different
|
|
1709
|
+
* `$quill`, before any mutation.
|
|
1710
|
+
* @param {Document} doc
|
|
1711
|
+
* @returns {Diagnostic[]}
|
|
1712
|
+
*/
|
|
1713
|
+
conform(doc) {
|
|
1714
|
+
try {
|
|
1715
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
1716
|
+
_assertClass(doc, Document);
|
|
1717
|
+
wasm.quill_conform(retptr, this.__wbg_ptr, doc.__wbg_ptr);
|
|
1718
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
1719
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
1720
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
1721
|
+
if (r2) {
|
|
1722
|
+
throw takeObject(r1);
|
|
1723
|
+
}
|
|
1724
|
+
return takeObject(r0);
|
|
1725
|
+
} finally {
|
|
1726
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1652
1729
|
/**
|
|
1653
1730
|
* Build a quill from a file tree. Pure: no backend, no engine; the
|
|
1654
1731
|
* declared backend is resolved later, at render time.
|
|
@@ -1697,6 +1774,39 @@ export class Quill {
|
|
|
1697
1774
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
1698
1775
|
}
|
|
1699
1776
|
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Parse `markdown` and conform it against this quill: the **primary
|
|
1779
|
+
* ingestion path**, and the bound twin of the schema-free
|
|
1780
|
+
* `Document.fromMarkdown`. The returned document rests at its canonical
|
|
1781
|
+
* form (a `richtext` field as a content object, a `plaintext` field as its
|
|
1782
|
+
* literal string), so `getStored` no longer answers "corpus or string?"
|
|
1783
|
+
* with "depends how this document was built".
|
|
1784
|
+
*
|
|
1785
|
+
* Parse warnings and the `conform::*` diagnostics both land on
|
|
1786
|
+
* `doc.warnings`. Throws on a parse failure, or when `markdown` declares a
|
|
1787
|
+
* `$quill` this quill does not answer to: nothing conforms under the wrong
|
|
1788
|
+
* schema. To open a document whose `$quill` is stale, use the transport
|
|
1789
|
+
* door (`Document.fromMarkdown`, `setQuillRef`, then `quill.conform`).
|
|
1790
|
+
* @param {string} markdown
|
|
1791
|
+
* @returns {Document}
|
|
1792
|
+
*/
|
|
1793
|
+
parse(markdown) {
|
|
1794
|
+
try {
|
|
1795
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
1796
|
+
const ptr0 = passStringToWasm0(markdown, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
1797
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1798
|
+
wasm.quill_parse(retptr, this.__wbg_ptr, ptr0, len0);
|
|
1799
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
1800
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
1801
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
1802
|
+
if (r2) {
|
|
1803
|
+
throw takeObject(r1);
|
|
1804
|
+
}
|
|
1805
|
+
return Document.__wrap(r0);
|
|
1806
|
+
} finally {
|
|
1807
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1700
1810
|
/**
|
|
1701
1811
|
* The resolved-value view of `doc` against this quill's schema: for every
|
|
1702
1812
|
* declared field the value the render projection would use and the
|
|
Binary file
|