@quillmark/wasm 0.131.0 → 0.133.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 CHANGED
@@ -1,5 +1,127 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.133.0 - 2026-10-29
4
+
5
+ Upgrade path: [0.132 → 0.133](docs/migrations/0.132-to-0.133.md). The
6
+ blueprint is retired: a model writes the JSON authoring document, so a prompt
7
+ built from `quill.blueprint` moves to `quill.authoringSchema`. A root
8
+ `example.md` is an ordinary file: a quill's example is what its `Quill.yaml`
9
+ declares, so move each value onto its field before upgrading.
10
+
11
+ ### LLM authoring
12
+
13
+ - feat(core,cli,wasm,python)!: **LLMs author documents as JSON; the blueprint
14
+ is retired.** The authoring document is the values form lifted to the whole
15
+ document, `{fields, body, cards: [{kind, fields, body}]}`, every rich-text
16
+ field and body a Markdown string and `null` absent.
17
+ `QuillConfig::authoring_schema()` is its JSON Schema, built by
18
+ `build_transform_schema` under the new `SchemaCodec::Text`: every cell admits
19
+ `null`, every declared object refuses an undeclared key, a variant-bearing enum is a `oneOf` per world, and each slot carries
20
+ its `title`, `description`, `default` and `examples`.
21
+ `Quill::to_authoring` exports a document, a field stored as `null` absent, and `Quill::from_authoring` imports
22
+ and conforms one, refusing a malformed shape with `authoring::invalid_shape`,
23
+ its RFC 6901 pointer in `args.pointer`. Export never fails: an undecodable
24
+ or string-held content leaf passes as stored, so every export validates
25
+ against the schema and imports back unchanged.
26
+ WASM `authoringSchema` / `toAuthoring` / `fromAuthoring`, Python
27
+ `authoring_schema` / `to_authoring` / `from_authoring`, and
28
+ `quillmark schema --authoring` expose them. `QuillConfig::blueprint()`,
29
+ `quill.blueprint`, `quillmark blueprint` and `print_blueprint` are deleted;
30
+ `quillmark validate` renders the empty and seeded documents.
31
+ `build_transform_schema` takes a `SchemaCodec`. The blueprint's load rules go
32
+ with it: a multi-line `description:` and an enum member holding `>`, `;` or
33
+ `|` load, and `quill::description_multiline` and
34
+ `quill::format_literal_reserved_char` are deleted. (#2331)
35
+
36
+ ### Examples
37
+
38
+ - feat(core)!: **`example:` and a body's `description` and `example` join the
39
+ quill schema.** A slot at any depth declares at most one `example:`, a value
40
+ of its type checked at load as `default:` is, under
41
+ `quill::example_{type_mismatch,not_in_enum,format_violation,held_stored,on_namespace,over_max,over_length}`
42
+ and `quill::richtext_example_import`. It answers no cell. A body's `description` is text for the writer and its
43
+ `example` markdown that imports without a drop; either beside
44
+ `enabled: false` is `quill::invalid_body`. `schema()` carries them,
45
+ `FieldSchema` and `BodyCardSchema` gain the fields, and WASM types them as
46
+ `QuillFieldSchema.example` and `QuillCardBody.{description,example}`. (#2329)
47
+ - feat(core,cli,wasm,python)!: **the example document is derived.**
48
+ `Quill::example_document()` returns `Option<Document>`: the seeded document
49
+ with every declared `example:` committed and each kind's `body.example` as
50
+ its body, `None` where the quill declares none. A root `example.md` is an
51
+ ordinary file: `EXAMPLE_FILE` and `quill::example_reference` are deleted,
52
+ WASM `exampleDocument()` and Python `example_document()` no longer throw, and
53
+ `quillmark validate` validates and renders the derived document, warning
54
+ `cli::example_file_ignored` while a root `example.md` remains. The
55
+ fixture quills declare the values their `example.md` held. (#2329)
56
+
57
+ ### Content
58
+
59
+ - feat(content,core,wasm): **`reviseContent` revises a body or field to a
60
+ content and keeps its prose anchors.** WASM `doc.reviseContent(addr, rt)`,
61
+ over core's `Card::revise_body_content` / `revise_field_content` and the
62
+ content crate's `delta::carry_anchors`, diffs a content built elsewhere
63
+ against the stored value, carries each prose anchor whose id `rt` does not
64
+ hold, and returns the `Revised` receipt with its text `delta`. `rt`'s own
65
+ anchors and island ids land as they are.
66
+ - feat(content)!: **normalizing content moves no text.** A table's slot
67
+ sharing its line with prose is canonical: `Content::normalize` leaves the
68
+ line as given, where it inserted a `\n` on each side, and `to_markdown`
69
+ breaks it instead. `overwrite`, `reviseContent` and
70
+ `serial::from_authored_value` take the shape where they threw `block island
71
+ in a line's prose`, an `IslandOp::Set` on such a table lands, and a stored
72
+ row holding it loads as stored under the same tag. Typst sets the table as a
73
+ block where its slot sits, closing a heading around it, and a hard break
74
+ after a line the slot ends clears. WASM gains `normalize(content)`, the form
75
+ `overwrite` stores. (#2330)
76
+
77
+ ## v0.132.0 - 2026-10-27
78
+
79
+ Upgrade path: [0.131 → 0.132](docs/migrations/0.131-to-0.132.md). A row
80
+ holding a `qm-*` element or a definition list loads as what it held, and every
81
+ Typst PDF now carries a title.
82
+
83
+ ### Quill bundles
84
+
85
+ - feat(core): **a quill reads and writes as one `.quill` bundle**, its file
86
+ tree as one zip: `Quill.yaml` at the archive root, `/` paths with no `..`,
87
+ stored or deflated entries, and a budget of 2048 entries, 32 MiB a file and
88
+ 64 MiB in all, counted off the central directory before anything inflates.
89
+ [`prose/references/quill-bundle.md`](prose/references/quill-bundle.md)
90
+ specifies the format. `Quill::from_bundle` and `Quill::to_bundle` sit beside
91
+ `from_tree`, and a refused bundle fails as `quill::bundle_invalid`,
92
+ `quill::bundle_unsupported`, `quill::bundle_path` or
93
+ `quill::bundle_too_large`. An archive listing one path as both a file and a
94
+ directory is refused.
95
+ - feat(bindings): **every surface reads and writes a bundle**: WASM
96
+ `Quill.fromBundle(bytes)` and `quill.toBundle()` in both builds, Python
97
+ `Quill.from_bundle(bytes)` and `quill.to_bundle()`. `quill_from_path` reads a
98
+ file named `*.quill` as a bundle, so `Quill.from_path` and every CLI command
99
+ taking a quill path take one; `workspace` refuses a file. `quillmark pack
100
+ <QUILL_PATH> [-o FILE]` writes one, by default `<name>@<version>.quill`.
101
+
102
+ ### Content
103
+
104
+ - feat(content)!: **a `qm-<name>` element and a definition list are no longer
105
+ content.** A `qm-*` tag other than `qm-span` and `qm-anchor` drops, its open
106
+ tag warning `parse::dropped_construct` under its name, and what it wrapped
107
+ imports as written. A definition list reads as the paragraph CommonMark
108
+ reads. A stored `element` or `description` container or `term` line loads as
109
+ what it held and saves without it, under the tag it would take anyway; the
110
+ authored lanes refuse either container. The Typst helper's `elements`
111
+ registry, `_qm-element` and `typst::unregistered_element` are gone, so a
112
+ plate calling `qm.elements.update(..)` fails to compile until the call goes.
113
+
114
+ ### Rendering
115
+
116
+ - feat(typst)!: **every Typst PDF carries a title**, in `/Info /Title` and XMP
117
+ `dc:title`: the render's new `title` option, else the plate's
118
+ `set document(title: ..)`, else the quill's `description`, trimmed.
119
+ `RenderOptions` gains `title`, the WASM and Python render options carry it,
120
+ and `quillmark render` takes `--title`.
121
+ - fix(typst): **a table cell breaks inside an email address or dotted name**,
122
+ such as `Michael.Marshall@us.af.mil`, where one wider than its column ran
123
+ into the next cell. The address still copies out of the PDF whole.
124
+
3
125
  ## v0.131.0 - 2026-10-26
4
126
 
5
127
  Upgrade path: [0.130 → 0.131](docs/migrations/0.130-to-0.131.md). A row
package/README.md CHANGED
@@ -240,8 +240,17 @@ values from the `Document` payload: there is no separate form-view projection.
240
240
  `quill.validate(doc)` scores it without invoking the backend.
241
241
 
242
242
  `quill.exampleDocument()` returns the quill's example, a filled-in page whose
243
- values are made up, pinned to the quill's `name@MAJOR.MINOR`; `undefined`
244
- when the quill has no `example.md` at its root.
243
+ values are made up: the seeded document with each `example` the schema
244
+ declares committed, a field's as its value and a body's as the body;
245
+ `undefined` when the quill declares none.
246
+
247
+ An LLM writes a document as JSON: `quill.authoringSchema` is its JSON Schema,
248
+ `quill.fromAuthoring(reply)` builds and conforms the `Document` (the JSON twin of
249
+ `quill.parse`), and `quill.toAuthoring(doc)` exports any document back, every
250
+ rich-text field and body a Markdown string. A shape error throws
251
+ `authoring::invalid_shape` at its JSON path; a value of the wrong type lands
252
+ with a `conform::*` warning and `quill.validate(doc)` reports it at its
253
+ document path.
245
254
 
246
255
  `quill.seedDocument()` returns a starter document: one card per kind, each
247
256
  carrying the kind's `seed` from `Quill.yaml` and no other field;
@@ -383,7 +392,7 @@ the local date): what a `today` date field and a plate's `datetime.today()`
383
392
  render as. A session keeps the date it opened with, so a preview left open past
384
393
  midnight renders yesterday's until it is reopened.
385
394
 
386
- `opts` takes `format`, `ppi`, `pages` and `regions`, on `engine.render` and
395
+ `opts` takes `format`, `ppi`, `pages`, `regions` and `title`, on `engine.render` and
387
396
  `session.render` alike. Any other key throws rather than reading as absent,
388
397
  `today` included, so `engine.render(quill, doc, { today })` rejects instead of
389
398
  rendering the local date. The date goes last:
@@ -452,10 +461,9 @@ if (cssPxPerPt > 0) { // 0 while the canvas has no layout
452
461
 
453
462
  A field declares no `required` key: nothing is required.
454
463
 
455
- **`default:`** — what an unanswered field renders. With one, `quill.blueprint`
456
- renders that value under a type-only `# <type>` annotation and the render path
457
- uses it when the document omits the field. Without one, the blueprint leaves the
458
- cell empty and an absent field blank-fills.
464
+ **`default:`** — what an unanswered field renders. With one, the render path
465
+ uses it when the document omits the field, and `quill.authoringSchema` carries
466
+ it as the field's `default`. Without one, an absent field blank-fills.
459
467
 
460
468
  An unanswered field draws no diagnostic. Partial documents are accepted, and
461
469
  `engine.render(quill, doc)` throws only for malformed input.
@@ -2153,14 +2153,14 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
2153
2153
 
2154
2154
  ## Apache License 2.0
2155
2155
 
2156
- - quillmark-acroform 0.131.0 (https://github.com/borb-sh/quillmark)
2157
- - quillmark-typst 0.131.0 (https://github.com/borb-sh/quillmark)
2158
- - quillmark-cli 0.131.0 (https://github.com/borb-sh/quillmark)
2159
- - quillmark-python 0.131.0
2160
- - quillmark-content 0.131.0 (https://github.com/borb-sh/quillmark)
2161
- - quillmark-core 0.131.0 (https://github.com/borb-sh/quillmark)
2162
- - quillmark 0.131.0 (https://github.com/borb-sh/quillmark)
2163
- - quillmark-pdf 0.131.0 (https://github.com/borb-sh/quillmark)
2156
+ - quillmark-acroform 0.133.0 (https://github.com/borb-sh/quillmark)
2157
+ - quillmark-typst 0.133.0 (https://github.com/borb-sh/quillmark)
2158
+ - quillmark-cli 0.133.0 (https://github.com/borb-sh/quillmark)
2159
+ - quillmark-python 0.133.0
2160
+ - quillmark-content 0.133.0 (https://github.com/borb-sh/quillmark)
2161
+ - quillmark-core 0.133.0 (https://github.com/borb-sh/quillmark)
2162
+ - quillmark 0.133.0 (https://github.com/borb-sh/quillmark)
2163
+ - quillmark-pdf 0.133.0 (https://github.com/borb-sh/quillmark)
2164
2164
  - ciborium-io 0.2.2 (https://github.com/enarx/ciborium)
2165
2165
  - ciborium-ll 0.2.2 (https://github.com/enarx/ciborium)
2166
2166
  - ciborium 0.2.2 (https://github.com/enarx/ciborium)
@@ -4523,7 +4523,7 @@ limitations under the License.
4523
4523
  - js-sys 0.3.106 (https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/js-sys)
4524
4524
  - lock_api 0.4.14 (https://github.com/Amanieu/parking_lot)
4525
4525
  - log 0.4.29 (https://github.com/rust-lang/log)
4526
- - num-bigint 0.4.6 (https://github.com/rust-num/num-bigint)
4526
+ - num-bigint 0.4.8 (https://github.com/rust-num/num-bigint)
4527
4527
  - num-integer 0.1.46 (https://github.com/rust-num/num-integer)
4528
4528
  - num-traits 0.2.19 (https://github.com/rust-num/num-traits)
4529
4529
  - once_cell 1.21.4 (https://github.com/matklad/once_cell)
@@ -4537,7 +4537,7 @@ limitations under the License.
4537
4537
  - proc-macro-hack 0.5.20+deprecated (https://github.com/dtolnay/proc-macro-hack)
4538
4538
  - rayon-core 1.13.0 (https://github.com/rayon-rs/rayon)
4539
4539
  - rayon 1.12.0 (https://github.com/rayon-rs/rayon)
4540
- - regex-automata 0.4.14 (https://github.com/rust-lang/regex)
4540
+ - regex-automata 0.4.18 (https://github.com/rust-lang/regex)
4541
4541
  - regex-syntax 0.8.10 (https://github.com/rust-lang/regex)
4542
4542
  - regex 1.12.3 (https://github.com/rust-lang/regex)
4543
4543
  - roxmltree 0.20.0 (https://github.com/RazrFalcon/roxmltree)
@@ -6248,8 +6248,8 @@ limitations under the License.
6248
6248
 
6249
6249
  ## Apache License 2.0
6250
6250
 
6251
- - quillmark-wasm 0.131.0 (https://github.com/borb-sh/quillmark)
6252
- - quillmark-fixtures 0.131.0
6251
+ - quillmark-wasm 0.133.0 (https://github.com/borb-sh/quillmark)
6252
+ - quillmark-fixtures 0.133.0
6253
6253
  - arraydeque 0.5.1 (https://github.com/andylokandy/arraydeque)
6254
6254
  - codex 0.3.0 (https://github.com/typst/codex)
6255
6255
  - color 0.3.3 (https://github.com/linebender/color)
@@ -7624,7 +7624,7 @@ SOFTWARE.
7624
7624
  ## MIT License
7625
7625
 
7626
7626
  - unsafe-libyaml 0.2.11 (https://github.com/dtolnay/unsafe-libyaml)
7627
- - zmij 1.0.21 (https://github.com/dtolnay/zmij)
7627
+ - zmij 1.0.23 (https://github.com/dtolnay/zmij)
7628
7628
 
7629
7629
  ~~~~text
7630
7630
  Permission is hereby granted, free of charge, to any
package/core/wasm.d.ts CHANGED
@@ -80,8 +80,7 @@ export type ContentLineKind =
80
80
  | { kind: "para" }
81
81
  | { kind: "heading"; attrs: { level: number } }
82
82
  | { kind: "code"; attrs?: { lang?: string } }
83
- | { kind: "rule" }
84
- | { kind: "term" };
83
+ | { kind: "rule" };
85
84
 
86
85
  /** An ancestor block a line nests inside, outermost first. Closed like
87
86
  * `ContentLine.kind`.
@@ -110,14 +109,7 @@ export type ContentContainer =
110
109
  attrs: { ordered: boolean; start: number; ordinal: number; checked?: boolean };
111
110
  instance?: number;
112
111
  }
113
- | { container: "quote"; instance?: number }
114
- | { container: "description"; instance?: number }
115
- | { container: "element"; attrs: ElementAttrs; instance?: number };
116
-
117
- /** A carrier element's name and attributes, one bag: `$name` is the part of
118
- * its `qm-<name>` tag after the prefix, and every other key an attribute as
119
- * written. */
120
- export type ElementAttrs = { $name: string; [attr: string]: string };
112
+ | { container: "quote"; instance?: number };
121
113
 
122
114
  /** A mark over char range `[start, end)` into `Content.text`. `type` is a
123
115
  * closed set, so `type === "link"` narrows `attrs` to `{ url: string }` with no
@@ -251,9 +243,10 @@ export interface Delta {
251
243
  }
252
244
 
253
245
  /**
254
- * The receipt of a markdown revise (`revise`, `writer.reviseBody`,
246
+ * The receipt of a revise (`revise`, `reviseContent`, `writer.reviseBody`,
255
247
  * `writer.reviseField`): the text `delta`, and one `parse::dropped_construct`
256
- * warning per construct the import dropped, anchored at the revised address.
248
+ * warning per construct a markdown import dropped, anchored at the revised
249
+ * address. `reviseContent` imports nothing, so its `warnings` is empty.
257
250
  */
258
251
  export interface Revised {
259
252
  delta: Delta;
@@ -365,7 +358,9 @@ export type LineOp =
365
358
  *
366
359
  * A `table` has no inline placement: markdown writes it as a block, so an
367
360
  * `insert` whose `at` is not an empty line throws, as does a `set` retyping an
368
- * inline island into one.
361
+ * inline island into one. A table already sharing its line, as a `join` or an
362
+ * `overwrite` of merged edits leaves one, stays there and takes its `set`;
363
+ * markdown writes it on a line of its own.
369
364
  */
370
365
  export type IslandOp =
371
366
  | ({ op: "set" } & ContentIsland)
@@ -508,6 +503,11 @@ export interface QuillCardUi {
508
503
  export interface QuillCardBody {
509
504
  /** When false, consumers must not accept or store body content for this card kind. Defaults to true. */
510
505
  enabled?: boolean;
506
+ /** What the body holds, for the writer. Never beside `enabled: false`. */
507
+ description?: string;
508
+ /** A made-up body in markdown, which `exampleDocument()` commits. Never
509
+ * beside `enabled: false`. */
510
+ example?: string;
511
511
  }
512
512
 
513
513
  export type QuillFieldType = "number" | "integer" | "boolean" | "array" | "object" | "date" | "datetime" | "text" | "richtext" | "enum" | "matrix";
@@ -515,7 +515,8 @@ export type QuillFieldType = "number" | "integer" | "boolean" | "array" | "objec
515
515
  /** Schema entry for a single field declared in a quill's `Quill.yaml`.
516
516
  *
517
517
  * `default` is the value an unanswered cell renders. An absent field without a
518
- * `default` blank-fills.
518
+ * `default` blank-fills. `example` is a made-up value of the same type, which
519
+ * answers no cell: `exampleDocument()` commits it.
519
520
  */
520
521
  export interface QuillFieldSchema {
521
522
  /** A trailing `?` marks the cell optional: unanswered, it renders `none`
@@ -527,6 +528,7 @@ export interface QuillFieldSchema {
527
528
  title?: string;
528
529
  description?: string;
529
530
  default?: unknown;
531
+ example?: unknown;
530
532
  /** The closed set of allowed values. Required on `type: "enum"`, and valid
531
533
  * nowhere else. */
532
534
  values?: string[];
@@ -591,6 +593,26 @@ export interface QuillSchema {
591
593
  card_kinds?: Record<string, QuillCardSchema>;
592
594
  }
593
595
 
596
+ /**
597
+ * One card of an `AuthoringDocument`: its kind, its fields in the values form,
598
+ * and its body as Markdown. `null` anywhere a value goes is absent.
599
+ */
600
+ export interface AuthoringCard {
601
+ kind: string;
602
+ fields?: Record<string, unknown> | null;
603
+ body?: string | null;
604
+ }
605
+
606
+ /**
607
+ * The JSON a model reads and writes, described by `Quill.authoringSchema`:
608
+ * the main card's fields and body, and the composable cards in order.
609
+ */
610
+ export interface AuthoringDocument {
611
+ fields?: Record<string, unknown> | null;
612
+ body?: string | null;
613
+ cards?: AuthoringCard[] | null;
614
+ }
615
+
594
616
  /**
595
617
  * Identity snapshot mirroring the `quill:` section of `Quill.yaml`. The schema
596
618
  * lives on `Quill.schema`; output formats are a resolved-backend capability read
@@ -687,8 +709,9 @@ export class Document {
687
709
  * The newest storage version this build writes via
688
710
  * [`toStored`](Document::to_stored): a document spelling a font mark, a
689
711
  * `table` element, a merged table cell or a table head 0.130 cannot draw
690
- * carries it, every other the tag before it, which a 0.130 build reads. The tag advances only when the wire format changes, not on
691
- * every release.
712
+ * carries it, every other the tag before it, which a 0.130 build reads.
713
+ * The tag advances only when the wire format changes, not on every
714
+ * release.
692
715
  */
693
716
  static currentStorageVersion(): string;
694
717
  /**
@@ -769,8 +792,9 @@ export class Document {
769
792
  /**
770
793
  * **Overwrite** the content value at `addr` with exactly `rt`: value
771
794
  * semantics, so the identity anchors of any previous value are gone. By
772
- * anchor fate `overwrite` destroys, [`revise`](Document::revise) rebases,
773
- * and [`applyChange`](Document::apply_change) preserves. An absent
795
+ * anchor fate `overwrite` destroys, [`revise`](Document::revise) and
796
+ * [`reviseContent`](Document::revise_content) rebase, and
797
+ * [`applyChange`](Document::apply_change) preserves. An absent
774
798
  * `addr.field` targets the body, an absent `addr.card` the main card.
775
799
  *
776
800
  * Throws on an out-of-range card, a malformed field name, or an `rt` that is
@@ -817,6 +841,23 @@ export class Document {
817
841
  * or `undefined`; drops `$seed` entirely once empty. Sibling kinds survive.
818
842
  */
819
843
  removeSeedOverlay(card_kind: string): any;
844
+ /**
845
+ * **Revise** the richtext value at `addr` to `rt`, keeping each stored prose
846
+ * anchor whose id `rt` does not hold: the content twin of
847
+ * [`revise`](Document::revise), for a value built elsewhere such as a
848
+ * merge's projection. Diffs `rt` against the current value, carries those
849
+ * anchors through the diff, and returns the
850
+ * `Revised` receipt, whose `delta` an editor bridge maps its own positions
851
+ * through and whose `warnings` is empty. `rt`'s own anchors and island ids
852
+ * land as they are. An absent `addr.field` targets the body, an absent
853
+ * `addr.card` the main card; an absent field diffs from empty. Richtext
854
+ * only: a `text` field takes `overwrite`.
855
+ *
856
+ * Throws on an out-of-range card, a malformed field name, a present
857
+ * non-content field value, or an `rt` that is not a canonical content
858
+ * object.
859
+ */
860
+ reviseContent(addr: Addr | string, rt: Content): Revised;
820
861
  /**
821
862
  * **Revise** the richtext value at `addr` from a markdown string: the
822
863
  * default write path. Imports the markdown, diffs it against the current
@@ -943,19 +984,34 @@ export class Quill {
943
984
  * The empty document: a main card carrying this quill's `$quill` and
944
985
  * `$kind: main`, no field committed, no composable card, no body. The
945
986
  * type-minimal valid input, and the document a plate is bound to render
946
- * (the quill authoring contract). `new Document(ref)` is the same document
987
+ * (the plate contract). `new Document(ref)` is the same document
947
988
  * reached by spelling the reference.
948
989
  */
949
990
  emptyDocument(): Document;
950
991
  /**
951
- * The quill's example document, `undefined` when the quill has no
952
- * `example.md` at its root: a filled-in page whose values are made up to show the
953
- * quill in use, never kept. It comes back pinned to this quill's
954
- * `name@MAJOR.MINOR` and conformed as `parse` conforms, its parse and
955
- * `conform::*` warnings on `doc.warnings`. Throws when the file does not
956
- * parse or its `$quill` is not this quill's bare name.
992
+ * The quill's example document, `undefined` when no slot or body declares
993
+ * an example: the seeded document with every declared `example` committed
994
+ * as its cell's value and each kind's `body.example` as its body. A
995
+ * filled-in page whose values are made up to show the quill in use, never
996
+ * kept.
957
997
  */
958
998
  exampleDocument(): Document | undefined;
999
+ /**
1000
+ * A document from an authoring document, conformed against this quill:
1001
+ * the JSON twin of `parse`. A `null` is absent; the document carries this
1002
+ * quill's `$quill`. A value the schema refuses lands with a `conform::*`
1003
+ * warning on `doc.warnings`, and `validate` reports the rest at document
1004
+ * paths. Throws, with every error found, on a value that is not the
1005
+ * authoring document's shape (`authoring::invalid_shape`) or a name or
1006
+ * kind no card can store (`edit::*`).
1007
+ */
1008
+ fromAuthoring(value: AuthoringDocument): Document;
1009
+ /**
1010
+ * Read a `.quill` bundle, the zip archive holding one quill's file tree.
1011
+ * Pure, as [`fromTree`](Self::from_tree) is. A bundle outside the format
1012
+ * throws one `quill::bundle_*` diagnostic.
1013
+ */
1014
+ static fromBundle(bytes: Uint8Array): Quill;
959
1015
  /**
960
1016
  * Build a quill from a file tree. Pure: the declared backend is resolved
961
1017
  * later, at render time. Accepts a `Map<string, Uint8Array>` or a plain
@@ -998,6 +1054,18 @@ export class Quill {
998
1054
  * `$kind: main` card of [`seedDocument`](Self::seed_document) alone.
999
1055
  */
1000
1056
  seedMain(): Card;
1057
+ /**
1058
+ * `doc` as an authoring document: every field in the values form (each
1059
+ * content leaf its codec's text), every body as Markdown, each card
1060
+ * `{kind, fields, body}`. Sparse: an absent or `null` field stays absent. A
1061
+ * content leaf that decodes under neither encoding exports as stored.
1062
+ */
1063
+ toAuthoring(doc: Document): AuthoringDocument;
1064
+ /**
1065
+ * This quill's file tree as a `.quill` bundle, the bytes
1066
+ * [`fromBundle`](Self::from_bundle) reads.
1067
+ */
1068
+ toBundle(): Uint8Array;
1001
1069
  /**
1002
1070
  * Flatten this quill back into its canonical file tree, the inverse of
1003
1071
  * [`fromTree`](Self::from_tree). Keys are `"/"`-joined relative paths.
@@ -1015,12 +1083,18 @@ export class Quill {
1015
1083
  * backend's `backend::declined_construct`.
1016
1084
  */
1017
1085
  validate(doc: Document): Diagnostic[];
1086
+ /**
1087
+ * JSON Schema (draft 2020-12) of the quill's authoring document: the
1088
+ * shape `fromAuthoring` takes and `toAuthoring` returns, every content
1089
+ * leaf a Markdown or literal string, each card kind under `$defs`
1090
+ * selected by `kind`.
1091
+ */
1092
+ readonly authoringSchema: Record<string, unknown>;
1018
1093
  /**
1019
1094
  * The *declared* backend identifier (e.g. `"typst"`): intent, not a
1020
1095
  * resolved capability. Capability is read from the engine.
1021
1096
  */
1022
1097
  readonly backendId: string;
1023
- readonly blueprint: string;
1024
1098
  /**
1025
1099
  * Identity snapshot of the `quill:` section of `Quill.yaml`. Pure config:
1026
1100
  * output formats are a resolved-backend capability read from
@@ -1120,6 +1194,14 @@ export function mapMarks(content: Content, bundle: ChangeBundle): ContentMark[];
1120
1194
  */
1121
1195
  export function mapPos(delta: Delta, pos: number, assoc: Assoc): number;
1122
1196
 
1197
+ /**
1198
+ * The canonical form of `rt`: the content `overwrite` stores from it, read
1199
+ * without a document. Normalizing rewrites structure, never the text, so the
1200
+ * answer's `text` is `rt.text`. Throws where `overwrite` would, with the same
1201
+ * error under this verb's name.
1202
+ */
1203
+ export function normalize(rt: Content): Content;
1204
+
1123
1205
  /**
1124
1206
  * Parse a canonical document-model `Diagnostic.path` (`cards.<kind>[<i>].<field>`,
1125
1207
  * `main.body`, `recipients[0].name`) into structured `DocPathSeg` segments, so
@@ -1186,6 +1268,7 @@ export interface InitOutput {
1186
1268
  readonly document_removeField: (a: number, b: number, c: number) => void;
1187
1269
  readonly document_removeSeedOverlay: (a: number, b: number, c: number, d: number) => void;
1188
1270
  readonly document_revise: (a: number, b: number, c: number, d: number, e: number) => void;
1271
+ readonly document_reviseContent: (a: number, b: number, c: number, d: number) => void;
1189
1272
  readonly document_seedOverlay: (a: number, b: number, c: number, d: number) => void;
1190
1273
  readonly document_setQuillRef: (a: number, b: number, c: number, d: number) => void;
1191
1274
  readonly document_storageVersionOf: (a: number, b: number, c: number) => void;
@@ -1205,13 +1288,16 @@ export interface InitOutput {
1205
1288
  readonly isPlain: (a: number, b: number) => void;
1206
1289
  readonly mapMarks: (a: number, b: number, c: number) => void;
1207
1290
  readonly mapPos: (a: number, b: number, c: number, d: number) => void;
1291
+ readonly normalize: (a: number, b: number) => void;
1208
1292
  readonly parseDocPath: (a: number, b: number, c: number) => void;
1209
1293
  readonly quill__resolve: (a: number, b: number, c: number, d: number, e: number) => void;
1294
+ readonly quill_authoringSchema: (a: number, b: number) => void;
1210
1295
  readonly quill_backendId: (a: number, b: number) => void;
1211
- readonly quill_blueprint: (a: number, b: number) => void;
1212
1296
  readonly quill_conform: (a: number, b: number, c: number) => void;
1213
1297
  readonly quill_emptyDocument: (a: number) => number;
1214
- readonly quill_exampleDocument: (a: number, b: number) => void;
1298
+ readonly quill_exampleDocument: (a: number) => number;
1299
+ readonly quill_fromAuthoring: (a: number, b: number, c: number) => void;
1300
+ readonly quill_fromBundle: (a: number, b: number, c: number) => void;
1215
1301
  readonly quill_fromTree: (a: number, b: number) => void;
1216
1302
  readonly quill_metadata: (a: number, b: number) => void;
1217
1303
  readonly quill_parse: (a: number, b: number, c: number, d: number) => void;
@@ -1219,6 +1305,8 @@ export interface InitOutput {
1219
1305
  readonly quill_seedCard: (a: number, b: number, c: number, d: number, e: number) => void;
1220
1306
  readonly quill_seedDocument: (a: number) => number;
1221
1307
  readonly quill_seedMain: (a: number, b: number) => void;
1308
+ readonly quill_toAuthoring: (a: number, b: number, c: number) => void;
1309
+ readonly quill_toBundle: (a: number, b: number) => void;
1222
1310
  readonly quill_toTree: (a: number) => number;
1223
1311
  readonly quill_validate: (a: number, b: number, c: number) => void;
1224
1312
  readonly quill_warnings: (a: number, b: number) => void;