@quillmark/wasm 0.95.1 → 0.97.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/core/wasm.d.ts CHANGED
@@ -102,7 +102,14 @@ export type ContentContainer =
102
102
  | { container: "list_item"; ordered: boolean; start: number; ordinal: number }
103
103
  | { container: "quote" };
104
104
 
105
- /** A mark over char range `[start, end)` into `Content.text`. */
105
+ /** A mark over char range `[start, end)` into `Content.text`. The open `type`
106
+ * arm blocks discriminant narrowing (as on `ContentIsland`), so read a
107
+ * payload-carrying arm behind its guard — `isLinkMark` (`url`) / `isAnchorMark`
108
+ * (`id`), from `@quillmark/wasm/runtime`; the bare arms carry no payload. An
109
+ * `anchor`'s `id` is a caller-supplied, opaque handle, unique per `Content` and
110
+ * invariant while the mark lives (positions rebase, the id never does); it has no
111
+ * markdown projection and survives only through the edit lane. See DOCUMENT_STORAGE
112
+ * § Anchor-id identity. */
106
113
  export type ContentMark = { start: number; end: number } & (
107
114
  | { type: "strong" | "emph" | "underline" | "strike" | "code" }
108
115
  | { type: "link"; url: string }
@@ -110,14 +117,45 @@ export type ContentMark = { start: number; end: number } & (
110
117
  | { type: string; attrs: unknown }
111
118
  );
112
119
 
113
- /** A structured object (table, figure, …) occupying one island slot in `Content.text`. */
114
- export interface ContentIsland {
120
+ /** A cell in a `TableProps` its plain `text` plus the `marks` over it. `marks`
121
+ * rides the same wire shape as prose `ContentMark`, but each mark's `start`/`end`
122
+ * are USV offsets into this cell's `text` (`0..text.length`), not into
123
+ * `Content.text`. */
124
+ export interface TableCell {
125
+ text: string;
126
+ marks: ContentMark[];
127
+ }
128
+
129
+ /** `props` of a `type: "table"` island: a pipe table normalized to one column
130
+ * count that `header`, every row of `rows`, and `aligns` all share. */
131
+ export interface TableProps {
132
+ header: TableCell[];
133
+ rows: TableCell[][];
134
+ /** Per-column alignment, one entry per column. */
135
+ aligns: ("none" | "left" | "center" | "right")[];
136
+ }
137
+
138
+ /** `props` of a `type: "image"` island. */
139
+ export interface ImageProps {
140
+ url: string;
141
+ alt: string;
142
+ }
143
+
144
+ /** A structured object occupying one island slot in `Content.text`. `type` is an
145
+ * open set: the engine pins `props` as `TableProps` for `table` and `ImageProps`
146
+ * for `image`; an island of any other type round-trips with opaque `props`. Like
147
+ * `ContentMark`, the open `type` arm means a discriminant check does not itself
148
+ * narrow `props` — read `props` as the matching shape behind the `isTableIsland` /
149
+ * `isImageIsland` guards (from `@quillmark/wasm/runtime`), which narrow it. */
150
+ export type ContentIsland = {
115
151
  id: string;
116
- type: string;
117
- props: unknown;
118
152
  /** How faithfully the markdown projection can carry this island. */
119
153
  loss: "lossless" | "degraded" | "unrepresentable";
120
- }
154
+ } & (
155
+ | { type: "table"; props: TableProps }
156
+ | { type: "image"; props: ImageProps }
157
+ | { type: string; props: unknown }
158
+ );
121
159
 
122
160
  /**
123
161
  * A write address — one navigation concept for the whole `Document` surface. An
@@ -161,7 +199,10 @@ export type Assoc = "before" | "after";
161
199
  /**
162
200
  * A mark edit in final-text coordinates (post-delta, post-line-op). `add` /
163
201
  * `remove` carry the `ContentMark` vocabulary (`{ type, … }`); `removeAnchor`
164
- * drops one identity anchor by id.
202
+ * drops one identity anchor by id. An `add` of an `anchor` requires a non-empty
203
+ * `id` not already live in the field — a collision or the empty id throws
204
+ * (ids are caller-supplied and unique per `Content`; DOCUMENT_STORAGE
205
+ * § Anchor-id identity).
165
206
  */
166
207
  export type MarkOp =
167
208
  | ({ op: "add" | "remove"; start: number; end: number } & (
@@ -203,6 +244,70 @@ export interface ChangeBundle {
203
244
 
204
245
 
205
246
 
247
+ /**
248
+ * One segment of a parsed `Diagnostic.path` (see `parseDocPath`). The head
249
+ * carries the document-model root — `main` (only before `body`), a `card`
250
+ * (`kind: null` is the unknown-kind `cards[i]` form), or a `field`; the tail is
251
+ * `field` / `index` / a terminal `body`.
252
+ */
253
+ export type DocPathSeg =
254
+ | { seg: "main" }
255
+ | { seg: "card"; kind: string | null; index: number }
256
+ | { seg: "field"; name: string }
257
+ | { seg: "index"; index: number }
258
+ | { seg: "body" };
259
+
260
+
261
+
262
+ /** The commitment-ladder rung that produced a `ResolvedField.value`. */
263
+ export type FieldSource = "authored" | "default" | "zero";
264
+
265
+ /**
266
+ * One resolved row: its `name`, the value the render projection would use, and
267
+ * the `FieldSource` rung it came from. Rows are an ordered array — declaration
268
+ * order is structural, not object-key order. The card body is a `body` sibling
269
+ * on its card, never a row in `fields`. Diagnostics stay `Quill.validate`'s;
270
+ * schema guidance (`example:`, labels) reads from `Quill.schema`.
271
+ */
272
+ export interface ResolvedField {
273
+ name: string;
274
+ value: unknown;
275
+ source: FieldSource;
276
+ }
277
+
278
+ /**
279
+ * The main card's resolved rows in declaration order, plus its body row —
280
+ * `null` when the main enables no body.
281
+ */
282
+ export interface ResolvedMain {
283
+ fields: ResolvedField[];
284
+ body: ResolvedField | null;
285
+ }
286
+
287
+ /**
288
+ * One composable card's resolved rows in declaration order, with its authored
289
+ * `kind` (`null` for an unknown-kind card), its document-array `index`, and its
290
+ * body row — `null` when the kind enables no body.
291
+ */
292
+ export interface ResolvedCard {
293
+ kind: string | null;
294
+ index: number;
295
+ fields: ResolvedField[];
296
+ body: ResolvedField | null;
297
+ }
298
+
299
+ /**
300
+ * The resolved-value view (`Quill.resolve`): the main card and every
301
+ * composable card. Value and provenance only — completeness and errors stay
302
+ * `Quill.validate`.
303
+ */
304
+ export interface Resolved {
305
+ main: ResolvedMain;
306
+ cards: ResolvedCard[];
307
+ }
308
+
309
+
310
+
206
311
  /** UI layout hints for a single field. Field display order is not a hint:
207
312
  * key order in the schema's `fields`/`properties` objects is declaration
208
313
  * order, the ordering contract. */
@@ -213,9 +318,23 @@ export interface QuillFieldUi {
213
318
  multiline?: boolean;
214
319
  }
215
320
 
321
+ /** One entry in a card's `ui.groups` registry: a display-label override for the
322
+ * group id (the map key). An empty object carries no override — the consumer
323
+ * derives the label from the id (`memo_for` → "Memo For"), as it does a field
324
+ * label from its key. */
325
+ export interface QuillGroupUi {
326
+ title?: string;
327
+ }
328
+
216
329
  /** UI layout hints for a card (main or named card kind). */
217
330
  export interface QuillCardUi {
218
331
  title?: string;
332
+ /** The card's group registry: the ordered table of contents naming every
333
+ * group a field's `ui.group` may reference. The map key is the group id, and
334
+ * key order is declaration order — the display-order contract, the same one
335
+ * `fields` key order carries. Absent when the card declares no groups (or
336
+ * uses the deprecated implicit-group form). */
337
+ groups?: Record<string, QuillGroupUi>;
219
338
  }
220
339
 
221
340
  /** Body namespace for a card (main or named card kind). */
@@ -338,15 +457,15 @@ export class Document {
338
457
  * A single composable card by index — the whole `Card`, the card-indexed
339
458
  * twin of the [`main`](Self::main) getter, so reading one card need not
340
459
  * materialize every card via [`cards`](Self::cards). An out-of-range
341
- * `index` throws `[EditError::IndexOutOfRange]`, matching the card write
460
+ * `index` throws `edit::index_out_of_range`, matching the card write
342
461
  * verbs.
343
462
  */
344
463
  card(index: number): Card;
345
464
  /**
346
- * The index of the first composable card whose `$id` equals `id`, or
347
- * `undefined` when none carries it. Resolves the canonical durable address
465
+ * The index of the composable card whose `$id` equals `id`, or
466
+ * `undefined` when none carries it. Resolves the durable card handle
348
467
  * without a hand-rolled scan over [`cards`](Self::cards); `$id` is
349
- * non-unique by design, so the first match wins.
468
+ * unique per document, so at most one card matches.
350
469
  */
351
470
  cardIndexById(id: string): number | undefined;
352
471
  clone(): Document;
@@ -388,17 +507,6 @@ export class Document {
388
507
  * Parse markdown into a typed Document. Throws on parse errors.
389
508
  */
390
509
  static fromMarkdown(markdown: string): Document;
391
- /**
392
- * Read the value at `addr` — the raw stored payload value of a field (a
393
- * content object for a richtext field, a scalar/array/object otherwise), or
394
- * the **body content** when `addr.field` is absent. A bare string is `Addr`
395
- * shorthand for `{ field }`. Reads are total over the field axis: an absent
396
- * field is `undefined`; only an out-of-range `addr.card` throws
397
- * `[EditError::IndexOutOfRange]`. Reads need no schema, so they live on
398
- * `Document`, not the typed writer; for the markdown projection of a
399
- * richtext value use [`getMarkdown`](Self::get_markdown).
400
- */
401
- get(addr: Addr | string): unknown;
402
510
  /**
403
511
  * The whole `$ext` map at `addr` (a card address, absent `card` = main), or
404
512
  * `undefined` when the card carries none. The fine-grained `$ext` read —
@@ -421,10 +529,23 @@ export class Document {
421
529
  *
422
530
  * `addr` is an optional **card address** (`{ card }`, absent = main). A
423
531
  * present `field` throws — a field's markdown is read through the
424
- * schema-plane `quill.view(doc).get(field)`, which interprets by declared
532
+ * schema-plane `quill.reader(doc).get(field)`, which interprets by declared
425
533
  * type (#978). An out-of-range `addr.card` throws.
426
534
  */
427
535
  getMarkdown(addr?: CardAddr): string;
536
+ /**
537
+ * Read the **verbatim stored value** at `addr` — the raw payload value of a
538
+ * field (a content object for a richtext field, a scalar/array/object
539
+ * otherwise), or the **body content** when `addr.field` is absent. A bare
540
+ * string is `Addr` shorthand for `{ field }`. Reads are total over the field
541
+ * axis: an absent field is `undefined`; only an out-of-range `addr.card`
542
+ * throws `edit::index_out_of_range`. Needs no schema, so it lives on
543
+ * `Document` — the read echo of the verbatim `store*` write, distinct from
544
+ * the interpreted schema-plane [`reader.get`](Self::reader_get). For the
545
+ * markdown projection use [`getMarkdown`](Self::get_markdown) (body) or
546
+ * `reader.get` (a field's declared type).
547
+ */
548
+ getStored(addr: Addr | string): unknown;
428
549
  /**
429
550
  * Insert a card — the single insertion verb: `at` absent appends, a number
430
551
  * inserts at that index (must be in `0..=cards.length`). Accepts a
@@ -525,7 +646,7 @@ export class Document {
525
646
  removeSeedNamespace(card_kind: string): any;
526
647
  /**
527
648
  * **Revise** the richtext value at `addr` from a markdown string — **edit
528
- * semantics**, the default write path, returning the text [`Delta`]. Imports
649
+ * semantics**, the default write path, returning the text `Delta`. Imports
529
650
  * the markdown, diffs it against the current value, rebases surviving
530
651
  * identity anchors, and returns the change an editor bridge maps its own
531
652
  * positions through (`mapPos`). An absent `addr.field` targets the body, an
@@ -664,6 +785,18 @@ export class Quill {
664
785
  * canonical shape.
665
786
  */
666
787
  static fromTree(tree: Map<string, Uint8Array>): Quill;
788
+ /**
789
+ * The resolved-value view of `doc` against this quill's schema — for every
790
+ * declared field the value the render projection would use and the
791
+ * `FieldSource` rung it came from (`"authored" | "default" | "zero"`), in
792
+ * one call. The card body is a `body` sibling on its card (row `name`
793
+ * `"body"`), never a row in `fields` — `null` when the kind enables no body.
794
+ *
795
+ * Value and provenance only: completeness and errors stay `validate`'s
796
+ * (a consumer merges it with its own diagnostic producers regardless), and
797
+ * schema guidance reads from `Quill.schema`.
798
+ */
799
+ resolve(doc: Document): Resolved;
667
800
  /**
668
801
  * Seed a starter composable `Card` of the given kind (carries `$kind`),
669
802
  * layering an optional per-kind seed `overlay` over the schema-example
@@ -749,6 +882,15 @@ export class Quill {
749
882
  */
750
883
  export function exportMarkdown(rt: Content): string;
751
884
 
885
+ /**
886
+ * Serialize structured [`DocPathSeg`] segments back to the canonical path
887
+ * string — the inverse of `parseDocPath`, for a consumer that builds a path
888
+ * rather than reads one. Throws on a segment array the deserializer rejects,
889
+ * and on an empty segment array (symmetric with `parseDocPath("")`, which
890
+ * throws "empty path").
891
+ */
892
+ export function formatDocPath(segs: DocPathSeg[]): string;
893
+
752
894
  /**
753
895
  * Import a markdown string to a canonical `Content` content — the pure,
754
896
  * document-free codec. Pair with `install(addr, importMarkdown(md))` to spell
@@ -763,18 +905,29 @@ export function importMarkdown(markdown: string): Content;
763
905
  export function init(): void;
764
906
 
765
907
  /**
766
- * Map a base content position through a `delta` to its new position the pure
767
- * position-mapping codec an editor bridge composes to hold a caret stable
768
- * across a `revise`. `assoc` decides the side of a same-position insertion
769
- * (`"after"` moves past it). Throws on a malformed `delta`.
908
+ * Map a base content position a USV index into `Content.text`, not a UTF-16
909
+ * offset through a `delta` to its new USV position: the pure position-mapping
910
+ * codec an editor bridge composes to hold a caret stable across a `revise`.
911
+ * `assoc` decides the side of a same-position insertion (`"after"` moves past
912
+ * it). Throws on a malformed `delta`.
770
913
  */
771
914
  export function mapPos(delta: Delta, pos: number, assoc: Assoc): number;
772
915
 
916
+ /**
917
+ * Parse a canonical document-model `Diagnostic.path`
918
+ * (`cards.<kind>[<i>].<field>`, `main.body`, `recipients[0].name`) into its
919
+ * structured [`DocPathSeg`] segments — the exported inverse of the engine's
920
+ * one path serializer, so a consumer routes on segments instead of regexing
921
+ * the string. Throws on a malformed path.
922
+ */
923
+ export function parseDocPath(path: string): DocPathSeg[];
924
+
773
925
  /**
774
926
  * Rebase `markdown` onto a `base` content — the pure, document-free twin of
775
927
  * `revise`: cold-import + `diff_import`, returning the new `content` and the
776
- * text `delta` (surviving anchors rebased). Use it to compute a revise without
777
- * a document in hand; `revise(addr, md)` fuses this with the store for
778
- * atomicity. Throws on an over-nested markdown input or a non-content `base`.
928
+ * text `delta` (its offsets USV indices into `Content.text`, surviving anchors
929
+ * rebased). Use it to compute a revise without a document in hand; `revise(addr,
930
+ * md)` fuses this with the store for atomicity. Throws on an over-nested
931
+ * markdown input or a non-content `base`.
779
932
  */
780
933
  export function rebase(base: Content, markdown: string): { content: Content; delta: Delta };
package/core/wasm.js CHANGED
@@ -5,5 +5,5 @@ import { __wbg_set_wasm } from "./wasm_bg.js";
5
5
  __wbg_set_wasm(wasm);
6
6
  wasm.__wbindgen_start();
7
7
  export {
8
- Document, Quill, exportMarkdown, importMarkdown, init, mapPos, rebase
8
+ Document, Quill, exportMarkdown, formatDocPath, importMarkdown, init, mapPos, parseDocPath, rebase
9
9
  } from "./wasm_bg.js";