@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.
@@ -9,12 +9,12 @@ export const document__addCard: (a: number, b: number, c: number, d: number, e:
9
9
  export const document__commitField: (a: number, b: number, c: number, d: number, e: number) => void;
10
10
  export const document__commitFields: (a: number, b: number, c: number, d: number, e: number) => void;
11
11
  export const document__readerGet: (a: number, b: number, c: number, d: number) => void;
12
+ export const document__readerGetContent: (a: number, b: number, c: number, d: number) => void;
12
13
  export const document__reviseField: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
13
14
  export const document_applyChange: (a: number, b: number, c: number, d: number) => void;
14
15
  export const document_blueprintInstruction: (a: number, b: number, c: number) => void;
15
16
  export const document_card: (a: number, b: number, c: number) => void;
16
17
  export const document_cardCount: (a: number) => number;
17
- export const document_cardIndexById: (a: number, b: number, c: number) => number;
18
18
  export const document_cards: (a: number, b: number) => void;
19
19
  export const document_clone: (a: number) => number;
20
20
  export const document_currentSchemaVersion: (a: number) => void;
@@ -78,8 +78,10 @@ export const mapPos: (a: number, b: number, c: number, d: number) => void;
78
78
  export const parseDocPath: (a: number, b: number, c: number) => void;
79
79
  export const quill_backendId: (a: number, b: number) => void;
80
80
  export const quill_blueprint: (a: number, b: number) => void;
81
+ export const quill_conform: (a: number, b: number, c: number) => void;
81
82
  export const quill_fromTree: (a: number, b: number) => void;
82
83
  export const quill_metadata: (a: number, b: number) => void;
84
+ export const quill_parse: (a: number, b: number, c: number, d: number) => void;
83
85
  export const quill_resolve: (a: number, b: number, c: number) => void;
84
86
  export const quill_schema: (a: number, b: number) => void;
85
87
  export const quill_seedCard: (a: number, b: number, c: number, d: number, e: number) => void;
@@ -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 `id` (`$id`), optional `ext` (`$ext`), and optional `seed`
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 (a content object for a richtext field, a scalar/array/object
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
- * Revise the richtext field at `addr` from markdown, typed *and*
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} markdown
232
+ * @param {string} text
189
233
  * @returns {Delta}
190
234
  */
191
- _reviseField(quill, addr, markdown) {
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(markdown, wasm.__wbindgen_export, wasm.__wbindgen_export2);
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 (a content object for a richtext field, a scalar/array/object
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
@@ -9,12 +9,12 @@ export const document__addCard: (a: number, b: number, c: number, d: number, e:
9
9
  export const document__commitField: (a: number, b: number, c: number, d: number, e: number) => void;
10
10
  export const document__commitFields: (a: number, b: number, c: number, d: number, e: number) => void;
11
11
  export const document__readerGet: (a: number, b: number, c: number, d: number) => void;
12
+ export const document__readerGetContent: (a: number, b: number, c: number, d: number) => void;
12
13
  export const document__reviseField: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
13
14
  export const document_applyChange: (a: number, b: number, c: number, d: number) => void;
14
15
  export const document_blueprintInstruction: (a: number, b: number, c: number) => void;
15
16
  export const document_card: (a: number, b: number, c: number) => void;
16
17
  export const document_cardCount: (a: number) => number;
17
- export const document_cardIndexById: (a: number, b: number, c: number) => number;
18
18
  export const document_cards: (a: number, b: number) => void;
19
19
  export const document_clone: (a: number) => number;
20
20
  export const document_currentSchemaVersion: (a: number) => void;
@@ -78,8 +78,10 @@ export const mapPos: (a: number, b: number, c: number, d: number) => void;
78
78
  export const parseDocPath: (a: number, b: number, c: number) => void;
79
79
  export const quill_backendId: (a: number, b: number) => void;
80
80
  export const quill_blueprint: (a: number, b: number) => void;
81
+ export const quill_conform: (a: number, b: number, c: number) => void;
81
82
  export const quill_fromTree: (a: number, b: number) => void;
82
83
  export const quill_metadata: (a: number, b: number) => void;
84
+ export const quill_parse: (a: number, b: number, c: number, d: number) => void;
83
85
  export const quill_resolve: (a: number, b: number, c: number) => void;
84
86
  export const quill_schema: (a: number, b: number) => void;
85
87
  export const quill_seedCard: (a: number, b: number, c: number, d: number, e: number) => void;
package/core/wasm.d.ts CHANGED
@@ -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 `id` (`$id`), optional `ext` (`$ext`), and optional `seed`
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[];
@@ -437,6 +435,16 @@ export interface Diagnostic {
437
435
  */
438
436
  path?: string;
439
437
  hint?: string;
438
+ /**
439
+ * The facts `message` interpolates, keyed by name. With `code`, the
440
+ * substitution unit needed to word this diagnostic in another language;
441
+ * `prose/canon/ERROR.md` § \"Diagnostic args\" tabulates the keys per code.
442
+ *
443
+ * Declared optional explicitly because `tsify` does not read
444
+ * `skip_serializing_if`: without this, a field the runtime omits is
445
+ * declared required. `sourceChain` carries that mismatch.
446
+ */
447
+ args?: Record<string, unknown>;
440
448
  sourceChain?: string[];
441
449
  }
442
450
 
@@ -487,13 +495,6 @@ export class Document {
487
495
  * verbs.
488
496
  */
489
497
  card(index: number): Card;
490
- /**
491
- * The index of the composable card whose `$id` equals `id`, or
492
- * `undefined` when none carries it. Resolves the durable card handle
493
- * without a hand-rolled scan over [`cards`](Self::cards); `$id` is
494
- * unique per document, so at most one card matches.
495
- */
496
- cardIndexById(id: string): number | undefined;
497
498
  clone(): Document;
498
499
  /**
499
500
  * Schema version this build writes via [`toJson`](Document::to_json).
@@ -561,8 +562,7 @@ export class Document {
561
562
  getMarkdown(addr?: CardAddr): string;
562
563
  /**
563
564
  * Read the **verbatim stored value** at `addr`: the raw payload value of a
564
- * field (a content object for a richtext field, a scalar/array/object
565
- * otherwise), or the **body content** when `addr.field` is absent. A bare
565
+ * field, or the **body content** when `addr.field` is absent. A bare
566
566
  * string is `Addr` shorthand for `{ field }`. Reads are total over the field
567
567
  * axis: an absent field is `undefined`; only an out-of-range `addr.card`
568
568
  * throws `edit::index_out_of_range`. Needs no schema, so it lives on
@@ -570,6 +570,16 @@ export class Document {
570
570
  * the interpreted schema-plane [`reader.get`](Self::reader_get). For the
571
571
  * markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
572
572
  * `reader.get` (a field's declared type).
573
+ *
574
+ * **A content field at rest has one stored form per codec**: a `richtext`
575
+ * field holds the canonical content object, a `plaintext` field its literal
576
+ * string. A document that came through the bound door (`quill.parse` /
577
+ * `quill.conform`) is at rest, so this read no longer depends on which lane
578
+ * built it. A document that came through the transport door
579
+ * (`Document.fromMarkdown`, a legacy stored row) may rest as authored until
580
+ * it is conformed, and this read reports what is there. For the corpus
581
+ * either way, use the schema-plane `reader.getContent`, which decodes
582
+ * through the codec the field's declared type names.
573
583
  */
574
584
  getStored(addr: Addr | string): unknown;
575
585
  /**
@@ -802,6 +812,12 @@ export class Document {
802
812
  */
803
813
  readonly main: Card;
804
814
  readonly quillRef: string;
815
+ /**
816
+ * The non-fatal diagnostics of the load that produced this document: parse
817
+ * warnings, plus the `conform::*` warnings when it came through
818
+ * `quill.parse`. Session state, not document value: `equals` and the
819
+ * storage DTO exclude it, and `fromJson` / `loadJson` clear it.
820
+ */
805
821
  readonly warnings: Diagnostic[];
806
822
  }
807
823
 
@@ -809,6 +825,23 @@ export class Quill {
809
825
  private constructor();
810
826
  free(): void;
811
827
  [Symbol.dispose](): void;
828
+ /**
829
+ * Land `doc`'s declared content fields at their canonical rest **in
830
+ * place**, returning the `conform::*` diagnostics for the values that would
831
+ * not commit (an empty array when everything rested).
832
+ *
833
+ * The read-repair verb: a document that arrived through the transport door
834
+ * (`fromMarkdown`, `fromJson`, a stored row) converges here, and is then
835
+ * eligible for rewrite under its current schema tag. Idempotent, and a
836
+ * no-op on an already-canonical document: an equal value is not rewritten,
837
+ * so YAML comments and stored bytes survive.
838
+ *
839
+ * A `!must_fill` marker anywhere in a field's value skips that field (the
840
+ * marker is the state), and a value the strict write refuses stays as
841
+ * authored with a diagnostic. Throws when `doc` declares a different
842
+ * `$quill`, before any mutation.
843
+ */
844
+ conform(doc: Document): Diagnostic[];
812
845
  /**
813
846
  * Build a quill from a file tree. Pure: no backend, no engine; the
814
847
  * declared backend is resolved later, at render time.
@@ -819,6 +852,21 @@ export class Quill {
819
852
  * canonical shape.
820
853
  */
821
854
  static fromTree(tree: Map<string, Uint8Array>): Quill;
855
+ /**
856
+ * Parse `markdown` and conform it against this quill: the **primary
857
+ * ingestion path**, and the bound twin of the schema-free
858
+ * `Document.fromMarkdown`. The returned document rests at its canonical
859
+ * form (a `richtext` field as a content object, a `plaintext` field as its
860
+ * literal string), so `getStored` no longer answers "corpus or string?"
861
+ * with "depends how this document was built".
862
+ *
863
+ * Parse warnings and the `conform::*` diagnostics both land on
864
+ * `doc.warnings`. Throws on a parse failure, or when `markdown` declares a
865
+ * `$quill` this quill does not answer to: nothing conforms under the wrong
866
+ * schema. To open a document whose `$quill` is stale, use the transport
867
+ * door (`Document.fromMarkdown`, `setQuillRef`, then `quill.conform`).
868
+ */
869
+ parse(markdown: string): Document;
822
870
  /**
823
871
  * The resolved-value view of `doc` against this quill's schema: for every
824
872
  * declared field the value the render projection would use and the