@quillmark/wasm 0.102.0 → 0.104.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.
@@ -181,6 +181,11 @@ export type ContentIsland = {
181
181
  * (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
182
182
  * rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
183
183
  * spelling), so no third navigation idiom re-fragments the surface.
184
+ *
185
+ * `doc.pathFor(addr)` mints the address as its canonical `DocPath` string, the
186
+ * anchor `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
187
+ * take: a card path is kind-qualified, so building one by hand needs the card's
188
+ * `$kind`, and a wrong-kind path matches nothing silently.
184
189
  */
185
190
  export interface Addr {
186
191
  card?: number;
@@ -479,12 +484,32 @@ export interface QuillCardUi {
479
484
  groups?: Record<string, QuillGroupUi>;
480
485
  }
481
486
 
487
+ /** A block construct a body can hold. `paragraph` is absent on purpose: it is
488
+ * the floor and cannot be declined. */
489
+ export type QuillBlockConstruct =
490
+ | "heading"
491
+ | "rule"
492
+ | "code"
493
+ | "list"
494
+ | "quote"
495
+ | "table"
496
+ | "image";
497
+
482
498
  /** Body namespace for a card (main or named card kind). */
483
499
  export interface QuillCardBody {
484
500
  /** When false, consumers must not accept or store body content for this card kind. Defaults to true. */
485
501
  enabled?: boolean;
486
502
  /** Example body content embedded verbatim in the blueprint body region. Fallback is "Write <card> body here." */
487
503
  example?: string;
504
+ /** Block constructs this quill's plate does not typeset in this body.
505
+ *
506
+ * Absent or empty means it declines nothing, which is the default. An
507
+ * editor reads this to decline a gesture before the author makes it; a body
508
+ * that holds one anyway draws a non-fatal `plate::unsupported_construct`
509
+ * warning carrying the construct and a count. It is the quill's claim about
510
+ * its own plate, and nothing verifies it: a construct absent from this list
511
+ * is not a promise that the plate typesets it. */
512
+ unsupported?: QuillBlockConstruct[];
488
513
  }
489
514
 
490
515
  /** Schema entry for a single field declared in a quill's `Quill.yaml`.
@@ -501,11 +526,8 @@ export interface QuillFieldSchema {
501
526
  description?: string;
502
527
  default?: unknown;
503
528
  example?: unknown;
504
- /** Closed value domain. On `type: "enum"` declared as `values`; the
505
- * deprecated `enum` modifier on `type: "string"` is accepted for one
506
- * release. Both round-trip through this field. */
507
- enum?: string[];
508
- /** Required on `type: "enum"`: the closed set of allowed string values. */
529
+ /** Required on `type: "enum"`, and valid nowhere else: the closed set of
530
+ * allowed string values. */
509
531
  values?: string[];
510
532
  ui?: QuillFieldUi;
511
533
  properties?: Record<string, QuillFieldSchema>;
@@ -752,7 +774,7 @@ export interface Location {
752
774
  }
753
775
 
754
776
  /**
755
- * What a committed `LiveSession.apply` changed. `dirtyPages` lists the pages
777
+ * What a committed `LiveSession.update` changed. `dirtyPages` lists the pages
756
778
  * whose rendered content differs from the previous compile, including pages
757
779
  * the edit added; removed pages are implied by `pageCount`. A preview
758
780
  * repaints `dirty ∩ visible` and nothing else.
@@ -812,6 +834,13 @@ export class Document {
812
834
  * verbs.
813
835
  */
814
836
  card(index: number): Card;
837
+ /**
838
+ * The composable card's own path, `cards.<kind>[index]`: the whole-card
839
+ * root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
840
+ * card rather than one of its fields. Total on the index axis for the same
841
+ * reason, out of range renders `cards[index]`.
842
+ */
843
+ cardPath(index: number): string;
815
844
  clone(): Document;
816
845
  /**
817
846
  * Storage version this build writes via [`toJson`](Document::to_json).
@@ -959,6 +988,29 @@ export class Document {
959
988
  * not a canonical content object.
960
989
  */
961
990
  overwrite(addr: Addr | string, rt: Content): void;
991
+ /**
992
+ * `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
993
+ * carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
994
+ * `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
995
+ * `Addr` mints one without restating the kind lookup, the `Addr` defaults
996
+ * or the range guard.
997
+ *
998
+ * The kind is the card's stored `$kind` verbatim, the quill-free rule the
999
+ * addressed mutators anchor with and the geometry translation uses, not
1000
+ * `validate`'s declared-kind filter: a `Document` holds a `$quill`
1001
+ * reference and no schema. That is the one edge where this path and a
1002
+ * `validate` diagnostic path differ for the same card.
1003
+ *
1004
+ * **Total on the index axis**, unlike the `Addr` reads (`getStored`,
1005
+ * `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
1006
+ * a read. An out-of-range `{card: 7, field: "from"}` extends the
1007
+ * unknown-kind root `edit::index_out_of_range` anchors at, rendering
1008
+ * `cards[7].from`, which parses back and resolves to nothing rather than
1009
+ * mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
1010
+ * a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
1011
+ * address throws.
1012
+ */
1013
+ pathFor(addr: Addr | string): string;
962
1014
  /**
963
1015
  * The canonical `$quill` reference grammar as author-facing text. Core is
964
1016
  * the single source of truth: drive schema `describe` and validation
@@ -1513,6 +1565,7 @@ export interface InitOutput {
1513
1565
  readonly document_bodyMarkdown: (a: number, b: number, c: number) => void;
1514
1566
  readonly document_card: (a: number, b: number, c: number) => void;
1515
1567
  readonly document_cardCount: (a: number) => number;
1568
+ readonly document_cardPath: (a: number, b: number, c: number) => void;
1516
1569
  readonly document_cards: (a: number, b: number) => void;
1517
1570
  readonly document_clone: (a: number) => number;
1518
1571
  readonly document_currentStorageVersion: (a: number) => void;
@@ -1532,6 +1585,7 @@ export interface InitOutput {
1532
1585
  readonly document_moveCard: (a: number, b: number, c: number, d: number) => void;
1533
1586
  readonly document_new: (a: number, b: number, c: number) => void;
1534
1587
  readonly document_overwrite: (a: number, b: number, c: number, d: number) => void;
1588
+ readonly document_pathFor: (a: number, b: number, c: number) => void;
1535
1589
  readonly document_quillRef: (a: number, b: number) => void;
1536
1590
  readonly document_quillRefHint: (a: number) => void;
1537
1591
  readonly document_removeCard: (a: number, b: number, c: number) => void;
@@ -368,6 +368,30 @@ export class Document {
368
368
  const ret = wasm.document_cardCount(this.__wbg_ptr);
369
369
  return ret >>> 0;
370
370
  }
371
+ /**
372
+ * The composable card's own path, `cards.<kind>[index]`: the whole-card
373
+ * root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
374
+ * card rather than one of its fields. Total on the index axis for the same
375
+ * reason, out of range renders `cards[index]`.
376
+ * @param {number} index
377
+ * @returns {string}
378
+ */
379
+ cardPath(index) {
380
+ let deferred1_0;
381
+ let deferred1_1;
382
+ try {
383
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
384
+ wasm.document_cardPath(retptr, this.__wbg_ptr, index);
385
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
386
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
387
+ deferred1_0 = r0;
388
+ deferred1_1 = r1;
389
+ return getStringFromWasm0(r0, r1);
390
+ } finally {
391
+ wasm.__wbindgen_add_to_stack_pointer(16);
392
+ wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
393
+ }
394
+ }
371
395
  /**
372
396
  * @returns {Card[]}
373
397
  */
@@ -815,6 +839,54 @@ export class Document {
815
839
  wasm.__wbindgen_add_to_stack_pointer(16);
816
840
  }
817
841
  }
842
+ /**
843
+ * `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
844
+ * carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
845
+ * `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
846
+ * `Addr` mints one without restating the kind lookup, the `Addr` defaults
847
+ * or the range guard.
848
+ *
849
+ * The kind is the card's stored `$kind` verbatim, the quill-free rule the
850
+ * addressed mutators anchor with and the geometry translation uses, not
851
+ * `validate`'s declared-kind filter: a `Document` holds a `$quill`
852
+ * reference and no schema. That is the one edge where this path and a
853
+ * `validate` diagnostic path differ for the same card.
854
+ *
855
+ * **Total on the index axis**, unlike the `Addr` reads (`getStored`,
856
+ * `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
857
+ * a read. An out-of-range `{card: 7, field: "from"}` extends the
858
+ * unknown-kind root `edit::index_out_of_range` anchors at, rendering
859
+ * `cards[7].from`, which parses back and resolves to nothing rather than
860
+ * mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
861
+ * a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
862
+ * address throws.
863
+ * @param {Addr | string} addr
864
+ * @returns {string}
865
+ */
866
+ pathFor(addr) {
867
+ let deferred2_0;
868
+ let deferred2_1;
869
+ try {
870
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
871
+ wasm.document_pathFor(retptr, this.__wbg_ptr, addHeapObject(addr));
872
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
873
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
874
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
875
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
876
+ var ptr1 = r0;
877
+ var len1 = r1;
878
+ if (r3) {
879
+ ptr1 = 0; len1 = 0;
880
+ throw takeObject(r2);
881
+ }
882
+ deferred2_0 = ptr1;
883
+ deferred2_1 = len1;
884
+ return getStringFromWasm0(ptr1, len1);
885
+ } finally {
886
+ wasm.__wbindgen_add_to_stack_pointer(16);
887
+ wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
888
+ }
889
+ }
818
890
  /**
819
891
  * @returns {string}
820
892
  */
@@ -2909,8 +2981,7 @@ if (!('encodeInto' in cachedTextEncoder)) {
2909
2981
 
2910
2982
  let WASM_VECTOR_LEN = 0;
2911
2983
 
2912
- import { uninitSentinel, UNINIT } from "../../runtime/uninit.js";
2913
- let wasmModule, wasm = uninitSentinel("@quillmark/wasm internal error: the 'typst' backend was used before instantiation.", "This is a bug in @quillmark/wasm, not in your code. Please report it.");
2984
+ let wasmModule, wasm;
2914
2985
  function __wbg_finalize_init(instance, module) {
2915
2986
  wasm = instance.exports;
2916
2987
  wasmModule = module;
@@ -2957,7 +3028,7 @@ async function __wbg_load(module, imports) {
2957
3028
  }
2958
3029
 
2959
3030
  function initSync(module) {
2960
- if (wasm !== undefined && !wasm[UNINIT]) return wasm;
3031
+ if (wasm !== undefined) return wasm;
2961
3032
 
2962
3033
 
2963
3034
  if (module !== undefined) {
@@ -2977,7 +3048,7 @@ function initSync(module) {
2977
3048
  }
2978
3049
 
2979
3050
  async function __wbg_init(module_or_path) {
2980
- if (wasm !== undefined && !wasm[UNINIT]) return wasm;
3051
+ if (wasm !== undefined) return wasm;
2981
3052
 
2982
3053
 
2983
3054
  if (module_or_path !== undefined) {
Binary file
@@ -16,6 +16,7 @@ export const document_blueprintInstruction: (a: number, b: number, c: number) =>
16
16
  export const document_bodyMarkdown: (a: number, b: number, c: number) => void;
17
17
  export const document_card: (a: number, b: number, c: number) => void;
18
18
  export const document_cardCount: (a: number) => number;
19
+ export const document_cardPath: (a: number, b: number, c: number) => void;
19
20
  export const document_cards: (a: number, b: number) => void;
20
21
  export const document_clone: (a: number) => number;
21
22
  export const document_currentStorageVersion: (a: number) => void;
@@ -35,6 +36,7 @@ export const document_makeCard: (a: number, b: number, c: number, d: number, e:
35
36
  export const document_moveCard: (a: number, b: number, c: number, d: number) => void;
36
37
  export const document_new: (a: number, b: number, c: number) => void;
37
38
  export const document_overwrite: (a: number, b: number, c: number, d: number) => void;
39
+ export const document_pathFor: (a: number, b: number, c: number) => void;
38
40
  export const document_quillRef: (a: number, b: number) => void;
39
41
  export const document_quillRefHint: (a: number) => void;
40
42
  export const document_removeCard: (a: number, b: number, c: number) => void;
package/core/wasm.d.ts CHANGED
@@ -181,6 +181,11 @@ export type ContentIsland = {
181
181
  * (`doc.storeField("qty", 3)`, `doc.revise("intro", md)`) the one coercion
182
182
  * rule. A bare number is *not* an addr (`{ card: 2 }` is the self-documenting
183
183
  * spelling), so no third navigation idiom re-fragments the surface.
184
+ *
185
+ * `doc.pathFor(addr)` mints the address as its canonical `DocPath` string, the
186
+ * anchor `Diagnostic.path` carries and `session.locate` / `session.fieldBoxes`
187
+ * take: a card path is kind-qualified, so building one by hand needs the card's
188
+ * `$kind`, and a wrong-kind path matches nothing silently.
184
189
  */
185
190
  export interface Addr {
186
191
  card?: number;
@@ -394,12 +399,32 @@ export interface QuillCardUi {
394
399
  groups?: Record<string, QuillGroupUi>;
395
400
  }
396
401
 
402
+ /** A block construct a body can hold. `paragraph` is absent on purpose: it is
403
+ * the floor and cannot be declined. */
404
+ export type QuillBlockConstruct =
405
+ | "heading"
406
+ | "rule"
407
+ | "code"
408
+ | "list"
409
+ | "quote"
410
+ | "table"
411
+ | "image";
412
+
397
413
  /** Body namespace for a card (main or named card kind). */
398
414
  export interface QuillCardBody {
399
415
  /** When false, consumers must not accept or store body content for this card kind. Defaults to true. */
400
416
  enabled?: boolean;
401
417
  /** Example body content embedded verbatim in the blueprint body region. Fallback is "Write <card> body here." */
402
418
  example?: string;
419
+ /** Block constructs this quill's plate does not typeset in this body.
420
+ *
421
+ * Absent or empty means it declines nothing, which is the default. An
422
+ * editor reads this to decline a gesture before the author makes it; a body
423
+ * that holds one anyway draws a non-fatal `plate::unsupported_construct`
424
+ * warning carrying the construct and a count. It is the quill's claim about
425
+ * its own plate, and nothing verifies it: a construct absent from this list
426
+ * is not a promise that the plate typesets it. */
427
+ unsupported?: QuillBlockConstruct[];
403
428
  }
404
429
 
405
430
  /** Schema entry for a single field declared in a quill's `Quill.yaml`.
@@ -416,11 +441,8 @@ export interface QuillFieldSchema {
416
441
  description?: string;
417
442
  default?: unknown;
418
443
  example?: unknown;
419
- /** Closed value domain. On `type: "enum"` declared as `values`; the
420
- * deprecated `enum` modifier on `type: "string"` is accepted for one
421
- * release. Both round-trip through this field. */
422
- enum?: string[];
423
- /** Required on `type: "enum"`: the closed set of allowed string values. */
444
+ /** Required on `type: "enum"`, and valid nowhere else: the closed set of
445
+ * allowed string values. */
424
446
  values?: string[];
425
447
  ui?: QuillFieldUi;
426
448
  properties?: Record<string, QuillFieldSchema>;
@@ -560,6 +582,13 @@ export class Document {
560
582
  * verbs.
561
583
  */
562
584
  card(index: number): Card;
585
+ /**
586
+ * The composable card's own path, `cards.<kind>[index]`: the whole-card
587
+ * root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
588
+ * card rather than one of its fields. Total on the index axis for the same
589
+ * reason, out of range renders `cards[index]`.
590
+ */
591
+ cardPath(index: number): string;
563
592
  clone(): Document;
564
593
  /**
565
594
  * Storage version this build writes via [`toJson`](Document::to_json).
@@ -707,6 +736,29 @@ export class Document {
707
736
  * not a canonical content object.
708
737
  */
709
738
  overwrite(addr: Addr | string, rt: Content): void;
739
+ /**
740
+ * `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
741
+ * carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
742
+ * `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
743
+ * `Addr` mints one without restating the kind lookup, the `Addr` defaults
744
+ * or the range guard.
745
+ *
746
+ * The kind is the card's stored `$kind` verbatim, the quill-free rule the
747
+ * addressed mutators anchor with and the geometry translation uses, not
748
+ * `validate`'s declared-kind filter: a `Document` holds a `$quill`
749
+ * reference and no schema. That is the one edge where this path and a
750
+ * `validate` diagnostic path differ for the same card.
751
+ *
752
+ * **Total on the index axis**, unlike the `Addr` reads (`getStored`,
753
+ * `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
754
+ * a read. An out-of-range `{card: 7, field: "from"}` extends the
755
+ * unknown-kind root `edit::index_out_of_range` anchors at, rendering
756
+ * `cards[7].from`, which parses back and resolves to nothing rather than
757
+ * mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
758
+ * a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
759
+ * address throws.
760
+ */
761
+ pathFor(addr: Addr | string): string;
710
762
  /**
711
763
  * The canonical `$quill` reference grammar as author-facing text. Core is
712
764
  * the single source of truth: drive schema `describe` and validation
@@ -1097,6 +1149,7 @@ export interface InitOutput {
1097
1149
  readonly document_bodyMarkdown: (a: number, b: number, c: number) => void;
1098
1150
  readonly document_card: (a: number, b: number, c: number) => void;
1099
1151
  readonly document_cardCount: (a: number) => number;
1152
+ readonly document_cardPath: (a: number, b: number, c: number) => void;
1100
1153
  readonly document_cards: (a: number, b: number) => void;
1101
1154
  readonly document_clone: (a: number) => number;
1102
1155
  readonly document_currentStorageVersion: (a: number) => void;
@@ -1116,6 +1169,7 @@ export interface InitOutput {
1116
1169
  readonly document_moveCard: (a: number, b: number, c: number, d: number) => void;
1117
1170
  readonly document_new: (a: number, b: number, c: number) => void;
1118
1171
  readonly document_overwrite: (a: number, b: number, c: number, d: number) => void;
1172
+ readonly document_pathFor: (a: number, b: number, c: number) => void;
1119
1173
  readonly document_quillRef: (a: number, b: number) => void;
1120
1174
  readonly document_quillRefHint: (a: number) => void;
1121
1175
  readonly document_removeCard: (a: number, b: number, c: number) => void;
package/core/wasm.js CHANGED
@@ -368,6 +368,30 @@ export class Document {
368
368
  const ret = wasm.document_cardCount(this.__wbg_ptr);
369
369
  return ret >>> 0;
370
370
  }
371
+ /**
372
+ * The composable card's own path, `cards.<kind>[index]`: the whole-card
373
+ * root [`pathFor`](Self::path_for) extends, for a consumer anchoring the
374
+ * card rather than one of its fields. Total on the index axis for the same
375
+ * reason, out of range renders `cards[index]`.
376
+ * @param {number} index
377
+ * @returns {string}
378
+ */
379
+ cardPath(index) {
380
+ let deferred1_0;
381
+ let deferred1_1;
382
+ try {
383
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
384
+ wasm.document_cardPath(retptr, this.__wbg_ptr, index);
385
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
386
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
387
+ deferred1_0 = r0;
388
+ deferred1_1 = r1;
389
+ return getStringFromWasm0(r0, r1);
390
+ } finally {
391
+ wasm.__wbindgen_add_to_stack_pointer(16);
392
+ wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1);
393
+ }
394
+ }
371
395
  /**
372
396
  * @returns {Card[]}
373
397
  */
@@ -815,6 +839,54 @@ export class Document {
815
839
  wasm.__wbindgen_add_to_stack_pointer(16);
816
840
  }
817
841
  }
842
+ /**
843
+ * `addr`'s canonical `DocPath` string, the anchor `Diagnostic.path`
844
+ * carries: `pathFor()` is `main.body`, `pathFor("intro")` `main.intro`,
845
+ * `pathFor({card: 2})` `cards.<kind>[2].body`. A consumer holding an
846
+ * `Addr` mints one without restating the kind lookup, the `Addr` defaults
847
+ * or the range guard.
848
+ *
849
+ * The kind is the card's stored `$kind` verbatim, the quill-free rule the
850
+ * addressed mutators anchor with and the geometry translation uses, not
851
+ * `validate`'s declared-kind filter: a `Document` holds a `$quill`
852
+ * reference and no schema. That is the one edge where this path and a
853
+ * `validate` diagnostic path differ for the same card.
854
+ *
855
+ * **Total on the index axis**, unlike the `Addr` reads (`getStored`,
856
+ * `isFill`, `bodyMarkdown`), which throw there: a path is an anchor, not
857
+ * a read. An out-of-range `{card: 7, field: "from"}` extends the
858
+ * unknown-kind root `edit::index_out_of_range` anchors at, rendering
859
+ * `cards[7].from`, which parses back and resolves to nothing rather than
860
+ * mis-targeting. So a per-keystroke call needs no `try`; a caller wanting
861
+ * a drop-it guard has [`cardCount`](Self::card_count). Only a malformed
862
+ * address throws.
863
+ * @param {Addr | string} addr
864
+ * @returns {string}
865
+ */
866
+ pathFor(addr) {
867
+ let deferred2_0;
868
+ let deferred2_1;
869
+ try {
870
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
871
+ wasm.document_pathFor(retptr, this.__wbg_ptr, addHeapObject(addr));
872
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
873
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
874
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
875
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
876
+ var ptr1 = r0;
877
+ var len1 = r1;
878
+ if (r3) {
879
+ ptr1 = 0; len1 = 0;
880
+ throw takeObject(r2);
881
+ }
882
+ deferred2_0 = ptr1;
883
+ deferred2_1 = len1;
884
+ return getStringFromWasm0(ptr1, len1);
885
+ } finally {
886
+ wasm.__wbindgen_add_to_stack_pointer(16);
887
+ wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
888
+ }
889
+ }
818
890
  /**
819
891
  * @returns {string}
820
892
  */
@@ -2377,8 +2449,7 @@ if (!('encodeInto' in cachedTextEncoder)) {
2377
2449
 
2378
2450
  let WASM_VECTOR_LEN = 0;
2379
2451
 
2380
- import { uninitSentinel, UNINIT } from "../runtime/uninit.js";
2381
- let wasmModule, wasm = uninitSentinel("@quillmark/wasm is not initialized. Call 'await init()' once at startup, before Quill, Document, Engine, or any other export is used.", "Add: import { init } from '@quillmark/wasm'; await init(); once, anywhere before first use. Extra calls are free.");
2452
+ let wasmModule, wasm;
2382
2453
  function __wbg_finalize_init(instance, module) {
2383
2454
  wasm = instance.exports;
2384
2455
  wasmModule = module;
@@ -2424,7 +2495,7 @@ async function __wbg_load(module, imports) {
2424
2495
  }
2425
2496
 
2426
2497
  function initSync(module) {
2427
- if (wasm !== undefined && !wasm[UNINIT]) return wasm;
2498
+ if (wasm !== undefined) return wasm;
2428
2499
 
2429
2500
 
2430
2501
  if (module !== undefined) {
@@ -2444,7 +2515,7 @@ function initSync(module) {
2444
2515
  }
2445
2516
 
2446
2517
  async function __wbg_init(module_or_path) {
2447
- if (wasm !== undefined && !wasm[UNINIT]) return wasm;
2518
+ if (wasm !== undefined) return wasm;
2448
2519
 
2449
2520
 
2450
2521
  if (module_or_path !== undefined) {
package/core/wasm_bg.wasm CHANGED
Binary file
@@ -14,6 +14,7 @@ export const document_blueprintInstruction: (a: number, b: number, c: number) =>
14
14
  export const document_bodyMarkdown: (a: number, b: number, c: number) => void;
15
15
  export const document_card: (a: number, b: number, c: number) => void;
16
16
  export const document_cardCount: (a: number) => number;
17
+ export const document_cardPath: (a: number, b: number, c: number) => void;
17
18
  export const document_cards: (a: number, b: number) => void;
18
19
  export const document_clone: (a: number) => number;
19
20
  export const document_currentStorageVersion: (a: number) => void;
@@ -33,6 +34,7 @@ export const document_makeCard: (a: number, b: number, c: number, d: number, e:
33
34
  export const document_moveCard: (a: number, b: number, c: number, d: number) => void;
34
35
  export const document_new: (a: number, b: number, c: number) => void;
35
36
  export const document_overwrite: (a: number, b: number, c: number, d: number) => void;
37
+ export const document_pathFor: (a: number, b: number, c: number) => void;
36
38
  export const document_quillRef: (a: number, b: number) => void;
37
39
  export const document_quillRefHint: (a: number) => void;
38
40
  export const document_removeCard: (a: number, b: number, c: number) => void;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@quillmark/wasm",
3
- "version": "0.102.0",
3
+ "version": "0.104.0",
4
4
  "description": "WebAssembly bindings for Quillmark, a schema-driven document engine",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "engines": {
8
- "node": ">=22"
8
+ "node": ">=24"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
@@ -1,46 +1,82 @@
1
1
  // @quillmark/wasm/runtime: canonical consumer API.
2
2
  //
3
- // `Quill`/`Document` are re-exported verbatim from the core build (their full
4
- // surface, no drift). Render-side types (`RenderResult`, `RenderOptions`,
5
- // `Artifact`, `OutputFormat`, `PageSize`, `PaintOptions`, `PaintResult`) are
6
- // defined HERE as the canonical, backend-neutral render contract: NOT sourced
7
- // from any one private backend build. A type-level drift guard
8
- // (`runtime.types.test-d.ts`, via `npm run typecheck`) asserts they stay
9
- // mutually assignable with the Typst backend's generated declarations. `Engine`
10
- // is the render dispatcher that hides the cross-WASM-memory seam.
11
-
12
- // CANONICAL INVARIANT: the root re-exports the core build's `Quill`/`Document`
13
- // verbatim; they are the SAME classes, never wrappers. There is exactly one
14
- // public entry point, so this is a structural fact. Replacing the re-export
15
- // with a wrapper is a breaking design change, not a refactor. See runtime.js.
3
+ // Render-side types (`RenderResult`, `RenderOptions`, `Artifact`,
4
+ // `OutputFormat`, `PageSize`, `PaintOptions`, `PaintResult`) are defined HERE as
5
+ // the canonical, backend-neutral render contract: NOT sourced from any one
6
+ // private backend build. A type-level drift guard (`runtime.types.test-d.ts`,
7
+ // via `npm run typecheck`) asserts they stay mutually assignable with the Typst
8
+ // backend's generated declarations. `Engine` is the render dispatcher that hides
9
+ // the cross-WASM-memory seam.
10
+
11
+ // CANONICAL INVARIANT: the `Quill`/`Document` `init` resolves to ARE the core
12
+ // build's classes, their full surface, never wrappers. There is exactly one
13
+ // public entry point, so this is a structural fact. Handing out a wrapper is a
14
+ // breaking design change, not a refactor. See runtime.js.
16
15
  //
17
16
  // ONE COPY PER PROCESS: two copies of this package are two WASM linear memories
18
17
  // and two `Quill`/`Document` classes. Every method taking a handle refuses one
19
18
  // belonging to another copy, with a `QuillmarkError` naming `npm ls
20
19
  // @quillmark/wasm`. Errors are the exception: `isQuillmarkError` is structural.
21
- export { Quill, Document } from '../core/wasm.js';
22
20
 
23
- import type { InitInput } from '../core/wasm.js';
21
+ // The instance types, so an annotation (`let q: Quill`) needs no await. Their
22
+ // values are `CoreSurface`'s.
23
+ export type { Quill, Document } from '../core/wasm.js';
24
+
25
+ import type {
26
+ InitInput,
27
+ Quill as CoreQuill,
28
+ Document as CoreDocument,
29
+ importMarkdown,
30
+ exportMarkdown,
31
+ rebase,
32
+ mapPos,
33
+ parseDocPath,
34
+ formatDocPath
35
+ } from '../core/wasm.js';
24
36
 
25
37
  /**
26
- * Instantiate the core WASM build. Call once at startup, before any other
27
- * export is used; extra calls are free.
38
+ * The core build's surface: what its WASM instance stands behind, and therefore
39
+ * what `init` resolves to. Exported nowhere statically, so awaiting is the only
40
+ * way to hold one.
28
41
  *
29
- * ```js
30
- * import { init, Quill, Engine } from '@quillmark/wasm';
31
- * await init();
42
+ * `Quill` and `Document` here are the classes, statics included
43
+ * (`Quill.fromTree`, `Document.fromMarkdown`), not the instance types above.
44
+ * Each member carries the core build's own declaration, docs and all.
45
+ */
46
+ export interface CoreSurface {
47
+ Quill: typeof CoreQuill;
48
+ Document: typeof CoreDocument;
49
+ importMarkdown: typeof importMarkdown;
50
+ exportMarkdown: typeof exportMarkdown;
51
+ rebase: typeof rebase;
52
+ mapPos: typeof mapPos;
53
+ parseDocPath: typeof parseDocPath;
54
+ formatDocPath: typeof formatDocPath;
55
+ }
56
+
57
+ /**
58
+ * Instantiate the core WASM build and resolve to its surface.
59
+ *
60
+ * ```ts
61
+ * import { init } from '@quillmark/wasm';
62
+ * const { Quill, Document } = await init();
32
63
  * ```
33
64
  *
34
65
  * The builds are `--target web`: classes export synchronously, the instance
35
66
  * behind them arrives here. Identical in every environment: the binary is
36
67
  * fetched and streamed in a browser, read off disk under Node, and the call
37
- * site is the same line. Reaching a class before this resolves throws
38
- * `runtime::not_initialized` naming the fix.
68
+ * site is the same line.
69
+ *
70
+ * THE ONLY DOOR to `Quill`, `Document` and the free functions, so the pre-init
71
+ * mistake is not expressible. Destructure at each entry point (route loader,
72
+ * hydration path, worker) rather than threading one result around: the gate is
73
+ * memoized and concurrency-safe, so every await after the first is free. A
74
+ * failed init clears the memo, so a retry is possible. Per realm: a Worker
75
+ * loads and initializes its own copy.
39
76
  *
40
- * Idempotent and concurrency-safe: every call returns the same promise, so
41
- * `await init()` at several entry points costs one instantiation. A failed init
42
- * clears the memo, so a retry is possible. Per realm: a Worker loads and
43
- * initializes its own copy.
77
+ * Both failure codes REJECT, so one `catch` covers the gate. Delivery follows
78
+ * the function kind across this surface: a sync verb throws, a
79
+ * promise-returning verb rejects, and nothing does both.
44
80
  *
45
81
  * Backends are NOT initialized here. `Engine` instantiates a backend inside its
46
82
  * lazy load, on first render against it.
@@ -48,15 +84,10 @@ import type { InitInput } from '../core/wasm.js';
48
84
  * @param source override the binary's source (bytes, a `Response`, a
49
85
  * `WebAssembly.Module`, a URL) for hosts that route assets themselves or
50
86
  * embed the binary. Pass it on the FIRST call; a later call passing a
51
- * different source throws `runtime::init_conflict` rather than silently
87
+ * different source rejects with `runtime::init_conflict` rather than silently
52
88
  * ignoring it. Passing the same value again is fine.
53
89
  */
54
- export declare function init(source?: InitInput): Promise<void>;
55
- // The document-free content codec, re-exported from the core build.
56
- export { importMarkdown, exportMarkdown, rebase, mapPos } from '../core/wasm.js';
57
- // The document-model path parser/serializer: route on `Diagnostic.path`
58
- // segments instead of regexing the string.
59
- export { parseDocPath, formatDocPath } from '../core/wasm.js';
90
+ export declare function init(source?: InitInput): Promise<CoreSurface>;
60
91
 
61
92
  import type { CardAddr } from '../core/wasm.js';
62
93
 
@@ -367,7 +398,10 @@ export interface FieldRegion {
367
398
  * The field's canonical `DocPath` address (`parseDocPath`-routable), not a
368
399
  * backend widget name: `main.signature_block` for a main field,
369
400
  * `cards.<kind>[<i>].signature_block` for a card field (`cards[<i>].…` when the
370
- * card's kind is unknown).
401
+ * card's kind is unknown). Nested addresses spell out in full, an array
402
+ * element bracketed and a key dotted — `main.references[0]`,
403
+ * `cards.<kind>[<i>].addr.city` — the same spelling `Diagnostic.path` uses,
404
+ * so the two join on string equality.
371
405
  */
372
406
  field: string;
373
407
  /** 0-based page index. */