@betteroffice/docx 0.0.4 → 0.2.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.
Files changed (70) hide show
  1. package/README.md +4 -7
  2. package/dist/chunk-47Q2FMFF.mjs +1 -0
  3. package/dist/chunk-5F6DLQZP.mjs +1 -0
  4. package/dist/chunk-6LQJAKOC.mjs +1 -0
  5. package/dist/chunk-ACGKK7IB.mjs +1 -0
  6. package/dist/{chunk-NTSSE5QK.mjs → chunk-AFMVSI4Z.mjs} +2 -2
  7. package/dist/chunk-GD4VNJ64.mjs +1 -0
  8. package/dist/{chunk-NJHOPXZW.mjs → chunk-HLDJMU3R.mjs} +1 -1
  9. package/dist/{chunk-YTILOUAA.mjs → chunk-JHJLG4I6.mjs} +1 -1
  10. package/dist/chunk-PGMXWI5X.mjs +1 -0
  11. package/dist/{chunk-NBSLB77E.mjs → chunk-WTFRNX5K.mjs} +1 -1
  12. package/dist/collaboration/index.d.mts +6 -6
  13. package/dist/{content-C3sTRz-u.d.mts → content-CvEtPl0c.d.mts} +124 -22
  14. package/dist/core.d.mts +8 -8
  15. package/dist/core.mjs +1 -1
  16. package/dist/{displayListQueries-DLzpvJV6.d.mts → displayListQueries-DF8F6fMl.d.mts} +87 -50
  17. package/dist/docx/index.d.mts +5 -5
  18. package/dist/docx/index.mjs +1 -1
  19. package/dist/editor/index.d.mts +21 -12
  20. package/dist/editor/index.mjs +1 -1
  21. package/dist/{fontLoader-CMH3bZ2Z.d.mts → fontLoader-b8eicJKV.d.mts} +1 -1
  22. package/dist/{formatting-BEkIBePP.d.mts → formatting-7zKCTu5a.d.mts} +11 -2
  23. package/dist/{frameDelta-B2kC6XiP.d.mts → frameDelta-pA4jrQ1G.d.mts} +16 -10
  24. package/dist/generated/edit/docx_edit_bg.wasm +0 -0
  25. package/dist/generated/layout/docx_layout_bg.wasm +0 -0
  26. package/dist/generated/opc/ooxml_opc_bg.wasm +0 -0
  27. package/dist/generated/parse/docx_parse_bg.wasm +0 -0
  28. package/dist/{index-2piKi4gO.d.mts → index-CHl2zLJ7.d.mts} +146 -77
  29. package/dist/layout/index.d.mts +40 -13
  30. package/dist/layout/index.mjs +1 -1
  31. package/dist/layout/pagination/index.d.mts +4 -4
  32. package/dist/layout/pagination/index.mjs +1 -1
  33. package/dist/layout/render/index.d.mts +33 -77
  34. package/dist/layout/render/index.mjs +1 -1
  35. package/dist/plugin-api/RenderedDomContext.d.mts +7 -7
  36. package/dist/plugin-api/index.d.mts +3 -3
  37. package/dist/plugin-api/resolveItemPositions.d.mts +3 -3
  38. package/dist/{rustDisplayList-B0M2eBkU.d.mts → rustDisplayList-BJqaN9tt.d.mts} +74 -50
  39. package/dist/{rustMeasureSource-D1KsQvVC.d.mts → rustMeasureSource-C0EZB055.d.mts} +5 -2
  40. package/dist/{selectiveSave-CVoajSKE.d.mts → selectiveSave-CRh-_Y_C.d.mts} +3 -3
  41. package/dist/styles/index.d.mts +6 -10
  42. package/dist/styles/index.mjs +1 -1
  43. package/dist/{styles-BK3Jecxs.d.mts → styles-7e-mq3c-.d.mts} +1 -1
  44. package/dist/types/content.d.mts +2 -2
  45. package/dist/types/document.d.mts +8 -7
  46. package/dist/{types-C1rv3KM-.d.mts → types-C4A8mWjU.d.mts} +44 -24
  47. package/dist/utils/comments.d.mts +2 -2
  48. package/dist/utils/index.d.mts +11 -13
  49. package/dist/utils/index.mjs +1 -1
  50. package/dist/utils/stylePreview.d.mts +2 -2
  51. package/dist/wasm-7SOSHNGP.mjs +1 -0
  52. package/dist/{wasm-JE7B3ROD.mjs → wasm-ZQAVP7P2.mjs} +1 -1
  53. package/dist/wasm-edit.d.mts +525 -185
  54. package/dist/wasm-edit.mjs +1 -1
  55. package/dist/wasm-layout.d.mts +31 -28
  56. package/dist/wasm-layout.mjs +1 -1
  57. package/dist/wasm-opc.mjs +1 -1
  58. package/dist/wasm-parse.d.mts +2 -1
  59. package/dist/wasm-parse.mjs +1 -1
  60. package/dist/yrs/index.d.mts +5 -5
  61. package/dist/yrs/index.mjs +1 -1
  62. package/dist/yrs/residentEngineWorker.mjs +1 -1
  63. package/package.json +19 -2
  64. package/dist/chunk-4V6MDZIK.mjs +0 -1
  65. package/dist/chunk-6KDV6AIL.mjs +0 -1
  66. package/dist/chunk-B4IR6YP4.mjs +0 -1
  67. package/dist/chunk-GGEGIQRK.mjs +0 -1
  68. package/dist/chunk-T4EZMUXM.mjs +0 -1
  69. package/dist/chunk-WBH3SXI6.mjs +0 -1
  70. package/dist/wasm-F2ETFAYL.mjs +0 -1
@@ -13,45 +13,76 @@ declare class EditSession {
13
13
  free(): void;
14
14
  [Symbol.dispose](): void;
15
15
  /**
16
- * Accepts tracked changes (S4b): pending insertions become plain content,
17
- * pending deletions are carried out; `pPrIns` marks clear (the split
18
- * stays), `pPrDel` marks join with the following paragraph (its pPr
19
- * survives). `target_json`: `{"revisionId": string}` for one coalesced
20
- * revision (any story) or
21
- * `{"story","startPara","startOffset","endPara","endOffset"}` for a Loc
22
- * range. Receipt: `{"revisionIds": [string, …]}` — the revision ids
23
- * resolved. Resolving never stamps a new revision.
16
+ * Accepts tracked changes: pending insertions become plain content,
17
+ * pending deletions are carried out; `pPrIns` marks clear so the split
18
+ * stays, `pPrDel` marks join with the following paragraph, whose own
19
+ * properties survive.
20
+ *
21
+ * `target_json` is either `{"revisionId": string}`, resolving that one
22
+ * coalesced revision wherever it appears in any story, or
23
+ * `{"story","startPara","startOffset","endPara","endOffset"}`, resolving
24
+ * every tracked change overlapping that range regardless of revision id.
25
+ * Receipt: `{"revisionIds": [string, …]}` — the ids actually resolved, in
26
+ * resolution order and deduplicated. Resolving applies a revision rather
27
+ * than authoring one, so it never stamps a new revision and ignores
28
+ * suggesting mode. Errors on an empty range and on a `revisionId` that
29
+ * matches nothing.
24
30
  */
25
31
  accept_change(target_json: string): string;
26
32
  /**
27
- * Adds a sticky-anchored comment. `ranges_json`:
33
+ * Adds a comment anchored to one or more ranges. `ranges_json`:
28
34
  * `[{"story","startPara","startOffset","endPara","endOffset"}, …]`;
29
- * `body_json` is any JSON value. Receipt: `{"commentId"}`.
35
+ * `body_json` is any JSON value, stored as given. The anchors are sticky,
36
+ * so they follow the text they cover, and the comment lives outside the
37
+ * story rather than as an attribute on it. Receipt: `{"commentId"}` — a
38
+ * freshly minted id. Errors when `ranges_json` is not an array of
39
+ * well-formed ranges, or is empty.
30
40
  */
31
41
  add_comment(ranges_json: string, author: string, date: string, body_json: string): string;
32
42
  /**
33
- * Apply one ordinary collapsed character deletion (or adjacent paragraph
34
- * merge at a boundary) and return the resulting resident FrameDelta.
43
+ * Deletes one character at this session's collapsed selection and returns
44
+ * the resulting binary `FrameDelta`. `direction` is `"backward"` or
45
+ * `"forward"`; a surrogate pair is removed whole. At a paragraph boundary
46
+ * this merges with the neighbouring paragraph instead.
47
+ *
48
+ * Errors on an unknown `direction`, when `expected_frame_epoch` is not a
49
+ * non-negative safe integer, under the same selection and readiness
50
+ * conditions as [`EditSession::apply_input`], and when there is no
51
+ * character to delete in that direction (document start or end).
35
52
  */
36
53
  apply_delete(direction: string, expected_frame_epoch: number): Uint8Array;
37
54
  /**
38
- * Instrumented twin of `apply_delete`, used only by opt-in browser perf
39
- * traces. Keeping this separate leaves the production hot path timer-free.
55
+ * Instrumented twin of [`EditSession::apply_delete`]: identical arguments,
56
+ * result and error contract, but it also records stage timings for
57
+ * [`EditSession::apply_input_profile_json`].
40
58
  */
41
59
  apply_delete_profiled(direction: string, expected_frame_epoch: number): Uint8Array;
42
60
  /**
43
- * Apply one ordinary collapsed body-text insertion and return the
44
- * resulting FrameDelta. Selection, measurement inputs, pagination
45
- * checkpoints, and display state all remain resident in this session.
61
+ * Applies one ordinary insertion at this session's collapsed selection
62
+ * and returns the resulting binary `FrameDelta`. The inserted text
63
+ * inherits the formatting at the caret; selection, measurement inputs,
64
+ * pagination checkpoints and display state all stay resident, so nothing
65
+ * but the frame crosses the boundary.
66
+ *
67
+ * Errors when `text` is empty or contains `\r`/`\n`, when
68
+ * `expected_frame_epoch` is not a non-negative safe integer, when there is
69
+ * no resident selection or it no longer resolves, when the selection is
70
+ * not collapsed, or when the resident layout state cannot absorb an edit
71
+ * in that paragraph. The caller must then run the full layout path.
46
72
  */
47
73
  apply_input(text: string, expected_frame_epoch: number): Uint8Array;
48
74
  /**
49
- * Last opt-in `apply_input_profiled` stage timings as a compact JSON object.
75
+ * Stage timings of the last profiled apply, in milliseconds:
76
+ * `{"selectionMs","editMs","lowerMs","measureMs","paginateMs",
77
+ * "displayInputMs","displayBuildMs","displayFinalizeMs","displayMs",
78
+ * "encodeMs"}`. `{}` before the first profiled call.
50
79
  */
51
80
  apply_input_profile_json(): string;
52
81
  /**
53
- * Instrumented twin of `apply_input`, used only by opt-in browser perf
54
- * traces. Keeping this separate leaves the production hot path timer-free.
82
+ * Instrumented twin of [`EditSession::apply_input`]: identical arguments,
83
+ * result and error contract, but it also records stage timings for
84
+ * [`EditSession::apply_input_profile_json`]. Separate so the ordinary
85
+ * input path pays no timer calls.
55
86
  */
56
87
  apply_input_profiled(text: string, expected_frame_epoch: number): Uint8Array;
57
88
  /**
@@ -61,423 +92,732 @@ declare class EditSession {
61
92
  */
62
93
  apply_local_update(update: Uint8Array): void;
63
94
  /**
64
- * Applies a paragraph style id to every paragraph intersecting
65
- * `[start, end)`. With no host style resolver at this boundary, this is
66
- * the PM fallback path: write `pStyle` without fabricating a resolved
67
- * paragraph/run formatting projection.
95
+ * Writes `style_id` as the `pStyle` of every paragraph intersecting
96
+ * `[start, end)`. Only that key changes: this boundary has no style
97
+ * resolver, so it never fabricates the paragraph attributes or run marks
98
+ * the style definition would imply. In suggesting mode the property
99
+ * change is recorded as a `pPrChange` revision.
68
100
  */
69
101
  apply_paragraph_style(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, style_id: string, author_name?: string | null, author_date?: string | null): void;
70
102
  /**
71
- * Applies a batch of raw story mutations in ONE transaction — the
72
- * coexistence bridge's mirror-into-yrs path (not a user-intent op). `ops_json`
73
- * is `[{ "op":"insert"|"delete"|"format"|"insertEmbed"|"setEmbedAttr"
74
- * |"setComment"|"removeComment", "index", … }, …]`; each op's index (and each
75
- * `setComment` `[start, end)` range) is read against the story state after all
76
- * prior ops in the batch. Attributes/payloads are faithful mirrors of the
77
- * bridge's lowered PM state (tracked-change stamps arrive inside `attrs`;
78
- * comments are keyed by the PM comment id and anchored sticky, side-map only).
103
+ * Applies a batch of raw story mutations in ONE transaction. Unlike every
104
+ * other op here these carry no user intent: indices are story-global
105
+ * UTF-16 units, not Locs, and nothing is inferred or stamped on the
106
+ * caller's behalf. `ops_json` is an array of:
107
+ *
108
+ * - `{"op":"insert","index","text"?,"attrs"?}`
109
+ * - `{"op":"delete","index","len"}`
110
+ * - `{"op":"format","index","len","attrs"?}`
111
+ * - `{"op":"insertEmbed","index","kind"?,"payload"?,"attrs"?}`
112
+ * - `{"op":"setEmbedAttr","index","key","value"?}`
113
+ * - `{"op":"setComment","id","ranges":[[start,end], …],"author"?,"date"?,"body"?}`
114
+ * - `{"op":"removeComment","id"}`
115
+ *
116
+ * Each op's `index`, and each `setComment` range, is read against the
117
+ * story state AFTER every preceding op in the batch. `attrs` and
118
+ * `payload` are JSON objects written verbatim, so tracked-change stamps
119
+ * travel inside `attrs`; comments are keyed by the given id and anchored
120
+ * sticky. Errors on an unknown `"op"`, a missing or negative `"index"`,
121
+ * or a missing required field, and leaves the story untouched — parsing
122
+ * completes before the transaction opens.
79
123
  */
80
124
  apply_raw_ops(story: string, ops_json: string): void;
81
125
  /**
82
- * Applies a remote/incremental yrs v1 update.
126
+ * Applies seed raw operations with deterministic item ordering.
127
+ */
128
+ apply_seed_raw_ops(story: string, ops_json: string): void;
129
+ /**
130
+ * Applies a remote or incremental yrs v1 update. It commits without a
131
+ * local origin, so this replica's undo manager never claims it. Errors on
132
+ * a malformed update.
83
133
  */
84
134
  apply_update(update: Uint8Array): void;
135
+ /**
136
+ * [`EditSession::apply_update`] plus an inference about where the peer
137
+ * that authored it is typing, for caret presence. Returns
138
+ * `{"clientId","story","paraId","endOffset"}` for the end of that peer's
139
+ * last text insertion, or `"null"` when the update carries work from more
140
+ * than one client, ends in a non-text insertion, or inserts nothing.
141
+ * Errors on a malformed update.
142
+ */
85
143
  apply_update_with_inference(update: Uint8Array): string;
86
144
  /**
87
- * Binary FrameDelta v1 display output. The returned `Vec<u8>` is exposed
88
- * by wasm-bindgen as a transferable-friendly `Uint8Array`.
145
+ * Display-only input JSON in, one binary `FrameDelta` v1 out (exposed as
146
+ * a transferable `Uint8Array`). `expected_frame_epoch` is the epoch of the
147
+ * frame the caller currently holds; pass `0` for the first frame. A
148
+ * mismatch makes the engine emit a full frame instead of a delta. Errors
149
+ * unless the epoch is a non-negative safe integer, and on build failure.
89
150
  */
90
151
  build_display_list_frame(input: string, expected_frame_epoch: number): Uint8Array;
91
152
  /**
92
- * Build display primitives against the same resident font store used by
93
- * this session's measurement path.
153
+ * `{ measured, options, layout }` JSON in, `DisplayList` JSON out, built
154
+ * against the same resident font store this session measures with.
94
155
  */
95
156
  build_display_list_json(input: string): string;
157
+ /**
158
+ * Whether [`EditSession::redo`] would reapply something.
159
+ */
96
160
  can_redo(): boolean;
161
+ /**
162
+ * Whether [`EditSession::undo`] would revert something.
163
+ */
97
164
  can_undo(): boolean;
98
165
  /**
99
- * Resolves the current local cell selection, or `null` before the host
100
- * establishes one. Deleted endpoints clamp to a surviving nearby cell.
166
+ * The current local cell selection as a [`TableRange`], or `"null"`
167
+ * before one is set. An endpoint whose cell was deleted clamps to a
168
+ * surviving nearby cell. Errors when the table itself no longer resolves.
101
169
  */
102
170
  cell_selection(): string;
103
171
  /**
104
- * Clears the authored `value` from a stable-id content-control embed.
172
+ * Removes the authored `value` from the content-control embed carrying
173
+ * `embed_id`, leaving the control itself in place. Errors when no embed
174
+ * has that id.
105
175
  */
106
176
  clear_content_control_value(embed_id: string): void;
107
177
  /**
108
- * Clears every direct formatting attribute over `[start, end)`, while
109
- * retaining hyperlinks and tracked-change stamps.
178
+ * Clears every direct run-formatting attribute over `[start, end)`.
179
+ * Protected attributes — hyperlinks and tracked-change stamps — survive,
180
+ * as do paragraph properties.
110
181
  */
111
182
  clear_formatting(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number): void;
112
183
  /**
113
- * Clear this editing wasm's resident measurement fonts.
184
+ * Drops every registered measurement font (ids restart at zero) and
185
+ * invalidates the retained paragraph measurement templates, so the next
186
+ * edit must pass back through the full layout path.
114
187
  */
115
188
  clear_measure_fonts(): void;
189
+ /**
190
+ * Stops queueing and discards anything not yet drained.
191
+ */
116
192
  clear_update_event_observation(): void;
117
193
  /**
118
194
  * Drops the update observer registered by [`EditSession::set_update_observer`].
119
195
  */
120
196
  clear_update_observer(): void;
197
+ /**
198
+ * This replica's client id, as passed to the constructor.
199
+ */
121
200
  client_id(): number;
122
201
  /**
123
- * Adds a story with one paragraph. Receipt: `{"paraId"}` (the final
124
- * pilcrow's paragraph).
202
+ * Adds a story holding one paragraph with `initial_text` (which must not
203
+ * contain paragraph breaks), `p_style` and `alignment`. Receipt:
204
+ * `{"paraId"}` — the paragraph ending at the story's pilcrow. Errors when
205
+ * the story id already exists.
125
206
  */
126
207
  create_story(story_id: string, initial_text: string, p_style: string, alignment: string): string;
127
208
  /**
128
- * Deletes every column covered by an explicit cell range.
209
+ * Deletes every column the [`TableRange`] `range_json` covers, along with
210
+ * the stories of the cells removed. Always a plain local edit.
129
211
  */
130
212
  delete_column(range_json: string): string;
131
213
  /**
132
- * Deletes `[start, end)` given as two Locs in one story. A range whose
133
- * ends sit in different paragraphs spans the boundary pilcrows, so the
134
- * plain delete also merges (the pilcrow-as-character dividend).
135
- * Suggesting mode retains the content with a `del` revision instead.
136
- * Receipt: `{"revisionId": string|null}`.
214
+ * Deletes `[start, end)`. Because a range crossing a paragraph boundary
215
+ * includes the boundary pilcrow, a plain delete also merges those
216
+ * paragraphs. Suggesting mode removes nothing and stamps the content
217
+ * `del` instead. Receipt: `{"revisionId": string|null}`.
137
218
  */
138
219
  delete_range(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, author_name?: string | null, author_date?: string | null): string;
139
220
  /**
140
- * Deletes every row covered by an explicit cell range.
221
+ * Deletes every row the [`TableRange`] `range_json` covers. In suggesting
222
+ * mode the rows are marked `trDel` instead of removed.
141
223
  */
142
224
  delete_row(range_json: string, author_name?: string | null, author_date?: string | null): string;
143
225
  /**
144
- * Removes one complete story (used for unreachable table-cell stories).
226
+ * Removes one complete story and its content. Errors on an unknown story.
145
227
  */
146
228
  delete_story(story_id: string): void;
147
229
  /**
148
- * Removes one complete table plus all of its reachable cell stories.
230
+ * Removes the table `table_json` ([`TableLocator`]) names plus every one
231
+ * of its reachable cell stories. Always a plain local edit; the receipt
232
+ * has `deletedTable: true`.
149
233
  */
150
234
  delete_table(table_json: string): string;
151
235
  /**
152
- * Hit-test without re-serializing the resident display list through JS.
236
+ * Region-aware hit test against the resident display list, so no
237
+ * display-list JSON crosses the boundary. `x`/`y` are page-local px.
238
+ * Returns
239
+ * `{"region":"body"|"header"|"footer"|"footnote"|"endnote","rId"?,`
240
+ * `"noteId"?,"pos":n|null,"target":"text"|"image"|"none"}`, or `"null"`
241
+ * for a page index outside the frame. A header/footer `pos` refers to
242
+ * that part's own document and a note `pos` to the `fn:{id}` / `en:{id}`
243
+ * story, never the body; `target` is what sits under the point, which is
244
+ * what a pointer cursor needs.
153
245
  */
154
246
  display_hit_test_regions_json(page_index: number, x: number, y: number): string;
155
247
  /**
156
- * Body range geometry without a display-list JSON round trip.
248
+ * Highlight rectangles for a body document range against the resident
249
+ * display list: a JSON array of `{pageIndex,x,y,width,height}` in
250
+ * page-local px, one entry per page the range touches. Body positions
251
+ * only. Errors when no display list is resident.
157
252
  */
158
253
  display_range_rects_json(from: number, to: number): string;
159
254
  /**
160
- * Region-scoped range geometry without a display-list JSON round trip.
255
+ * Same rectangles as [`EditSession::display_range_rects_json`], scoped to
256
+ * a region. `region` is `"body"`, `"header"`, `"footer"`, `"footnote"` or
257
+ * `"endnote"`; `part_id` names one header/footer part (an empty string
258
+ * matches any) or the note whose story the positions belong to.
259
+ * `from`/`to` are positions in THAT region's document, and a
260
+ * header/footer part paints on every page carrying it, so the result
261
+ * holds one rect set per such page, each tagged with its `pageIndex`.
262
+ * Errors on an unknown `region` and when no display list is resident.
263
+ */
264
+ display_range_rects_region_json(region: string, part_id: string, from: number, to: number): string;
265
+ /**
266
+ * Nearest caret position on the adjacent visual line. `direction` is
267
+ * `"up"` or `"down"`; `goal_x` is the page-local x the caret is trying to
268
+ * hold across successive moves (a non-finite value falls back to the
269
+ * caret's own x). Returns `{"position","goalX"}`, or `"null"` when there
270
+ * is no line in that direction. Errors on an unknown `direction` and when
271
+ * no display list is resident.
161
272
  */
162
- display_range_rects_region_json(region: string, r_id: string, from: number, to: number): string;
163
273
  display_vertical_move_json(position: number, direction: string, goal_x: number): string;
274
+ /**
275
+ * Pops the oldest queued transaction, in arrival order. Byte 0 is `1`
276
+ * when the transaction had no local origin and `0` otherwise; the rest is
277
+ * the v1 update. Empty when the queue is drained or observation never
278
+ * started.
279
+ */
164
280
  drain_update_event(): Uint8Array;
281
+ /**
282
+ * The yrs v1 update carrying everything this replica has that the peer
283
+ * described by `remote_state_vector` does not. Errors on a malformed
284
+ * state vector.
285
+ */
165
286
  encode_diff(remote_state_vector: Uint8Array): Uint8Array;
166
287
  /**
167
- * Full document state as one yrs v1 update (Yjs wire format).
288
+ * The full document state as one yrs v1 update. Hand it to
289
+ * [`EditSession::load`] on a fresh replica to reproduce this document.
168
290
  */
169
291
  encode_state(): Uint8Array;
292
+ /**
293
+ * This replica's yrs v1 state vector — what a peer sends so
294
+ * [`EditSession::encode_diff`] can compute the update it is missing.
295
+ */
170
296
  encode_state_vector(): Uint8Array;
171
297
  /**
172
- * Encodes one paragraph location as a sticky position.
298
+ * Encodes one Loc as opaque sticky-position bytes that keep pointing at
299
+ * the same content as the story is edited. Publish them over an awareness
300
+ * transport and resolve them with
301
+ * [`EditSession::resolve_sticky_position`].
173
302
  */
174
303
  encode_sticky_position(story: string, para_id: string, offset: number): Uint8Array;
304
+ /**
305
+ * This peer's selection in transportable form:
306
+ * `{"story","anchor":[byte, …],"head":[byte, …]}` with sticky-encoded
307
+ * endpoints, or `"null"` before a selection is set. A peer resolves it
308
+ * with [`EditSession::resolve_encoded_selection`].
309
+ */
175
310
  encoded_selection(): string;
176
311
  /**
177
312
  * Applies a set-valued, tri-state inline formatting delta over
178
- * `[start, end)` in one transaction. Omitted fields are kept and `null`
179
- * fields are cleared.
313
+ * `[start, end)` in one transaction. An omitted key keeps the current
314
+ * value, `null` clears it, and any other value sets it. `delta_json`:
315
+ *
316
+ * ```json
317
+ * {
318
+ * "bold": true, "italic": true,
319
+ * "underline": true | {"style"?: string, "color"?: string},
320
+ * "strike": true | {"double"?: boolean},
321
+ * "color": {"rgb": string} | {"themeColor": string},
322
+ * "highlight": string,
323
+ * "fontSize": 12,
324
+ * "fontFamily": {"ascii": string, "hAnsi"?: string},
325
+ * "other": {"anyAttr": value}
326
+ * }
327
+ * ```
328
+ *
329
+ * `false` clears `bold`, `italic`, `underline` and `strike`. `color`
330
+ * takes exactly one of `rgb` or `themeColor`. `other` writes arbitrary
331
+ * run attributes, with `null` removing one. Always a plain local edit, so
332
+ * there is no receipt. Errors when a key carries a type not listed here.
180
333
  */
181
334
  format_range(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, delta_json: string): void;
182
335
  /**
183
- * Inserts a column left (`after = false`) or right (`after = true`) of a cell.
336
+ * Stories changed by the latest undo or redo, sorted.
337
+ */
338
+ history_stories(): string[];
339
+ /**
340
+ * Inserts a column left (`after = false`) or right (`after = true`) of
341
+ * the cell `at_json` ([`CellLoc`]) names. Always a plain local edit.
184
342
  */
185
343
  insert_column(at_json: string, after: boolean): string;
186
344
  /**
187
- * Inserts one native inline image embed at a paragraph-keyed location.
345
+ * Inserts one inline image embed at `(story, para_id, offset)`.
346
+ * `payload_json` is the image's authored payload object, stored as given.
347
+ * The embed occupies one story unit. Receipt:
348
+ * `{"revisionId": string|null}`. Errors when the payload is not an
349
+ * object.
188
350
  */
189
351
  insert_image(story: string, para_id: string, offset: number, payload_json: string, author_name?: string | null, author_date?: string | null): string;
190
352
  /**
191
- * Inserts a native page-break embed at a Loc.
353
+ * Inserts a page-break embed at `(story, para_id, offset)`, occupying one
354
+ * story unit. Always a plain local edit.
192
355
  */
193
356
  insert_page_break(story: string, para_id: string, offset: number): void;
194
357
  /**
195
- * Inserts a row above (`after = false`) or below (`after = true`) a cell.
358
+ * Inserts a row above (`after = false`) or below (`after = true`) the
359
+ * cell `at_json` names. `at_json` is a [`CellLoc`].
196
360
  */
197
361
  insert_row(at_json: string, after: boolean, author_name?: string | null, author_date?: string | null): string;
198
362
  /**
199
- * Inserts a native section-break embed at a Loc.
363
+ * Inserts a section-break embed at `(story, para_id, offset)`.
364
+ * `break_type` must be `"nextPage"`, `"continuous"`, `"oddPage"` or
365
+ * `"evenPage"`; anything else errors. Always a plain local edit.
200
366
  */
201
367
  insert_section_break(story: string, para_id: string, offset: number, break_type: string): void;
202
368
  /**
203
- * Inserts a rectangular structural table at a paragraph-keyed location.
369
+ * Inserts a `rows` x `columns` table at `(story, para_id, offset)`,
370
+ * creating one story per cell. Errors when either dimension is zero.
204
371
  */
205
372
  insert_table(story: string, para_id: string, offset: number, rows: number, columns: number, author_name?: string | null, author_date?: string | null): string;
206
373
  /**
207
- * Inserts paragraph-break-free text at `(story, para_id, offset)`.
208
- * Receipt: `{"revisionId": string|null}` (non-null in suggesting mode).
374
+ * Inserts `text` at `(story, para_id, offset)`. It must contain no
375
+ * paragraph or line breaks, and it inherits the formatting at the
376
+ * insertion point. Receipt: `{"revisionId": string|null}` — non-null in
377
+ * suggesting mode, where the text is stamped `ins` and coalesces into an
378
+ * adjacent insertion by the same author rather than opening a second
379
+ * revision.
209
380
  */
210
381
  insert_text(story: string, para_id: string, offset: number, text: string, author_name?: string | null, author_date?: string | null): string;
211
382
  /**
212
- * Inserts a typed watermark embed at a Loc.
383
+ * Inserts a watermark embed at `(story, para_id, offset)`, its payload
384
+ * taken verbatim from the `watermark_json` object. Always a plain local
385
+ * edit. Errors when the JSON is not an object.
213
386
  */
214
387
  insert_watermark(story: string, para_id: string, offset: number, watermark_json: string): void;
215
388
  /**
216
- * Paginate and retain the measured input and Layout. The full JSON return
217
- * remains the migration parity bridge until binary frames consume it.
389
+ * `{ measured, options }` JSON in, `Layout` JSON out. Both the measured
390
+ * input and the resulting layout are retained for the resident edit path.
391
+ * Errors on unparseable input or on layout failure.
218
392
  */
219
393
  layout_document_json(input: string): string;
220
394
  /**
221
- * Paginate and compose section/page regions inside the resident engine.
395
+ * Region-layout input JSON in, a paginated envelope with section and page
396
+ * regions already composed as JSON out — ready for the display builder
397
+ * with no host-side layout mutation. Retains the pass for resident edits.
222
398
  */
223
399
  layout_document_with_regions_json(input: string): string;
400
+ /**
401
+ * Same full region pass as [`Self::layout_document_with_regions_json`],
402
+ * but the reply carries only `{ layout, headersFooters?, notesConverged }`
403
+ * — the measured arena stays retained wasm-side and is fetched on demand
404
+ * via [`Self::retained_kernel_inputs_json`].
405
+ */
406
+ layout_document_with_regions_retained_json(input: string): string;
407
+ /**
408
+ * Region-layout input JSON in, the font families and sizes that input
409
+ * needs as JSON out, so the host can register fonts before laying out.
410
+ */
224
411
  layout_font_requirements_json(input: string): string;
225
412
  /**
226
- * Every tracked-change run/paragraph-mark revision across all stories,
227
- * in deterministic story/position order.
413
+ * Every pending tracked change across all stories, in deterministic
414
+ * story-then-position order:
415
+ * `[{"revisionId","author","date","kind","story","preview",
416
+ * "range":{"story","start":{"paraId","offset"},"end":{…}}}, …]`. `kind`
417
+ * is one of `"insertion"`, `"deletion"`, `"pPrIns"`, `"pPrDel"`,
418
+ * `"pPrChange"`, `"trIns"`, `"trDel"`, `"tableIns"` or `"tableDel"`.
419
+ * `preview` holds the first few characters of the affected text, and is
420
+ * empty for every structural kind, which covers no text.
228
421
  */
229
422
  list_revisions(): string;
230
423
  /**
231
- * Hydrates this replica from an encoded yrs update (the bytes form of
232
- * `load` — typically another replica's `encode_state()` output).
424
+ * Hydrates this replica from an encoded yrs v1 update, typically another
425
+ * replica's [`EditSession::encode_state`] output. Identical to
426
+ * [`EditSession::apply_update`]; the separate name marks the initial-load
427
+ * call site. Errors on a malformed update.
233
428
  */
234
429
  load(update: Uint8Array): void;
235
430
  /**
236
- * Seeds stories from JSON (the json form of `load`):
431
+ * Seeds stories from JSON:
237
432
  * `[{"storyId","paragraphs":[{"text","pStyle"?,"alignment"?}, …]}, …]`.
238
- * Paragraph text must not contain paragraph breaks. Returns
239
- * `{storyId: [paraId, …]}` in document order. This is an S1 seeding
240
- * scaffold composed from public ops; the real `load(ParsedDocument)`
241
- * belongs to the ops track.
433
+ * `pStyle` defaults to `"Normal"` and `alignment` to `"left"`; paragraph
434
+ * text must not contain paragraph breaks. Receipt:
435
+ * `{storyId: [paraId, …]}` with each story's paragraphs in document
436
+ * order. Errors when a story entry has no `storyId`, no `paragraphs`
437
+ * array, or an empty one, and when a story id already exists.
242
438
  */
243
439
  load_json(stories_json: string): string;
244
440
  /**
245
- * `{"start","end"}` — the paragraph's story span; `end` is its pilcrow's
246
- * index, so `end - start` is the paragraph length (`offset` domain).
441
+ * `{"start","end"}` — the paragraph's span in story-global UTF-16 units.
442
+ * `end` is the index of its own pilcrow, so `end - start` is the
443
+ * paragraph length and the upper bound of a Loc `offset` in it. Errors
444
+ * when the paragraph is not in `story`.
247
445
  */
248
446
  locate_paragraph(story: string, para_id: string): string;
249
447
  /**
250
- * Materializes the retained canonical package for compatibility APIs.
448
+ * Re-parses the DOCX bytes retained by the last
449
+ * [`EditSession::open_docx`] and returns the COMPLETE package envelope as
450
+ * JSON, or `None` when no DOCX has been opened. Unlike `open_docx` this
451
+ * keeps every part; it reflects the source file, not later edits.
251
452
  */
252
453
  materialize_docx(): string | undefined;
253
454
  /**
254
- * Paragraph-measure compatibility export on the resident engine module.
455
+ * Measurement input JSON in, `ParagraphExtent` JSON out. Also records the
456
+ * paragraph's immutable width/font envelope under its stable block id, so
457
+ * a later resident edit re-measures only the changed block. Errors with
458
+ * the engine's message for input it cannot measure.
255
459
  */
256
460
  measure_paragraph_json(input: string): string;
257
461
  /**
258
- * Merges a rectangular cell range into its top-left cell.
462
+ * Merges the rectangle the [`TableRange`] `range_json` covers into its
463
+ * top-left cell, whose story survives; the other cells' stories are
464
+ * deleted. Always a plain local edit. Errors when the range covers fewer
465
+ * than two cells or has no top-left anchor cell.
259
466
  */
260
467
  merge_cells(range_json: string): string;
261
468
  /**
262
469
  * Merges `para_id` with the FOLLOWING paragraph by deleting (plain) or
263
- * `del`-marking (suggesting) its pilcrow. Errors on the story's final
264
- * paragraph. Receipt: `{"revisionId": string|null}`.
470
+ * `del`- and `pPrDel`-marking (suggesting) its pilcrow. On a plain merge
471
+ * the survivor adopts the deleted mark's properties and paraId, so the
472
+ * earlier paragraph's identity wins. Receipt:
473
+ * `{"revisionId": string|null}`. Errors on the story's final paragraph,
474
+ * which has no following paragraph to merge with.
265
475
  */
266
476
  merge_paragraphs(story: string, para_id: string, author_name?: string | null, author_date?: string | null): string;
267
477
  /**
268
- * Creates a replica. `client_id` must be a non-negative safe integer —
269
- * the host allocates it (yjs-style random 32-bit ids are fine).
478
+ * Creates a replica. The host allocates `client_id` (a random 32-bit id
479
+ * is fine) and must keep it unique across the replicas that will merge.
480
+ * Errors unless it is a non-negative safe integer.
270
481
  */
271
482
  constructor(client_id: number);
272
483
  /**
273
- * Parses a DOCX and optionally seeds its editable stories.
484
+ * Parses a DOCX package, optionally seeds its editable stories into this
485
+ * replica, and retains the source bytes for
486
+ * [`EditSession::materialize_docx`].
487
+ *
488
+ * Returns `{"envelope","referencedFonts":[string, …]}`. The envelope is
489
+ * the parsed package with the parts the host does not need stripped —
490
+ * body content, header/footer and note content, numbering, media and
491
+ * charts are emptied, section entries keep only their properties — so
492
+ * styles, theme, settings, fonts and relationships still cross while the
493
+ * bulk of the document stays in Rust. Errors on bytes that are not a
494
+ * readable DOCX.
274
495
  */
275
496
  open_docx(bytes: Uint8Array, seed_stories: boolean): string;
276
497
  /**
277
- * Resolve one glyph outline from the session's resident font store.
498
+ * One glyph outline from this session's resident font store:
499
+ * `{"upem":n,"cmds":[{"t":"M"|"L"|"Q"|"C"|"Z", …}]}` — commands in font
500
+ * units, y-up. `font_id` comes from
501
+ * [`EditSession::register_measure_font`] and `glyph_id` from shaping.
502
+ * Errors when the glyph cannot be extracted.
278
503
  */
279
504
  outline_glyph_json(font_id: number, glyph_id: number): string;
280
505
  /**
281
- * Compact paragraph-position projection in one story traversal:
282
- * `[{"paraId","length"}]`. Length counts UTF-16 text and inline embed
283
- * units before each paragraph's pilcrow. The JS input shim uses this
284
- * instead of crossing the wasm boundary once per paragraph.
506
+ * Compact paragraph-position projection built in one story traversal:
507
+ * `[{"paraId","length"}, …]` in document order, where `length` counts the
508
+ * UTF-16 text and inline embed units before that paragraph's pilcrow —
509
+ * exactly the `offset` domain of a Loc in it. One call replaces crossing
510
+ * the boundary once per paragraph. Errors on an unknown story.
285
511
  */
286
512
  paragraph_spans(story: string): string;
287
513
  /**
288
- * `[{"paraId","text","properties"}]` in document order. `properties`
289
- * carries pStyle/alignment plus any op-set extras.
514
+ * `[{"paraId","text","properties"}, …]` in document order. `text` is the
515
+ * paragraph's plain text without its pilcrow; `properties` is the
516
+ * pilcrow's authored property map (`pStyle`, `alignment` and whatever
517
+ * else has been set on it). Errors on an unknown story.
290
518
  */
291
519
  paragraphs(story: string): string;
292
520
  /**
293
- * Reapplies the latest locally undone transaction.
521
+ * Reapplies the latest locally undone transaction and reports whether
522
+ * anything was reapplied.
294
523
  */
295
524
  redo(): boolean;
296
525
  /**
297
- * Current local redo stack size. Zero before a story starts tracking.
298
- */
299
- redo_depth(): number;
300
- /**
301
- * Register font bytes in this editing wasm's resident measurement store.
302
- * Returned ids are valid for measurement and display work in this module.
526
+ * Registers raw sfnt bytes in this session's resident measurement store
527
+ * and returns the font id that measurement and display inputs reference.
528
+ * Errors on bytes the font parser rejects.
303
529
  */
304
530
  register_measure_font(bytes: Uint8Array): number;
305
531
  /**
306
- * Rejects tracked changes — the inverse of [`EditSession::accept_change`]:
307
- * pending insertions roll back, pending deletions restore their text;
308
- * `pPrIns` marks join back with the following paragraph, `pPrDel` marks
309
- * clear (the split stays). Same target and receipt shapes.
532
+ * Rejects tracked changes — the inverse of
533
+ * [`EditSession::accept_change`]: pending insertions roll back, pending
534
+ * deletions restore their text; `pPrIns` marks join back with the
535
+ * following paragraph, `pPrDel` marks clear so the split stays, and a
536
+ * `pPrChange` restores the paragraph's previous properties. Same target,
537
+ * receipt and error contract.
310
538
  */
311
539
  reject_change(target_json: string): string;
312
540
  /**
313
- * Replaces `[start, end)` with text in one transaction. The inserted text
314
- * adopts the first replaced unit's formatting; in suggesting mode the
315
- * deletion and insertion share one revision id.
541
+ * Replaces `[start, end)` with `text` in one transaction. The inserted
542
+ * text adopts the first replaced unit's formatting; in suggesting mode
543
+ * the deletion and the insertion share one revision id. Receipt:
544
+ * `{"revisionId": string|null}`.
316
545
  */
317
546
  replace_range(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, text: string, author_name?: string | null, author_date?: string | null): string;
547
+ /**
548
+ * `{"frameEpoch", "caretRect": {…}|null}` for the session's own collapsed
549
+ * body selection. `caretRect` is null whenever there is no selection, the
550
+ * selection is not a collapsed body caret, or the retained layout has no
551
+ * geometry for it. `frameEpoch` identifies the frame the rect belongs to.
552
+ */
318
553
  resident_caret_snapshot_json(): string;
319
554
  /**
320
- * Current offsets of a comment's sticky anchors:
321
- * `[{"story","start","end"}]`. Errors when an anchor no longer resolves.
555
+ * Where a comment's sticky anchors currently sit:
556
+ * `[{"story","start","end"}, …]`, one entry per anchored range, in
557
+ * story-global UTF-16 units. Errors on an unknown comment id and when an
558
+ * anchor no longer resolves.
322
559
  */
323
560
  resolve_comment(comment_id: string): string;
561
+ /**
562
+ * Resolves another peer's encoded selection against this replica's
563
+ * current state: `{"anchor":{"story","paraId","offset"},"head":{…}}`.
564
+ * Errors on malformed bytes or an endpoint that no longer resolves.
565
+ */
324
566
  resolve_encoded_selection(story: string, anchor: Uint8Array, head: Uint8Array): string;
325
567
  /**
326
- * Resolves one encoded sticky position to a paragraph location.
568
+ * Resolves sticky bytes from [`EditSession::encode_sticky_position`] back
569
+ * to `{"story","paraId","offset"}`. Errors when the bytes are malformed
570
+ * or the position no longer resolves in `story`.
327
571
  */
328
572
  resolve_sticky_position(story: string, position: Uint8Array): string;
329
573
  /**
330
- * Parses a DOCX, seeds its stories, and returns thin host metadata.
574
+ * Retained `{ measured, options }` for the main-thread display-list
575
+ * fallback after a retained-only region layout.
576
+ */
577
+ retained_kernel_inputs_json(): string;
578
+ /**
579
+ * [`EditSession::open_docx`] with seeding always on.
331
580
  */
332
581
  seed_from_docx(bytes: Uint8Array): string;
333
582
  /**
334
- * Resolves this peer's current sticky selection as two public Locs, or
335
- * `null` before the host establishes an initial selection.
583
+ * Notes the story a direct operation is about to edit; a different story
584
+ * than the previous edit or caret closes the current undo step.
585
+ */
586
+ select_story(story: string): void;
587
+ /**
588
+ * This peer's current selection as `{"anchor":{"story","paraId","offset"},
589
+ * "head":{…}}`, or `"null"` before [`EditSession::set_selection`] is
590
+ * called. Errors when an endpoint no longer resolves.
336
591
  */
337
592
  selection(): string;
338
593
  /**
339
- * Aggregated toolbar/a11y state over one paragraph-addressed story
340
- * range. Toggle marks are `true`, `false`, or `"mixed"`; value marks
341
- * are their uniform value or `null` when absent/mixed.
594
+ * Aggregated toolbar and accessibility state over `[start, end)`:
595
+ *
596
+ * ```json
597
+ * {
598
+ * "bold": true | false | "mixed", "italic": …, "underline": …, "strike": …,
599
+ * "fontFamily": string|null, "fontSize": number|null, "color": string|null,
600
+ * "paraId": string, "styleId": string|null, "alignment": string|null,
601
+ * "paragraphProperties": {…},
602
+ * "hasSelection": bool, "isMultiParagraph": bool, "inTable": bool,
603
+ * "isSingleEmbed": bool, "embedKind": string|null, "isImage": bool,
604
+ * "inInsertion": bool, "inDeletion": bool
605
+ * }
606
+ * ```
607
+ *
608
+ * A toggle mark is `"mixed"` when the range disagrees about it; a value
609
+ * mark is `null` when it is absent OR not uniform, so the two cases are
610
+ * not distinguished. `isImage` is `embedKind == "image"`, and
611
+ * `inInsertion`/`inDeletion` report whether the range sits inside a
612
+ * pending tracked change.
342
613
  */
343
614
  selection_context(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number): string;
344
615
  /**
345
- * Replaces the selected cells' complete border property object.
616
+ * Merges the sides of the JSON object `borders_json` into every selected
617
+ * cell's `tcPr.borders`; `insideH`/`insideV` resolve to the physical edges
618
+ * interior to the selection. `range_json` is a [`TableRange`]. Always a
619
+ * plain local edit.
346
620
  */
347
621
  set_cell_borders(range_json: string, borders_json: string): string;
348
622
  /**
349
- * Stores a rectangular anchor-cell → head-cell selection outside the yrs
350
- * document. `range_json` is a [`TableRange`]. The table embed is held by a
351
- * sticky index and the endpoints by stable cell-story identity.
623
+ * Stores a rectangular anchor-cell to head-cell selection outside the yrs
624
+ * document. `range_json` is a [`TableRange`]:
625
+ * `{"anchor":{"story","tableIndex","row","column"},"head":{…}}`. The table
626
+ * embed is held by a sticky index and each endpoint by its cell story's
627
+ * stable identity, so the selection survives unrelated edits and follows
628
+ * inserted or deleted rows and columns. Errors when the two endpoints are
629
+ * not in the same table, or when either cell does not resolve.
352
630
  */
353
631
  set_cell_selection(range_json: string): void;
354
632
  /**
355
- * Sets/clears selected cells' background color (hex without or with `#`).
633
+ * Sets every selected cell's background to `color` (hex, with or without
634
+ * a leading `#`), or clears it when `color` is absent. `range_json` is a
635
+ * [`TableRange`]. Always a plain local edit.
356
636
  */
357
637
  set_cell_shading(range_json: string, color?: string | null): string;
358
638
  /**
359
- * Merges a JSON cell-format patch into every selected cell's `tcPr`.
639
+ * Merges the JSON object `patch_json` into every selected cell's `tcPr`;
640
+ * a `null` value removes that key. `range_json` is a [`TableRange`].
641
+ * Always a plain local edit. Errors when the patch touches `rowspan`,
642
+ * `colspan`, `gridSpan` or `vMerge`, which only merge and split may set.
360
643
  */
361
644
  set_cell_text_format(range_json: string, patch_json: string): string;
362
645
  /**
363
- * Sets one grid-column width in twips.
646
+ * Sets the grid width, in twips, of the column holding the cell `at_json`
647
+ * ([`CellLoc`]) names. Always a plain local edit. Errors unless
648
+ * `width_twips` is finite and positive.
364
649
  */
365
650
  set_column_width(at_json: string, width_twips: number): string;
366
651
  /**
367
- * Sets the authored `value` on a stable-id content-control embed.
652
+ * Sets the authored `value` (any JSON) on the content-control embed
653
+ * carrying `embed_id`, searching every story. Errors when no embed has
654
+ * that id.
368
655
  */
369
656
  set_content_control_value(embed_id: string, value_json: string): void;
370
657
  /**
371
- * Sets the authored `value` on a content-control embed at a paragraph-keyed
372
- * position. This is the fallback for valid controls that have no authored
373
- * `w:id`/tag and therefore cannot be addressed by stable payload identity.
658
+ * Sets the authored `value` on the content-control embed at
659
+ * `(story, para_id, offset)` — the way to reach a control with no
660
+ * authored `w:id` or tag, which
661
+ * [`EditSession::set_content_control_value`] cannot address. Errors when
662
+ * that position holds no embed.
374
663
  */
375
664
  set_content_control_value_at(story: string, para_id: string, offset: number, value_json: string): void;
376
665
  /**
377
- * Sets or clears the protected hyperlink attribute over `[start, end)`.
378
- * `hyperlink_json` is an object (`{href, tooltip?, rId?}`) or `null`.
666
+ * Sets or clears the hyperlink attribute over `[start, end)`.
667
+ * `hyperlink_json` is `{"href", "tooltip"?, "rId"?}` or `null` to unlink.
668
+ * The attribute is protected: ordinary formatting ops cannot write or
669
+ * erase it, only this one. Errors when the JSON is neither an object nor
670
+ * `null`.
379
671
  */
380
672
  set_hyperlink(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, hyperlink_json: string): void;
381
673
  /**
382
- * Commits image geometry fields to a stable-id image embed in one
383
- * transaction. `null` fields clear; `other` is flattened into the payload.
674
+ * Writes geometry fields onto the image embed carrying `embed_id` in one
675
+ * transaction. Every key of the `geometry_json` object becomes a payload
676
+ * entry, with `null` clearing it; the entries of a nested `"other"`
677
+ * object are flattened into the payload alongside them. Errors when
678
+ * `geometry_json` or its `"other"` is not an object, and when no embed
679
+ * has that id.
384
680
  */
385
681
  set_image_geometry(embed_id: string, geometry_json: string): void;
386
682
  /**
387
- * Sets one paragraph property (any JSON value) on `para_id`'s pilcrow.
388
- * `paraId` / the embed discriminator are reserved.
683
+ * Sets one paragraph property to any JSON value on `para_id`'s pilcrow,
684
+ * searching every story. Unlike
685
+ * [`EditSession::set_paragraph_attrs`] this writes a single key and never
686
+ * records a revision. Errors when the paragraph is unknown and when `key`
687
+ * names schema-managed identity (`paraId` or the embed discriminator).
389
688
  */
390
689
  set_paragraph_attr(para_id: string, key: string, value_json: string): void;
391
690
  /**
392
691
  * Applies a tri-state paragraph-property delta to every paragraph
393
- * intersecting `[start, end)` in one transaction.
692
+ * intersecting `[start, end)` in one transaction. An omitted key keeps
693
+ * the current value and `null` clears it. `attrs_json` recognises
694
+ * `alignment`, `lineSpacing`, `lineSpacingRule`, `spaceBefore`,
695
+ * `spaceAfter`, `indentLeft`, `indentRight`, `indentFirstLine`,
696
+ * `hangingIndent`, `bidi`, `tabs`
697
+ * (`[{"position":number,"alignment":string,"leader"?:string}, …]`) and
698
+ * `defaultTextFormatting` (an object of run defaults). Any other key —
699
+ * whether written at the top level or nested under `"other"` — is stored
700
+ * as an opaque paragraph property. Spacing and indents are authored OOXML
701
+ * units (twips, line-spacing units), never pixels. In suggesting mode a
702
+ * change is recorded as a `pPrChange` revision. Errors when a recognised
703
+ * key carries the wrong type, and when a key names schema-managed
704
+ * identity such as `paraId`.
394
705
  */
395
706
  set_paragraph_attrs(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, attrs_json: string, author_name?: string | null, author_date?: string | null): void;
396
707
  /**
397
- * Stores this peer's anchor/head as sticky positions. `Assoc::After`
398
- * makes a collapsed caret advance with text inserted at the caret.
708
+ * Stores this peer's anchor and head as sticky positions, replacing any
709
+ * previous selection. Both endpoints must lie in `story`. The positions
710
+ * live outside the yrs document, so they are never serialized as content
711
+ * or carried in an update. `Assoc::After` makes a collapsed caret advance
712
+ * with text inserted at it.
399
713
  */
400
714
  set_selection(story: string, anchor_para: string, anchor_offset: number, head_para: string, head_offset: number): void;
401
715
  /**
402
- * Sets the table-wide preferred width in twips.
716
+ * Sets the preferred width, in twips, of the table `table_json`
717
+ * ([`TableLocator`]) names. Always a plain local edit. Errors unless
718
+ * `width_twips` is finite and positive.
403
719
  */
404
720
  set_table_width(table_json: string, width_twips: number): string;
405
721
  /**
406
- * Subscribes `callback(update: Uint8Array)` to every committed
407
- * transaction (v1 encoding — feed it straight to `apply_update` on a
408
- * peer). One observer per session; a second call replaces the first.
409
- * The facade fans out to multiple JS listeners over this single hook.
722
+ * Subscribes `callback(update: Uint8Array, isRemote: 0|1)` to every
723
+ * committed transaction. `update` is v1-encoded — feed it straight to
724
+ * [`EditSession::apply_update`] on a peer — and is copied out of wasm
725
+ * memory, so JS may hold it across later edits. The second argument is
726
+ * `1` when the transaction had no local origin. One observer per session;
727
+ * a second call replaces the first, and a throwing callback is ignored.
410
728
  */
411
729
  set_update_observer(callback: Function): void;
412
730
  /**
413
- * Splits the cell covering `at` into the requested grid. Omitted
414
- * dimensions unmerge the cell into its existing covered slots.
731
+ * Splits the cell `at_json` ([`CellLoc`]) covers into a `rows` x
732
+ * `columns` grid; the original story stays in the top-left slot and every
733
+ * other slot gets a fresh one-paragraph cell story. Omitting both
734
+ * dimensions unmerges the cell into the slots it already covers, which
735
+ * then requires a merged cell. Always a plain local edit. Errors on a
736
+ * zero dimension or a grid smaller than the cell already covers.
415
737
  */
416
738
  split_cell(at_json: string, rows?: number | null, columns?: number | null): string;
417
739
  /**
418
740
  * Splits a paragraph at `(story, para_id, offset)` by inserting one
419
- * pilcrow. Under the S1 split the FIRST half keeps the original paraId and
420
- * the SECOND half is re-minted. Receipt:
741
+ * pilcrow. The FIRST half keeps the original paraId and the second is
742
+ * re-minted. A split at the paragraph end leaves the empty second half
743
+ * with only the inherited property subset; a mid-paragraph split keeps
744
+ * its properties. Paragraph borders are cleared either way. Suggesting
745
+ * mode stamps the new pilcrow `ins` and `pPrIns`. Receipt:
421
746
  * `{"firstParaId","secondParaId","revisionId": string|null}`.
422
747
  */
423
748
  split_paragraph(story: string, para_id: string, offset: number, author_name?: string | null, author_date?: string | null): string;
749
+ /**
750
+ * Starts queueing committed transactions for
751
+ * [`EditSession::drain_update_event`] instead of pushing them through a
752
+ * callback. Idempotent while observation is running.
753
+ */
424
754
  start_update_event_observation(): void;
425
755
  /**
426
- * The story's `canonical-stream-v1` FNV-1a checksum as a decimal string
427
- * (u64 exceeds JS safe-integer range). The coexistence watchdog compares
428
- * this against the PM projector's checksum after every mirrored edit.
756
+ * The story's `canonical-stream-v1` FNV-1a checksum (see
757
+ * [`crate::canonical`]) as a DECIMAL STRING, because a u64 exceeds the
758
+ * JavaScript safe-integer range. Two stories with the same authored
759
+ * content share a checksum even when their paragraph and comment ids
760
+ * differ. Errors on an unknown story.
429
761
  */
430
762
  story_checksum(story: string): string;
431
763
  /**
432
- * Story ids currently in the document, sorted for determinism.
764
+ * Every story id in the document, sorted so the order is stable across
765
+ * replicas.
433
766
  */
434
767
  story_ids(): string[];
435
768
  /**
436
- * Story length in UTF-16 units (every embed, pilcrows included, = 1).
769
+ * Story length in UTF-16 units, every embed (pilcrows included) counting
770
+ * as one. Errors on an unknown story.
437
771
  */
438
772
  story_len(story: string): number;
439
773
  /**
440
- * The raw formatted-segment view (the render bridge's input):
441
- * `[{"kind":"text","text",…} | {"kind":"pilcrow","paraId","properties",…}
442
- * | {"kind":"embed",…}]`, each with `"attributes"` (run marks plus
443
- * `ins`/`del` revision values).
774
+ * The story as an ordered run of formatted segments — the same view
775
+ * lowering reads:
776
+ *
777
+ * - `{"kind":"text","text","attributes"}`
778
+ * - `{"kind":"pilcrow","paraId","properties","attributes"}`
779
+ * - `{"kind":"embed","embedKind","payload","attributes"}`
780
+ *
781
+ * A text segment covers one maximal run of identically formatted
782
+ * characters; each pilcrow and embed is its own segment worth one unit.
783
+ * `attributes` holds the segment's run marks together with any `ins`/`del`
784
+ * tracked-change stamps. Errors on an unknown story.
444
785
  */
445
786
  story_segments(story: string): string;
446
787
  /**
447
- * Applies one run mark over `[start, end)` (two Locs in one story). Simple
448
- * marks toggle; font/size/color set (see [`apply_mark`]). `mark_json`:
788
+ * Applies one run mark over `[start, end)`. `mark_json`:
449
789
  * `{"type":"bold"|"italic"|"underline"|"strike"|"superscript"|"subscript"} |
450
790
  * {"type":"fontFamily"|"color","value":string} |
451
- * {"type":"fontSize","value":number}`.
791
+ * {"type":"fontSize","value":number}`. The six boolean types TOGGLE —
792
+ * they turn on unless the whole range already carries the mark — while
793
+ * font family, size and color SET. Formatting is always a plain local
794
+ * edit, never a tracked change, so there is no receipt. Errors on an
795
+ * unknown `"type"` or a missing/mistyped `"value"`.
452
796
  */
453
797
  toggle_mark(story: string, start_para: string, start_offset: number, end_para: string, end_offset: number, mark_json: string): void;
454
798
  /**
455
- * Starts local undo tracking for a structural table transaction. Besides
456
- * the parent story (which owns the table embed), the stories root must be
457
- * in scope so undo/redo also removes/restores cell-story map entries.
458
- */
459
- track_table_undo(story: string): void;
460
- /**
461
- * Starts local-origin undo tracking for one story. Hosts call this lazily
462
- * after import/seeding but before the first direct input operation, so the
463
- * initial document is not an undo step.
799
+ * Starts local-origin undo tracking across every story. Call this after
800
+ * import or seeding but before the first edit, so the initial document is
801
+ * not an undo step; later calls keep the history.
464
802
  */
465
- track_undo(story: string): void;
803
+ track_undo(): void;
466
804
  /**
467
- * Reverts the latest local-origin transaction. Remote/system mirror
468
- * transactions are excluded by `DocUndoManager`'s tracked-origin policy.
805
+ * Reverts the latest local-origin step and reports whether anything was
806
+ * reverted. Remote and system transactions are excluded by the manager's
807
+ * tracked-origin policy; `false` before tracking starts.
469
808
  */
470
809
  undo(): boolean;
471
810
  /**
472
- * Current local undo stack size. Zero before a story starts tracking.
473
- */
474
- undo_depth(): number;
475
- /**
476
- * Lowers a story through the resident Rust bridge. Errors with an
477
- * unsupported-embed message on any non-native content until that class is
478
- * promoted to native.
479
- * `env_json` carries theme colors, the default tab stop, and list numeric
480
- * ids (see [`parse_render_env`]).
811
+ * Lowers one story to a `LayoutBlock[]` JSON array — the block, run and
812
+ * table vocabulary the layout engine consumes. `env_json` supplies the
813
+ * document-level values lowering cannot read off the story:
814
+ * `{"themeColors":{slot: hex},"defaultTabStopTwips":number|null,
815
+ * "pageContentHeight":number|null,"numericIds":{yrsId: number},
816
+ * "tocStyleIds":[styleId],"showHiddenText":bool,
817
+ * "defaultParagraphStyleId":string}`, all
818
+ * optional. Errors when the story does not end in a pilcrow, holds a
819
+ * malformed table, references itself through a cell story, or contains an
820
+ * embed lowering does not support.
481
821
  */
482
822
  yrs_blocks_for_story(story: string, env_json: string): string;
483
823
  }