@betteroffice/docx 0.2.0 → 0.3.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 (69) hide show
  1. package/README.md +522 -3
  2. package/dist/{chunk-JHJLG4I6.mjs → chunk-5B4VMUXM.mjs} +1 -1
  3. package/dist/chunk-5JEQC76K.mjs +1 -0
  4. package/dist/chunk-7GJG6LLU.mjs +1 -0
  5. package/dist/chunk-FE6FWGBJ.mjs +1 -0
  6. package/dist/chunk-H5YYCN42.mjs +1 -0
  7. package/dist/chunk-NT2OYIJ4.mjs +57 -0
  8. package/dist/chunk-QE4ZDRKV.mjs +1 -0
  9. package/dist/chunk-VQXNED2P.mjs +2 -0
  10. package/dist/chunk-Z4HZIPBS.mjs +1 -0
  11. package/dist/collaboration/index.d.mts +8 -6
  12. package/dist/compareDocx-XXTZV4CG.mjs +1 -0
  13. package/dist/computeLayout-LWLAJWYA.mjs +1 -0
  14. package/dist/{content-CvEtPl0c.d.mts → content-BzoC6bSz.d.mts} +48 -8
  15. package/dist/core.d.mts +172 -9
  16. package/dist/core.mjs +1 -1
  17. package/dist/{displayListQueries-DF8F6fMl.d.mts → displayListQueries-BYFrBkw5.d.mts} +2 -2
  18. package/dist/docx/index.d.mts +5 -4
  19. package/dist/docx/index.mjs +1 -1
  20. package/dist/editor/index.d.mts +10 -8
  21. package/dist/editor/index.mjs +1 -1
  22. package/dist/{fontLoader-b8eicJKV.d.mts → fontLoader-CkXcPB1C.d.mts} +1 -1
  23. package/dist/{formatting-7zKCTu5a.d.mts → formatting-gqLFeJ9X.d.mts} +8 -0
  24. package/dist/{frameDelta-pA4jrQ1G.d.mts → frameDelta-CVt5FAXT.d.mts} +14 -3
  25. package/dist/generated/edit/docx_edit_bg.wasm +0 -0
  26. package/dist/generated/layout/docx_layout_bg.wasm +0 -0
  27. package/dist/generated/opc/ooxml_opc_bg.wasm +0 -0
  28. package/dist/generated/parse/docx_parse_bg.wasm +0 -0
  29. package/dist/{index-CHl2zLJ7.d.mts → index-BbZwdkPz.d.mts} +457 -29
  30. package/dist/layout/index.d.mts +6 -6
  31. package/dist/layout/index.mjs +1 -1
  32. package/dist/layout/pagination/index.d.mts +4 -4
  33. package/dist/layout/render/index.d.mts +12 -10
  34. package/dist/layout/render/index.mjs +1 -1
  35. package/dist/pagedExport-D3E4jZ-B.d.mts +907 -0
  36. package/dist/plugin-api/RenderedDomContext.d.mts +10 -9
  37. package/dist/plugin-api/RenderedDomContext.mjs +1 -1
  38. package/dist/plugin-api/index.d.mts +21 -4
  39. package/dist/plugin-api/resolveItemPositions.d.mts +3 -3
  40. package/dist/rezip-Bxiq4Z_R.d.mts +24 -0
  41. package/dist/{rustDisplayList-BJqaN9tt.d.mts → rustDisplayList-CwOoUn3t.d.mts} +2 -2
  42. package/dist/{rustMeasureSource-C0EZB055.d.mts → rustMeasureSource-CyBMcy1x.d.mts} +12 -4
  43. package/dist/{selectiveSave-CRh-_Y_C.d.mts → selectiveSave-r-NMK6aI.d.mts} +1 -22
  44. package/dist/styles/index.d.mts +2 -2
  45. package/dist/{styles-7e-mq3c-.d.mts → styles-AryxLAhx.d.mts} +1 -1
  46. package/dist/types/content.d.mts +2 -2
  47. package/dist/types/document.d.mts +6 -6
  48. package/dist/{types-C4A8mWjU.d.mts → types-B4jD0rrc.d.mts} +19 -2
  49. package/dist/utils/comments.d.mts +2 -2
  50. package/dist/utils/index.d.mts +7 -4
  51. package/dist/utils/index.mjs +1 -1
  52. package/dist/utils/stylePreview.d.mts +2 -2
  53. package/dist/wasm-G62X4WRW.mjs +1 -0
  54. package/dist/wasm-US6R7SWN.mjs +1 -0
  55. package/dist/wasm-edit.d.mts +246 -13
  56. package/dist/wasm-edit.mjs +1 -1
  57. package/dist/wasm-layout.d.mts +8 -1
  58. package/dist/wasm-layout.mjs +1 -1
  59. package/dist/yrs/index.d.mts +7 -5
  60. package/dist/yrs/index.mjs +1 -1
  61. package/dist/yrs/residentEngineWorker.mjs +1 -1
  62. package/package.json +2 -2
  63. package/dist/chunk-6LQJAKOC.mjs +0 -1
  64. package/dist/chunk-AFMVSI4Z.mjs +0 -57
  65. package/dist/chunk-GD4VNJ64.mjs +0 -1
  66. package/dist/chunk-WRWRCBLK.mjs +0 -1
  67. package/dist/chunk-WTFRNX5K.mjs +0 -1
  68. package/dist/wasm-7SOSHNGP.mjs +0 -1
  69. package/dist/wasm-ZQAVP7P2.mjs +0 -1
@@ -0,0 +1,907 @@
1
+ /**
2
+ * Result envelopes shared by the formats' host edit APIs. Targets, steps, receipts and failure
3
+ * codes stay format-owned; these shapes only fix how every format reports success and refusal.
4
+ */
5
+ /** Why a host operation was refused, as data. The document is unchanged. */
6
+ interface OperationFailure<Code extends string, Target> {
7
+ code: Code;
8
+ /** The request step that failed, when one did. */
9
+ stepIndex?: number;
10
+ /** The earlier step an `overlapping-steps` failure conflicts with. */
11
+ conflictingStepIndex?: number;
12
+ /** The failing step's target as requested or resolved. */
13
+ target?: Target;
14
+ message: string;
15
+ }
16
+ /** A policy refusal carrying the version the document is still at. */
17
+ interface OperationRefusal<Failure> {
18
+ ok: false;
19
+ version: string;
20
+ failure: Failure;
21
+ }
22
+ /**
23
+ * An accepted edit request. `applied` is false when every step was a no-op; the version then
24
+ * stays `baseVersion` and no history or change notification was produced.
25
+ */
26
+ interface EditSuccess<Receipt> {
27
+ ok: true;
28
+ baseVersion: string;
29
+ version: string;
30
+ applied: boolean;
31
+ /** One receipt per request step, in request order. */
32
+ receipts: Receipt[];
33
+ }
34
+ /** A validated edit request. Validation reserves nothing and cannot be committed later. */
35
+ interface ValidationSuccess<Preview> {
36
+ ok: true;
37
+ baseVersion: string;
38
+ wouldApply: boolean;
39
+ previews: Preview[];
40
+ }
41
+
42
+ /**
43
+ * Shapes shared by the formats' read-only structured exports. Content trees, anchors, story or
44
+ * sheet selectors, diagnostic codes and limits stay format-owned; these only fix how every format
45
+ * reports diagnostics, truncation and Markdown markers.
46
+ */
47
+ type ExportSeverity = 'info' | 'warning' | 'error';
48
+ /** Something an export omitted or could not represent, anchored where it applies. */
49
+ interface ExportDiagnostic<Code extends string, Anchor> {
50
+ code: Code;
51
+ severity: ExportSeverity;
52
+ anchor: Anchor | null;
53
+ message: string;
54
+ }
55
+ /** Whether an export stopped at its limits before the end of the content. */
56
+ interface ExportCompletion {
57
+ truncated: boolean;
58
+ }
59
+ /** A Markdown marker comment and the anchor of the content it precedes. */
60
+ interface MarkdownAnchor<Anchor> {
61
+ marker: string;
62
+ anchor: Anchor;
63
+ }
64
+
65
+ /**
66
+ * Read types shared by the DOCX read APIs: where read content lives, which stories a read
67
+ * covers, heading classification and content-control metadata. Plain JSON, produced by Rust.
68
+ */
69
+
70
+ /**
71
+ * Where a piece of read content lives. Paragraph, range, table and control anchors resolve
72
+ * against the version or snapshot they were read at; table indices and control ids are not stable
73
+ * across saves. A `sourcePart` anchor addresses retained source XML (the part, its SHA-256 and
74
+ * zero-based element-child ordinals from the part's root); it is provenance, not an edit target.
75
+ * An `unlocated` anchor marks content of `story` with no location of its own, and says why.
76
+ */
77
+ type DocxAnchor = {
78
+ kind: 'paragraph';
79
+ story: string;
80
+ paraId: string;
81
+ } | ({
82
+ kind: 'range';
83
+ } & DocxTextRange) | {
84
+ kind: 'table';
85
+ story: string;
86
+ tableIndex: number;
87
+ } | {
88
+ kind: 'control';
89
+ story: string;
90
+ controlId: string;
91
+ } | {
92
+ kind: 'sourcePart';
93
+ part: string;
94
+ partSha256: string;
95
+ path: number[];
96
+ } | {
97
+ kind: 'unlocated';
98
+ story: string;
99
+ reason: DocxUnlocatedReason;
100
+ };
101
+ /**
102
+ * Why content has no location: another paragraph of the story carries the same id, the story is
103
+ * too large to read within `maxBytes` or does not exist, or content the editing stream leaves out
104
+ * can no longer be found in its source XML.
105
+ */
106
+ type DocxUnlocatedReason = 'duplicate-paragraph-id' | 'story-too-large' | 'missing-story' | 'provenance-unavailable';
107
+ /** A category of stories a read covers. */
108
+ type DocxStorySelection = 'body' | 'headers' | 'footers' | 'footnotes' | 'endnotes' | 'comments';
109
+ /**
110
+ * A content control's identity and properties. `controlId` is the engine identity, distinct from
111
+ * the authored `w:id` (`ooxmlId`), tag and alias, none of which need be unique.
112
+ */
113
+ interface DocxControlMetadata {
114
+ controlId: string;
115
+ ooxmlId: string | null;
116
+ controlType: string;
117
+ tag: string | null;
118
+ alias: string | null;
119
+ lock: string | null;
120
+ showingPlaceholder: boolean;
121
+ dataBound: boolean;
122
+ }
123
+ /**
124
+ * A zero-based outline level (0..8). Direct formatting wins, then the paragraph style with
125
+ * inheritance, then document defaults; only without any of them does a `HeadingN` style id count.
126
+ */
127
+ interface DocxHeadingInfo {
128
+ outlineLevel: number;
129
+ source: {
130
+ kind: 'direct';
131
+ } | {
132
+ kind: 'style';
133
+ styleId: string;
134
+ } | {
135
+ kind: 'documentDefault';
136
+ } | {
137
+ kind: 'builtinStyleId';
138
+ styleId: string;
139
+ };
140
+ }
141
+ /** A heading paragraph of a story. */
142
+ interface DocxParagraphHeading {
143
+ paraId: string;
144
+ heading: DocxHeadingInfo;
145
+ }
146
+
147
+ /**
148
+ * Read-only structured export of DOCX content: ordered stories of typed blocks and inlines, each
149
+ * with the location it was read from, and diagnostics for everything omitted or unrepresentable.
150
+ * Plain JSON, produced by one Rust walker for sessions, bytes and the native facade.
151
+ *
152
+ * Text, tab and atom inlines carry `range` anchors into the projected text of their view (the
153
+ * batch projection: tabs are `\t`, every other atom one U+FFFC). In the markup view inserted and
154
+ * unchanged text use accepted-view ranges and deleted text original-view ranges. Children of an
155
+ * atom carry the atom's or control's anchor. Ids are deterministic export-tree paths.
156
+ */
157
+
158
+ type DocxRevisionView = 'accepted' | 'original' | 'markup';
159
+ /** `session` anchors resolve against the returned version; `snapshot` ones against the content. */
160
+ type DocxAnchorScope = 'session' | 'snapshot';
161
+ type DocxStoryKind = 'body' | 'header' | 'footer' | 'footnote' | 'endnote' | 'comment';
162
+ interface DocxStructuredContent extends ExportCompletion {
163
+ schemaVersion: 1;
164
+ revisionView: DocxRevisionView;
165
+ anchorScope: DocxAnchorScope;
166
+ includedStories: DocxStorySelection[];
167
+ includeFormatting: boolean;
168
+ stories: DocxExportStory[];
169
+ diagnostics: DocxExportDiagnostic[];
170
+ }
171
+ /** One story. Table cells and block controls nest inside the blocks that own them. */
172
+ interface DocxExportStory {
173
+ story: string;
174
+ kind: DocxStoryKind;
175
+ part: string | null;
176
+ noteId: string | null;
177
+ comment: DocxCommentMetadata | null;
178
+ /** The sections referencing a header or footer part, inheritance applied. */
179
+ uses: Array<{
180
+ sectionIndex: number;
181
+ variant: 'default' | 'first' | 'even';
182
+ }>;
183
+ blocks: DocxExportBlock[];
184
+ }
185
+ interface DocxCommentMetadata {
186
+ id: string;
187
+ author: string | null;
188
+ date: string | null;
189
+ parentId: string | null;
190
+ resolved: boolean;
191
+ /** The ranges the comment annotates. */
192
+ anchors: DocxAnchor[];
193
+ }
194
+ interface DocxParagraphData {
195
+ styleId: string | null;
196
+ inlines: DocxExportInline[];
197
+ }
198
+ /** `format` is the OOXML numbering format; `marker` the rendered marker, `null` if unresolved. */
199
+ interface DocxListInfo {
200
+ numId: string;
201
+ abstractNumId: string | null;
202
+ level: number;
203
+ format: string;
204
+ marker: string | null;
205
+ suffix: 'tab' | 'space' | 'nothing';
206
+ markerHidden: boolean;
207
+ }
208
+ type DocxExportBlock = {
209
+ id: string;
210
+ anchor: DocxAnchor;
211
+ } & ({
212
+ kind: 'paragraph';
213
+ paragraph: DocxParagraphData;
214
+ } | {
215
+ kind: 'heading';
216
+ paragraph: DocxParagraphData;
217
+ heading: DocxHeadingInfo;
218
+ }
219
+ /** A numbered heading is a list item with a heading. */
220
+ | {
221
+ kind: 'listItem';
222
+ paragraph: DocxParagraphData;
223
+ list: DocxListInfo;
224
+ heading: DocxHeadingInfo | null;
225
+ } | {
226
+ kind: 'table';
227
+ table: DocxExportTable;
228
+ } | {
229
+ kind: 'contentControl';
230
+ control: DocxControlMetadata;
231
+ story: string | null;
232
+ blocks: DocxExportBlock[];
233
+ }
234
+ /** The break that starts section `sectionIndex`, typed by that section's start. */
235
+ | {
236
+ kind: 'sectionBreak';
237
+ sectionIndex: number;
238
+ breakType: 'continuous' | 'nextPage' | 'nextColumn' | 'oddPage' | 'evenPage';
239
+ }
240
+ /** A page or column break between blocks. */
241
+ | {
242
+ kind: 'break';
243
+ breakType: 'page' | 'column';
244
+ } | {
245
+ kind: 'unsupported';
246
+ element: string;
247
+ });
248
+ /**
249
+ * A table on its zero-based grid. Every covered grid position of a row appears once, as a cell
250
+ * owning content or as a vertical-merge continuation (`rowSpan: 0`) naming its origin.
251
+ */
252
+ interface DocxExportTable {
253
+ gridColumns: number;
254
+ rows: Array<{
255
+ header: boolean;
256
+ gridBefore: number;
257
+ gridAfter: number;
258
+ cells: DocxExportCell[];
259
+ }>;
260
+ }
261
+ interface DocxExportCell {
262
+ anchor: DocxAnchor;
263
+ story: string | null;
264
+ column: number;
265
+ gridSpan: number;
266
+ rowSpan: number;
267
+ verticalMerge: 'none' | 'restart' | 'continue';
268
+ mergeOrigin: {
269
+ row: number;
270
+ column: number;
271
+ } | null;
272
+ blocks: DocxExportBlock[];
273
+ }
274
+ type DocxExportInline = {
275
+ id: string;
276
+ anchor: DocxAnchor;
277
+ /** `null` when the export excludes formatting. */
278
+ marks: DocxFormattingMark[] | null;
279
+ link: {
280
+ href: string;
281
+ title: string | null;
282
+ } | null;
283
+ /** Revision attribution; only the markup view carries any. */
284
+ revisions: DocxInlineRevision[];
285
+ } & ({
286
+ kind: 'text';
287
+ text: string;
288
+ } | {
289
+ kind: 'tab';
290
+ } | {
291
+ kind: 'break';
292
+ breakType: 'line' | 'page' | 'column';
293
+ } | {
294
+ kind: 'noteReference';
295
+ noteKind: 'footnote' | 'endnote';
296
+ noteId: string;
297
+ story: string | null;
298
+ } | {
299
+ kind: 'commentReference';
300
+ commentId: string;
301
+ story: string | null;
302
+ }
303
+ /** A field with its cached result; never evaluated. */
304
+ | {
305
+ kind: 'field';
306
+ fieldType: string;
307
+ instruction: string;
308
+ cachedResult: DocxCachedResult;
309
+ dirty: boolean;
310
+ locked: boolean;
311
+ } | {
312
+ kind: 'image';
313
+ altText: string | null;
314
+ relationshipId: string | null;
315
+ part: string | null;
316
+ externalTarget: string | null;
317
+ } | {
318
+ kind: 'contentControl';
319
+ control: DocxControlMetadata;
320
+ inlines: DocxExportInline[];
321
+ } | {
322
+ kind: 'unsupported';
323
+ element: string;
324
+ altText: string | null;
325
+ });
326
+ type DocxCachedResult = {
327
+ kind: 'missing';
328
+ } | {
329
+ kind: 'inline';
330
+ inlines: DocxExportInline[];
331
+ } | {
332
+ kind: 'blocks';
333
+ blocks: DocxExportBlock[];
334
+ };
335
+ type DocxFormattingMark = {
336
+ kind: 'bold' | 'italic' | 'strike' | 'subscript' | 'superscript' | 'hidden';
337
+ } | {
338
+ kind: 'underline';
339
+ style: string;
340
+ };
341
+ interface DocxInlineRevision {
342
+ kind: 'insertion' | 'deletion' | 'moveFrom' | 'moveTo';
343
+ id: string | null;
344
+ author: string | null;
345
+ date: string | null;
346
+ }
347
+ type DocxExportDiagnosticCode = 'unsupported-content' | 'unsupported-revision' | 'unsupported-numbering' | 'unresolved-style' | 'unresolved-reference' | 'provenance-unavailable' | 'ambiguous-identity' | 'image-data-omitted' | 'field-cached-result' | 'missing-field-result' | 'formatting-omitted' | 'stories-omitted' | 'revision-content-excluded' | 'merge-continuation-content-omitted' | 'legacy-control-value' | 'parse-warning' | 'truncated' | 'markdown-lossy';
348
+ type DocxExportDiagnostic = ExportDiagnostic<DocxExportDiagnosticCode, DocxAnchor>;
349
+ /**
350
+ * What to export. `revisionView` is required; `stories` defaults to `['body']`,
351
+ * `includeFormatting` to `true`, `maxBlocks` to 10,000 (at most 1,000,000; every nested block
352
+ * counts) and `maxBytes` to 8,388,608 (1,024 to 67,108,864, measured on the compact JSON).
353
+ */
354
+ interface DocxExportOptions {
355
+ revisionView: DocxRevisionView;
356
+ stories?: readonly DocxStorySelection[];
357
+ includeFormatting?: boolean;
358
+ maxBlocks?: number;
359
+ maxBytes?: number;
360
+ }
361
+ /** `maxBytes` bounds the Markdown text; the default and range are the export's. */
362
+ interface DocxMarkdownOptions {
363
+ maxBytes?: number;
364
+ }
365
+ /**
366
+ * Markdown rendered from structured content. Each `<!-- docx-export:N -->` marker precedes the
367
+ * block `anchors` maps it to. Markdown keeps no Word pagination, typography or layout.
368
+ */
369
+ interface DocxMarkdownContent extends ExportCompletion {
370
+ markdown: string;
371
+ anchors: MarkdownAnchor<DocxAnchor>[];
372
+ diagnostics: DocxExportDiagnostic[];
373
+ }
374
+ /**
375
+ * Options out of range or above a hard maximum, or a session holding no document content.
376
+ * Unsupported document content is diagnosed, never refused. A paged export also refuses a
377
+ * layout older than the document (`stale-document`), one whose fonts, options or named version
378
+ * changed (`stale-layout`), no retained or measurable layout (`layout-unavailable`), a revision
379
+ * view the markup pages do not show (`unsupported-revision-layout`) and notes that did not
380
+ * settle (`layout-not-converged`).
381
+ */
382
+ type DocxExportFailureCode = 'invalid-options' | 'limit-exceeded' | 'unsupported' | 'stale-document' | 'stale-layout' | 'layout-unavailable' | 'unsupported-revision-layout' | 'layout-not-converged';
383
+ /** Why an export was refused; `target` is the anchor the refusal concerns, if any. */
384
+ interface DocxExportFailure {
385
+ code: DocxExportFailureCode;
386
+ target: DocxAnchor | null;
387
+ message: string;
388
+ }
389
+ type DocxExportRefusal = OperationRefusal<DocxExportFailure>;
390
+ /** A session export: the content with the version it was read at, or a refusal. */
391
+ type DocxExportResult<T> = {
392
+ ok: true;
393
+ version: string;
394
+ content: T;
395
+ } | DocxExportRefusal;
396
+
397
+ /**
398
+ * Content-control discovery: every control of a document in document order, with the metadata the
399
+ * structured export reports, its canonical text, placement, anchor, nesting and effective lock.
400
+ * Plain JSON, produced by one Rust inventory for sessions, bytes, the native facade and Python.
401
+ *
402
+ * `controlId` is an opaque engine locator scoped to the version (or snapshot) it was read at; it
403
+ * does not survive save and reopen. An inline control's id can name a different control after
404
+ * edits, so list again after a version change or select by tag or `ooxmlId`. Fill controls with a
405
+ * `setContentControlText` edit step; concurrent fills from collaborators resolve last-writer-wins
406
+ * for an inline control and merge like concurrent typing for a block control.
407
+ */
408
+
409
+ /**
410
+ * A control's canonical displayed text: tabs stay tabs, line breaks and paragraph boundaries read
411
+ * as LF. `unavailable` when the content has no faithful text projection or the session cannot
412
+ * read it.
413
+ */
414
+ type DocxContentControlValue = {
415
+ kind: 'text';
416
+ text: string;
417
+ } | {
418
+ kind: 'unavailable';
419
+ reason: 'non-text-content' | 'tracked-revisions' | 'provenance-unavailable' | 'unsupported-story';
420
+ };
421
+ /**
422
+ * One content control. `lock` is the control's own authored lock; `effectiveLock` combines it
423
+ * with every control containing it, and `known` is false when any of them carries a lock value
424
+ * the engine does not know.
425
+ */
426
+ interface DocxContentControl extends DocxControlMetadata {
427
+ placement: 'inline' | 'block';
428
+ anchor: DocxAnchor;
429
+ parentControlId: string | null;
430
+ value: DocxContentControlValue;
431
+ /** Whether a plain-text control accepts line breaks (`w:multiLine`); `null` for other types. */
432
+ multiLine: boolean | null;
433
+ effectiveLock: {
434
+ content: boolean;
435
+ control: boolean;
436
+ known: boolean;
437
+ };
438
+ }
439
+ /**
440
+ * What to list. `stories` defaults to every category, `maxControls` to 10,000 (at most
441
+ * 1,000,000) and `maxBytes` to 8,388,608 (1,024 to 67,108,864, measured on the compact JSON).
442
+ * Exceeding a limit refuses with `limit-exceeded` rather than returning a prefix.
443
+ */
444
+ interface DocxContentControlsOptions {
445
+ stories?: readonly DocxStorySelection[];
446
+ maxControls?: number;
447
+ maxBytes?: number;
448
+ }
449
+ /**
450
+ * The control a write addresses. `controlId` is the engine locator for the version it was read
451
+ * at; `tag` is the template author's name; `ooxmlId` is the authored `w:id` as listings report it,
452
+ * which survives save and reopen. A tag or `ooxmlId` must be carried by exactly one control of the
453
+ * whole document.
454
+ */
455
+ type DocxContentControlSelector = {
456
+ kind: 'id';
457
+ controlId: string;
458
+ } | {
459
+ kind: 'tag';
460
+ tag: string;
461
+ } | {
462
+ kind: 'ooxmlId';
463
+ ooxmlId: string;
464
+ };
465
+ /** Which controls a find returns: every exact, case-sensitive match, none trimmed. */
466
+ type DocxContentControlQuery = DocxContentControlSelector | {
467
+ kind: 'alias';
468
+ alias: string;
469
+ };
470
+ type DocxContentControlDiagnostic = ExportDiagnostic<DocxExportDiagnosticCode, DocxAnchor>;
471
+ /**
472
+ * The controls of a document in document order: body, headers, footers, footnotes, endnotes,
473
+ * comments, each control before its descendants. `complete` is false when diagnostics name a
474
+ * coverage gap. Controls kept only as source XML (raw blocks, comment bodies) are never writable;
475
+ * they carry `sourcePart` anchors while the package holds their current XML, and a raw block
476
+ * changed since opening anchors its controls to the block instead.
477
+ */
478
+ interface DocxContentControlsSnapshot {
479
+ schemaVersion: 1;
480
+ anchorScope: 'session' | 'snapshot';
481
+ includedStories: DocxStorySelection[];
482
+ controls: DocxContentControl[];
483
+ complete: boolean;
484
+ diagnostics: DocxContentControlDiagnostic[];
485
+ }
486
+ /** Options out of range or above a hard maximum, or a session holding no document content. */
487
+ type DocxContentControlReadFailure = DocxExportFailure;
488
+ /** A session read: the controls with the version they were read at, or a refusal. */
489
+ type DocxContentControlsResult = {
490
+ ok: true;
491
+ version: string;
492
+ content: DocxContentControlsSnapshot;
493
+ } | OperationRefusal<DocxContentControlReadFailure>;
494
+
495
+ /**
496
+ * Versioned reads and version-checked edit batches over one DOCX session. Every shape here is
497
+ * plain JSON so it can cross a worker boundary unchanged; the semantics live in Rust.
498
+ *
499
+ * Offsets are half-open UTF-16 positions into a paragraph's projected text. Each inline atom
500
+ * (hard break, image, content control, note reference, field or other embed) occupies one
501
+ * U+FFFC, tabs stay `\t`, and paragraph marks are not part of the text. The accepted view shows
502
+ * pending insertions and hides pending deletions; the original view does the reverse.
503
+ */
504
+
505
+ type DocxTextView = 'accepted' | 'original';
506
+ /** Provenance only: history and revision authorship are chosen separately. */
507
+ type DocxEditSource = 'host' | 'agent';
508
+ /** `separate`: exactly one undo step. `none`: outside undo history, keeping existing entries. */
509
+ type DocxEditHistory = 'separate' | 'none';
510
+ interface DocxParagraphTarget {
511
+ story: string;
512
+ paraId: string;
513
+ }
514
+ interface DocxTextPosition {
515
+ paraId: string;
516
+ offset: number;
517
+ }
518
+ interface DocxTextRange {
519
+ story: string;
520
+ start: DocxTextPosition;
521
+ end: DocxTextPosition;
522
+ view: DocxTextView;
523
+ }
524
+ type DocxSearchScope = {
525
+ kind: 'story';
526
+ story: string;
527
+ } | ({
528
+ kind: 'paragraph';
529
+ } & DocxParagraphTarget);
530
+ /**
531
+ * The text a step addresses: a paragraph's whole accepted text, an explicit range (both ends in
532
+ * one paragraph), or the one exact, case-sensitive, paragraph-local match of `text`.
533
+ */
534
+ type DocxTextTarget = ({
535
+ kind: 'paragraph';
536
+ } & DocxParagraphTarget) | ({
537
+ kind: 'range';
538
+ } & DocxTextRange) | {
539
+ kind: 'search';
540
+ text: string;
541
+ within: DocxSearchScope;
542
+ view: DocxTextView;
543
+ };
544
+ type DocxEditTarget = DocxTextTarget | {
545
+ kind: 'paragraphs';
546
+ story: string;
547
+ firstParaId: string;
548
+ lastParaId: string;
549
+ } | {
550
+ kind: 'contentControl';
551
+ selector: DocxContentControlSelector;
552
+ };
553
+ /** Refuses the step unless its target currently reads exactly `text`. */
554
+ interface DocxEditGuard {
555
+ text: string;
556
+ }
557
+ /** Records a text step as a tracked change with host-supplied authorship. */
558
+ interface DocxEditSuggestion {
559
+ author: string;
560
+ date: string;
561
+ }
562
+ /** One new paragraph; without `styleId` it takes the anchor paragraph's style. */
563
+ interface DocxParagraphInput {
564
+ text: string;
565
+ styleId?: string;
566
+ }
567
+ type DocxEditOperation = {
568
+ op: 'insertText';
569
+ target: DocxTextTarget;
570
+ at: 'start' | 'end';
571
+ text: string;
572
+ } | {
573
+ op: 'replaceText';
574
+ target: DocxTextTarget;
575
+ text: string;
576
+ } | {
577
+ op: 'deleteText';
578
+ target: DocxTextTarget;
579
+ } | {
580
+ op: 'insertParagraphs';
581
+ target: DocxParagraphTarget;
582
+ at: 'start' | 'end';
583
+ paragraphs: readonly DocxParagraphInput[];
584
+ } | {
585
+ op: 'deleteParagraphs';
586
+ story: string;
587
+ firstParaId: string;
588
+ lastParaId: string;
589
+ } | {
590
+ op: 'setParagraphStyle';
591
+ target: DocxParagraphTarget;
592
+ styleId: string;
593
+ } | Omit<DocxSetContentControlTextStep, 'expect'>;
594
+ /**
595
+ * Replaces a plain- or rich-text content control's content with plain text and clears its
596
+ * placeholder state. CRLF becomes LF; LF is a line break (a paragraph break in a rich-text block
597
+ * control), and a plain-text control accepts it only with `w:multiLine`. The text takes the
598
+ * formatting of the control's first text run (a control showing its placeholder takes its own run
599
+ * properties). `expect` compares against the control's `value`; `suggest` is refused.
600
+ */
601
+ interface DocxSetContentControlTextStep {
602
+ op: 'setContentControlText';
603
+ target: DocxContentControlSelector;
604
+ text: string;
605
+ expect?: DocxEditGuard;
606
+ }
607
+ type DocxEditStep = (Exclude<DocxEditOperation, {
608
+ op: 'setContentControlText';
609
+ }> & {
610
+ expect?: DocxEditGuard;
611
+ suggest?: DocxEditSuggestion;
612
+ }) | DocxSetContentControlTextStep;
613
+ interface DocxEditRequest {
614
+ /** The version the targets were read at; a changed document refuses with `stale-version`. */
615
+ expectVersion: string;
616
+ /** Defaults to `host`. */
617
+ source?: DocxEditSource;
618
+ /** Defaults to `separate`. */
619
+ history?: DocxEditHistory;
620
+ steps: readonly DocxEditStep[];
621
+ }
622
+ /**
623
+ * `locked-target` is locked document content. `read-only` comes only from an editor host that
624
+ * does not accept edits, never from a session.
625
+ */
626
+ type DocxEditFailureCode = 'stale-version' | 'missing-target' | 'ambiguous-target' | 'content-mismatch' | 'overlapping-steps' | 'locked-target' | 'read-only' | 'tracked-revision-conflict' | 'unsupported' | 'invalid-step' | 'limit-exceeded';
627
+ /** Why a `setContentControlText` step was refused, beside its failure code. */
628
+ type DocxEditFailureReason = 'missing-control' | 'missing-tag' | 'ambiguous-tag' | 'ambiguous-control-id' | 'missing-ooxml-id' | 'ambiguous-ooxml-id' | 'content-locked' | 'bound-control' | 'unsupported-control-type' | 'unsupported-children' | 'nested-controls' | 'unknown-lock' | 'unsupported-suggestion' | 'provenance-unavailable' | 'unsupported-story' | 'multiline-not-allowed' | 'invalid-text';
629
+ type DocxEditFailure = OperationFailure<DocxEditFailureCode, DocxEditTarget> & {
630
+ reason?: DocxEditFailureReason;
631
+ };
632
+ /** The content control a step resolved to, and where it is. */
633
+ interface DocxResolvedControl {
634
+ controlId: string;
635
+ anchor: DocxAnchor;
636
+ }
637
+ type DocxEditRefusal = OperationRefusal<DocxEditFailure>;
638
+ /**
639
+ * What one step did. Ranges use the final accepted view; a deletion reports its collapsed
640
+ * boundary. `removedParagraphs` are historical ids, not anchors.
641
+ */
642
+ interface DocxEditReceipt {
643
+ stepIndex: number;
644
+ changed: boolean;
645
+ range?: DocxTextRange;
646
+ newParagraphs: DocxParagraphTarget[];
647
+ removedParagraphs: DocxParagraphTarget[];
648
+ revisionIds: string[];
649
+ control?: DocxResolvedControl;
650
+ }
651
+ /** What one step would do; it cannot be committed later. */
652
+ interface DocxEditPreview {
653
+ stepIndex: number;
654
+ target: DocxEditTarget;
655
+ wouldChange: boolean;
656
+ newParagraphCount: number;
657
+ wouldCreateRevisions: boolean;
658
+ control?: DocxResolvedControl;
659
+ }
660
+ type DocxEditResult = (EditSuccess<DocxEditReceipt> & {
661
+ source: DocxEditSource;
662
+ changedStories: string[];
663
+ }) | DocxEditRefusal;
664
+ type DocxValidationResult = ValidationSuccess<DocxEditPreview> | DocxEditRefusal;
665
+ type DocxAtomKind = 'lineBreak' | 'image' | 'contentControl' | 'noteReference' | 'field' | 'other';
666
+ /** One U+FFFC in projected text that stands for an inline atom. */
667
+ interface DocxTextAtom {
668
+ offset: number;
669
+ kind: DocxAtomKind;
670
+ }
671
+ interface DocxParagraphText {
672
+ story: string;
673
+ paraId: string;
674
+ text: string;
675
+ styleId?: string;
676
+ atoms: DocxTextAtom[];
677
+ }
678
+ interface DocxReadParagraphsRequest {
679
+ /** Defaults to `body`; child stories are never included implicitly. */
680
+ story?: string;
681
+ /** Restricts the read to these paragraphs, returned in story order. */
682
+ paraIds?: readonly string[];
683
+ view: DocxTextView;
684
+ }
685
+ type DocxReadParagraphsResult = {
686
+ ok: true;
687
+ version: string;
688
+ view: DocxTextView;
689
+ paragraphs: DocxParagraphText[];
690
+ } | DocxEditRefusal;
691
+ interface DocxFindTextRequest {
692
+ text: string;
693
+ within: DocxSearchScope;
694
+ view: DocxTextView;
695
+ /** Defaults to 100; at most 10,000. */
696
+ limit?: number;
697
+ }
698
+ /** One search hit; `range` is reusable as a `{ kind: 'range' }` target. */
699
+ interface DocxTextMatch {
700
+ text: string;
701
+ range: DocxTextRange;
702
+ }
703
+ type DocxFindTextResult = {
704
+ ok: true;
705
+ version: string;
706
+ matches: DocxTextMatch[];
707
+ truncated: boolean;
708
+ } | DocxEditRefusal;
709
+
710
+ /**
711
+ * Page fragments of a structured export: the physical page, region and story occurrence showing
712
+ * each exported block and inline, read from the layout the export was captured with. Plain JSON
713
+ * produced by the Rust engine; ordinary exports never lay anything out.
714
+ *
715
+ * Pages are counted physically from zero, blank parity fillers included; the displayed number and
716
+ * label follow the section's PAGE numbering and may restart, repeat or use Roman and letter
717
+ * formats. A header or footer part is exported once and has an occurrence on every page that
718
+ * shows it. Text slices use the export's paragraph-local ranges; an atom (field, control, image,
719
+ * note mark, break) is sliced whole, or marked `partial` when only part of its display content is
720
+ * on the page. Geometry, when requested, is in unzoomed CSS pixels (96 per inch) from the
721
+ * physical page's top-left corner.
722
+ */
723
+
724
+ /**
725
+ * A paged export's options: the export's, plus `includeGeometry` (default `false`),
726
+ * `expectLayoutVersion` (refused as `stale-layout` when the retained layout is another),
727
+ * `maxFragments` (default 100,000, at most 1,000,000) and `maxLayoutBytes` (the page map's own
728
+ * budget: default 8,388,608, 1,024 to 67,108,864).
729
+ */
730
+ interface DocxPageExportOptions extends DocxExportOptions {
731
+ includeGeometry?: boolean;
732
+ expectLayoutVersion?: string;
733
+ maxFragments?: number;
734
+ maxLayoutBytes?: number;
735
+ }
736
+ /** Structured content with the page map captured with it. */
737
+ interface DocxPagedStructuredContent<L> {
738
+ structured: DocxStructuredContent;
739
+ layout: L;
740
+ }
741
+ /** Markdown options for a paged export; `pageMarkers` defaults to `false`. */
742
+ interface DocxPageMarkdownOptions extends DocxMarkdownOptions {
743
+ pageMarkers?: boolean;
744
+ }
745
+ /**
746
+ * The page map of a session export. Its references describe the authoritative layout of
747
+ * `documentVersion` computed from the inputs `provenance` fingerprints; a later edit may
748
+ * supersede that layout before it is ever painted.
749
+ */
750
+ interface DocxLayoutMap extends DocxPageMapContent {
751
+ documentVersion: string;
752
+ layoutVersion: string;
753
+ provenance: DocxLayoutProvenance;
754
+ }
755
+ /** The page map of a bytes export: deterministic, with no session token. */
756
+ interface DocxSnapshotLayoutMap extends DocxPageMapContent {
757
+ snapshotFingerprint: string;
758
+ provenance: DocxSnapshotLayoutProvenance;
759
+ }
760
+ /**
761
+ * What both page maps hold. `exportFingerprint` identifies the structured content.
762
+ * `schemaVersion` versions the map on its own: additive fields keep it, and a change existing
763
+ * readers would misread bumps it.
764
+ */
765
+ interface DocxPageMapContent {
766
+ schemaVersion: 1;
767
+ exportFingerprint: string;
768
+ revisionView: DocxRevisionView;
769
+ /** Pages are laid out with revision markup. */
770
+ layoutRevisionView: 'markup';
771
+ pages: DocxExportPage[];
772
+ occurrences: DocxStoryOccurrence[];
773
+ fragments: DocxPageFragment[];
774
+ diagnostics: DocxPageDiagnostic[];
775
+ truncated: boolean;
776
+ }
777
+ interface DocxSnapshotLayoutProvenance {
778
+ engineVersion: string;
779
+ /** The fonts, fallback order and measurement defaults, by font content. */
780
+ fontSetFingerprint: string;
781
+ /** Sections, settings, notes, render environment and layout options. */
782
+ optionsFingerprint: string;
783
+ }
784
+ interface DocxLayoutProvenance extends DocxSnapshotLayoutProvenance {
785
+ layoutEpoch: string;
786
+ }
787
+ interface DocxExportPage {
788
+ pageIndex: number;
789
+ sectionIndex: number;
790
+ sectionPageIndex: number;
791
+ displayedNumber: number;
792
+ displayedLabel: string;
793
+ numberingFormat: string;
794
+ /** `fallback` when the format could not be written and the page is numbered in decimal. */
795
+ numberingStatus: 'resolved' | 'fallback';
796
+ parityFiller: boolean;
797
+ size: {
798
+ width: number;
799
+ height: number;
800
+ };
801
+ }
802
+ interface DocxStoryOccurrence {
803
+ id: string;
804
+ pageIndex: number;
805
+ story: string;
806
+ part: string | null;
807
+ sectionIndex: number | null;
808
+ region: {
809
+ kind: 'body';
810
+ } | {
811
+ kind: 'header' | 'footer';
812
+ variant: 'default' | 'first' | 'even';
813
+ } | {
814
+ kind: 'footnote' | 'endnote';
815
+ noteId: string;
816
+ placement: 'pageBottom' | 'beneathText' | 'sectionEnd' | 'documentEnd';
817
+ };
818
+ }
819
+ /** The part of one exported node (`nodeId`, in block `blockId`) one occurrence shows. */
820
+ interface DocxPageFragment {
821
+ id: string;
822
+ pageIndex: number;
823
+ occurrenceId: string;
824
+ nodeId: string;
825
+ blockId: string;
826
+ anchor: DocxAnchor;
827
+ slice: {
828
+ kind: 'text';
829
+ range: DocxTextRange;
830
+ } | {
831
+ kind: 'atom';
832
+ range: DocxTextRange | null;
833
+ coverage: 'whole' | 'partial';
834
+ } | {
835
+ kind: 'block';
836
+ } | {
837
+ kind: 'table';
838
+ rows: Array<{
839
+ rowIndex: number;
840
+ continuedFromPrevious: boolean;
841
+ continuedOnNext: boolean;
842
+ repeatedHeader: boolean;
843
+ }>;
844
+ };
845
+ continuedFromPrevious: boolean;
846
+ continuedOnNext: boolean;
847
+ repeatedTableHeader: boolean;
848
+ geometry: DocxFragmentGeometry | null;
849
+ }
850
+ interface DocxFragmentGeometry {
851
+ unit: 'cssPx';
852
+ origin: 'pageTopLeft';
853
+ rects: Array<{
854
+ x: number;
855
+ y: number;
856
+ width: number;
857
+ height: number;
858
+ }>;
859
+ }
860
+ interface DocxPageDiagnostic {
861
+ code: 'unmapped-content' | 'anchor-only' | 'not-laid-out' | 'unsupported-numbering' | 'unsupported-note-layout' | 'clipped-content' | 'geometry-unavailable' | 'truncated';
862
+ nodeId: string | null;
863
+ pageIndex: number | null;
864
+ message: string;
865
+ }
866
+ /** One font a headless layout may measure with. */
867
+ interface DocxHeadlessFont {
868
+ /** Names the font in `fontChains` and `defaultChain`. */
869
+ key: string;
870
+ /** TrueType or OpenType bytes, base64-encoded. */
871
+ data: string;
872
+ }
873
+ /**
874
+ * The fonts and options of a headless layout, plain JSON. Only these fonts are measured with;
875
+ * nothing is looked up on the system. A font requirement (`family|bold|italic`, family
876
+ * lowercase) takes the chain named by its key, else by its lowercase family, else
877
+ * `defaultChain`, in fallback order; one left with no font is not laid out, and the export is
878
+ * refused as `layout-unavailable`.
879
+ */
880
+ interface DocxHeadlessLayoutOptions {
881
+ fonts: readonly DocxHeadlessFont[];
882
+ fontChains?: Readonly<Record<string, readonly string[]>>;
883
+ defaultChain: readonly string[];
884
+ /**
885
+ * Text naming no font or size, measured and given its font chain in this family: default
886
+ * `Calibri` at 11 points.
887
+ */
888
+ measurementDefaults?: {
889
+ fontFamily?: string;
890
+ fontSize?: number;
891
+ };
892
+ /**
893
+ * How stories render: hidden text laid out (default `false`) and the default tab stop in
894
+ * twips (default the document's).
895
+ */
896
+ renderEnvironment?: {
897
+ showHiddenText?: boolean;
898
+ defaultTabStopTwips?: number;
899
+ };
900
+ /** Word layout compatibility options; default the document's settings. */
901
+ compatibility?: {
902
+ noLeading?: boolean;
903
+ doNotExpandShiftReturn?: boolean;
904
+ };
905
+ }
906
+
907
+ export type { DocxUnlocatedReason as $, DocxExportDiagnostic as A, DocxExportDiagnosticCode as B, DocxExportFailureCode as C, DocxExportFailure as D, DocxExportInline as E, DocxExportPage as F, DocxExportRefusal as G, DocxExportResult as H, DocxExportStory as I, DocxExportTable as J, DocxFormattingMark as K, DocxFragmentGeometry as L, DocxHeadingInfo as M, DocxHeadlessFont as N, DocxInlineRevision as O, DocxLayoutProvenance as P, DocxListInfo as Q, DocxPageDiagnostic as R, DocxPageFragment as S, DocxPageMapContent as T, DocxParagraphData as U, DocxParagraphHeading as V, DocxRevisionView as W, DocxSnapshotLayoutProvenance as X, DocxStoryKind as Y, DocxStoryOccurrence as Z, DocxStorySelection as _, DocxExportOptions as a, DocxReadParagraphsRequest as a0, DocxReadParagraphsResult as a1, DocxFindTextRequest as a2, DocxFindTextResult as a3, DocxEditRequest as a4, DocxValidationResult as a5, DocxEditResult as a6, DocxTextTarget as a7, DocxEditRefusal as a8, DocxAtomKind as a9, ValidationSuccess as aA, DocxEditFailure as aa, DocxEditFailureCode as ab, DocxEditFailureReason as ac, DocxEditGuard as ad, DocxEditHistory as ae, DocxEditOperation as af, DocxEditPreview as ag, DocxEditReceipt as ah, DocxEditSource as ai, DocxEditStep as aj, DocxEditSuggestion as ak, DocxEditTarget as al, DocxParagraphInput as am, DocxParagraphTarget as an, DocxParagraphText as ao, DocxResolvedControl as ap, DocxSearchScope as aq, DocxSetContentControlTextStep as ar, DocxTextAtom as as, DocxTextMatch as at, DocxTextPosition as au, DocxTextRange as av, DocxTextView as aw, EditSuccess as ax, OperationFailure as ay, OperationRefusal as az, DocxMarkdownContent as b, DocxStructuredContent as c, DocxPageExportOptions as d, DocxHeadlessLayoutOptions as e, DocxPagedStructuredContent as f, DocxSnapshotLayoutMap as g, DocxMarkdownOptions as h, DocxLayoutMap as i, DocxPageMarkdownOptions as j, DocxContentControlReadFailure as k, DocxContentControlQuery as l, DocxContentControlsOptions as m, DocxContentControlsSnapshot as n, DocxAnchor as o, DocxAnchorScope as p, DocxCachedResult as q, DocxCommentMetadata as r, DocxContentControl as s, DocxContentControlDiagnostic as t, DocxContentControlSelector as u, DocxContentControlValue as v, DocxContentControlsResult as w, DocxControlMetadata as x, DocxExportBlock as y, DocxExportCell as z };