@docx-editor.dev/core 2.14.1 → 2.15.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 (133) hide show
  1. package/README.md +42 -0
  2. package/dist/automation.cjs +1 -1
  3. package/dist/automation.d.ts +6 -5
  4. package/dist/automation.js +1 -1
  5. package/dist/binding.cjs +1 -1
  6. package/dist/binding.d.ts +16 -10
  7. package/dist/binding.js +1 -1
  8. package/dist/chunk-24APKZAN.cjs +11 -0
  9. package/dist/chunk-2YH4MSHX.cjs +2 -0
  10. package/dist/chunk-5Y7AADI6.js +1 -0
  11. package/dist/chunk-AREFLNUP.js +11 -0
  12. package/dist/chunk-AS7YZNQE.cjs +2 -0
  13. package/dist/chunk-AVGCKH6A.cjs +20 -0
  14. package/dist/chunk-CDYVDQRI.cjs +5 -0
  15. package/dist/chunk-FGBADUSK.cjs +1 -0
  16. package/dist/chunk-HOEWFH5U.cjs +1 -0
  17. package/dist/chunk-KFELX7CN.js +2 -0
  18. package/dist/{chunk-OKEDGR65.js → chunk-KXPVOPR5.js} +1 -1
  19. package/dist/chunk-LGFKIF4M.cjs +1 -0
  20. package/dist/chunk-M52QXFKI.js +1 -0
  21. package/dist/chunk-MNUKSXRO.js +1 -0
  22. package/dist/chunk-PBOIGBDO.js +2 -0
  23. package/dist/chunk-PMHGONET.cjs +1 -0
  24. package/dist/chunk-PXKZUTHX.cjs +2 -0
  25. package/dist/chunk-Q4AB7E4O.cjs +1 -0
  26. package/dist/chunk-QJYH6AYD.js +1 -0
  27. package/dist/chunk-QRC37MWG.cjs +20 -0
  28. package/dist/chunk-RJSB6RJ7.js +20 -0
  29. package/dist/chunk-SB54HLFJ.js +20 -0
  30. package/dist/chunk-VP7SDFCM.js +1 -0
  31. package/dist/chunk-XCESLTJL.js +2 -0
  32. package/dist/{chunk-KIAP7PFQ.cjs → chunk-YL4Q5LZP.cjs} +1 -1
  33. package/dist/chunk-Z4527AXR.js +5 -0
  34. package/dist/collaboration/replication.cjs +1 -1
  35. package/dist/collaboration/replication.d.ts +4 -3
  36. package/dist/collaboration/replication.js +1 -1
  37. package/dist/collaboration.d.ts +4 -3
  38. package/dist/contracts/editor.d.ts +7 -7
  39. package/dist/contracts/interaction.d.ts +7 -7
  40. package/dist/contracts/modules.d.ts +8 -7
  41. package/dist/{custom-node-writes-DntmaAVW.d.ts → custom-node-writes-C9ArIlJh.d.ts} +2 -2
  42. package/dist/{editor-a6VvsfYU.d.ts → editor-sRxrFJd8.d.ts} +29 -21
  43. package/dist/editor.cjs +1 -1
  44. package/dist/editor.d.ts +27 -58
  45. package/dist/editor.js +1 -1
  46. package/dist/export.cjs +2 -0
  47. package/dist/export.d.ts +337 -0
  48. package/dist/export.js +2 -0
  49. package/dist/font-resolver-BYEHQGTw.d.ts +251 -0
  50. package/dist/headless-document-view-DELC4E5v.d.ts +134 -0
  51. package/dist/hf-references-DTrHkktY.d.ts +70 -0
  52. package/dist/{index-C5ZnSRkF.d.ts → index-C3Gvq4jN.d.ts} +55 -246
  53. package/dist/index.cjs +1 -1
  54. package/dist/index.d.ts +18 -16
  55. package/dist/index.js +1 -1
  56. package/dist/{shaped-measurer-CFPnXFs9.d.cts → layout-shaping-DoGR5cf8.d.ts} +86 -12
  57. package/dist/layout.cjs +1 -1
  58. package/dist/layout.d.ts +1106 -729
  59. package/dist/layout.js +1 -1
  60. package/dist/{note-properties-CDFiNXcD.d.ts → note-properties-DSe8igrz.d.ts} +2 -2
  61. package/dist/{omml-equation-BY49UOIF.d.ts → omml-equation-BpRmfDAf.d.ts} +1 -1
  62. package/dist/output.cjs +1 -1
  63. package/dist/output.d.ts +6 -6
  64. package/dist/output.js +1 -1
  65. package/dist/{protocol-gOY5GA8K.d.cts → protocol-DZzKxH5r.d.ts} +18 -12
  66. package/dist/{review-items-CCS1h93f.d.ts → review-items-DYRx187i.d.ts} +2 -2
  67. package/dist/{review-reads-BjZYeMd4.d.ts → review-reads-LbGUdNzn.d.ts} +22 -25
  68. package/dist/{revision-projection-BeXVrSSV.d.ts → revision-projection-DHRJH48u.d.ts} +1 -1
  69. package/dist/{semantic-cell-selection-BK91NCCG.d.ts → semantic-cell-selection-BXVWCBYm.d.ts} +4 -4
  70. package/dist/{semantic-interaction-BmQ7h2cq.d.ts → semantic-interaction-DZsDmPg5.d.ts} +1 -1
  71. package/dist/{semantic-paint-WJD2KeG1.d.ts → semantic-paint-f7SqN4oW.d.ts} +2 -2
  72. package/dist/{semantic-records-BpozY7-j.d.cts → semantic-records-EIdwId-a.d.ts} +301 -205
  73. package/dist/store.cjs +1 -1
  74. package/dist/store.d.ts +15 -65
  75. package/dist/store.js +1 -1
  76. package/dist/{tree-op-types-D6HzlPR4.d.ts → tree-op-types-egdarvH_.d.ts} +7 -3
  77. package/dist/{tree-package-fragment-CWFjgH6a.d.ts → tree-package-fragment-DjkH4ESI.d.ts} +4 -70
  78. package/dist/{tree-session-contract-B2HfGt79.d.ts → tree-session-contract-CGOOgPjW.d.ts} +29 -23
  79. package/dist/{tree-store-APgWx6qn.d.ts → tree-store-DKJB0IcA.d.ts} +2 -2
  80. package/package.json +7 -2
  81. package/dist/automation.d.cts +0 -82
  82. package/dist/binding.d.cts +0 -153
  83. package/dist/chunk-2PIHW2QM.cjs +0 -1
  84. package/dist/chunk-2QTY5S6T.js +0 -1
  85. package/dist/chunk-4Z5MODAE.cjs +0 -2
  86. package/dist/chunk-5TKAPFZT.cjs +0 -2
  87. package/dist/chunk-DRQHIQ4R.cjs +0 -1
  88. package/dist/chunk-F2K6SDHA.cjs +0 -20
  89. package/dist/chunk-FBA57EUJ.js +0 -2
  90. package/dist/chunk-KTAQ7BRQ.js +0 -20
  91. package/dist/chunk-LBAHXZCU.cjs +0 -5
  92. package/dist/chunk-MCDUQYWP.js +0 -5
  93. package/dist/chunk-MQP26KCF.js +0 -1
  94. package/dist/chunk-NDJGSR6M.cjs +0 -19
  95. package/dist/chunk-NJNFJPGB.cjs +0 -11
  96. package/dist/chunk-O5M4CR4P.cjs +0 -2
  97. package/dist/chunk-UKUOZXUD.js +0 -19
  98. package/dist/chunk-VQ4R5LTU.js +0 -2
  99. package/dist/chunk-ZBEJHJN2.js +0 -11
  100. package/dist/chunk-ZVTW7RGD.js +0 -2
  101. package/dist/collaboration/replication.d.cts +0 -216
  102. package/dist/collaboration.d.cts +0 -176
  103. package/dist/contracts/document.d.cts +0 -273
  104. package/dist/contracts/editor.d.cts +0 -10
  105. package/dist/contracts/interaction.d.cts +0 -10
  106. package/dist/contracts/modules.d.cts +0 -130
  107. package/dist/contracts/types.d.cts +0 -562
  108. package/dist/custom-node-writes-C46r3_5O.d.cts +0 -310
  109. package/dist/document-properties-D6Ahr8D6.d.cts +0 -28
  110. package/dist/document-properties-D6Ahr8D6.d.ts +0 -28
  111. package/dist/editor-AJ06hyyg.d.cts +0 -1994
  112. package/dist/editor.d.cts +0 -393
  113. package/dist/failure-BnGjoXf0.d.cts +0 -64
  114. package/dist/index-Cbw4lkOt.d.cts +0 -3391
  115. package/dist/index.d.cts +0 -23
  116. package/dist/layout.d.cts +0 -2486
  117. package/dist/note-properties-Y6qYh2Hv.d.cts +0 -67
  118. package/dist/omml-equation-DB8d-jCq.d.cts +0 -84
  119. package/dist/output.d.cts +0 -74
  120. package/dist/protocol-BsmQgblT.d.ts +0 -1358
  121. package/dist/review-items-CaAkgi5s.d.cts +0 -360
  122. package/dist/review-reads-DEsV0OOW.d.cts +0 -163
  123. package/dist/revision-projection-DXbrfNGD.d.cts +0 -156
  124. package/dist/semantic-cell-selection-BMhku3B1.d.cts +0 -451
  125. package/dist/semantic-interaction-DUAnxbgf.d.cts +0 -160
  126. package/dist/semantic-paint-DufNL1Zr.d.cts +0 -247
  127. package/dist/semantic-records-92UnKeU_.d.ts +0 -2821
  128. package/dist/shaped-measurer-BWbindlI.d.ts +0 -168
  129. package/dist/store.d.cts +0 -2500
  130. package/dist/tree-op-types-BUulYD5y.d.cts +0 -3099
  131. package/dist/tree-package-fragment-Dhyw7oPm.d.cts +0 -732
  132. package/dist/tree-session-contract-BY9xd7s_.d.cts +0 -613
  133. package/dist/tree-store-DEEQ9wz_.d.cts +0 -416
@@ -1,732 +0,0 @@
1
- import { b as OoxmlPackage, y as SupportedImageMime, O as OoxmlPart, a as OoxmlNode, g as OoxmlElement, E as RevisionAttributionInput, C as ImageDecodePort, F as DrawingTreeDocOp, r as TreeOpRejection, T as TreeDocOp } from './tree-op-types-BUulYD5y.cjs';
2
- import { N as NoteKind, T as TreeModelChange, a as TreeDocumentStore, c as TreeStoryRef, d as TransactionContext, b as TransactOptions, S as SelectionMark, e as TreeDocumentCheckpoint } from './tree-store-DEEQ9wz_.cjs';
3
-
4
- /** A freshly allocated drawing property id, or the reason one could not be minted. */
5
- type DrawingPropertyIdResult = {
6
- readonly ok: true;
7
- readonly id: number;
8
- } | {
9
- readonly ok: false;
10
- readonly reason: 'invalidArgs';
11
- };
12
- /**
13
- * Mint a `wp:docPr` id unused anywhere in the package.
14
- *
15
- * Package-wide rather than per-part: Word treats these ids as document-global, and a collision
16
- * makes it renumber on open.
17
- *
18
- * Solo: `highest + 1`, the dense sequence Word writes. With a collaboration actor bound —
19
- * explicit argument, or the open store transaction — the id is the next unused value in that
20
- * actor's stripe. Two peers inserting a picture from one snapshot otherwise both mint `id="1"`,
21
- * and the merged document carries two drawings under one document-global id.
22
- */
23
- declare function allocateDrawingPropertyId(pkg: OoxmlPackage, actorId?: string): DrawingPropertyIdResult;
24
- /**
25
- * Store raw bytes for a part and declare its exact content type.
26
- *
27
- * Does not create a relationship; callers decide which owner points at the part.
28
- */
29
- declare function withBinaryPart(pkg: OoxmlPackage, partName: string, bytes: Uint8Array, contentType: string): OoxmlPackage;
30
- /**
31
- * Add image bytes to the package: the media part, its content type, and the relationship.
32
- *
33
- * All three together — bytes with no relationship are unreachable, and a relationship with no
34
- * content-type record makes the package invalid.
35
- */
36
- declare function withEmbeddedImage(pkg: OoxmlPackage, ownerPartName: string, input: Readonly<{
37
- bytes: Uint8Array;
38
- mime: SupportedImageMime;
39
- }>): Readonly<{
40
- ok: true;
41
- pkg: OoxmlPackage;
42
- partName: string;
43
- relationshipId: string;
44
- docPrId: number;
45
- }> | Readonly<{
46
- ok: false;
47
- reason: 'invalidArgs' | 'invalid-image';
48
- }>;
49
- /** Remove an orphaned image media part after a package-wide internal relationship target check. */
50
- declare function withoutUnreferencedImagePart(pkg: OoxmlPackage, partName: string): OoxmlPackage;
51
- interface ExternalImageFetchPort {
52
- /** Atomically resolve, reject non-public addresses, and connect for one HTTPS hop. */
53
- requestPublicHttps(url: string, init: Readonly<{
54
- redirect: 'manual';
55
- signal: AbortSignal;
56
- }>): Promise<Readonly<{
57
- status: number;
58
- location: string | null;
59
- contentType: string | null;
60
- body: AsyncIterable<Uint8Array>;
61
- /** Must equal the requested absolute URL for this hop. */
62
- connectedUrl: string;
63
- }>>;
64
- }
65
-
66
- /** `w:headerReference w:type` vocabulary (ECMA-376 §17.10.5): default, first page, even pages. */
67
- type HeaderFooterVariant = 'default' | 'first' | 'even';
68
- /** Header vs footer region kind for chrome and lifecycle ops. */
69
- type HeaderFooterKind = 'header' | 'footer';
70
- /**
71
- * A section's resolved header and footer parts, by variant.
72
- *
73
- * The `even` variant is only honoured when `w:evenAndOddHeaders` is set in settings.xml —
74
- * without it Word ignores an authored even header, and so does this.
75
- */
76
- interface HeaderFooterParts {
77
- readonly headers: ReadonlyMap<HeaderFooterVariant, OoxmlPart>;
78
- readonly footers: ReadonlyMap<HeaderFooterVariant, OoxmlPart>;
79
- /** `w:evenAndOddHeaders` in settings.xml — without it the `even` variant is ignored. */
80
- readonly evenAndOddHeaders: boolean;
81
- /** Whether this section enables first-page header/footer furniture (`w:titlePg`). */
82
- readonly titlePage: boolean;
83
- }
84
- /**
85
- * One resolved furniture slot with enough metadata for "Same as previous" chrome.
86
- *
87
- * `inherited: true` means this section has no declared reference for the slot and the
88
- * part comes from a predecessor. The first section never reports inherited — omitting a
89
- * ref there is blank furniture, not inheritance from a later section.
90
- */
91
- interface HeaderFooterSlotMeta {
92
- readonly part: OoxmlPart;
93
- readonly partName: string;
94
- readonly rId: string;
95
- readonly inherited: boolean;
96
- }
97
- /** Per-section resolution including declared-vs-inherited metadata. */
98
- interface HeaderFooterSectionResolution {
99
- readonly headers: ReadonlyMap<HeaderFooterVariant, HeaderFooterSlotMeta>;
100
- readonly footers: ReadonlyMap<HeaderFooterVariant, HeaderFooterSlotMeta>;
101
- readonly evenAndOddHeaders: boolean;
102
- readonly titlePage: boolean;
103
- }
104
- /**
105
- * `w:sectPr` nodes in section order, aligned with layout's `enumerateDocumentSections`.
106
- *
107
- * `null` means a section with no `w:sectPr` node (Word defaults, inherits HF from previous).
108
- * Paragraph-level breaks first; the final entry covers remaining blocks (body-level or null).
109
- */
110
- declare function collectSectionPropertyNodes(root: OoxmlNode): Array<OoxmlElement | null>;
111
- /**
112
- * Resolve header/footer parts for every section with declared-vs-inherited metadata.
113
- *
114
- * Index aligns with `enumerateDocumentSections` in the layout package. Existing merged
115
- * maps stay available via {@link resolveHeaderFooterPartsBySection}.
116
- */
117
- declare function resolveHeaderFooterResolutionBySection(pkg: OoxmlPackage): readonly HeaderFooterSectionResolution[];
118
- /**
119
- * Resolve header/footer parts for every section, applying OOXML inheritance.
120
- *
121
- * Index aligns with `enumerateDocumentSections` in the layout package.
122
- */
123
- declare function resolveHeaderFooterPartsBySection(pkg: OoxmlPackage): readonly HeaderFooterParts[];
124
- /**
125
- * Resolve the main-document header/footer references to their parts, gated by the
126
- * settings the section actually declares.
127
- *
128
- * Returns the FINAL section's effective parts (after inheritance). Multi-section hosts
129
- * should prefer `resolveHeaderFooterPartsBySection`.
130
- */
131
- declare function resolveHeaderFooterParts(pkg: OoxmlPackage): HeaderFooterParts;
132
-
133
- /** Lifecycle impact — furniture always reaches multiple pages; never narrower than flow-structural. */
134
- type HeaderFooterLifecycleImpact = 'flow-structural' | 'global';
135
- /**
136
- * A header/footer lifecycle mutation: create, remove, or relink a variant.
137
- *
138
- * Package-level, like note lifecycle: each touches the document, the header/footer part, the
139
- * relationships and `[Content_Types].xml` together.
140
- */
141
- type HeaderFooterLifecycleOp = {
142
- readonly op: 'createHeaderFooter';
143
- readonly sectionIndex: number;
144
- readonly kind: HeaderFooterKind;
145
- readonly variant: HeaderFooterVariant;
146
- /** When true, also set section `w:titlePg` in the same package transaction. */
147
- readonly titlePage?: boolean;
148
- /** When true, also set document `w:evenAndOddHeaders` in the same package transaction. */
149
- readonly evenAndOddHeaders?: boolean;
150
- } | {
151
- readonly op: 'deleteHeaderFooter';
152
- readonly sectionIndex: number;
153
- readonly kind: HeaderFooterKind;
154
- readonly variant: HeaderFooterVariant;
155
- } | {
156
- readonly op: 'linkToPrevious';
157
- readonly sectionIndex: number;
158
- readonly kind: HeaderFooterKind;
159
- readonly variant: HeaderFooterVariant;
160
- } | {
161
- readonly op: 'unlinkFromPrevious';
162
- readonly sectionIndex: number;
163
- readonly kind: HeaderFooterKind;
164
- readonly variant: HeaderFooterVariant;
165
- } | {
166
- readonly op: 'setSectionFurnitureOptions';
167
- readonly sectionIndex?: number;
168
- readonly titlePage?: boolean;
169
- readonly evenAndOddHeaders?: boolean;
170
- readonly headerDistanceTwips?: number;
171
- readonly footerDistanceTwips?: number;
172
- };
173
- /** Why a header/footer lifecycle op was refused. */
174
- type HeaderFooterLifecycleRejection = 'invalidArgs' | 'tree-invariant';
175
- /** A new package, or a typed rejection. Pure and all-or-nothing — no partial writes. */
176
- type HeaderFooterLifecycleResult = {
177
- readonly ok: true;
178
- readonly package: OoxmlPackage;
179
- readonly impact: HeaderFooterLifecycleImpact;
180
- readonly createdRId?: string;
181
- readonly createdPartName?: string;
182
- } | {
183
- readonly ok: false;
184
- readonly reason: HeaderFooterLifecycleRejection;
185
- readonly detail?: string;
186
- };
187
- /** Whether an op is a header/footer lifecycle op rather than a story-level one. */
188
- declare function isHeaderFooterLifecycleOp(op: {
189
- readonly op: string;
190
- }): op is HeaderFooterLifecycleOp;
191
- /**
192
- * Apply one furniture lifecycle op atomically. Rejected ops leave the input package
193
- * untouched (pure function — callers discard the result).
194
- */
195
- declare function applyHeaderFooterLifecycleOp(pkg: OoxmlPackage, op: HeaderFooterLifecycleOp): HeaderFooterLifecycleResult;
196
-
197
- /** Cap on nodes visited while scanning for note references across stories. */
198
- declare const MAX_NOTE_REFERENCE_SCAN = 20000;
199
- /**
200
- * Cap on XML parts walked in one package-wide note-reference scan (N/N+1 gate).
201
- * Soft targets are not allowed: exceeding this marks the shared budget truncated.
202
- */
203
- declare const MAX_NOTE_REFERENCE_PARTS = 256;
204
- /**
205
- * A load-time note problem worth reporting.
206
- *
207
- * `dangling-note-reference` is a citation pointing at no note; `note-reference-scan-truncated`
208
- * says the scan hit its budget, so absence of further diagnostics is not proof of correctness.
209
- */
210
- type NoteDiagnosticCode = 'dangling-note-reference' | 'note-reference-scan-truncated';
211
- /**
212
- * Load-time note diagnostics. Array API preserved; truncation is signaled as a typed
213
- * entry rather than by throwing or rejecting the package.
214
- */
215
- type NoteDiagnostic = {
216
- readonly code: 'dangling-note-reference';
217
- readonly noteKind: NoteKind;
218
- readonly noteId: number;
219
- /** Paragraph / container node id when known. */
220
- readonly sourceNodeId?: string;
221
- } | {
222
- /** Hard visited/part budget or soft hit cap stopped the scan before full coverage. */
223
- readonly code: 'note-reference-scan-truncated';
224
- };
225
- /** One note reference found in a story, with where it sits. */
226
- interface NoteReferenceHit {
227
- readonly noteKind: NoteKind;
228
- readonly noteId: number;
229
- readonly nodeId: string;
230
- readonly paragraphId: string;
231
- /** Canonical UTF-16 atom offset within {@link paragraphId} (U+FFFC model). */
232
- readonly atomOffset: number;
233
- readonly customMarkFollows: boolean;
234
- /** Canonical part name that owns this reference. */
235
- readonly partName: string;
236
- }
237
- /** Mutable visited-node + part budget shared across parts / package snapshots. */
238
- interface NoteReferenceScanBudget {
239
- visited: number;
240
- readonly maxVisited: number;
241
- parts: number;
242
- readonly maxParts: number;
243
- /** Set when a walk stops before finishing because a cap was hit. */
244
- truncated: boolean;
245
- }
246
- /** A bounded budget for scanning note references, so a crafted document cannot stall a load. */
247
- declare function createNoteReferenceScanBudget(maxVisited?: number, maxParts?: number): NoteReferenceScanBudget;
248
- /**
249
- * Resolve the footnotes or endnotes part via safe Internal document relationships.
250
- *
251
- * Unusable matching relationships (External, unsafe target, missing part, wrong root)
252
- * are skipped — never fetched, never accepted — so a decoy first match cannot hide a
253
- * later usable Internal notes part (same continue-past-bad pattern as settingsPartOf).
254
- */
255
- declare function resolveNotesPart(pkg: OoxmlPackage, noteKind: NoteKind): OoxmlPart | null;
256
- /** Walk a part without applying a layout projection. */
257
- declare function collectNoteReferences(part: OoxmlPart, options?: {
258
- readonly maxHits?: number;
259
- readonly budget?: NoteReferenceScanBudget;
260
- }): readonly NoteReferenceHit[];
261
- /** Collect references across every XML part under one shared part + visited-node budget. */
262
- declare function collectPackageNoteReferences(pkg: OoxmlPackage, options?: {
263
- readonly budget?: NoteReferenceScanBudget;
264
- /** Soft hit cap for diagnostics. Omit / Infinity for mutation scans. */
265
- readonly maxHits?: number;
266
- }): readonly NoteReferenceHit[];
267
- /**
268
- * Load diagnostics for dangling note references. Fail-open: never throws or mutates;
269
- * returns diagnostics for callers to surface. Does not invent missing note bodies.
270
- *
271
- * When the hard visited/part budget truncates or the soft hit cap binds, appends a single
272
- * `note-reference-scan-truncated` entry so incomplete coverage is visible without breaking
273
- * consumers that filter on `dangling-note-reference`.
274
- */
275
- declare function diagnoseNoteReferences(pkg: OoxmlPackage): readonly NoteDiagnostic[];
276
- /** Whether a notes-part root contains a note with the given id (any type). */
277
- declare function notesPartHasId(part: OoxmlPart, noteId: number): boolean;
278
- /** List normal (body) note ids in document order, bounded. */
279
- declare function normalNoteIds(part: OoxmlPart): readonly number[];
280
-
281
- /** How far a note lifecycle op reaches — which parts a caller must expect to have changed. */
282
- type NoteLifecycleImpact = 'flow-structural' | 'global';
283
- /**
284
- * A note lifecycle mutation: insert, delete, convert, or set properties.
285
- *
286
- * Package-level rather than story-level, because every one of these touches the main document,
287
- * the notes part, the document relationships AND `[Content_Types].xml` together.
288
- */
289
- type NoteLifecycleOp = {
290
- readonly op: 'insertNote';
291
- readonly noteKind: NoteKind;
292
- readonly paragraphId: string;
293
- readonly offset: number;
294
- /**
295
- * Write the citing reference as a TRACKED insertion: the reference run goes inside a
296
- * `w:ins` carrying this attribution. The note body stays plain — rejecting the
297
- * reference removes it, and the orphaned body is swept by the same cascade an
298
- * untracked reference deletion triggers.
299
- */
300
- readonly revision?: RevisionAttributionInput;
301
- } | {
302
- readonly op: 'deleteNote';
303
- readonly noteKind: NoteKind;
304
- readonly noteId: number;
305
- } | {
306
- readonly op: 'convertNote';
307
- readonly fromKind: NoteKind;
308
- readonly noteId: number;
309
- } | {
310
- /**
311
- * Convert every normal note of `fromKind` in document order. One atomic package
312
- * transaction / undo unit with the same validation as repeated `convertNote`.
313
- */
314
- readonly op: 'convertAllNotes';
315
- readonly fromKind: NoteKind;
316
- } | {
317
- readonly op: 'setNoteProperties';
318
- readonly scope: 'document' | 'section';
319
- readonly sectionIndex?: number;
320
- readonly footnote?: {
321
- readonly numFmt?: string;
322
- readonly numRestart?: string;
323
- readonly position?: string;
324
- readonly numStart?: number;
325
- };
326
- readonly endnote?: {
327
- readonly numFmt?: string;
328
- readonly numRestart?: string;
329
- readonly position?: string;
330
- readonly numStart?: number;
331
- };
332
- };
333
- /** Why a note lifecycle op was refused. */
334
- type NoteLifecycleRejection = 'invalidArgs' | 'invalid-property-value' | 'tree-invariant';
335
- /**
336
- * A new package, or a typed rejection.
337
- *
338
- * Application is PURE and all-or-nothing: there are no partial writes, so a refused op leaves the
339
- * caller's package untouched rather than half-migrated across four parts.
340
- */
341
- type NoteLifecycleResult = {
342
- readonly ok: true;
343
- readonly package: OoxmlPackage;
344
- readonly impact: NoteLifecycleImpact;
345
- readonly noteId?: number;
346
- readonly noteKind?: NoteKind;
347
- readonly createdPartName?: string;
348
- } | {
349
- readonly ok: false;
350
- readonly reason: NoteLifecycleRejection;
351
- readonly detail?: string;
352
- };
353
- /** Whether an op is a note lifecycle op rather than a story-level one. */
354
- declare function isNoteLifecycleOp(op: {
355
- readonly op: string;
356
- }): op is NoteLifecycleOp;
357
- /** Attribution and limits applied to one note lifecycle op. */
358
- interface NoteLifecycleOptions {
359
- /**
360
- * Shared part + visited-node budget for reference scans. When omitted a fresh default
361
- * budget is used. Truncation rejects the op with the original package unchanged.
362
- */
363
- readonly scanBudget?: NoteReferenceScanBudget;
364
- }
365
- /**
366
- * Apply one note lifecycle op atomically. Rejected ops leave the input package untouched.
367
- */
368
- declare function applyNoteLifecycleOp(pkg: OoxmlPackage, op: NoteLifecycleOp, options?: NoteLifecycleOptions): NoteLifecycleResult;
369
- /**
370
- * How deleting text cascades into the notes it referenced.
371
- *
372
- * A note's body and the citation reaching it are one thing to a reader, so removing the reference
373
- * must remove the body too or the notes part keeps an entry nothing points at.
374
- */
375
- interface CascadeDeletedNoteReferencesOptions {
376
- /**
377
- * Independent full budgets per snapshot. When omitted each snapshot gets its own
378
- * default budget — never share one counter across before/after walks.
379
- */
380
- readonly beforeBudget?: NoteReferenceScanBudget;
381
- readonly afterBudget?: NoteReferenceScanBudget;
382
- }
383
- /**
384
- * Remove note bodies for references that disappeared between two package snapshots.
385
- * Used when `deleteText` or `deleteBlock` removes a `noteReference` atom so body+ref stay
386
- * one undo unit.
387
- *
388
- * Each snapshot gets an independent full visited/part budget. If either scan truncates
389
- * the cascade fails closed so a hostile package cannot skip body deletion silently —
390
- * without accidentally halving capacity by charging both walks to one counter.
391
- */
392
- declare function cascadeDeletedNoteReferences(before: OoxmlPackage, after: OoxmlPackage, options?: CascadeDeletedNoteReferencesOptions): OoxmlPackage | null;
393
-
394
- interface InsertImageInput {
395
- readonly paragraphId: string;
396
- readonly offset: number;
397
- readonly bytes: Uint8Array;
398
- readonly mime: SupportedImageMime;
399
- readonly widthPoints: number;
400
- readonly heightPoints: number;
401
- readonly decodePort: ImageDecodePort;
402
- readonly expectedPackageRevision: number;
403
- readonly commitGuard?: () => boolean;
404
- readonly title?: string;
405
- readonly description?: string;
406
- readonly hyperlink?: string;
407
- /** Present in suggesting mode: the inserted drawing's run goes into a `w:ins`. */
408
- readonly revision?: RevisionAttributionInput;
409
- /**
410
- * Collaboration actor for the ids this insert mints — `wp:docPr/@id`, the image
411
- * relationship, and a hyperlink relationship when one is asked for.
412
- *
413
- * EXPLICIT, and not the ambient `runWithTransactionActor` binding, because this entry is
414
- * async: the mint runs after `await validateEmbeddedImageForCommit` and the ambient actor
415
- * is synchronous-only. A wrap around the call would compile, read as correct, and be gone
416
- * by the time the id is taken. Omitted (solo) keeps Word's dense `highest + 1` sequence.
417
- */
418
- readonly actorId?: string;
419
- }
420
- interface ReplaceImageOptions {
421
- readonly expectedPackageRevision: number;
422
- readonly commitGuard?: () => boolean;
423
- /** Collaboration actor for the replacement's minted ids. See {@link InsertImageInput.actorId}. */
424
- readonly actorId?: string;
425
- }
426
- type ImageIntentResult = (Extract<PackageTransactResult, {
427
- ok: true;
428
- }> & {
429
- readonly drawingNodeId?: string;
430
- readonly mediaPartName?: string;
431
- }) | Extract<PackageTransactResult, {
432
- ok: false;
433
- }>;
434
- interface ApplyImagePropertiesInput {
435
- readonly drawingNodeId: string;
436
- readonly ops: readonly DrawingTreeDocOp[];
437
- readonly hyperlink: string | null;
438
- }
439
-
440
- /** Attribution stamped on one remote canonical publication. */
441
- interface RemotePackageAttribution {
442
- readonly origin: string;
443
- readonly actorId?: string;
444
- readonly operationId?: string;
445
- }
446
-
447
- type NoteCascadeFn = (before: OoxmlPackage, after: OoxmlPackage) => OoxmlPackage | null;
448
- /**
449
- * Editable story target.
450
- *
451
- * Body and headerFooter mirror `EditorScope`. Notes use one lazy store per notes part
452
- * (`notesPart`) — not one store per note — resolved through safe document relationships.
453
- */
454
- type StoryScope = {
455
- readonly kind: 'body';
456
- } | {
457
- readonly kind: 'headerFooter';
458
- readonly rId: string;
459
- } | {
460
- readonly kind: 'notesPart';
461
- readonly noteKind: NoteKind;
462
- };
463
- /**
464
- * Why a story scope could not be resolved to a part.
465
- *
466
- * Several of these are FILE-hostile shapes rather than caller mistakes:
467
- * `external-relationship` and `bad-relationship-target` are how a crafted document tries to
468
- * point a story at something outside the package, and both are refused rather than followed.
469
- */
470
- type StoryTargetRejection = 'unknown-scope' | 'dangling-relationship' | 'wrong-relationship-type' | 'external-relationship' | 'bad-relationship-target' | 'missing-part' | 'not-a-story-part' | 'too-many-story-stores';
471
- /** A story scope resolved to a part, or the typed reason it could not be. */
472
- type StoryResolveResult = {
473
- readonly ok: true;
474
- readonly story: TreeStoryRef;
475
- readonly store: TreeDocumentStore;
476
- } | {
477
- readonly ok: false;
478
- readonly reason: StoryTargetRejection;
479
- readonly detail?: string;
480
- };
481
- /** Whether a package-level transaction committed, or why it was refused. */
482
- type PackageTransactResult = {
483
- readonly ok: true;
484
- readonly change: TreeModelChange | null;
485
- } | {
486
- readonly ok: false;
487
- readonly reason: StoryTargetRejection | TreeOpRejection;
488
- readonly detail?: string;
489
- };
490
- /** Cap on simultaneously opened editable story stores (body + HF parts). Fail closed. */
491
- declare const DEFAULT_MAX_EDITABLE_STORY_PARTS = 64;
492
- /** How a package store is constructed: limits, history depth, and review contributions. */
493
- interface TreePackageStoreOptions {
494
- readonly historyLimit?: number;
495
- /** Bound on opened story stores; defaults to {@link DEFAULT_MAX_EDITABLE_STORY_PARTS}. */
496
- readonly maxEditableStoryParts?: number;
497
- /**
498
- * Test seam for note-reference cascade after `deleteText` / `deleteBlock`. Production uses
499
- * {@link cascadeDeletedNoteReferences}.
500
- */
501
- readonly cascadeDeletedNoteReferences?: NoteCascadeFn;
502
- }
503
- /**
504
- * Package-level mutation authority: routes `TreeDocOp`s to the store for a story part,
505
- * publishes one ModelChange / undo unit per transaction, and keeps `currentPackage()`
506
- * coherent for save/reopen.
507
- */
508
- declare class TreePackageStore {
509
- private pkg;
510
- private packageRev;
511
- private readonly body;
512
- /** Opened non-body story stores, keyed by canonical part name. */
513
- private readonly stories;
514
- /** rId → part name for opened HF stores (and resolved targets). */
515
- private readonly rIdToPartName;
516
- private readonly undoOrder;
517
- private readonly redoOrder;
518
- private readonly subscribers;
519
- private readonly historyLimit;
520
- private readonly maxEditableStoryParts;
521
- private readonly cascadeNoteReferences;
522
- private lastChange;
523
- /**
524
- * Hyperlink externals minted via {@link replacePackageShell} (outside package history).
525
- * Re-applied on snapshot install so lifecycle undo cannot drop shell `r:id`s; not used for
526
- * lifecycle-cloned owned relationships, which history snapshots already restore.
527
- */
528
- private shellHyperlinks;
529
- /**
530
- * Open IME composition session. Captures the package/story checkpoint at begin so a
531
- * mid-composition note-ref cascade can promote the whole composition to one package
532
- * undo unit (or restore on cancel) instead of a story-only pointer that orphans note bodies.
533
- */
534
- private compositionSession;
535
- private commitCounter;
536
- /**
537
- * Memo for {@link currentPackage}, keyed on that method's COMPLETE read set by object identity:
538
- * the shell, the body part, and each open story's part in map order. Identity is the only sound
539
- * key — `packageRevision` is excluded, because shell writes (`replacePackageShell`, story-store
540
- * grafts, lazy opens) move `this.pkg` or a `store.part` without bumping it. Parts are frozen, so
541
- * a matching tuple proves the snapshot cannot differ; nothing invalidates explicitly.
542
- */
543
- private currentPackageMemo;
544
- constructor(pkg: OoxmlPackage, main: OoxmlPart, options?: TreePackageStoreOptions);
545
- get packageRevision(): number;
546
- get canUndo(): boolean;
547
- get canRedo(): boolean;
548
- get lastModelChange(): TreeModelChange | null;
549
- /** Body store — independent revision/index from every HF store. */
550
- bodyStore(): TreeDocumentStore;
551
- /**
552
- * The current package with every opened story store's part merged in.
553
- * Pure snapshot of authority; callers must not mutate.
554
- *
555
- * Memoized on input identity: repeated calls with unchanged authority return the
556
- * SAME frozen instance instead of minting a copy per call. Layout asks for this
557
- * once per paragraph when keying drawing tokens, so the un-memoized `withPart`
558
- * map copies dominated large-document keystroke flushes.
559
- *
560
- * Stores whose parts are absent from the package shell (deleted furniture/notes)
561
- * stay parked for undo/redo identity but are not re-injected into the snapshot.
562
- */
563
- currentPackage(): OoxmlPackage;
564
- subscribe(listener: (change: TreeModelChange) => void): () => void;
565
- /**
566
- * Resolve a story scope to its store. Fail closed for dangling / wrong-typed / missing
567
- * targets — layout may fail open on the same rId, but mutation must not invent a part.
568
- */
569
- resolveStory(scope: StoryScope): StoryResolveResult;
570
- /** Current part for a scope, or null when the target is refused. */
571
- partFor(scope: StoryScope): OoxmlPart | null;
572
- /** Per-story revision, or null when the target is refused. */
573
- revisionFor(scope: StoryScope): number | null;
574
- /**
575
- * Commit ops against one story as ONE transaction / undo unit / ModelChange.
576
- * Header/footer and notes-part commits publish `impact: 'global'`.
577
- * Deleting a `noteReference` via `deleteText` or a block subtree via `deleteBlock`
578
- * cascades the note body in the same package undo unit.
579
- */
580
- transact(scope: StoryScope, build: (ctx: TransactionContext) => void, options?: Omit<TransactOptions, 'story' | 'minimumImpact'>): PackageTransactResult;
581
- private commitStoryTransaction;
582
- /** Whether a package-wide IME composition session is open on any story. */
583
- compositionSessionOpen(): boolean;
584
- beginComposition(scope: StoryScope, selectionBefore?: SelectionMark | null): boolean;
585
- endComposition(): void;
586
- cancelComposition(): void;
587
- /**
588
- * Commit one furniture or note lifecycle op as a single ModelChange / undo unit that
589
- * restores the entire package atomically (parts, rels, content-types, settings).
590
- */
591
- applyLifecycleOp(op: HeaderFooterLifecycleOp | NoteLifecycleOp | TreeDocOp): PackageTransactResult;
592
- private commitLifecycleOp;
593
- undo(): TreeModelChange | null;
594
- redo(): TreeModelChange | null;
595
- selectionForUndo(): SelectionMark | null;
596
- selectionForRedo(): SelectionMark | null;
597
- /** See {@link openStoryPartsOf}. */
598
- openStoryParts(): readonly OoxmlPart[];
599
- /** How many story stores are open (body counts as one). */
600
- openedStoryCount(): number;
601
- /** See {@link openStoryTokenOf}. */
602
- openStoryToken(): string;
603
- /** Insert a validated raster image as one package undo unit (task 12). */
604
- insertImage(scope: StoryScope, input: InsertImageInput): Promise<ImageIntentResult>;
605
- /** Land a clipboard fragment (resource merge + blocks) as one package undo unit. */
606
- applyFragmentPaste(scope: StoryScope, input: FragmentPasteInput): FragmentPasteResult;
607
- /** Replace a picture drawing's embedded media in one package undo unit. */
608
- replaceImage(scope: StoryScope, drawingNodeId: string, bytes: Uint8Array, mime: SupportedImageMime, decodePort: ImageDecodePort, options: ReplaceImageOptions): Promise<ImageIntentResult>;
609
- /** Delete a picture drawing and collect orphaned media in one package undo unit. */
610
- deleteImage(scope: StoryScope, drawingNodeId: string): ImageIntentResult;
611
- /** Propose the deletion as a tracked change: the drawing goes into a `w:del`, media stays. */
612
- deleteImageTracked(scope: StoryScope, drawingNodeId: string, revision: RevisionAttributionInput): ImageIntentResult;
613
- /** Fetch external bytes explicitly and embed them; no fetch on open/load. */
614
- embedExternalImage(scope: StoryScope, drawingNodeId: string, url: string, port: ExternalImageFetchPort, signal: AbortSignal, decodePort: ImageDecodePort, actorId?: string): Promise<ImageIntentResult>;
615
- /** Metadata plus hyperlink target creation in one package transaction. */
616
- setDrawingMetadataWithHyperlink(scope: StoryScope, drawingNodeId: string, title: string, description: string, hyperlink: string | null): ImageIntentResult;
617
- /** Properties batch with hyperlink relationship create/update/remove in one package unit. */
618
- applyImageProperties(scope: StoryScope, input: ApplyImagePropertiesInput): ImageIntentResult;
619
- /**
620
- * Promote a story transaction that wrote package bytes to one package undo pointer.
621
- * Used by image intents and note-reference cascade.
622
- */
623
- promoteStoryTransactionToPackageUnit(beforePackage: OoxmlPackage, store: TreeDocumentStore, checkpoint: TreeDocumentCheckpoint, beforeDepth: number): TreeModelChange;
624
- /**
625
- * Publish a story transaction the coordinator did not run.
626
- *
627
- * Comment writes commit straight on the story store and hand the new shell back through
628
- * {@link replacePackageShell}, so they never pass through `applyTreeOps` — the one place
629
- * every other edit bumps the revision and publishes. The subscriber channel therefore
630
- * stayed silent for a comment: `Editor.on('change')` never fired, and a review rail keyed
631
- * on it only caught up on the next unrelated caret move, so a reply someone had just
632
- * written was invisible until they clicked elsewhere.
633
- *
634
- * The STORY's own change is published rather than a synthetic one, because it carries the
635
- * dirty anchor paragraphs and the `text-local` impact the marker ops computed; a synthetic
636
- * `global` would make every comment cost a full relayout. History is deliberately
637
- * untouched — the story transaction already recorded its undo entry, exactly as
638
- * `applyTreeOps` leaves a non-cascading story edit.
639
- *
640
- * A `null` change is an identity no-op (nothing was written), and publishes nothing.
641
- */
642
- publishStoryWrite(change: TreeModelChange | null): TreeModelChange | null;
643
- /**
644
- * Record a write that spanned SEVERAL parts as one package undo unit.
645
- *
646
- * A comment spans parts — the body in `comments.xml`, the thread record in
647
- * `commentsExtended.xml`, the markers in the story — and those writes reach the store through
648
- * the story store rather than `transact`. The story store's history cannot undo them: `undo()`
649
- * on a story pointer syncs the STORY PART alone, so undoing a comment restored the markers and
650
- * left the body, or the reverse. The caller discards the story entry and hands the package it
651
- * started from to this instead, the same promotion the note cascade does.
652
- */
653
- adoptPackageUnit(before: OoxmlPackage): void;
654
- /** Install a full package snapshot (public seam for post-fetch cleanup). */
655
- installPackageSnapshot(snapshot: OoxmlPackage): void;
656
- /**
657
- * Install a package this replica did not author, verbatim. No shell merge — see
658
- * `publishRemoteCanonicalPackage` for why merging one here diverges two replicas.
659
- */
660
- installAuthoritativePackageSnapshot(snapshot: OoxmlPackage): void;
661
- /** Publish one remotely materialized canonical package as one revision. */
662
- publishRemotePackage(pkg: OoxmlPackage, attribution: RemotePackageAttribution): PackageTransactResult;
663
- /**
664
- * Replace the package shell while preserving opened stores. Used when numbering /
665
- * content-types mutate the package outside story trees.
666
- */
667
- replacePackageShell(pkg: OoxmlPackage): void;
668
- /**
669
- * Install a full package snapshot: body + opened story stores track the snapshot's parts.
670
- * Stores whose parts disappeared stay parked (history identity preserved) so a later
671
- * package undo can reconnect them; rId cache rebuilds from remaining relationships.
672
- *
673
- * Numbering / shell-minted hyperlink resources (via {@link replacePackageShell}) are merged
674
- * onto the snapshot so lifecycle undo cannot orphan story `numId` / `r:id` references.
675
- * Furniture and notes parts remain snapshot-owned; shell hyperlink `.rels` for those owners
676
- * park when the part is temporarily absent and are pruned once history can no longer restore
677
- * the owner. Lifecycle-cloned owned relationships are not shell-minted and GC with the part.
678
- */
679
- private installPackageSnapshotInternal;
680
- private openNotesPartStore;
681
- private openHeaderFooterStore;
682
- private storyRefForPart;
683
- private syncPackageFromStore;
684
- private pushUndoPointer;
685
- /**
686
- * Drop parked story stores that no current package part and no undo/redo pointer can
687
- * restore. History-reachable identities stay so edit→delete→undo reconnects the same
688
- * store; unreachable parked entries must not hold `maxEditableStoryParts` forever.
689
- *
690
- * Also prunes scoped hyperlink shell resources parked for owners that are no longer
691
- * live and not history-reachable (see `pruneUnreachableHyperlinkShell`).
692
- */
693
- private evictUnreachableStories;
694
- private publish;
695
- private publishSynthetic;
696
- }
697
-
698
- /** Decoded fragment payloads above this cap are refused before any package work. */
699
- declare const MAX_FRAGMENT_DECODED_BYTES: number;
700
- interface FragmentPasteInput {
701
- readonly paragraphId: string;
702
- readonly offset: number;
703
- /** The fragment package zip (from the clipboard codec or the HTML projection). */
704
- readonly fragmentBytes: Uint8Array;
705
- readonly lastMarkCovered: boolean;
706
- /** Ops that clear the current selection first (the surface's deleteSelectionPlan). */
707
- readonly priorOps?: readonly TreeDocOp[];
708
- /**
709
- * Collaboration actor for the ids this paste mints.
710
- *
711
- * A paste freshens three package-wide namespaces — bookmark `@w:id`, revision `@w:id` and
712
- * `wp:docPr/@id` — and the merge reads the actor off the open transaction. Without one, two
713
- * replicas pasting the same fragment from one snapshot mint the same numbers, and only the
714
- * merged document shows it. Omitted (solo) keeps Word's dense sequences.
715
- */
716
- readonly actorId?: string;
717
- }
718
- type FragmentPasteResult = (Extract<PackageTransactResult, {
719
- ok: true;
720
- }> & {
721
- readonly blockCount: number;
722
- }) | Extract<PackageTransactResult, {
723
- ok: false;
724
- }>;
725
- /**
726
- * Read the fragment through the bounded file-open trust boundary, merge its resources,
727
- * and land its blocks — all inside one transaction. Any refusal leaves the document
728
- * exactly as it was; the caller (the paste router) degrades to the next flavour.
729
- */
730
- declare function applyFragmentPaste(store: TreePackageStore, scope: StoryScope, input: FragmentPasteInput): FragmentPasteResult;
731
-
732
- export { resolveHeaderFooterResolutionBySection as $, type ApplyImagePropertiesInput as A, applyFragmentPaste as B, type CascadeDeletedNoteReferencesOptions as C, DEFAULT_MAX_EDITABLE_STORY_PARTS as D, applyHeaderFooterLifecycleOp as E, type FragmentPasteInput as F, applyNoteLifecycleOp as G, type HeaderFooterVariant as H, type InsertImageInput as I, cascadeDeletedNoteReferences as J, collectNoteReferences as K, collectPackageNoteReferences as L, MAX_FRAGMENT_DECODED_BYTES as M, type NoteDiagnostic as N, collectSectionPropertyNodes as O, type PackageTransactResult as P, createNoteReferenceScanBudget as Q, type ReplaceImageOptions as R, type StoryScope as S, TreePackageStore as T, diagnoseNoteReferences as U, isHeaderFooterLifecycleOp as V, isNoteLifecycleOp as W, normalNoteIds as X, notesPartHasId as Y, resolveHeaderFooterParts as Z, resolveHeaderFooterPartsBySection as _, type StoryTargetRejection as a, resolveNotesPart as a0, withBinaryPart as a1, withEmbeddedImage as a2, withoutUnreferencedImagePart as a3, type HeaderFooterParts as b, type HeaderFooterSectionResolution as c, type ImageIntentResult as d, type FragmentPasteResult as e, type DrawingPropertyIdResult as f, type HeaderFooterKind as g, type HeaderFooterLifecycleImpact as h, type HeaderFooterLifecycleOp as i, type HeaderFooterLifecycleRejection as j, type HeaderFooterLifecycleResult as k, type HeaderFooterSlotMeta as l, MAX_NOTE_REFERENCE_PARTS as m, MAX_NOTE_REFERENCE_SCAN as n, type NoteDiagnosticCode as o, type NoteLifecycleImpact as p, type NoteLifecycleOp as q, type NoteLifecycleOptions as r, type NoteLifecycleRejection as s, type NoteLifecycleResult as t, type NoteReferenceHit as u, type NoteReferenceScanBudget as v, type RemotePackageAttribution as w, type StoryResolveResult as x, type TreePackageStoreOptions as y, allocateDrawingPropertyId as z };