@quillmark/wasm 0.90.0 → 0.92.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,35 +1,54 @@
1
1
  # Changelog
2
2
 
3
- ## v0.90.0 - 2026-06-10
4
-
5
-
6
-
7
- ## v0.89.1 - 2026-06-10
8
-
9
- - chore(release): v0.89.1-rc.1 (#714)
10
- - feat(wasm)!: 0.90 canonical API engine-free Quill, single root export, typed errors; Python parity (#713)
11
- - Proposal: WASM bindings split (core + render) via backend-decoupled Quill (#710)
12
- - Add version selector matching and mismatch warnings (#708)
13
- - docs: density-optimization pass on user-facing docs (#703)
14
- - Remove role annotation from root block metadata header (#707)
15
- - canon: audit and correct all prose/canon/ docs (#704)
16
- - Fix makeCard fields/body typed as required in WASM .d.ts (#702)
17
- - Update CLAUDE.md
18
-
19
-
20
- ## v0.89.1-rc.1 - 2026-06-10
21
-
22
- - feat(wasm)!: 0.90 canonical API engine-free Quill, single root export, typed errors; Python parity (#713)
23
- - Proposal: WASM bindings split (core + render) via backend-decoupled Quill (#710)
24
- - Add version selector matching and mismatch warnings (#708)
25
- - docs: density-optimization pass on user-facing docs (#703)
26
- - Remove role annotation from root block metadata header (#707)
27
- - canon: audit and correct all prose/canon/ docs (#704)
28
- - Fix makeCard fields/body typed as required in WASM .d.ts (#702)
29
- - Update CLAUDE.md
3
+ ## v0.92.0 - 2026-06-22
4
+
5
+ - 0.92 technical-debt sweep: correctness, $seed hardening, de-duplication (#727)
6
+ - dotnet: add $seed namespace writers (parity with Python/WASM)
7
+ - refactor(core): unify $ext/$seed into one out-of-band Meta concept
8
+ - Cleanup: simplify QuillWorld::font to a single expression
9
+ - Cleanup: de-narrate comments, sync canon binding tables with .NET
10
+ - dotnet: fix stale schema version (CI) + review-flagged polish
11
+ - docs(migration): cover the !fill !must_fill rename in the 0.92 guide
12
+ - dotnet: fix native-lib copy to test project + two correctness bugs
13
+ - Remove Document.seed(kind) for strict ext/seed symmetry
14
+ - dotnet: expose $seed on the Card DTO
15
+ - refactor(dotnet): rename engine class Quillmark -> QuillmarkEngine
16
+ - Reject !fill: treat as a noncanonical tag, not a fill alias
17
+ - Fix binding build break + warn on unsupported fill positions
18
+ - fix(dotnet): resolve engine type in test namespace (CS0426)
19
+ - docs(dotnet): trim README to a dense, consumer-focused surface
20
+ - Address review nits: loud divergence, docs, coverage
21
+ - Add storage schema 0.92.0: persist nested !must_fill
22
+ - docs(canon): consolidate binding overviews into BINDINGS.md
23
+ - feat($seed): reject $seed on composable cards (root-only, like $quill)
24
+ - docs: move dotnet binding into canon, delete DESIGN.md
25
+ - docs: reframe QmBytes by-value return as a tested assumption, not a defect
26
+ - Carry nested !must_fill across the live wire (CardWire)
27
+ - Address review: trap FFI panics, fix depth-limit asymmetry, Equals contract
28
+ - Detect nested !must_fill on sequence-item inline first key
29
+ - docs($seed): correct two claims flagged in review
30
+ - Fix invalid '--' inside XML comment in Quillmark.csproj
31
+ - fix(docs): drop canon links that break mkdocs --strict
32
+ - Promote .NET binding: CI test job, NuGet release, first-class docs
33
+ - Spike: .NET binding symmetrical to the Python binding
34
+ - Capture and round-trip nested !must_fill markers
35
+ - Make QuillValue an annotated value tree (fill on nodes)
36
+ - fix(bindings): bump currentSchemaVersion to 0.92.0; add $seed JS test
37
+ - Rename !fill tag to !must_fill (accept !fill as deprecated alias)
38
+ - docs($seed): document the per-kind seed-overlay key across canon and spec
39
+ - test($seed): cover parse/emit/storage, overlay layering, advisory validation
40
+ - feat(core): first-class $seed key for per-card-kind seed overlays
41
+ - Remove RenderSession and canvas-preview APIs from Python binding (#722)
42
+
43
+
44
+ ## v0.91.0 - 2026-06-17
45
+
46
+ - Upgrade Typst backend to 0.15 (#720)
47
+ - Security audit: resolve 10 findings, document 6 open issues (#719)
48
+ - Hygiene pass: simplifications, dead code removal, and docs cleanup (#718)
30
49
 
31
50
 
32
- ## Unreleased
51
+ ## v0.90.0 - 2026-06-10
33
52
 
34
53
  - **Breaking (Rust API + bindings):** `Quill` is now engine-free, validated
35
54
  data. It no longer holds a backend; the `Quillmark` engine becomes a backend
@@ -127,6 +146,30 @@
127
146
  bindings now use `unchecked_optional_param_type`. Callers can build a bare
128
147
  card with `Document.makeCard('kind')`.
129
148
 
149
+ ## v0.89.1 - 2026-06-10
150
+
151
+ - chore(release): v0.89.1-rc.1 (#714)
152
+ - feat(wasm)!: 0.90 canonical API — engine-free Quill, single root export, typed errors; Python parity (#713)
153
+ - Proposal: WASM bindings split (core + render) via backend-decoupled Quill (#710)
154
+ - Add version selector matching and mismatch warnings (#708)
155
+ - docs: density-optimization pass on user-facing docs (#703)
156
+ - Remove role annotation from root block metadata header (#707)
157
+ - canon: audit and correct all prose/canon/ docs (#704)
158
+ - Fix makeCard fields/body typed as required in WASM .d.ts (#702)
159
+ - Update CLAUDE.md
160
+
161
+
162
+ ## v0.89.1-rc.1 - 2026-06-10
163
+
164
+ - feat(wasm)!: 0.90 canonical API — engine-free Quill, single root export, typed errors; Python parity (#713)
165
+ - Proposal: WASM bindings split (core + render) via backend-decoupled Quill (#710)
166
+ - Add version selector matching and mismatch warnings (#708)
167
+ - docs: density-optimization pass on user-facing docs (#703)
168
+ - Remove role annotation from root block metadata header (#707)
169
+ - canon: audit and correct all prose/canon/ docs (#704)
170
+ - Fix makeCard fields/body typed as required in WASM .d.ts (#702)
171
+ - Update CLAUDE.md
172
+
130
173
  ## v0.88.0 - 2026-06-05
131
174
 
132
175
  - **Breaking (bindings + Rust API):** a single canonical **`Card` wire shape** now
package/README.md CHANGED
@@ -28,8 +28,9 @@ or cross a memory boundary yourself.
28
28
  bash scripts/build-wasm.sh
29
29
  ```
30
30
 
31
- The script builds for `bundler` and `experimental-nodejs-module` targets with
32
- `--weak-refs` enabled (see [Lifecycle](#lifecycle)).
31
+ The script builds two feature variants — the core (no Typst) and the default
32
+ (Typst backend) — both with `--target bundler` and `--weak-refs` enabled
33
+ (see [Lifecycle](#lifecycle)).
33
34
 
34
35
  ## Test
35
36
 
@@ -144,9 +145,9 @@ genuinely malformed Markdown.
144
145
 
145
146
  ### Storage compatibility across versions
146
147
 
147
- The `schema` value (`quillmark/document@0.81.0`) is the **model version**,
148
+ The `schema` value (`quillmark/document@0.82.0`) is the **model version**,
148
149
  not the running crate version. It is a hand-set constant, bumped only when
149
- the `Document` model itself changes — so every `0.81.x` patch release reads
150
+ the `Document` model itself changes — so every `0.82.x` patch release reads
150
151
  and writes that same value.
151
152
 
152
153
  - **Upgrading is safe.** A newer build always reads documents written by an
@@ -328,10 +329,9 @@ A field's *cell* is inferred from whether its schema declares a `default:`:
328
329
  default value followed by a `; delete-ok` annotation, and the default
329
330
  is used when the document omits the field.
330
331
 
331
- `QuillFieldSchema` no longer carries a `required` axis. The legacy
332
- `validation::missing_required` code has been replaced by
333
- `validation::field_absent`; the `validation::must_fill_sentinel`
334
- code covers unreplaced sentinels.
332
+ `QuillFieldSchema` has no `required` axis. Absent Unendorsed fields emit
333
+ `validation::field_absent`; a surviving `<must-fill>` sentinel emits
334
+ `validation::must_fill_sentinel`.
335
335
 
336
336
  ### Errors
337
337
 
@@ -1,6 +1,52 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
 
4
+ /**
5
+ * A path to a value nested inside a field `value`: `string` keys and
6
+ * `number` array indices, e.g. `["addr", "street"]` or `["recipients", 0, "name"]`.
7
+ */
8
+ export type PathStep = string | number;
9
+
10
+ /** A field or comment entry in a `Card.payloadItems` list. */
11
+ export type PayloadItem =
12
+ | {
13
+ type: "field";
14
+ key: string;
15
+ value: unknown;
16
+ fill?: boolean;
17
+ /**
18
+ * Paths to `!must_fill` markers nested *inside* `value` (the `value`
19
+ * projection itself is fill-free). Absent when the field has no nested
20
+ * placeholders. Preserved across `pushCard` / `makeCard`.
21
+ */
22
+ nestedFills?: PathStep[][];
23
+ }
24
+ | { type: "comment"; text: string; inline?: boolean };
25
+
26
+ /**
27
+ * A single card block. The one shape exchanged in both directions: returned by
28
+ * `Document.main` / `Document.cards` / `Document.removeCard` / `Quill.seedCard`,
29
+ * and accepted by `Document.pushCard` / `Document.insertCard`. Build a fresh
30
+ * one with `Document.makeCard`.
31
+ *
32
+ * `$` system entries are hoisted to named fields: `kind` (the `$kind`, empty
33
+ * string when none), optional `quill` (the `$quill` `name@version`, main card
34
+ * only), optional `id` (`$id`), optional `ext` (`$ext`), and optional `seed`
35
+ * (the `$seed` per-kind overlay map, main card only). `payloadItems` carries
36
+ * user fields and comments in order.
37
+ */
38
+ export interface Card {
39
+ kind: string;
40
+ quill?: string;
41
+ id?: string;
42
+ ext?: Record<string, unknown>;
43
+ seed?: Record<string, unknown>;
44
+ payloadItems: PayloadItem[];
45
+ body: string;
46
+ }
47
+
48
+
49
+
4
50
  /**
5
51
  * Page dimensions in Typst points (1 pt = 1/72 inch).
6
52
  *
@@ -72,33 +118,6 @@ export interface PaintResult {
72
118
 
73
119
 
74
120
 
75
- /** A field or comment entry in a `Card.payloadItems` list. */
76
- export type PayloadItem =
77
- | { type: "field"; key: string; value: unknown; fill?: boolean }
78
- | { type: "comment"; text: string; inline?: boolean };
79
-
80
- /**
81
- * A single card block. The one shape exchanged in both directions: returned by
82
- * `Document.main` / `Document.cards` / `Document.removeCard` / `Quill.seedCard`,
83
- * and accepted by `Document.pushCard` / `Document.insertCard`. Build a fresh
84
- * one with `Document.makeCard`.
85
- *
86
- * `$` system entries are hoisted to named fields: `kind` (the `$kind`, empty
87
- * string when none), optional `quill` (the `$quill` `name@version`, main card
88
- * only), optional `id` (`$id`), and optional `ext` (`$ext`). `payloadItems`
89
- * carries user fields and comments in order.
90
- */
91
- export interface Card {
92
- kind: string;
93
- quill?: string;
94
- id?: string;
95
- ext?: Record<string, unknown>;
96
- payloadItems: PayloadItem[];
97
- body: string;
98
- }
99
-
100
-
101
-
102
121
  /** UI layout hints for a single field. */
103
122
  export interface QuillFieldUi {
104
123
  group?: string;
@@ -227,8 +246,9 @@ export class Document {
227
246
  [Symbol.dispose](): void;
228
247
  /**
229
248
  * Authoring-ergonomics header introducing a blueprint to an LLM/MCP
230
- * consumer for the given `quillName`. Surfaced verbatim by every binding
231
- * so the wording stays uniform across CLI / Python / MCP.
249
+ * consumer for the given `quillName`. Re-exposes core's canonical text for
250
+ * JS consumers; any surface that draws from the same core source stays
251
+ * uniform.
232
252
  */
233
253
  static blueprintInstruction(quill_name: string): string;
234
254
  clone(): Document;
@@ -244,16 +264,17 @@ export class Document {
244
264
  */
245
265
  equals(other: Document): boolean;
246
266
  /**
247
- * Render a Diagnostic as the canonical pretty-printed text every binding
248
- * shows (CLI, Python, MCP). Single source of truth so a Diagnostic looks
267
+ * Render a Diagnostic as the canonical pretty-printed text (core's
268
+ * `Diagnostic::fmt_pretty`). Single source of truth so a Diagnostic looks
249
269
  * identical no matter which consumer surfaces it.
250
270
  */
251
271
  static formatDiagnostic(diag: Diagnostic): string;
252
272
  /**
253
- * Authoring-format rules for the card-yaml markdown surface the same
254
- * text every binding (CLI, Python, MCP) shows so callers reading errors
255
- * from one binding can use the rules from any other. Read once at
256
- * startup and cache; the value never changes between calls.
273
+ * Authoring-format rules for the card-yaml markdown surface. The canonical
274
+ * text is core's (`quillmark_core::document::FORMAT_RULES`), re-exposed
275
+ * here for JS consumers so it matches any other surface that draws from the
276
+ * same source. Read once at startup and cache; the value never changes
277
+ * between calls.
257
278
  */
258
279
  static formatRules(): string;
259
280
  /**
@@ -294,11 +315,11 @@ export class Document {
294
315
  */
295
316
  pushCard(card: Card): void;
296
317
  /**
297
- * The canonical `$quill` reference grammar as author-facing text. Single
298
- * source of truth (CLI, Python, MCP): drive schema `describe` and
299
- * validation messages from this instead of re-stating the rule — it
300
- * matches the `hint` on `parse::invalid_quill_reference`. Cache it; the
301
- * value never changes.
318
+ * The canonical `$quill` reference grammar as author-facing text. Core is
319
+ * the single source of truth: drive schema `describe` and validation
320
+ * messages from this instead of re-stating the rule — it matches the
321
+ * `hint` on `parse::invalid_quill_reference`. Cache it; the value never
322
+ * changes.
302
323
  */
303
324
  static quillRefHint(): string;
304
325
  removeCard(index: number): Card | undefined;
@@ -338,6 +359,12 @@ export class Document {
338
359
  * `undefined`. Throws if `name` does not match `[a-z_][a-z0-9_]*`.
339
360
  */
340
361
  removeField(name: string): any;
362
+ /**
363
+ * Remove `cardKind` from the main card's `$seed` map, returning its
364
+ * overlay or `undefined`; drops `$seed` entirely once empty. Sibling
365
+ * kinds survive.
366
+ */
367
+ removeSeedNamespace(card_kind: string): any;
341
368
  replaceBody(body: string): void;
342
369
  /**
343
370
  * Read the `schema` version tag from a raw storage DTO string without a
@@ -379,13 +406,13 @@ export class Document {
379
406
  */
380
407
  setExtNamespace(namespace: string, value: any): void;
381
408
  /**
382
- * Update a payload field on the main card. Clears any existing `!fill` marker.
409
+ * Update a payload field on the main card. Clears any existing `!must_fill` marker.
383
410
  *
384
411
  * Throws if `name` does not match `[a-z_][a-z0-9_]*`.
385
412
  */
386
413
  setField(name: string, value: any): void;
387
414
  /**
388
- * Update a payload field on the main card and mark it as `!fill`.
415
+ * Update a payload field on the main card and mark it as `!must_fill`.
389
416
  * Throws on invalid name (see [`setField`](Document::set_field)).
390
417
  */
391
418
  setFill(name: string, value: any): void;
@@ -393,6 +420,13 @@ export class Document {
393
420
  * Replace the QUILL reference string. Throws if `ref_str` is invalid.
394
421
  */
395
422
  setQuillRef(ref_str: string): void;
423
+ /**
424
+ * Merge a card-kind's seed `overlay` into the main card's `$seed` map
425
+ * under `cardKind`, preserving sibling kinds. Sets the starting values
426
+ * new cards of that kind spawn with. Throws if `overlay` cannot be
427
+ * serialized or nests too deep.
428
+ */
429
+ setSeedNamespace(card_kind: string, overlay: any): void;
396
430
  /**
397
431
  * Serialize this document to a versioned storage DTO string.
398
432
  *
@@ -456,12 +490,17 @@ export class Quill {
456
490
  static fromTree(tree: Map<string, Uint8Array>): Quill;
457
491
  /**
458
492
  * Seed a starter composable `Card` of the given kind (carries `$kind`),
459
- * committing its fields' `example:` values and leaving every other field
460
- * absent. Returns `undefined` if `cardKind` is not declared in this
461
- * quill's schema, else a `Card` that feeds straight into
462
- * `Document.pushCard` / `insertCard`.
493
+ * layering an optional per-kind seed `overlay` over the schema-example
494
+ * base (`overlay › example › absent`). Returns `undefined` if `cardKind`
495
+ * is not declared in this quill's schema, else a `Card` that feeds
496
+ * straight into `Document.pushCard` / `insertCard`.
497
+ *
498
+ * Pass `document.main.seed?.[cardKind]` as `overlay` so a card added to a
499
+ * template-derived document inherits its curated starting values; omit it
500
+ * (or pass `undefined` / `null`) for the bare schema seed. `overlay` is a
501
+ * plain object — this reads the document, it does not mutate it.
463
502
  */
464
- seedCard(card_kind: string): Card | undefined;
503
+ seedCard(card_kind: string, overlay: Record<string, unknown> | undefined): Card | undefined;
465
504
  /**
466
505
  * Seed a starter `Document` from the schema — the main card plus one
467
506
  * instance of each composable card kind, each committing its fields'