@quillmark/wasm 0.100.0 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.101.0 - 2026-08-03
4
+
5
+ - refactor(core): gate the raw-plate seam behind a feature, and fixes from review
6
+ - docs(core): state the conform gate's codes instead of linking a private item
7
+ - refactor(core): bind a live session to its quill so apply takes a Document
8
+ - feat(quillmark): the facade names what the read and preview flows return
9
+ - docs(content,wasm): density pass over the island channel's prose
10
+ - feat(content,core,wasm)!: reach islands through the op vocabulary
11
+ - refactor(core)!: `Payload` becomes a read view
12
+ - refactor(core)!: collapse the schema-free field projection
13
+ - refactor(core)!: fold `Quill`'s file queries into `FileTreeNode`
14
+ - fix(core): repoint the doc references the `from_yaml` removal orphaned
15
+ - refactor(quillmark): move the facade gate off the front page, and stop tests reaching past it
16
+ - docs: migration guide for the 0.101 surface removals
17
+ - refactor(core)!: drop the lossy `QuillConfig::from_yaml`
18
+ - refactor(core)!: `Document::from_main_and_cards` becomes crate-internal
19
+ - feat(quillmark): the facade covers authoring, and the examples enter through the bound door
20
+
21
+
3
22
  ## v0.100.0 - 2026-08-03
4
23
 
5
24
  A content field gets one resting form, and the last reserved `$` key with no
@@ -240,13 +240,42 @@ export type LineOp =
240
240
  | { op: "setContainers"; line: number; containers: ContentContainer[] }
241
241
  | { op: "setContinues"; line: number; continues: boolean };
242
242
 
243
+ /**
244
+ * An island edit: the only channel that reaches an island's payload, a table's
245
+ * cells or an image's url.
246
+ *
247
+ * Both ops move one island entry and leave the field's text and marks alone, so
248
+ * an island edit keeps every identity anchor in the field. That is why a table
249
+ * edit lowers to `applyChange` rather than `install`, which drops them all.
250
+ *
251
+ * `set` addresses an existing island by `id`; an `id` no island carries throws
252
+ * rather than passing silently. `insert` places a new island's slot at `at` (a
253
+ * post-delta USV position) together with its entry, so a slot never exists
254
+ * without an island behind it; its `id` must be non-empty and unused. Deleting
255
+ * an island needs no op: a `delta` that removes its slot drops the island.
256
+ *
257
+ * A `set` stores the `loss` it is given: nothing re-derives the class from the
258
+ * new `props`, so a write that changes what markdown can carry must say so.
259
+ *
260
+ * An island is *inline* (a slot inside a paragraph) unless its line says
261
+ * otherwise. A **block** island is one bundle of all three channels, in the
262
+ * order they apply: `delta` inserts the `\n` that opens the line, `islandOps`
263
+ * inserts the slot, `lineOps` tags the line `{ op: "setKind", kind: "island" }`.
264
+ * `{ op: "split" }` cannot open that line, since line ops run after island ops.
265
+ */
266
+ export type IslandOp =
267
+ | ({ op: "set" } & ContentIsland)
268
+ | ({ op: "insert"; at: number } & ContentIsland);
269
+
243
270
  /**
244
271
  * A committed content edit bundle for `applyChange`: a text `delta` (default no
245
- * text change), then `lineOps`, then `markOps` (mark ranges are in post-delta
246
- * coordinates). Every field is optional.
272
+ * text change), then `islandOps`, then `lineOps`, then `markOps` (mark ranges
273
+ * are in final-text coordinates: every earlier channel applied). Every field is
274
+ * optional.
247
275
  */
248
276
  export interface ChangeBundle {
249
277
  delta?: Delta;
278
+ islandOps?: IslandOp[];
250
279
  lineOps?: LineOp[];
251
280
  markOps?: MarkOp[];
252
281
  }
@@ -722,11 +751,16 @@ export class Document {
722
751
  free(): void;
723
752
  [Symbol.dispose](): void;
724
753
  /**
725
- * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
726
- * at `addr`, the editor splice: text delta first, then line ops, then mark
727
- * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
754
+ * **Apply** a committed content edit `bundle`
755
+ * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
756
+ * splice: text delta first, then island ops, then line ops, then mark ops
757
+ * (mark ranges in final-text coordinates), each all-or-nothing. An absent
728
758
  * `addr.field` targets the body, an absent `addr.card` the main card.
729
759
  *
760
+ * The island channel keeps a table or image edit on the op path: it moves
761
+ * the island alone, so the anchors elsewhere in the field survive an edit
762
+ * `install` would clear.
763
+ *
730
764
  * Throws on an out-of-range card, a field that is not richtext, a malformed
731
765
  * bundle, or an op that applies out of bounds (the value is unchanged on a
732
766
  * failed apply).
@@ -251,11 +251,16 @@ export class Document {
251
251
  }
252
252
  }
253
253
  /**
254
- * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
255
- * at `addr`, the editor splice: text delta first, then line ops, then mark
256
- * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
254
+ * **Apply** a committed content edit `bundle`
255
+ * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
256
+ * splice: text delta first, then island ops, then line ops, then mark ops
257
+ * (mark ranges in final-text coordinates), each all-or-nothing. An absent
257
258
  * `addr.field` targets the body, an absent `addr.card` the main card.
258
259
  *
260
+ * The island channel keeps a table or image edit on the op path: it moves
261
+ * the island alone, so the anchors elsewhere in the field survive an edit
262
+ * `install` would clear.
263
+ *
259
264
  * Throws on an out-of-range card, a field that is not richtext, a malformed
260
265
  * bundle, or an op that applies out of bounds (the value is unchanged on a
261
266
  * failed apply).
Binary file
@@ -240,13 +240,42 @@ export type LineOp =
240
240
  | { op: "setContainers"; line: number; containers: ContentContainer[] }
241
241
  | { op: "setContinues"; line: number; continues: boolean };
242
242
 
243
+ /**
244
+ * An island edit: the only channel that reaches an island's payload, a table's
245
+ * cells or an image's url.
246
+ *
247
+ * Both ops move one island entry and leave the field's text and marks alone, so
248
+ * an island edit keeps every identity anchor in the field. That is why a table
249
+ * edit lowers to `applyChange` rather than `install`, which drops them all.
250
+ *
251
+ * `set` addresses an existing island by `id`; an `id` no island carries throws
252
+ * rather than passing silently. `insert` places a new island's slot at `at` (a
253
+ * post-delta USV position) together with its entry, so a slot never exists
254
+ * without an island behind it; its `id` must be non-empty and unused. Deleting
255
+ * an island needs no op: a `delta` that removes its slot drops the island.
256
+ *
257
+ * A `set` stores the `loss` it is given: nothing re-derives the class from the
258
+ * new `props`, so a write that changes what markdown can carry must say so.
259
+ *
260
+ * An island is *inline* (a slot inside a paragraph) unless its line says
261
+ * otherwise. A **block** island is one bundle of all three channels, in the
262
+ * order they apply: `delta` inserts the `\n` that opens the line, `islandOps`
263
+ * inserts the slot, `lineOps` tags the line `{ op: "setKind", kind: "island" }`.
264
+ * `{ op: "split" }` cannot open that line, since line ops run after island ops.
265
+ */
266
+ export type IslandOp =
267
+ | ({ op: "set" } & ContentIsland)
268
+ | ({ op: "insert"; at: number } & ContentIsland);
269
+
243
270
  /**
244
271
  * A committed content edit bundle for `applyChange`: a text `delta` (default no
245
- * text change), then `lineOps`, then `markOps` (mark ranges are in post-delta
246
- * coordinates). Every field is optional.
272
+ * text change), then `islandOps`, then `lineOps`, then `markOps` (mark ranges
273
+ * are in final-text coordinates: every earlier channel applied). Every field is
274
+ * optional.
247
275
  */
248
276
  export interface ChangeBundle {
249
277
  delta?: Delta;
278
+ islandOps?: IslandOp[];
250
279
  lineOps?: LineOp[];
251
280
  markOps?: MarkOp[];
252
281
  }
@@ -722,11 +751,16 @@ export class Document {
722
751
  free(): void;
723
752
  [Symbol.dispose](): void;
724
753
  /**
725
- * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
726
- * at `addr`, the editor splice: text delta first, then line ops, then mark
727
- * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
754
+ * **Apply** a committed content edit `bundle`
755
+ * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
756
+ * splice: text delta first, then island ops, then line ops, then mark ops
757
+ * (mark ranges in final-text coordinates), each all-or-nothing. An absent
728
758
  * `addr.field` targets the body, an absent `addr.card` the main card.
729
759
  *
760
+ * The island channel keeps a table or image edit on the op path: it moves
761
+ * the island alone, so the anchors elsewhere in the field survive an edit
762
+ * `install` would clear.
763
+ *
730
764
  * Throws on an out-of-range card, a field that is not richtext, a malformed
731
765
  * bundle, or an op that applies out of bounds (the value is unchanged on a
732
766
  * failed apply).
@@ -251,11 +251,16 @@ export class Document {
251
251
  }
252
252
  }
253
253
  /**
254
- * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
255
- * at `addr`, the editor splice: text delta first, then line ops, then mark
256
- * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
254
+ * **Apply** a committed content edit `bundle`
255
+ * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
256
+ * splice: text delta first, then island ops, then line ops, then mark ops
257
+ * (mark ranges in final-text coordinates), each all-or-nothing. An absent
257
258
  * `addr.field` targets the body, an absent `addr.card` the main card.
258
259
  *
260
+ * The island channel keeps a table or image edit on the op path: it moves
261
+ * the island alone, so the anchors elsewhere in the field survive an edit
262
+ * `install` would clear.
263
+ *
259
264
  * Throws on an out-of-range card, a field that is not richtext, a malformed
260
265
  * bundle, or an op that applies out of bounds (the value is unchanged on a
261
266
  * failed apply).
Binary file
package/core/wasm.d.ts CHANGED
@@ -240,13 +240,42 @@ export type LineOp =
240
240
  | { op: "setContainers"; line: number; containers: ContentContainer[] }
241
241
  | { op: "setContinues"; line: number; continues: boolean };
242
242
 
243
+ /**
244
+ * An island edit: the only channel that reaches an island's payload, a table's
245
+ * cells or an image's url.
246
+ *
247
+ * Both ops move one island entry and leave the field's text and marks alone, so
248
+ * an island edit keeps every identity anchor in the field. That is why a table
249
+ * edit lowers to `applyChange` rather than `install`, which drops them all.
250
+ *
251
+ * `set` addresses an existing island by `id`; an `id` no island carries throws
252
+ * rather than passing silently. `insert` places a new island's slot at `at` (a
253
+ * post-delta USV position) together with its entry, so a slot never exists
254
+ * without an island behind it; its `id` must be non-empty and unused. Deleting
255
+ * an island needs no op: a `delta` that removes its slot drops the island.
256
+ *
257
+ * A `set` stores the `loss` it is given: nothing re-derives the class from the
258
+ * new `props`, so a write that changes what markdown can carry must say so.
259
+ *
260
+ * An island is *inline* (a slot inside a paragraph) unless its line says
261
+ * otherwise. A **block** island is one bundle of all three channels, in the
262
+ * order they apply: `delta` inserts the `\n` that opens the line, `islandOps`
263
+ * inserts the slot, `lineOps` tags the line `{ op: "setKind", kind: "island" }`.
264
+ * `{ op: "split" }` cannot open that line, since line ops run after island ops.
265
+ */
266
+ export type IslandOp =
267
+ | ({ op: "set" } & ContentIsland)
268
+ | ({ op: "insert"; at: number } & ContentIsland);
269
+
243
270
  /**
244
271
  * A committed content edit bundle for `applyChange`: a text `delta` (default no
245
- * text change), then `lineOps`, then `markOps` (mark ranges are in post-delta
246
- * coordinates). Every field is optional.
272
+ * text change), then `islandOps`, then `lineOps`, then `markOps` (mark ranges
273
+ * are in final-text coordinates: every earlier channel applied). Every field is
274
+ * optional.
247
275
  */
248
276
  export interface ChangeBundle {
249
277
  delta?: Delta;
278
+ islandOps?: IslandOp[];
250
279
  lineOps?: LineOp[];
251
280
  markOps?: MarkOp[];
252
281
  }
@@ -470,11 +499,16 @@ export class Document {
470
499
  free(): void;
471
500
  [Symbol.dispose](): void;
472
501
  /**
473
- * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
474
- * at `addr`, the editor splice: text delta first, then line ops, then mark
475
- * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
502
+ * **Apply** a committed content edit `bundle`
503
+ * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
504
+ * splice: text delta first, then island ops, then line ops, then mark ops
505
+ * (mark ranges in final-text coordinates), each all-or-nothing. An absent
476
506
  * `addr.field` targets the body, an absent `addr.card` the main card.
477
507
  *
508
+ * The island channel keeps a table or image edit on the op path: it moves
509
+ * the island alone, so the anchors elsewhere in the field survive an edit
510
+ * `install` would clear.
511
+ *
478
512
  * Throws on an out-of-range card, a field that is not richtext, a malformed
479
513
  * bundle, or an op that applies out of bounds (the value is unchanged on a
480
514
  * failed apply).
package/core/wasm_bg.js CHANGED
@@ -251,11 +251,16 @@ export class Document {
251
251
  }
252
252
  }
253
253
  /**
254
- * **Apply** a committed content edit `bundle` (`{ delta?, lineOps?, markOps? }`)
255
- * at `addr`, the editor splice: text delta first, then line ops, then mark
256
- * ops (mark ranges in final-text coordinates), each all-or-nothing. An absent
254
+ * **Apply** a committed content edit `bundle`
255
+ * (`{ delta?, islandOps?, lineOps?, markOps? }`) at `addr`, the editor
256
+ * splice: text delta first, then island ops, then line ops, then mark ops
257
+ * (mark ranges in final-text coordinates), each all-or-nothing. An absent
257
258
  * `addr.field` targets the body, an absent `addr.card` the main card.
258
259
  *
260
+ * The island channel keeps a table or image edit on the op path: it moves
261
+ * the island alone, so the anchors elsewhere in the field survive an edit
262
+ * `install` would clear.
263
+ *
259
264
  * Throws on an out-of-range card, a field that is not richtext, a malformed
260
265
  * bundle, or an op that applies out of bounds (the value is unchanged on a
261
266
  * failed apply).
package/core/wasm_bg.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillmark/wasm",
3
- "version": "0.100.0",
3
+ "version": "0.101.0",
4
4
  "description": "WebAssembly bindings for Quillmark, a schema-driven document engine",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -84,6 +84,7 @@ export type {
84
84
  CardAddr,
85
85
  Delta,
86
86
  Assoc,
87
+ IslandOp,
87
88
  LineOp,
88
89
  MarkOp,
89
90
  ChangeBundle,