@betteroffice/docx 0.4.3 → 0.5.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 (124) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +108 -598
  3. package/dist/chunk-25WGDXBF.mjs +1 -0
  4. package/dist/chunk-2CCPNW44.mjs +1 -0
  5. package/dist/chunk-32A4I3T4.mjs +1 -0
  6. package/dist/chunk-4LO3PSLZ.mjs +2 -0
  7. package/dist/chunk-67MGRMP3.mjs +1 -0
  8. package/dist/chunk-6AUR4AA2.mjs +1 -0
  9. package/dist/chunk-6WT6HKAY.mjs +1 -0
  10. package/dist/chunk-77ZWGQZN.mjs +1 -0
  11. package/dist/chunk-7C3Y7LIH.mjs +1 -0
  12. package/dist/chunk-7WIUNGQW.mjs +1 -0
  13. package/dist/chunk-7WWFGMMF.mjs +1 -0
  14. package/dist/chunk-AK2NG7PT.mjs +1 -0
  15. package/dist/chunk-BR5BFOHF.mjs +1 -0
  16. package/dist/chunk-CDNWHQH2.mjs +1 -0
  17. package/dist/chunk-CRTTEHZN.mjs +1 -0
  18. package/dist/chunk-ETDMQ5GE.mjs +1 -0
  19. package/dist/{wasm-KSZTTO3B.mjs → chunk-GBOHQ3CJ.mjs} +1 -1
  20. package/dist/chunk-H7K4SJKK.mjs +1 -0
  21. package/dist/chunk-ICJH7QUY.mjs +1 -0
  22. package/dist/chunk-IHETKRDA.mjs +1 -0
  23. package/dist/chunk-ISBZLVIF.mjs +1 -0
  24. package/dist/chunk-JSYH6HNV.mjs +2 -0
  25. package/dist/chunk-KICHSQFN.mjs +1 -0
  26. package/dist/chunk-KXIGXLFA.mjs +5 -0
  27. package/dist/chunk-KXLTK7AT.mjs +57 -0
  28. package/dist/chunk-L3JRNJ34.mjs +1 -0
  29. package/dist/chunk-LKDHP22R.mjs +1 -0
  30. package/dist/chunk-LPOEM5WH.mjs +1 -0
  31. package/dist/chunk-M44BABH2.mjs +1 -0
  32. package/dist/chunk-MAYPJU23.mjs +1 -0
  33. package/dist/chunk-N5RE2S3U.mjs +2 -0
  34. package/dist/chunk-NLYHFVF5.mjs +1 -0
  35. package/dist/chunk-ONYCW7VV.mjs +4 -0
  36. package/dist/chunk-QGZ2AB3M.mjs +1 -0
  37. package/dist/chunk-QWHU7YIW.mjs +2 -0
  38. package/dist/{chunk-VH7P4734.mjs → chunk-QX2CDKPG.mjs} +1 -1
  39. package/dist/chunk-RGDE6YQB.mjs +1 -0
  40. package/dist/chunk-TE3AU2JK.mjs +1 -0
  41. package/dist/chunk-UDVEZ722.mjs +1 -0
  42. package/dist/chunk-UQSVFDRV.mjs +2 -0
  43. package/dist/chunk-VHOOSS4D.mjs +1 -0
  44. package/dist/chunk-WIDM4EMT.mjs +1 -0
  45. package/dist/chunk-YITJ4QAO.mjs +1 -0
  46. package/dist/collaboration/index.d.mts +111 -11
  47. package/dist/collaboration/index.mjs +1 -1
  48. package/dist/{content-DSb-6a9T.d.mts → content-DVT06V_6.d.mts} +24 -3
  49. package/dist/core.d.mts +9 -9
  50. package/dist/core.mjs +1 -1
  51. package/dist/displayListQueries-6XjS7B5e.d.mts +1473 -0
  52. package/dist/docx/index.d.mts +8 -7
  53. package/dist/docx/index.mjs +1 -2
  54. package/dist/docxWorker.mjs +1 -0
  55. package/dist/editor/index.d.mts +14 -12
  56. package/dist/editor/index.mjs +1 -1
  57. package/dist/{fontLoader-BNSs0E8K.d.mts → fontLoader-CBkmh4ps.d.mts} +1 -1
  58. package/dist/{formatting-gqLFeJ9X.d.mts → formatting-p5MneNuy.d.mts} +32 -1
  59. package/dist/generated/edit/docx_edit_bg.wasm +0 -0
  60. package/dist/generated/layout/docx_layout_bg.wasm +0 -0
  61. package/dist/generated/opc/ooxml_opc_bg.wasm +0 -0
  62. package/dist/generated/parse/docx_parse_bg.wasm +0 -0
  63. package/dist/index-C-KKULi5.d.mts +5596 -0
  64. package/dist/layout/index.d.mts +4 -4
  65. package/dist/layout/index.mjs +1 -1
  66. package/dist/layout/pagination/index.d.mts +4 -4
  67. package/dist/layout/render/index.d.mts +37 -53
  68. package/dist/layout/render/index.mjs +3 -1
  69. package/dist/{pagedExport-BmSlEhoP.d.mts → pagedExport-DDgA5O7E.d.mts} +92 -9
  70. package/dist/plugin-api/RenderedDomContext.d.mts +5 -7
  71. package/dist/plugin-api/index.d.mts +3 -3
  72. package/dist/plugin-api/resolveItemPositions.d.mts +3 -3
  73. package/dist/{rezip-Bxiq4Z_R.d.mts → rezip-CfwAYdV4.d.mts} +7 -1
  74. package/dist/styles/index.d.mts +3 -3
  75. package/dist/styles/index.mjs +1 -1
  76. package/dist/{styles-AryxLAhx.d.mts → styles-DZZz2oRy.d.mts} +2 -2
  77. package/dist/types/content.d.mts +2 -2
  78. package/dist/types/document.d.mts +6 -6
  79. package/dist/{types-Cz7S77Ut.d.mts → types-bvPg3KsF.d.mts} +16 -3
  80. package/dist/utils/comments.d.mts +2 -2
  81. package/dist/utils/findReplace.mjs +1 -2
  82. package/dist/utils/index.d.mts +5 -5
  83. package/dist/utils/index.mjs +1 -1
  84. package/dist/utils/listState.d.mts +2 -5
  85. package/dist/utils/stylePreview.d.mts +2 -2
  86. package/dist/utils/stylePreview.mjs +1 -1
  87. package/dist/wasm-edit.d.mts +233 -48
  88. package/dist/wasm-edit.mjs +1 -1
  89. package/dist/wasm-layout.d.mts +7 -1
  90. package/dist/wasm-layout.mjs +1 -1
  91. package/dist/wasm-opc.mjs +1 -1
  92. package/dist/wasm-parse.d.mts +7 -1
  93. package/dist/wasm-parse.mjs +1 -1
  94. package/dist/worker.d.mts +60 -0
  95. package/dist/worker.mjs +1 -0
  96. package/dist/yrs/docxWorker.d.mts +20 -0
  97. package/dist/yrs/docxWorker.mjs +3 -0
  98. package/dist/yrs/index.d.mts +12 -7
  99. package/dist/yrs/index.mjs +1 -1
  100. package/package.json +14 -4
  101. package/dist/chunk-3RPZ44TT.mjs +0 -1
  102. package/dist/chunk-47Q2FMFF.mjs +0 -1
  103. package/dist/chunk-5Z22FORG.mjs +0 -1
  104. package/dist/chunk-7ZV6P6NZ.mjs +0 -57
  105. package/dist/chunk-AXFMDV66.mjs +0 -1
  106. package/dist/chunk-EBYC3CX7.mjs +0 -1
  107. package/dist/chunk-FK7X7557.mjs +0 -1
  108. package/dist/chunk-GKWXOZZH.mjs +0 -1
  109. package/dist/chunk-LIOWZSE7.mjs +0 -1
  110. package/dist/chunk-ML6E23W2.mjs +0 -1
  111. package/dist/chunk-MLEMGJP7.mjs +0 -1
  112. package/dist/chunk-QBMNRD5V.mjs +0 -2
  113. package/dist/chunk-SHVHVJUB.mjs +0 -1
  114. package/dist/compareDocx-URPCPAQT.mjs +0 -1
  115. package/dist/computeLayout-ZTO6TBWX.mjs +0 -1
  116. package/dist/displayListQueries-BVBDVXoP.d.mts +0 -306
  117. package/dist/frameDelta-CLeO7K5z.d.mts +0 -807
  118. package/dist/index-DzZVJC8-.d.mts +0 -2467
  119. package/dist/parseWasm-BESKFFA3.mjs +0 -1
  120. package/dist/rustDisplayList-B7uPoItK.d.mts +0 -315
  121. package/dist/wasm-JPDPN2B2.mjs +0 -1
  122. package/dist/wasm-QI7MWC5D.mjs +0 -1
  123. package/dist/yrs/residentEngineWorker.d.mts +0 -2
  124. package/dist/yrs/residentEngineWorker.mjs +0 -1
@@ -0,0 +1,1473 @@
1
+ import { a as TextModernEffects } from './formatting-p5MneNuy.mjs';
2
+ import { D as DrawingScene, c as ShapeTextBodyProperties } from './content-DVT06V_6.mjs';
3
+ import { L as Layout } from './types-bvPg3KsF.mjs';
4
+ import { MeasuredBlock } from './layout/pagination/index.mjs';
5
+
6
+ interface DisplayList {
7
+ /** Contract version. Undefined reads as legacy version 0. */
8
+ contractVersion?: number;
9
+ pages: DisplayPage[];
10
+ }
11
+ /**
12
+ * Modern (`w14:*`) run text-effect payload carried on text/glyph primitives.
13
+ * Same shape as the document model's `TextModernEffects` — px distances,
14
+ * degree directions, 0..1 opacities, resolved `#rrggbb` colors.
15
+ */
16
+ type DisplayTextModernEffects = TextModernEffects;
17
+ interface DisplayPage {
18
+ pageIndex: number;
19
+ width: number;
20
+ height: number;
21
+ /** Authored body content box (page-local px), derived from page margins. */
22
+ contentBounds?: DisplayBounds;
23
+ /** Authored body column boxes in reading order (page-local px). */
24
+ columnBounds?: DisplayBounds[];
25
+ /** Stable section identity for this page. Undefined = legacy/global section. */
26
+ sectionId?: string;
27
+ /** Zero-based section ordinal. */
28
+ sectionIndex?: number;
29
+ /** Zero-based page ordinal within the section. */
30
+ sectionPageIndex?: number;
31
+ /** Effective page number within the section, after any restart. */
32
+ sectionPageNumber?: number;
33
+ /** Formatted PAGE label (for example, "vii"). */
34
+ pageLabel?: string;
35
+ primitives: DisplayPrimitive[];
36
+ /** Leading primitives painted beneath the header and footer. */
37
+ watermarkPrimitiveCount?: number;
38
+ /** Resolved page background. Undefined = transparent/host white. */
39
+ background?: string;
40
+ pageBorders?: PageBorderPrimitive[];
41
+ header?: HfRegion;
42
+ footer?: HfRegion;
43
+ /** Footnote/endnote regions in page coordinates. Undefined = none. */
44
+ noteAreas?: NoteRegion[];
45
+ /** Page-local rects of host layout reservations; nothing paints them. Undefined = none. */
46
+ reservations?: DisplayReservation[];
47
+ /** Table cell edges without a visible border, for a view-only overlay; nothing paints them. Undefined = none. */
48
+ tableGridlines?: DisplayGridline[];
49
+ /** Geometry only: the page's content is built when the host asks for it. */
50
+ unbuilt?: boolean;
51
+ /** For an unbuilt page, the lowest and highest body position its layout places. */
52
+ positionSpan?: [number, number];
53
+ /** For an unbuilt page, the relationship ids of the header and footer parts its build paints. */
54
+ hfParts?: {
55
+ header?: string;
56
+ footer?: string;
57
+ };
58
+ }
59
+ /** One table cell edge segment in page-local px. */
60
+ interface DisplayGridline {
61
+ x1: number;
62
+ y1: number;
63
+ x2: number;
64
+ y2: number;
65
+ }
66
+ /** Where a host's layout reservation landed, in page-local px. */
67
+ interface DisplayReservation extends DisplayBounds {
68
+ owner: string;
69
+ id: string;
70
+ }
71
+ /** A page-local rectangle emitted as display-list metadata. */
72
+ interface DisplayBounds {
73
+ x: number;
74
+ y: number;
75
+ width: number;
76
+ height: number;
77
+ }
78
+ /** Page note region; primitives retain normal doc/a11y metadata. */
79
+ interface NoteRegion {
80
+ kind?: 'footnote' | 'endnote';
81
+ sectionId?: string;
82
+ y?: number;
83
+ height?: number;
84
+ columns?: number;
85
+ separatorPrimitives?: DisplayPrimitive[];
86
+ primitives?: DisplayPrimitive[];
87
+ noteIds?: number[];
88
+ /**
89
+ * Per-note backlink metadata (W17): the body-doc range of each note's
90
+ * reference mark plus its formatted label, so the a11y mirror can wire
91
+ * note ↔ reference associations (doc-noteref / doc-backlink). Parallel to
92
+ * `noteIds`; undefined = legacy region without backlink data.
93
+ */
94
+ notes?: NoteRegionNote[];
95
+ }
96
+ /** Backlink metadata for one note in a NoteRegion. */
97
+ interface NoteRegionNote {
98
+ id?: number;
99
+ /** Body-doc range of the reference mark anchoring this note. */
100
+ anchorDocStart?: number;
101
+ anchorDocEnd?: number;
102
+ /** Formatted reference label (display number / custom mark). File-derived. */
103
+ label?: string;
104
+ }
105
+ interface HfRegion {
106
+ rId: string;
107
+ kind: 'header' | 'footer';
108
+ y: number;
109
+ height: number;
110
+ primitives: DisplayPrimitive[];
111
+ }
112
+ type DisplayPrimitive = TextRunPrimitive | GlyphRunPrimitive | RectPrimitive | LinePrimitive | ImagePrimitive | ShapePrimitive | DecorationPrimitive;
113
+ interface TableCellRef {
114
+ row: number;
115
+ col: number;
116
+ rowSpan: number;
117
+ colSpan: number;
118
+ continuation?: boolean;
119
+ /** Stable semantic cell identity. */
120
+ cellId?: string;
121
+ /** Cell participates as a row/column header. */
122
+ isHeader?: boolean;
123
+ /** Header cell was repeated on a continuation page. */
124
+ repeatedHeader?: boolean;
125
+ /** Word `w:noWrap` cell behavior. */
126
+ noWrap?: boolean;
127
+ /** IDs of header cells that label this data cell. */
128
+ headerIds?: string[];
129
+ /** Collapsed-border ownership retained for exact fragment replay. */
130
+ ownsTopBorder?: boolean;
131
+ ownsRightBorder?: boolean;
132
+ ownsBottomBorder?: boolean;
133
+ ownsLeftBorder?: boolean;
134
+ }
135
+ /** Table-fragment semantics shared by every primitive emitted for that fragment. */
136
+ interface DisplayTableMetadata {
137
+ tableId?: string;
138
+ rowStart?: number;
139
+ rowEnd?: number;
140
+ rowCount?: number;
141
+ columnCount?: number;
142
+ headerRowCount?: number;
143
+ caption?: string;
144
+ description?: string;
145
+ parentTableId?: string;
146
+ }
147
+ /** Resolved review presentation for the primitive's `commentIds`. */
148
+ interface DisplayCommentMetadata {
149
+ status?: 'active' | 'resolved';
150
+ authorId?: string;
151
+ paletteIndex?: number;
152
+ color?: string;
153
+ selected?: boolean;
154
+ /** Reviewer display name (file-derived, attacker-controlled). */
155
+ authorName?: string;
156
+ /** Comment date string, passed through verbatim. */
157
+ date?: string;
158
+ /** Plain-text comment body excerpt (builder-capped, file-derived). */
159
+ text?: string;
160
+ /** Number of replies in the thread. */
161
+ replyCount?: number;
162
+ /** Reply summaries in thread order (builder-capped). */
163
+ replies?: DisplayCommentReply[];
164
+ }
165
+ /** One reply summary inside DisplayCommentMetadata. */
166
+ interface DisplayCommentReply {
167
+ authorName?: string;
168
+ date?: string;
169
+ text?: string;
170
+ }
171
+ /**
172
+ * Inert field identity for a11y announcement. `instruction` is the raw Word
173
+ * field instruction, carried for announcement/inspection ONLY — it is never
174
+ * parsed into behavior or executed by any consumer (see the repo security guidelines security).
175
+ */
176
+ interface DisplayFieldMetadata {
177
+ /** Painter-resolved category (PAGE, NUMPAGES, DATE, TIME, OTHER). */
178
+ category?: string;
179
+ /** Raw Word field type token (e.g. TOC, PAGEREF, REF). */
180
+ type?: string;
181
+ /** Raw field instruction text (announce-only, builder-capped). */
182
+ instruction?: string;
183
+ }
184
+ /** Footnote/endnote reference identity on the body reference-mark primitive. */
185
+ interface DisplayNoteRef {
186
+ kind?: 'footnote' | 'endnote';
187
+ id?: number;
188
+ }
189
+ /** Scoped clip/group membership emitted by the Rust compiler. */
190
+ interface DisplayClipGroupMetadata {
191
+ id?: string;
192
+ clip?: {
193
+ x?: number;
194
+ y?: number;
195
+ w?: number;
196
+ h?: number;
197
+ };
198
+ opacity?: number;
199
+ }
200
+ /** Horizontal paint slot for text laid out with guessed metrics. */
201
+ interface DisplayPaintClip {
202
+ x: number;
203
+ w: number;
204
+ }
205
+ interface StructuralRevision {
206
+ scope: 'pmark' | 'table' | 'row' | 'cell';
207
+ author: string;
208
+ date?: string;
209
+ revisionId: string;
210
+ kind: 'ins' | 'del' | 'merge';
211
+ rowIndex?: number;
212
+ colIndex?: number;
213
+ }
214
+ interface SdtAttrs {
215
+ groupId: string;
216
+ sdtType: string;
217
+ depth?: number;
218
+ tag?: string;
219
+ alias?: string;
220
+ lock?: string;
221
+ checked?: boolean;
222
+ bound?: boolean;
223
+ repeatingItem?: boolean;
224
+ }
225
+ interface InlineSdtWidgetAttrs {
226
+ kind: 'checkbox';
227
+ /** Rich control kind. Undefined = legacy checkbox. */
228
+ controlKind?: 'checkbox' | 'dropDownList' | 'comboBox' | 'date' | 'picture' | 'repeatingSection';
229
+ groupId: string;
230
+ pos: number;
231
+ tag?: string;
232
+ alias?: string;
233
+ checked?: boolean;
234
+ controlId?: number;
235
+ value?: string;
236
+ selectedIndex?: number;
237
+ listItems?: Array<{
238
+ displayText?: string;
239
+ value?: string;
240
+ }>;
241
+ dateFormat?: string;
242
+ dateLanguage?: string;
243
+ locked?: boolean;
244
+ }
245
+ interface ChartA11yAttrs {
246
+ label: string;
247
+ }
248
+ interface DocAttrs {
249
+ docStart?: number;
250
+ docEnd?: number;
251
+ blockId?: number;
252
+ blockKey?: string;
253
+ fragmentDocStart?: number;
254
+ fragmentDocEnd?: number;
255
+ paraId?: string;
256
+ fromLine?: number;
257
+ toLine?: number;
258
+ /** Resolved line index within the owning paragraph. */
259
+ lineIndex?: number;
260
+ /**
261
+ * Table cell the primitive paints inside, when any. The a11y mirror builds
262
+ * real ARIA table semantics (role table/row/cell, aria-row/colindex) from
263
+ * this — without it a table block reads as a flat run of text.
264
+ */
265
+ cell?: TableCellRef;
266
+ /** Sanitized hyperlink target when this primitive paints linked content. */
267
+ href?: string;
268
+ /** Optional hyperlink tooltip/title for popup UI. */
269
+ tooltip?: string;
270
+ /** ScreenTip exposed as DOM `title`; undefined falls back to `tooltip`. */
271
+ linkTitle?: string;
272
+ /** Safe hyperlink target frame. */
273
+ linkTarget?: string;
274
+ /** Link history bit. Undefined = host-unmanaged. */
275
+ linkHistory?: boolean;
276
+ /** Location within the target document. */
277
+ linkDocLocation?: string;
278
+ commentIds?: string[];
279
+ /**
280
+ * Inert field identity when this primitive paints a field result. The a11y
281
+ * mirror announces it (data-field-* + aria-description); nothing executes it.
282
+ */
283
+ field?: DisplayFieldMetadata;
284
+ /**
285
+ * Footnote/endnote reference identity when this primitive is the body
286
+ * reference mark — the mirror renders it as a doc-noteref link to the
287
+ * note's mirror element (W17 backlinks).
288
+ */
289
+ noteRef?: DisplayNoteRef;
290
+ revision?: {
291
+ author: string;
292
+ date: string;
293
+ revisionId: string;
294
+ kind: 'ins' | 'del';
295
+ };
296
+ /** Synthetic numbering glyph for the first line of a list paragraph. */
297
+ listMarker?: boolean;
298
+ /** Pending suggestion paint for a synthetic numbering glyph. */
299
+ listMarkerRevision?: 'ins' | 'del';
300
+ structuralRevision?: StructuralRevision;
301
+ /** Innermost block-level content-control identity for this primitive. */
302
+ sdt?: SdtAttrs;
303
+ /** Full outer-to-inner content-control ancestry. */
304
+ sdtPath?: SdtAttrs[];
305
+ /** Inline content-control widget metadata when this text run is its glyph. */
306
+ inlineSdtWidget?: InlineSdtWidgetAttrs;
307
+ /** Accessibility summary for primitives that compose one chart block. */
308
+ chart?: ChartA11yAttrs;
309
+ /** Logical/source order, independent of visual bidi paint order. */
310
+ logicalOrder?: number;
311
+ /** Resolved bidi embedding level. */
312
+ bidiLevel?: number;
313
+ /** BCP-47 language for a11y/font fallback. */
314
+ lang?: string;
315
+ /** Decorative content is omitted from the accessibility mirror. */
316
+ decorative?: boolean;
317
+ /** Authored accessibility name. */
318
+ ariaLabel?: string;
319
+ /** Authored accessibility description. */
320
+ ariaDescription?: string;
321
+ /** Hidden authored object. Undefined = visible. */
322
+ hiddenObject?: boolean;
323
+ /** Stable logical scene/group identity. */
324
+ groupId?: string;
325
+ /** Review presentation for comment-associated primitives. */
326
+ comment?: DisplayCommentMetadata;
327
+ /** Scoped clip/group membership. Undefined = ungrouped. */
328
+ clipGroup?: DisplayClipGroupMetadata;
329
+ /** Enclosing table-fragment identity and accessibility semantics. */
330
+ table?: DisplayTableMetadata;
331
+ /** Inline native-shape atom; true only for paragraph-inline shapes. */
332
+ inlineShapeAtom?: boolean;
333
+ }
334
+ interface TextRunPrimitive extends DocAttrs {
335
+ kind: 'text';
336
+ text: string;
337
+ x: number;
338
+ baselineY: number;
339
+ width: number;
340
+ paintClip?: DisplayPaintClip;
341
+ font: string;
342
+ color: string;
343
+ letterSpacing?: number;
344
+ wordSpacing?: number;
345
+ rtl?: boolean;
346
+ /** 0..1 alpha applied only to this run. Absent = opaque. */
347
+ opacity?: number;
348
+ /** Degrees clockwise around the primitive's geometry center. Absent = 0. */
349
+ rotationDeg?: number;
350
+ /** Horizontal text scale as a percentage (100 = normal). Absent = 100. */
351
+ horizontalScale?: number;
352
+ /** Render glyphs uppercase without changing the accessible source text. */
353
+ allCaps?: boolean;
354
+ /** Render lowercase glyphs as small uppercase. */
355
+ smallCaps?: boolean;
356
+ /** Hidden run shown in editing view as dimmed/dotted, matching the DOM painter. */
357
+ hidden?: boolean;
358
+ /** CSS-like shadow effect from run formatting. */
359
+ textShadow?: 'shadow' | 'emboss' | 'imprint';
360
+ /** Outlined / hollow text. */
361
+ textOutline?: boolean;
362
+ /** CJK emphasis mark. */
363
+ emphasisMark?: 'dot' | 'comma' | 'circle' | 'underDot';
364
+ /** Legacy text-effect class hook for the a11y mirror. */
365
+ textEffect?: 'blinkBackground' | 'lights' | 'antsBlack' | 'antsRed' | 'shimmer' | 'sparkle';
366
+ /** Modern w14 text effects (glow/shadow/reflection/textFill/textOutline). */
367
+ modernEffects?: DisplayTextModernEffects;
368
+ /** Shaped tab/TOC leader metadata. Undefined = ordinary text. */
369
+ leaderGlyphs?: Omit<LeaderGlyphPrimitive, 'kind'>;
370
+ }
371
+ interface PositionedGlyph {
372
+ id: number;
373
+ x: number;
374
+ y: number;
375
+ cluster: number;
376
+ advance?: number;
377
+ /** Logical cluster order before bidi reordering. */
378
+ logicalOrder?: number;
379
+ /** Bidi embedding level for this cluster. */
380
+ bidiLevel?: number;
381
+ }
382
+ /** Shaped glyph run with source text for accessibility. */
383
+ interface GlyphRunPrimitive extends DocAttrs {
384
+ kind: 'glyphRun';
385
+ fontId: number;
386
+ size: number;
387
+ color: string;
388
+ text: string;
389
+ glyphs: PositionedGlyph[];
390
+ echo?: {
391
+ x: number;
392
+ right: number;
393
+ kern?: boolean;
394
+ primaryFont?: boolean;
395
+ kerning?: number;
396
+ letterSpacing?: number;
397
+ position?: number;
398
+ scale?: number;
399
+ canEmpty?: boolean;
400
+ /** Unstretched width of a line that justification stretches to `right`. */
401
+ stretch?: number;
402
+ /** Width a centered line centers in from `x`. */
403
+ centerWidth?: number;
404
+ };
405
+ paintClip?: DisplayPaintClip;
406
+ fallbackFont?: string;
407
+ wordSpacing?: number;
408
+ rtl?: boolean;
409
+ /** 0..1 alpha applied only to this run. Absent = opaque. */
410
+ opacity?: number;
411
+ /** Degrees clockwise around the primitive's geometry center. Absent = 0. */
412
+ rotationDeg?: number;
413
+ /** Horizontal text scale as a percentage (100 = normal). Absent = 100. */
414
+ horizontalScale?: number;
415
+ /** Render glyphs uppercase without changing the accessible source text. */
416
+ allCaps?: boolean;
417
+ /** Render lowercase glyphs as small uppercase. */
418
+ smallCaps?: boolean;
419
+ /** Hidden run shown in editing view as dimmed/dotted, matching the DOM painter. */
420
+ hidden?: boolean;
421
+ /** CSS-like shadow effect from run formatting. */
422
+ textShadow?: 'shadow' | 'emboss' | 'imprint';
423
+ /** Outlined / hollow text. */
424
+ textOutline?: boolean;
425
+ /** CJK emphasis mark. */
426
+ emphasisMark?: 'dot' | 'comma' | 'circle' | 'underDot';
427
+ /** Legacy text-effect class hook for the a11y mirror. */
428
+ textEffect?: 'blinkBackground' | 'lights' | 'antsBlack' | 'antsRed' | 'shimmer' | 'sparkle';
429
+ /** Modern w14 text effects (glow/shadow/reflection/textFill/textOutline). */
430
+ modernEffects?: DisplayTextModernEffects;
431
+ /** Shaped tab/TOC leader metadata. Undefined = ordinary glyph run. */
432
+ leaderGlyphs?: Omit<LeaderGlyphPrimitive, 'kind'>;
433
+ }
434
+ interface RectPrimitive extends DocAttrs {
435
+ kind: 'rect';
436
+ x: number;
437
+ y: number;
438
+ w: number;
439
+ h: number;
440
+ fill: string;
441
+ /** Alpha multiplier. Undefined = 1. */
442
+ opacity?: number;
443
+ }
444
+ /** Word/CSS line recipe retained instead of flattening to a solid stroke. */
445
+ type DisplayBorderStyle = 'solid' | 'double' | 'dotted' | 'dashed' | 'dashDot' | 'dashDotDot' | 'triple' | 'thinThick' | 'thickThin' | 'wave' | 'doubleWave' | 'groove' | 'ridge' | 'inset' | 'outset';
446
+ interface LinePrimitive extends DocAttrs {
447
+ kind: 'line';
448
+ x1: number;
449
+ y1: number;
450
+ x2: number;
451
+ y2: number;
452
+ strokeWidth: number;
453
+ color: string;
454
+ dash?: number[];
455
+ role?: 'border' | 'table-border' | 'table-cut' | 'separator';
456
+ /** Full border recipe. Undefined = infer solid/dash from `dash`. */
457
+ borderStyle?: DisplayBorderStyle;
458
+ /** Secondary color for 3-D/multi-stroke recipes. */
459
+ secondaryColor?: string;
460
+ /** Alpha multiplier. Undefined = 1. */
461
+ opacity?: number;
462
+ /** Owner of the retained Word border recipe. */
463
+ borderOwner?: 'cell' | 'fragment' | 'paragraph' | 'textBox';
464
+ }
465
+ interface PageBorderSide {
466
+ width: number;
467
+ color: string;
468
+ style: 'solid' | 'double' | 'dotted' | 'dashed' | 'groove' | 'ridge' | 'inset' | 'outset';
469
+ }
470
+ interface PageBorderPrimitive {
471
+ kind: 'pageBorder';
472
+ x: number;
473
+ y: number;
474
+ w: number;
475
+ h: number;
476
+ zOrder?: 'front' | 'back';
477
+ top?: PageBorderSide;
478
+ right?: PageBorderSide;
479
+ bottom?: PageBorderSide;
480
+ left?: PageBorderSide;
481
+ }
482
+ interface ImagePrimitive extends DocAttrs {
483
+ kind: 'image';
484
+ shapeType?: string;
485
+ relId: string;
486
+ x: number;
487
+ y: number;
488
+ w: number;
489
+ h: number;
490
+ rotationDeg?: number;
491
+ /** 0..1 alpha applied only to this image. Absent = opaque. */
492
+ opacity?: number;
493
+ /** Flip about the content-frame center. Undefined = false. */
494
+ flipH?: boolean;
495
+ /** Flip about the content-frame center. Undefined = false. */
496
+ flipV?: boolean;
497
+ /** Original image frame when w/h are a transformed layout bbox. */
498
+ contentFrame?: {
499
+ x?: number;
500
+ y?: number;
501
+ w?: number;
502
+ h?: number;
503
+ };
504
+ /** Canvas/CSS filter string for renderer-owned effects, e.g. watermark washout. */
505
+ filter?: string;
506
+ /** True for decorative/non-content images such as picture watermarks. */
507
+ decorative?: boolean;
508
+ crop?: {
509
+ top: number;
510
+ right: number;
511
+ bottom: number;
512
+ left: number;
513
+ };
514
+ altText?: string;
515
+ /** Ordered image effects. Undefined = use legacy `filter` only. */
516
+ effects?: Array<{
517
+ kind?: string;
518
+ amount?: number;
519
+ threshold?: number;
520
+ colors?: string[];
521
+ rawName?: string;
522
+ }>;
523
+ /** Picture border recipe. Undefined = none. */
524
+ border?: {
525
+ width?: number;
526
+ color?: string;
527
+ style?: string;
528
+ dash?: number[];
529
+ };
530
+ }
531
+ type ShapePathCommand = {
532
+ type: 'move';
533
+ x: number;
534
+ y: number;
535
+ } | {
536
+ type: 'line';
537
+ x: number;
538
+ y: number;
539
+ } | {
540
+ type: 'quad';
541
+ cpx: number;
542
+ cpy: number;
543
+ x: number;
544
+ y: number;
545
+ } | {
546
+ type: 'cubic';
547
+ cp1x: number;
548
+ cp1y: number;
549
+ cp2x: number;
550
+ cp2y: number;
551
+ x: number;
552
+ y: number;
553
+ } | {
554
+ type: 'close';
555
+ };
556
+ interface ShapePrimitive extends DocAttrs {
557
+ kind: 'shape';
558
+ x: number;
559
+ y: number;
560
+ w: number;
561
+ h: number;
562
+ /** Page-local path commands scaled from the shape's normalized geometry. */
563
+ geometryPath: ShapePathCommand[];
564
+ fill?: string;
565
+ stroke?: {
566
+ color: string;
567
+ width: number;
568
+ /** DrawingML/CSS dash style token. */
569
+ dash?: string;
570
+ };
571
+ transform?: {
572
+ rotation?: number;
573
+ flipH?: boolean;
574
+ flipV?: boolean;
575
+ };
576
+ /** True when the shape carries no accessible inner text. */
577
+ decorative?: boolean;
578
+ /** Alpha multiplier. Undefined = 1. */
579
+ opacity?: number;
580
+ /** Lossless paint server; undefined = legacy `fill`. */
581
+ fillPaint?: {
582
+ kind?: 'none' | 'solid' | 'gradient' | 'pattern' | 'picture' | 'theme';
583
+ color?: string;
584
+ angle?: number;
585
+ gradientType?: string;
586
+ stops?: Array<{
587
+ position?: number;
588
+ color?: string;
589
+ }>;
590
+ patternPreset?: string;
591
+ foregroundColor?: string;
592
+ backgroundColor?: string;
593
+ pictureRelId?: string;
594
+ /**
595
+ * Resolved SAFE embedded source for a picture fill (`blob:`/`data:` only —
596
+ * external-mode blip relationships are never resolved, so opening a file
597
+ * cannot trigger a network fetch). The canvas image resolver rejects any
598
+ * other scheme as defense in depth. Absent = unresolvable, paint the
599
+ * legacy `fill`/`color` instead.
600
+ */
601
+ pictureSrc?: string;
602
+ /** Picture source crop fractions (`a:srcRect`, 0..1; negative = outset). */
603
+ pictureSrcRect?: {
604
+ left?: number;
605
+ top?: number;
606
+ right?: number;
607
+ bottom?: number;
608
+ };
609
+ /** Picture fill mode. Absent = 'stretch' (`a:stretch`). */
610
+ pictureFillMode?: 'stretch' | 'tile';
611
+ /** Tile parameters when `pictureFillMode` = 'tile'. Offsets px, scales fractions. */
612
+ pictureTile?: {
613
+ offsetX?: number;
614
+ offsetY?: number;
615
+ scaleX?: number;
616
+ scaleY?: number;
617
+ alignment?: string;
618
+ flip?: 'none' | 'x' | 'y' | 'xy';
619
+ };
620
+ /** Stretch target rect fractions of the shape box (`a:fillRect`, 0..1). */
621
+ pictureStretchRect?: {
622
+ left?: number;
623
+ top?: number;
624
+ right?: number;
625
+ bottom?: number;
626
+ };
627
+ /** Picture alpha 0..1 (`a:alphaModFix`). Absent = opaque. */
628
+ pictureOpacity?: number;
629
+ themeRefIndex?: number;
630
+ };
631
+ /** Lossless DrawingML stroke details beyond the legacy `stroke` triple. */
632
+ strokePaint?: {
633
+ color?: string;
634
+ width?: number;
635
+ dash?: string;
636
+ customDash?: number[];
637
+ compound?: 'single' | 'double' | 'thickThin' | 'thinThick' | 'triple';
638
+ alignment?: 'center' | 'inset';
639
+ cap?: 'flat' | 'round' | 'square';
640
+ join?: 'bevel' | 'miter' | 'round';
641
+ miterLimit?: number;
642
+ headEnd?: {
643
+ type?: string;
644
+ width?: string;
645
+ length?: string;
646
+ };
647
+ tailEnd?: {
648
+ type?: string;
649
+ width?: string;
650
+ length?: string;
651
+ };
652
+ };
653
+ /** Ordered 2-D effects. Undefined = none. */
654
+ effects?: Array<{
655
+ kind?: string;
656
+ color?: string;
657
+ opacity?: number;
658
+ blurRadius?: number;
659
+ distance?: number;
660
+ direction?: number;
661
+ size?: number;
662
+ rawName?: string;
663
+ }>;
664
+ /** Effect extents in page px. Undefined = zero. */
665
+ effectExtent?: {
666
+ top?: number;
667
+ right?: number;
668
+ bottom?: number;
669
+ left?: number;
670
+ };
671
+ /** Versioned heterogeneous DrawingML group/canvas scene. */
672
+ drawingScene?: DrawingScene;
673
+ /** Full DrawingML `a:bodyPr` projection for shape text. */
674
+ textBodyProperties?: ShapeTextBodyProperties;
675
+ }
676
+ interface DecorationPrimitive extends DocAttrs {
677
+ kind: 'decoration';
678
+ deco: 'underline' | 'strike' | 'highlight' | 'comment-range' | 'spell';
679
+ x: number;
680
+ y: number;
681
+ w: number;
682
+ h: number;
683
+ color: string;
684
+ dashed?: boolean;
685
+ dotted?: boolean;
686
+ /** Exact highlight font-box/source slice. Undefined = legacy rect. */
687
+ highlightSlice?: {
688
+ sourceStart?: number;
689
+ sourceEnd?: number;
690
+ ascent?: number;
691
+ descent?: number;
692
+ includesTrailingWhitespace?: boolean;
693
+ };
694
+ /** Full border/decoration recipe. Undefined = solid/dashed/dotted flags. */
695
+ style?: DisplayBorderStyle;
696
+ }
697
+ /** Shaped tab/TOC leader glyphs; absent metrics mean no painted leader. */
698
+ interface LeaderGlyphPrimitive extends DocAttrs {
699
+ /** Primitive tag. Undefined when embedded as run metadata. */
700
+ kind?: 'leaderGlyphs';
701
+ glyph?: string;
702
+ count?: number;
703
+ x?: number;
704
+ baselineY?: number;
705
+ advance?: number;
706
+ width?: number;
707
+ font?: string;
708
+ fontId?: number;
709
+ size?: number;
710
+ color?: string;
711
+ rtl?: boolean;
712
+ }
713
+
714
+ /**
715
+ * Locate an image primitive in a built DisplayList by its document position.
716
+ *
717
+ * The canvas image-selection overlay needs the selected image's page-local
718
+ * rect to place its resize handles, and on the canvas path the painted DOM
719
+ * image (`.layout-run-image`) is parked/hidden — its rect is unusable. The
720
+ * display list carries every inline image as an `ImagePrimitive` stamped with
721
+ * `docStart` (= the image atom's document position, the same value the DOM path reads
722
+ * from `data-doc-start`), so the primitive found here is the geometry source
723
+ * that replaces `imageInfo.element.getBoundingClientRect()`.
724
+ *
725
+ * Body primitives only: header/footer image primitives carry doc positions in a
726
+ * different doc (the HF editor), so a body image pmPos must never match one.
727
+ *
728
+ */
729
+
730
+ type DisplayListImageRegion = 'body' | 'header' | 'footer';
731
+ interface LocatedImagePrimitive {
732
+ primitive: ImagePrimitive;
733
+ /** page the primitive paints on (page-local px are relative to this page) */
734
+ pageIndex: number;
735
+ /** Document region containing the image. Undefined reads as body. */
736
+ region?: DisplayListImageRegion;
737
+ /** Header/footer relationship id when `region` is not body. */
738
+ rId?: string;
739
+ }
740
+ /**
741
+ * First body image primitive whose `docStart` equals `pos`, or null. `pos` is
742
+ * the image node's document position (a node selection's `from`, or the left
743
+ * edge of a one-atom text selection).
744
+ */
745
+ declare function findImagePrimitiveByDocPos(list: DisplayList, pos: number, region?: DisplayListImageRegion, rId?: string): LocatedImagePrimitive | null;
746
+ /** Topmost positioned image painted under a page-local point, or null. */
747
+ declare function findImagePrimitiveAtPoint(list: DisplayList, pageIndex: number, x: number, y: number, region?: DisplayListImageRegion, rId?: string): LocatedImagePrimitive | null;
748
+ /**
749
+ * Capture an inline body's authored anchor offsets from display-list geometry.
750
+ * Horizontal position is relative to the page content/column box; vertical
751
+ * position is relative to the containing paragraph fragment. Header/footer
752
+ * images deliberately return undefined until their paragraph/content-origin
753
+ * metadata is part of the display-list contract.
754
+ */
755
+ declare function captureInlinePositionEmuFromDisplayList(queries: DisplayListQueries, pos: number): {
756
+ horizontalEmu: number;
757
+ verticalEmu: number;
758
+ } | undefined;
759
+
760
+ declare const FRAME_DELTA_VERSION = 1;
761
+ declare const FRAME_DELTA_HEADER_BYTES = 80;
762
+ declare const FRAME_DELTA_PAGE_OP_BYTES = 48;
763
+ type FrameDeltaErrorCode = 'invalid-frame' | 'unsupported-version' | 'stale-frame' | 'base-mismatch';
764
+ declare class FrameDeltaError extends Error {
765
+ readonly code: FrameDeltaErrorCode;
766
+ constructor(code: FrameDeltaErrorCode, message: string);
767
+ }
768
+ interface FramePageUpsert {
769
+ readonly kind: 'upsert';
770
+ readonly pageIndex: number;
771
+ readonly pageId: bigint;
772
+ readonly fingerprint: bigint;
773
+ /** Zero-copy view into {@link DecodedFrameDelta.bytes}. */
774
+ readonly primitiveIds: BigUint64Array;
775
+ readonly page: DisplayPage;
776
+ }
777
+ interface FramePageRemove {
778
+ readonly kind: 'remove';
779
+ readonly pageIndex: number;
780
+ readonly pageId: bigint;
781
+ }
782
+ interface FramePageMove {
783
+ readonly kind: 'move';
784
+ readonly pageIndex: number;
785
+ readonly pageId: bigint;
786
+ readonly fingerprint: bigint;
787
+ }
788
+ interface FramePrimitivePositionPatch {
789
+ readonly primitiveId: bigint;
790
+ readonly docStart?: number | null;
791
+ readonly docEnd?: number | null;
792
+ readonly fragmentDocStart?: number | null;
793
+ readonly fragmentDocEnd?: number | null;
794
+ readonly inlineWidgetPos?: number | null;
795
+ }
796
+ interface FramePagePositionPatch {
797
+ readonly kind: 'patch-positions';
798
+ readonly pageIndex: number;
799
+ readonly pageId: bigint;
800
+ readonly fingerprint: bigint;
801
+ readonly patches: readonly FramePrimitivePositionPatch[];
802
+ }
803
+ interface FramePositionShiftRun {
804
+ readonly start: number;
805
+ readonly count: number;
806
+ readonly changedMask: number;
807
+ readonly delta: number;
808
+ }
809
+ /** A note region note's new backlink anchor; null clears the field. */
810
+ interface FrameNoteAnchor {
811
+ readonly area: number;
812
+ readonly note: number;
813
+ readonly start: number | null;
814
+ readonly end: number | null;
815
+ }
816
+ interface FramePagePositionShift {
817
+ readonly kind: 'shift-positions';
818
+ readonly pageIndex: number;
819
+ readonly pageId: bigint;
820
+ readonly fingerprint: bigint;
821
+ readonly runs: readonly FramePositionShiftRun[];
822
+ readonly anchors: readonly FrameNoteAnchor[];
823
+ readonly spanDelta?: number;
824
+ }
825
+ /** Shift the body positions and fingerprints of consecutive retained pages. */
826
+ interface FramePageShiftRange {
827
+ readonly kind: 'shift-range';
828
+ readonly pageIndex: number;
829
+ readonly pageId: bigint;
830
+ readonly count: number;
831
+ readonly delta: number;
832
+ readonly salt: bigint;
833
+ }
834
+ type FramePageOperation = FramePageUpsert | FramePageRemove | FramePageMove | FramePagePositionPatch | FramePagePositionShift | FramePageShiftRange;
835
+ interface DecodedFrameDelta {
836
+ readonly protocolVersion: typeof FRAME_DELTA_VERSION;
837
+ readonly full: boolean;
838
+ readonly docEpoch: number;
839
+ readonly layoutEpoch: number;
840
+ readonly frameEpoch: number;
841
+ readonly baseFrameEpoch: number;
842
+ readonly pageCount: number;
843
+ readonly contractVersion?: number;
844
+ readonly operations: readonly FramePageOperation[];
845
+ /** Complete binary frame; safe to transfer when the caller owns its buffer. */
846
+ readonly bytes: Uint8Array;
847
+ }
848
+ interface RetainedFramePage {
849
+ readonly pageIndex: number;
850
+ readonly pageId: bigint;
851
+ readonly fingerprint: bigint;
852
+ readonly primitiveIds: BigUint64Array;
853
+ readonly page: DisplayPage;
854
+ }
855
+ interface RetainedFrame {
856
+ readonly protocolVersion: typeof FRAME_DELTA_VERSION;
857
+ readonly docEpoch: number;
858
+ readonly layoutEpoch: number;
859
+ readonly frameEpoch: number;
860
+ readonly contractVersion?: number;
861
+ readonly pages: readonly RetainedFramePage[];
862
+ /** IDs whose canvas/mirror/interactive projections must be replaced. */
863
+ readonly damagedPageIds: ReadonlySet<bigint>;
864
+ /** Removed surfaces, retained separately because they are absent from pages. */
865
+ readonly removedPageIds: ReadonlySet<bigint>;
866
+ readonly displayList: DisplayList;
867
+ }
868
+ /**
869
+ * Decode and fully validate one binary FrameDelta v1 without mutating retained
870
+ * browser state. Page payloads are typed values, not embedded JSON strings.
871
+ */
872
+ declare function decodeFrameDelta(input: Uint8Array | ArrayBuffer): DecodedFrameDelta;
873
+ /** @internal Decode in resumable slices without publishing partial state. */
874
+ declare function decodeFrameDeltaSteps(input: Uint8Array | ArrayBuffer): Generator<void, DecodedFrameDelta>;
875
+ /** Apply one already-validated frame atomically, rejecting stale generations. */
876
+ declare function applyFrameDelta(previous: RetainedFrame | null, delta: DecodedFrameDelta): RetainedFrame;
877
+ /**
878
+ * Apply a frame while reusing position-only page arenas owned exclusively by
879
+ * the caller. Worker/main resident-engine hot paths replace their outer frame
880
+ * atomically and have no concurrent readers; avoiding deep suffix clones keeps
881
+ * geometry shifts from creating periodic multi-megabyte GC stalls.
882
+ */
883
+ declare function applyFrameDeltaOwned(previous: RetainedFrame | null, delta: DecodedFrameDelta): RetainedFrame;
884
+ /** Position shift revision, omitted from serialization. */
885
+ declare function displayPageRevision(page: DisplayPage): number;
886
+ /** @internal Whether `page` has only copied position shifts since `base`. */
887
+ declare function displayPageIsShiftOf(page: DisplayPage, base: DisplayPage): boolean;
888
+ /** Counts shifts touching this page's note anchors. */
889
+ declare function displayPageNoteAnchorRevision(page: DisplayPage): number;
890
+
891
+ /**
892
+ * JS seam to the Rust display-list builder.
893
+ *
894
+ * Marshals the `{ measured, options, layout }` envelope across the wasm
895
+ * boundary and hands back a DisplayList. Every paint and geometry decision
896
+ * happens in Rust; this module is serialization glue and nothing else, so a
897
+ * failure here is terminal — the types below carry no second engine to fall
898
+ * back to, only a typed {@link RustDisplayListSourceError} naming the stage
899
+ * that failed.
900
+ *
901
+ * Two transports exist. {@link buildRustDisplayList} sends the whole envelope
902
+ * and parses a DisplayList back. {@link buildRustDisplayFrame} prefers an
903
+ * engine that already retains pagination: it sends only the display-level
904
+ * extras and receives a binary FrameDelta, which is applied to the previous
905
+ * frame so unchanged pages keep object identity — the invariant the query
906
+ * facade's page-delta adoption depends on. An engine without
907
+ * `buildDisplayListFrame` takes the full-JSON path instead.
908
+ *
909
+ * The wasm module is loaded lazily on first build, so the inlined binary costs
910
+ * nothing until a display list is actually requested.
911
+ */
912
+
913
+ /**
914
+ * One header/footer part in the `headersFooters` envelope field: the measured
915
+ * blocks of the header/footer document identified by `rId`, plus the band
916
+ * metrics the caller already computed. The builder passes the metrics through
917
+ * verbatim and re-derives none of them.
918
+ */
919
+ interface DisplayListHfVariant {
920
+ rId: string;
921
+ kind: 'header' | 'footer';
922
+ type: 'default' | 'first' | 'even';
923
+ /** `toMeasuredBlocks(content.blocks, content.measures)` — same schema as body `measured` */
924
+ measured: MeasuredBlock[];
925
+ /** HeaderFooterContent.height (in-flow stack incl. floating blocks) */
926
+ height: number;
927
+ /** HeaderFooterContent.flowHeight (in-flow band height; fallback: height) */
928
+ flowHeight?: number;
929
+ visualTop?: number;
930
+ visualBottom?: number;
931
+ /**
932
+ * Per-page resolved widths of PAGE/NUMPAGES field runs in this HF part, so a
933
+ * centered/right-aligned line carrying such a field re-centers per page. The
934
+ * line width is measured ONCE at the field's fallback text ("1"), so without
935
+ * this the builder holds the same centered position on every page even though
936
+ * "Page 2 of 3"/"Page 10 of 12" have different widths. Omitted ⇒ the fields
937
+ * ride the char-distributed fallback width on every page.
938
+ */
939
+ fieldWidths?: DisplayListFieldWidths[];
940
+ }
941
+ /**
942
+ * Per-page widths of one PAGE/NUMPAGES field run in an HF part. `pmStart` is the
943
+ * field run's position in the header/footer document, and is the key the Rust
944
+ * builder matches on. `fallbackWidth` is the width the measure baked into `line.width`
945
+ * (the field's fallback text); `perPage[i]` is the width of the field's resolved
946
+ * text on layout page index `i` (PAGE → that page's number, NUMPAGES → total).
947
+ */
948
+ interface DisplayListFieldWidths {
949
+ pmStart: number;
950
+ fallbackWidth: number;
951
+ perPage: number[];
952
+ }
953
+ /**
954
+ * Optional header/footer payload of the builder envelope. Absent ⇒ the Rust
955
+ * output is byte-identical to the body-only build. Flags come off the section
956
+ * properties / settings the DOM painter uses; distances are the same px the
957
+ * painter resolves (`headerDistance ?? page.margins.header ?? 48`).
958
+ */
959
+ interface DisplayListHeadersFooters {
960
+ titlePg?: boolean;
961
+ evenAndOddHeaders?: boolean;
962
+ headerDistance?: number;
963
+ footerDistance?: number;
964
+ /** Page-level Word watermark, painted behind body/header/footer content. */
965
+ watermark?: DisplayListWatermark;
966
+ variants: DisplayListHfVariant[];
967
+ /** Stable section identity. Undefined ⇒ the envelope covers the whole document. */
968
+ sectionId?: string;
969
+ /** Zero-based section index. */
970
+ sectionIndex?: number;
971
+ }
972
+ type DisplayListWatermark = DisplayListTextWatermark | DisplayListPictureWatermark;
973
+ interface DisplayListTextWatermark {
974
+ kind: 'text';
975
+ text: string;
976
+ font: string;
977
+ color: string;
978
+ semitransparent: boolean;
979
+ layout: 'diagonal' | 'horizontal';
980
+ fontSize?: number;
981
+ /** Undefined defaults to true for watermarks. */
982
+ decorative?: boolean;
983
+ }
984
+ interface DisplayListPictureWatermark {
985
+ kind: 'picture';
986
+ relId?: string;
987
+ dataUrl?: string;
988
+ scale: number;
989
+ washout: boolean;
990
+ widthEmu?: number;
991
+ heightEmu?: number;
992
+ /** Undefined defaults to true for watermarks. */
993
+ decorative?: boolean;
994
+ }
995
+ /** One measured note in a page/section note area. */
996
+ interface DisplayListNoteItem {
997
+ kind?: 'footnote' | 'endnote';
998
+ id?: number;
999
+ displayLabel?: string;
1000
+ measured?: MeasuredBlock[];
1001
+ height?: number;
1002
+ anchorDocStart?: number;
1003
+ anchorDocEnd?: number;
1004
+ customMarkFollows?: boolean;
1005
+ }
1006
+ /** Typed non-fragmented note-region input for the Rust display builder. */
1007
+ interface DisplayListNoteArea {
1008
+ pageIndex?: number;
1009
+ sectionId?: string;
1010
+ kind?: 'footnote' | 'endnote';
1011
+ placement?: 'pageBottom' | 'beneathText' | 'sectEnd' | 'docEnd';
1012
+ y?: number;
1013
+ height?: number;
1014
+ columns?: number;
1015
+ separator?: DisplayListNoteItem;
1016
+ notes?: DisplayListNoteItem[];
1017
+ }
1018
+ /** Stable reviewer palette entry for comments/revisions. */
1019
+ interface DisplayListCommentAuthor {
1020
+ id?: string;
1021
+ name?: string;
1022
+ paletteIndex?: number;
1023
+ color?: string;
1024
+ }
1025
+ /** One reply of a comment thread (a11y announcement input). */
1026
+ interface DisplayListCommentReply {
1027
+ id?: number;
1028
+ authorId?: string;
1029
+ authorName?: string;
1030
+ date?: string;
1031
+ /** Plain-text body (the builder caps it before it reaches primitives). */
1032
+ text?: string;
1033
+ }
1034
+ /**
1035
+ * Per-comment thread metadata keyed by comment id, joined by the builder onto
1036
+ * every primitive carrying that id in `commentIds` so the a11y mirror can
1037
+ * announce the complete thread (author name, date, body, replies). All string
1038
+ * values are file-derived/attacker-controlled; consumers must only ever
1039
+ * assign them via textContent/setAttribute.
1040
+ */
1041
+ interface DisplayListCommentThread {
1042
+ /** Comment id — matches the numeric ids in `resolvedCommentIds`/`commentIds`. */
1043
+ id?: number;
1044
+ authorId?: string;
1045
+ authorName?: string;
1046
+ date?: string;
1047
+ /** Plain-text body (builder-capped before emission). */
1048
+ text?: string;
1049
+ /** Replies in thread order (builder-capped count and text). */
1050
+ replies?: DisplayListCommentReply[];
1051
+ }
1052
+ /** The `{ measured, options, layout }` envelope the Rust builder consumes. */
1053
+ interface DisplayListBuildInputs {
1054
+ /** Serialization contract version. Undefined reads as version 0. */
1055
+ contractVersion?: number;
1056
+ measured: MeasuredBlock[];
1057
+ options: unknown;
1058
+ layout: Layout;
1059
+ /** header/footer parts + section flags; omitted ⇒ body-only display list */
1060
+ headersFooters?: DisplayListHeadersFooters;
1061
+ /**
1062
+ * Doc-wide font-id chains keyed `"<family lowercase>|<bold 0|1>|<italic 0|1>"`
1063
+ * → measurement `FontStore` ids — the SAME map the measurement input carries.
1064
+ * Present only under Rust measurement (the ids must belong to a populated
1065
+ * store); its presence against that store is what gates GlyphRun emission.
1066
+ * Omitted ⇒ every text run is emitted as a browser-measured
1067
+ * `TextRunPrimitive` rather than a shaped `GlyphRun`.
1068
+ */
1069
+ fontChains?: Record<string, number[]>;
1070
+ /** Page/section note regions. Undefined = no note emission. */
1071
+ noteAreas?: DisplayListNoteArea[];
1072
+ /** Resolved comments suppressed from active tint. Undefined = none known. */
1073
+ resolvedCommentIds?: number[];
1074
+ /** Stable reviewer palette. Undefined ⇒ the builder's built-in colors. */
1075
+ commentAuthors?: DisplayListCommentAuthor[];
1076
+ /** Per-comment thread metadata for a11y announcements. Undefined = none. */
1077
+ commentThreads?: DisplayListCommentThread[];
1078
+ }
1079
+ /**
1080
+ * Minimal build surface, injectable so tests can fake the wasm module. Only
1081
+ * `buildDisplayListJson` is required; the optional members are what an engine
1082
+ * that retains its own pagination and display state additionally offers.
1083
+ */
1084
+ interface RustDisplayListEngine {
1085
+ buildDisplayListJson(input: string): string;
1086
+ /** Binary FrameDelta build; the stateless layout wasm does not offer it. */
1087
+ buildDisplayListFrame?(input: string, expectedFrameEpoch: number): Uint8Array;
1088
+ /** Applies one keystroke and returns its frame, without a layout round trip. */
1089
+ applyInput?(text: string, expectedFrameEpoch: number): Uint8Array;
1090
+ displayHitTestRegionsJson?(pageIndex: number, x: number, y: number): string;
1091
+ displayVerticalMoveJson?(position: number, direction: 'up' | 'down', goalX: number): string;
1092
+ displayRangeRectsJson?(from: number, to: number): string;
1093
+ /** @internal */
1094
+ displayRangeRectsOnPagesJson?(from: number, to: number, firstPage: number, lastPage: number): string;
1095
+ displayRangeRectsRegionJson?(region: string, partId: string, from: number, to: number): string;
1096
+ /** The bytes and media type of the part a `media:{n}` image source names. */
1097
+ mediaSource?(token: string): {
1098
+ bytes: Uint8Array;
1099
+ mimeType: string;
1100
+ } | null;
1101
+ /** Changes whenever the package `mediaSource` reads changes. */
1102
+ mediaScope?(): number;
1103
+ }
1104
+ type RustDisplayListSourceErrorStage = 'load' | 'build' | 'parse' | 'decode' | 'apply';
1105
+ interface RustDisplayFrameResult {
1106
+ displayList: DisplayList;
1107
+ /**
1108
+ * The retained frame to pass as `previous` on the next build. Null when the
1109
+ * engine answered over full JSON, which retains nothing.
1110
+ */
1111
+ frame: RetainedFrame | null;
1112
+ transport: 'frame-delta-v1' | 'json';
1113
+ }
1114
+ /**
1115
+ * Typed terminal error from the mandatory Rust display-list source. Hosts may
1116
+ * surface this through their editor error boundary; it is never permission to
1117
+ * silently substitute painter geometry.
1118
+ */
1119
+ declare class RustDisplayListSourceError extends Error {
1120
+ readonly stage: RustDisplayListSourceErrorStage;
1121
+ constructor(stage: RustDisplayListSourceErrorStage, cause: unknown);
1122
+ }
1123
+ /**
1124
+ * Query surface over an already-built display list, injectable so tests can
1125
+ * fake the wasm module.
1126
+ *
1127
+ * The required `*Json` members take the display-list JSON as an argument and
1128
+ * the Rust side re-parses it per query, so callers should cache the string.
1129
+ * The OPTIONAL session-handle members parse the list once (`openDisplayList` →
1130
+ * a handle) and answer many queries by handle with no re-serialization,
1131
+ * reusing the same hit and range logic so results are byte-identical. They are
1132
+ * optional because the embedded wasm may not carry them; `hasDisplayListSession`
1133
+ * and `hasRangeRectsRegion` report what is present, and
1134
+ * `createDisplayListQueries` falls back to the `*Json` path when it is not.
1135
+ */
1136
+ interface RustDisplayListQueryEngine {
1137
+ /**
1138
+ * region-aware hit test → `{"region","rId"?,"noteId"?,"pos","target"}` or
1139
+ * `"null"` JSON
1140
+ */
1141
+ hitTestRegionsJson(displayList: string, pageIndex: number, x: number, y: number): string;
1142
+ /** closest caret position on the adjacent visual line */
1143
+ verticalMoveJson?(displayList: string, position: number, direction: 'up' | 'down', goalX: number): string;
1144
+ /** body document range → JSON array of `{pageIndex,x,y,width,height}` rects */
1145
+ rangeRectsJson(displayList: string, from: number, to: number): string;
1146
+ /** @internal */
1147
+ rangeRectsOnPagesJson?(displayList: string, from: number, to: number, firstPage: number, lastPage: number): string;
1148
+ /** @internal */
1149
+ hasRangeRectsOnPages?(): boolean;
1150
+ /**
1151
+ * Region-aware document range → JSON array of rects. `region` is a
1152
+ * `DisplayListHitRegion` discriminant; `partId` names the instance — a
1153
+ * header/footer part (empty for body, or to match any band of the kind) or a
1154
+ * note id. Optional — the facade returns `[]` when it is absent.
1155
+ */
1156
+ rangeRectsRegionJson?(displayList: string, region: string, partId: string, from: number, to: number): string;
1157
+ /** true when the embedded wasm carries the region-aware range-rect exports */
1158
+ hasRangeRectsRegion?(): boolean;
1159
+ /** true when the embedded wasm carries the session-handle exports below */
1160
+ hasDisplayListSession?(): boolean;
1161
+ /** parse a display list once, return a handle for the by-handle queries */
1162
+ openDisplayList?(displayList: string): number;
1163
+ /** free a handle's parsed display list */
1164
+ closeDisplayList?(handle: number): void;
1165
+ /** patch a stored display list's changed pages in place (see layout wasm) */
1166
+ updateDisplayList?(handle: number, update: string): void;
1167
+ /** true when the embedded wasm carries the page-delta update export */
1168
+ hasDisplayListUpdate?(): boolean;
1169
+ /** region-aware hit test against a stored display list (by handle) */
1170
+ hitTestRegionsByHandle?(handle: number, pageIndex: number, x: number, y: number): string;
1171
+ /** adjacent visual-line move against a stored display list */
1172
+ verticalMoveByHandle?(handle: number, position: number, direction: 'up' | 'down', goalX: number): string;
1173
+ /** body document range against a stored display list (by handle) */
1174
+ rangeRectsByHandle?(handle: number, from: number, to: number): string;
1175
+ /** @internal */
1176
+ rangeRectsOnPagesByHandle?(handle: number, from: number, to: number, firstPage: number, lastPage: number): string;
1177
+ /** region-aware document range against a stored display list (by handle) */
1178
+ rangeRectsRegionByHandle?(handle: number, region: string, partId: string, from: number, to: number): string;
1179
+ }
1180
+ /** The wasm query surface once {@link loadRustDisplayListQueryEngine} has loaded it, else null. */
1181
+ declare function loadedRustDisplayListQueryEngine(): RustDisplayListQueryEngine | null;
1182
+ /**
1183
+ * Lazily load the wasm query surface (hit-test + range-rects). Shares the
1184
+ * module promise with `buildRustDisplayList`, so on the canvas-renderer path
1185
+ * the engine is already resolved by the time the first display list lands.
1186
+ */
1187
+ declare function loadRustDisplayListQueryEngine(): Promise<RustDisplayListQueryEngine>;
1188
+ /** Display-only fields sent to an engine that already retains pagination. */
1189
+ declare function encodeDisplayListFrameExtras(inputs: DisplayListBuildInputs): string;
1190
+ /**
1191
+ * Build a DisplayList for a computed layout through the Rust engine. Throws
1192
+ * {@link RustDisplayListSourceError} tagged with the failing stage — `load`,
1193
+ * `build` or `parse` — when the wasm module cannot be loaded, the builder
1194
+ * rejects the input, or its output does not parse.
1195
+ */
1196
+ declare function buildRustDisplayList(inputs: DisplayListBuildInputs, engine?: RustDisplayListEngine): Promise<DisplayList>;
1197
+ /**
1198
+ * Build one display frame. An engine that retains pagination returns a binary
1199
+ * FrameDelta, decoded and applied on top of `previous` so unchanged pages keep
1200
+ * object identity; `previous` also supplies the frame epoch the engine checks
1201
+ * before sending a delta rather than a full frame, unless `expectedFrameEpoch`
1202
+ * overrides it (the engine numbers its frame after that epoch). An engine without
1203
+ * `buildDisplayListFrame` takes the full-JSON path, and its result carries
1204
+ * `frame: null` and `transport: 'json'`.
1205
+ *
1206
+ * Throws {@link RustDisplayListSourceError} tagged with the failing stage:
1207
+ * `load`, `build`, `decode` or `apply`.
1208
+ */
1209
+ declare function buildRustDisplayFrame(inputs: DisplayListBuildInputs, engine?: RustDisplayListEngine, previous?: RetainedFrame | null, expectedFrameEpoch?: number): Promise<RustDisplayFrameResult>;
1210
+
1211
+ /**
1212
+ * Synchronous query facade over one built DisplayList, backed by the Rust
1213
+ * hit-testing module (`crates/docx-layout/src/hit.rs`).
1214
+ *
1215
+ * This is the canvas renderer's only source of pointer and selection geometry:
1216
+ * every rect comes from the immutable display list, never from DOM rects. A
1217
+ * facade is created per display-list build, since the list never mutates in
1218
+ * place, and it holds no state a caller has to keep in sync.
1219
+ *
1220
+ * **Two sources.** A resident editing engine queries its own display list
1221
+ * directly and takes no display-list JSON at all. Otherwise the shared layout
1222
+ * wasm answers, and the facade prefers a SESSION HANDLE: the list is parsed
1223
+ * into the Rust store once (`openDisplayList`) and every later query goes by
1224
+ * handle, with no per-query re-serialization. When the session exports are
1225
+ * absent it stringifies the list once and reuses that string for the JSON-arg
1226
+ * exports. The two paths run the same hit and range logic, so results are
1227
+ * byte-identical and only the cost differs.
1228
+ *
1229
+ * **Handle acquisition is lazy** — on the first query that needs one, or when
1230
+ * a host calls `prime()` from idle time — so replacing the facade on every
1231
+ * keystroke costs no serialization on the input path. A new facade also tries
1232
+ * to ADOPT its predecessor's parsed list, shipping a page delta for the pages
1233
+ * that changed instead of reopening the whole list; superseded generations
1234
+ * chain their donor, so a deferred pickup still costs one delta. The donor's
1235
+ * own later queries degrade to its JSON-arg path.
1236
+ *
1237
+ * **Handle release.** `dispose()` frees the handle immediately, and ending a
1238
+ * facade's line frees every handle the line's facades hold. Only a facade
1239
+ * holding a handle is registered with a `FinalizationRegistry`, which covers
1240
+ * one dropped without `dispose()` (a `useMemo` replacement, say); the Rust
1241
+ * store additionally caps live handles and evicts the oldest, so a missed
1242
+ * finalize cannot grow memory without bound.
1243
+ *
1244
+ * **Failure.** A wasm TRAP poisons the whole instance: a guard held across the
1245
+ * query leaks and every later call into it fails, so the engine is marked dead,
1246
+ * all queries stop, and `onDisplayListQuerySourceFailure` subscribers are told
1247
+ * to rebuild the session. An ordinary error just falls back — a bad handle is
1248
+ * dropped and the query retried over JSON.
1249
+ *
1250
+ * Queries are synchronous and return `null`/`[]` until the lazily imported
1251
+ * wasm module resolves. In practice it is already loaded by the time a facade
1252
+ * exists, because building the display list went through the same module.
1253
+ */
1254
+
1255
+ /**
1256
+ * Query surface of an editing engine that already holds the display list.
1257
+ * None of these take display-list JSON, so this source never opens a handle
1258
+ * and never serializes anything.
1259
+ */
1260
+ interface ResidentDisplayListQueryEngine {
1261
+ displayHitTestRegionsJson(pageIndex: number, x: number, y: number): string;
1262
+ displayVerticalMoveJson(position: number, direction: 'up' | 'down', goalX: number): string;
1263
+ displayRangeRectsJson(from: number, to: number): string;
1264
+ /** @internal */
1265
+ displayRangeRectsOnPagesJson?(from: number, to: number, firstPage: number, lastPage: number): string;
1266
+ displayRangeRectsRegionJson(region: DisplayListHitRegion, partId: string, from: number, to: number): string;
1267
+ }
1268
+ /** which part of a page owns a hit — mirrors `HitRegion` in hit.rs */
1269
+ type DisplayListHitRegion = 'body' | 'header' | 'footer' | 'footnote' | 'endnote';
1270
+ /**
1271
+ * What a click at a hit point would act on — mirrors `HoverTarget` in hit.rs.
1272
+ * `'text'` is the typeable area (a run's box, or the content box around it),
1273
+ * which is what a pointer cursor keys off; `pos` cannot say, since it resolves
1274
+ * everywhere on a page that carries text.
1275
+ */
1276
+ type DisplayListHoverTarget = 'text' | 'image' | 'none';
1277
+ /**
1278
+ * Region-aware hit result. For `header`/`footer` the position refers to the
1279
+ * header/footer document identified by `rId`, and for `footnote`/`endnote` to
1280
+ * the note story named by `noteId` — NOT the body document, so the caller must
1281
+ * route the selection to that editor. `pos` is null when the point is inside
1282
+ * the region but resolves to no position.
1283
+ */
1284
+ interface DisplayListRegionHit {
1285
+ region: DisplayListHitRegion;
1286
+ rId?: string;
1287
+ /** note whose story a `footnote`/`endnote` position addresses */
1288
+ noteId?: number;
1289
+ pos: number | null;
1290
+ /** Absent from a wasm build predating it; read that as "not text". */
1291
+ target?: DisplayListHoverTarget;
1292
+ }
1293
+ /**
1294
+ * Result of an up/down caret move. `goalX` is the page-local x to feed back
1295
+ * into the next move so a run of them holds one column.
1296
+ */
1297
+ interface DisplayListVerticalMove {
1298
+ position: number;
1299
+ goalX: number;
1300
+ }
1301
+ /** one highlight rectangle of a document range, page-local px */
1302
+ interface DisplayListRect {
1303
+ pageIndex: number;
1304
+ x: number;
1305
+ y: number;
1306
+ width: number;
1307
+ height: number;
1308
+ }
1309
+ /** Explicit lifecycle of the mandatory Rust query source. */
1310
+ type DisplayListQuerySourceState = {
1311
+ status: 'loading';
1312
+ } | {
1313
+ status: 'ready';
1314
+ } | {
1315
+ status: 'error';
1316
+ error: Error;
1317
+ };
1318
+ /** One paragraph fragment box on one page, in page-local px. */
1319
+ interface DisplayListParagraphGeometry extends DisplayListRect {
1320
+ from: number;
1321
+ to: number;
1322
+ blockId?: number | string;
1323
+ paraId?: string;
1324
+ }
1325
+ /** One ordered visual line reconstructed from authoritative primitives. */
1326
+ interface VisualLineExtent {
1327
+ top: number;
1328
+ bottom: number;
1329
+ }
1330
+ interface DisplayListVisualLine extends DisplayListRect {
1331
+ baseline: number;
1332
+ from: number;
1333
+ to: number;
1334
+ blockId?: number | string;
1335
+ paraId?: string;
1336
+ }
1337
+ /** Image primitive plus its explicit page/region geometry. */
1338
+ interface DisplayListImageGeometry extends LocatedImagePrimitive {
1339
+ rect: DisplayListRect;
1340
+ pos: number;
1341
+ }
1342
+ /**
1343
+ * Sync query surface over one immutable DisplayList. A new instance is
1344
+ * created per display-list build (the list never mutates in place).
1345
+ */
1346
+ interface DisplayListQueries {
1347
+ /** the list this instance queries (page sizes, region bands, …) */
1348
+ readonly displayList: DisplayList;
1349
+ /** false until the wasm module is loaded — queries return null/[] before */
1350
+ isReady(): boolean;
1351
+ /** Loading/ready/error state for hosts that must not silently fall back. */
1352
+ sourceState(): DisplayListQuerySourceState;
1353
+ /** Resolves when the Rust query engine is ready; rejects on load failure. */
1354
+ whenReady(): Promise<void>;
1355
+ pageCount(): number;
1356
+ pageSize(pageIndex: number): {
1357
+ width: number;
1358
+ height: number;
1359
+ } | null;
1360
+ pageBounds(pageIndex: number): DisplayListRect | null;
1361
+ contentBounds(pageIndex: number): DisplayListRect | null;
1362
+ columnBounds(pageIndex: number): DisplayListRect[];
1363
+ /** Body paragraph fragment boxes containing `pos`, including page splits. */
1364
+ paragraphRects(pos: number): DisplayListParagraphGeometry[];
1365
+ /** Ordered body visual lines across all pages. */
1366
+ visualLines(): readonly DisplayListVisualLine[];
1367
+ /** The part of {@link visualLines} on one page, computed for that page alone. */
1368
+ visualLinesOnPage(pageIndex: number): readonly DisplayListVisualLine[];
1369
+ /** Vertical span of the page's visual lines in page coordinates, or null when it has none. */
1370
+ visualLineExtent(pageIndex: number): VisualLineExtent | null;
1371
+ /** Visual line containing `pos`, or null. */
1372
+ visualLineAtPosition(pos: number): DisplayListVisualLine | null;
1373
+ /** Topmost image under a page-local point. Body by default. */
1374
+ imageAtPoint(pageIndex: number, x: number, y: number, region?: DisplayListImageRegion, rId?: string): DisplayListImageGeometry | null;
1375
+ /** Image whose atom starts at `pos`. Body by default. */
1376
+ imageByPos(pos: number, region?: DisplayListImageRegion, rId?: string): DisplayListImageGeometry | null;
1377
+ /** region-aware point → doc position (page-local coordinates) */
1378
+ hitTestRegions(pageIndex: number, x: number, y: number): DisplayListRegionHit | null;
1379
+ verticalMove(position: number, direction: 'up' | 'down', goalX?: number): DisplayListVerticalMove | null;
1380
+ /** body document range → highlight rects */
1381
+ rangeRects(from: number, to: number): DisplayListRect[];
1382
+ /** @internal */
1383
+ rangeRectsOnPages?(from: number, to: number, firstPage: number, lastPage: number): DisplayListRect[];
1384
+ /**
1385
+ * Header/footer document range → highlight rects for the region's band. `region` is
1386
+ * `'header' | 'footer'`; `rId` identifies the HF doc, and
1387
+ * `from`/`to` are positions in THAT doc. The same HF doc paints on every page
1388
+ * carrying the part, so this returns one rect-set per such page (each tagged
1389
+ * with its `pageIndex`) — the caller picks the page it is editing. Returns
1390
+ * `[]` when the region-aware exports are absent, which is feature-detected.
1391
+ */
1392
+ hfRangeRects(region: 'header' | 'footer', rId: string, from: number, to: number): DisplayListRect[];
1393
+ /**
1394
+ * Note document range → highlight rects for that note's story. `from`/`to`
1395
+ * are positions in the `fn:{noteId}` / `en:{noteId}` document, never the
1396
+ * body's. A note paints on one page only, so every rect shares its
1397
+ * `pageIndex`.
1398
+ */
1399
+ noteRangeRects(region: 'footnote' | 'endnote', noteId: number, from: number, to: number): DisplayListRect[];
1400
+ /**
1401
+ * Caret geometry for a collapsed HF selection — the HF twin of `caretRect`.
1402
+ * Resolves `[pos, pos+1)` in the HF doc (left edge is the caret), falling back
1403
+ * to `[pos-1, pos)` (right edge) at end-of-line / end-of-doc. Returns one
1404
+ * caret rect per page carrying the part; the caller picks the edited page.
1405
+ */
1406
+ hfCaretRects(region: 'header' | 'footer', rId: string, pos: number): DisplayListRect[];
1407
+ /**
1408
+ * Caret geometry for a collapsed selection in a note story — the note twin of
1409
+ * `hfCaretRects`. A note paints on one page, so this returns at most one rect.
1410
+ */
1411
+ noteCaretRects(region: 'footnote' | 'endnote', noteId: number, pos: number): DisplayListRect[];
1412
+ /** Header/footer sidebar anchors, one per page carrying the part. */
1413
+ hfAnchorRects(region: 'header' | 'footer', rId: string, pos: number): DisplayListRect[];
1414
+ /**
1415
+ * Caret geometry for a collapsed body selection: the collapsed-range rect.
1416
+ * Resolves `[pos, pos+1)` first (rect's left edge is the caret), then falls
1417
+ * back to `[pos-1, pos)` using the right edge (end-of-doc / end-of-line).
1418
+ */
1419
+ caretRect(pos: number): DisplayListRect | null;
1420
+ /**
1421
+ * Anchor geometry for sidebar markers: like `caretRect` but scans
1422
+ * `[pos, pos+2)` forward first so *node* positions (paragraph/table
1423
+ * markers carrying structural tracked-change attrs) resolve to their first
1424
+ * content line instead of the previous block's tail.
1425
+ */
1426
+ anchorRect(pos: number): DisplayListRect | null;
1427
+ /** Explicit body-sidebar alias retained alongside `anchorRect`. */
1428
+ sidebarAnchorRect(pos: number): DisplayListRect | null;
1429
+ /**
1430
+ * Acquire the Rust session handle now (adopting the donor facade's parsed
1431
+ * list when possible). Optional: the first query acquires it on demand;
1432
+ * hosts call this from idle time to keep serialization off interaction
1433
+ * paths. No-op once attempted, superseded, or disposed.
1434
+ */
1435
+ prime(): void;
1436
+ /**
1437
+ * Release the wasm session handle backing this facade. Idempotent; safe to
1438
+ * call even when no handle was opened (JSON-arg fallback path). Callers that
1439
+ * forget are covered by a `FinalizationRegistry`, but disposing eagerly frees
1440
+ * the parsed display list in the Rust store immediately.
1441
+ */
1442
+ dispose(): void;
1443
+ }
1444
+ /**
1445
+ * Ends `line`: closes the store handles its facades hold, which then query
1446
+ * over JSON, and its superseded facades answer nothing until a facade of the
1447
+ * same line is built. Call it when the session behind the line goes away.
1448
+ */
1449
+ declare function endDisplayListQueriesLine(line: object): void;
1450
+ type DisplayListQuerySource = RustDisplayListQueryEngine | ResidentDisplayListQueryEngine;
1451
+ /** True once a query trapped in this engine's wasm instance. */
1452
+ declare function isDisplayListQuerySourceDead(engine: DisplayListQuerySource | null | undefined): boolean;
1453
+ /** Subscribe to wasm traps so the host can rebuild the dead session. */
1454
+ declare function onDisplayListQuerySourceFailure(listener: (error: Error) => void): () => void;
1455
+ /**
1456
+ * Build a query facade for one display list. The optional `engine` makes the
1457
+ * facade synchronous and deterministic in tests; without it the shared wasm
1458
+ * module is loaded lazily and queries no-op (`null`/`[]`) until it resolves.
1459
+ *
1460
+ * `previous` (the facade this build replaces) enables handle adoption: instead
1461
+ * of re-serializing and re-parsing the WHOLE list into the Rust store, the new
1462
+ * facade takes over the previous parsed list and patches only the pages that
1463
+ * changed. The donor facade's remaining queries degrade to its own JSON-arg
1464
+ * path (same stale-list semantics it always had after replacement).
1465
+ *
1466
+ * `line` names the document the list lays out, such as its load. A facade of another
1467
+ * document starts a new line and ends the previous one, so a facade of the
1468
+ * replaced document never answers from the new one. Without `line` a superseded
1469
+ * facade answers from its own list.
1470
+ */
1471
+ declare function createDisplayListQueries(list: DisplayList, engine?: RustDisplayListQueryEngine | ResidentDisplayListQueryEngine, previous?: DisplayListQueries | null, line?: object | null): DisplayListQueries;
1472
+
1473
+ export { createDisplayListQueries as $, type FrameDeltaErrorCode as A, type FramePageOperation as B, type LocatedImagePrimitive as C, type DisplayListRect as D, type ResidentDisplayListQueryEngine as E, FRAME_DELTA_HEADER_BYTES as F, type GlyphRunPrimitive as G, type HfRegion as H, type ImagePrimitive as I, type RetainedFrame as J, type RetainedFramePage as K, type LinePrimitive as L, type RustDisplayFrameResult as M, type RustDisplayListEngine as N, type RustDisplayListQueryEngine as O, type PositionedGlyph as P, RustDisplayListSourceError as Q, type RectPrimitive as R, type RustDisplayListSourceErrorStage as S, type TextRunPrimitive as T, type TableCellRef as U, type VisualLineExtent as V, applyFrameDelta as W, applyFrameDeltaOwned as X, buildRustDisplayFrame as Y, buildRustDisplayList as Z, captureInlinePositionEmuFromDisplayList as _, type DisplayListQueries as a, decodeFrameDelta as a0, decodeFrameDeltaSteps as a1, displayPageIsShiftOf as a2, displayPageNoteAnchorRevision as a3, displayPageRevision as a4, encodeDisplayListFrameExtras as a5, endDisplayListQueriesLine as a6, findImagePrimitiveAtPoint as a7, findImagePrimitiveByDocPos as a8, isDisplayListQuerySourceDead as a9, loadRustDisplayListQueryEngine as aa, loadedRustDisplayListQueryEngine as ab, onDisplayListQuerySourceFailure as ac, type DisplayListHeadersFooters as b, type DisplayPage as c, type DisplayPrimitive as d, type DisplayList as e, type DisplayListRegionHit as f, type DecodedFrameDelta as g, type DecorationPrimitive as h, type DisplayBounds as i, type DisplayListBuildInputs as j, type DisplayListHfVariant as k, type DisplayListHitRegion as l, type DisplayListHoverTarget as m, type DisplayListImageGeometry as n, type DisplayListImageRegion as o, type DisplayListParagraphGeometry as p, type DisplayListPictureWatermark as q, type DisplayListQuerySourceState as r, type DisplayListTextWatermark as s, type DisplayListVerticalMove as t, type DisplayListVisualLine as u, type DisplayListWatermark as v, type DocAttrs as w, FRAME_DELTA_PAGE_OP_BYTES as x, FRAME_DELTA_VERSION as y, FrameDeltaError as z };