@docx-editor.dev/core 0.0.1-placeholder → 2.0.1

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 (116) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +92 -2
  3. package/THIRD_PARTY_NOTICES.md +18 -0
  4. package/dist/automation.cjs +1 -0
  5. package/dist/automation.d.cts +74 -0
  6. package/dist/automation.d.ts +74 -0
  7. package/dist/automation.js +1 -0
  8. package/dist/binding.cjs +1 -0
  9. package/dist/binding.d.cts +82 -0
  10. package/dist/binding.d.ts +82 -0
  11. package/dist/binding.js +1 -0
  12. package/dist/chunk-5KSCB2OZ.js +2 -0
  13. package/dist/chunk-BSC44TIT.js +5 -0
  14. package/dist/chunk-DLPL5DAG.js +12 -0
  15. package/dist/chunk-DOEIARE2.js +2 -0
  16. package/dist/chunk-G7YCQBZE.cjs +5 -0
  17. package/dist/chunk-HBL3NNH5.cjs +1 -0
  18. package/dist/chunk-HR7K3W6A.js +1 -0
  19. package/dist/chunk-HVAV2JSN.js +11 -0
  20. package/dist/chunk-MYH2HCUJ.cjs +2 -0
  21. package/dist/chunk-NSM75TN6.cjs +1 -0
  22. package/dist/chunk-PHDVKUWZ.js +1 -0
  23. package/dist/chunk-QADYGK5L.cjs +12 -0
  24. package/dist/chunk-REZUWYB7.js +1 -0
  25. package/dist/chunk-RNBHTPW7.js +10 -0
  26. package/dist/chunk-UD2ZXLFI.cjs +2 -0
  27. package/dist/chunk-VYAVK2AH.cjs +1 -0
  28. package/dist/chunk-YUK46A2N.cjs +11 -0
  29. package/dist/chunk-ZMIX42J7.cjs +10 -0
  30. package/dist/chunk-ZT55Q52J.cjs +2 -0
  31. package/dist/chunk-ZUALAR4M.js +2 -0
  32. package/dist/content-control-walk-CbTqHq6O.d.cts +56 -0
  33. package/dist/content-control-walk-D06GijR0.d.ts +56 -0
  34. package/dist/contracts/document.cjs +1 -0
  35. package/dist/contracts/document.d.cts +246 -0
  36. package/dist/contracts/document.d.ts +246 -0
  37. package/dist/contracts/document.js +0 -0
  38. package/dist/contracts/editor.cjs +1 -0
  39. package/dist/contracts/editor.d.cts +11 -0
  40. package/dist/contracts/editor.d.ts +11 -0
  41. package/dist/contracts/editor.js +1 -0
  42. package/dist/contracts/interaction.cjs +1 -0
  43. package/dist/contracts/interaction.d.cts +11 -0
  44. package/dist/contracts/interaction.d.ts +11 -0
  45. package/dist/contracts/interaction.js +0 -0
  46. package/dist/contracts/modules.cjs +1 -0
  47. package/dist/contracts/modules.d.cts +90 -0
  48. package/dist/contracts/modules.d.ts +90 -0
  49. package/dist/contracts/modules.js +1 -0
  50. package/dist/contracts/types.cjs +1 -0
  51. package/dist/contracts/types.d.cts +452 -0
  52. package/dist/contracts/types.d.ts +452 -0
  53. package/dist/contracts/types.js +0 -0
  54. package/dist/editor-C1QRi1v4.d.ts +1671 -0
  55. package/dist/editor-D0UDock4.d.cts +1671 -0
  56. package/dist/editor.cjs +1 -0
  57. package/dist/editor.css +6017 -0
  58. package/dist/editor.d.cts +271 -0
  59. package/dist/editor.d.ts +271 -0
  60. package/dist/editor.js +1 -0
  61. package/dist/hf-references-BdjsQNE_.d.ts +71 -0
  62. package/dist/hf-references-CgEOSw3i.d.cts +71 -0
  63. package/dist/image-resources-BJnTpG66.d.ts +195 -0
  64. package/dist/image-resources-BpIydXtU.d.cts +195 -0
  65. package/dist/index-CrW-IxXt.d.cts +2515 -0
  66. package/dist/index-ZqBEOrTV.d.ts +2515 -0
  67. package/dist/index.cjs +1 -0
  68. package/dist/index.d.cts +22 -0
  69. package/dist/index.d.ts +22 -0
  70. package/dist/index.js +1 -0
  71. package/dist/layout.cjs +1 -0
  72. package/dist/layout.d.cts +2316 -0
  73. package/dist/layout.d.ts +2316 -0
  74. package/dist/layout.js +1 -0
  75. package/dist/note-nodes-BPSTVDMr.d.ts +108 -0
  76. package/dist/note-nodes-C6DLxlvj.d.cts +108 -0
  77. package/dist/note-properties-CnmCoory.d.cts +68 -0
  78. package/dist/note-properties-m75hmP70.d.ts +68 -0
  79. package/dist/ooxml-package-CR5us6ad.d.cts +354 -0
  80. package/dist/ooxml-package-D_CtywTW.d.ts +354 -0
  81. package/dist/ooxml-tree-BU0e3DVi.d.cts +871 -0
  82. package/dist/ooxml-tree-BU0e3DVi.d.ts +871 -0
  83. package/dist/output.cjs +1 -0
  84. package/dist/output.d.cts +158 -0
  85. package/dist/output.d.ts +158 -0
  86. package/dist/output.js +1 -0
  87. package/dist/protocol-CAkOBBGE.d.cts +1201 -0
  88. package/dist/protocol-oxHaWmt4.d.ts +1201 -0
  89. package/dist/review-support-DS8DYX2a.d.cts +326 -0
  90. package/dist/review-support-Fy3vdIea.d.ts +326 -0
  91. package/dist/revision-projection-72ZApe-g.d.cts +84 -0
  92. package/dist/revision-projection-DHAkcD_L.d.ts +84 -0
  93. package/dist/semantic-cell-selection-CZjBSmMv.d.cts +427 -0
  94. package/dist/semantic-cell-selection-DsmHmLJ5.d.ts +427 -0
  95. package/dist/semantic-interaction-D-Dszxrn.d.cts +187 -0
  96. package/dist/semantic-interaction-Dy-dCUFF.d.ts +187 -0
  97. package/dist/semantic-paint-drawings-BA3z9jl8.d.ts +21 -0
  98. package/dist/semantic-paint-drawings-D7qbB0E2.d.cts +21 -0
  99. package/dist/semantic-records-CJR3BvHs.d.cts +1432 -0
  100. package/dist/semantic-records-CWodBJsz.d.ts +1432 -0
  101. package/dist/shaped-measurer-B-TAtcQU.d.ts +613 -0
  102. package/dist/shaped-measurer-CNIT_svZ.d.cts +613 -0
  103. package/dist/store.cjs +1 -0
  104. package/dist/store.d.cts +2247 -0
  105. package/dist/store.d.ts +2247 -0
  106. package/dist/store.js +1 -0
  107. package/dist/tree-op-types-CwOeiaQ8.d.ts +1431 -0
  108. package/dist/tree-op-types-DMiW6nIH.d.cts +1431 -0
  109. package/dist/tree-package-store-D5S7VKs5.d.ts +708 -0
  110. package/dist/tree-package-store-DOKMtCnh.d.cts +708 -0
  111. package/dist/tree-session-CiUel5Kz.d.ts +542 -0
  112. package/dist/tree-session-D47_imvR.d.cts +542 -0
  113. package/dist/tree-store-CxifqwIv.d.cts +273 -0
  114. package/dist/tree-store-hLtjeyWE.d.ts +273 -0
  115. package/package.json +105 -15
  116. package/index.js +0 -1
@@ -0,0 +1,11 @@
1
+ export { L as EditorScope, U as InteractionAffinity, W as InteractionOutcome, X as InteractionOutcomeCode, a7 as SemanticIdentity, a8 as SemanticTarget, V as ViewScope } from '../editor-D0UDock4.cjs';
2
+ import './document.cjs';
3
+ import './types.cjs';
4
+ import '../review-support-DS8DYX2a.cjs';
5
+ import '../ooxml-tree-BU0e3DVi.cjs';
6
+ import '../tree-op-types-DMiW6nIH.cjs';
7
+ import '../semantic-interaction-D-Dszxrn.cjs';
8
+ import '../semantic-records-CJR3BvHs.cjs';
9
+ import '../image-resources-BpIydXtU.cjs';
10
+ import '../ooxml-package-CR5us6ad.cjs';
11
+ import '../revision-projection-72ZApe-g.cjs';
@@ -0,0 +1,11 @@
1
+ export { L as EditorScope, U as InteractionAffinity, W as InteractionOutcome, X as InteractionOutcomeCode, a7 as SemanticIdentity, a8 as SemanticTarget, V as ViewScope } from '../editor-C1QRi1v4.js';
2
+ import './document.js';
3
+ import './types.js';
4
+ import '../review-support-Fy3vdIea.js';
5
+ import '../ooxml-tree-BU0e3DVi.js';
6
+ import '../tree-op-types-CwOeiaQ8.js';
7
+ import '../semantic-interaction-Dy-dCUFF.js';
8
+ import '../semantic-records-CWodBJsz.js';
9
+ import '../image-resources-BJnTpG66.js';
10
+ import '../ooxml-package-D_CtywTW.js';
11
+ import '../revision-projection-DHAkcD_L.js';
File without changes
@@ -0,0 +1 @@
1
+ 'use strict';var chunkVYAVK2AH_cjs=require('../chunk-VYAVK2AH.cjs');Object.defineProperty(exports,"resolveEditorModules",{enumerable:true,get:function(){return chunkVYAVK2AH_cjs.a}});
@@ -0,0 +1,90 @@
1
+ import { e as OoxmlPart } from '../ooxml-tree-BU0e3DVi.cjs';
2
+ export { R as RevisionAddress } from '../tree-op-types-DMiW6nIH.cjs';
3
+ import { R as RevisionDisplayMode } from '../revision-projection-72ZApe-g.cjs';
4
+ import { R as ReviewModelInput, a as ReviewItem, b as ReviewRevisionItem } from '../review-support-DS8DYX2a.cjs';
5
+ export { C as CommentRecord, c as ReviewCommentItem, d as ReviewCustomItem, e as ReviewPosition, f as ReviewRange, g as ReviewRevisionKind } from '../review-support-DS8DYX2a.cjs';
6
+
7
+ /**
8
+ * `@docx-editor.dev/core/contracts/modules` — the `EditorModule` seam.
9
+ *
10
+ * How a paid or optional capability contributes to the engine without the free tier importing
11
+ * it: the review module and custom nodes both arrive through here, and their absence leaves the
12
+ * corresponding chrome disabled with the engine's own reason.
13
+ *
14
+ * NOT a plugin system. The shape is closed: every contribution point is named
15
+ * here, core iterates registered modules at its existing dispatch points, and
16
+ * core never imports a capability package. A capability absent from this file
17
+ * is not extendable from outside — deliberately, so the one-pipeline principle
18
+ * survives the packaging boundary.
19
+ * The free engine behaves identically with an empty registry: documents
20
+ * round-trip losslessly, revisions render in their final-state projection, and
21
+ * the review chrome slots stay disabled with the engine's own reason.
22
+ *
23
+ * @packageDocumentation
24
+ * @public
25
+ */
26
+
27
+ /**
28
+ * Derives the review queue — every pending revision decision and comment
29
+ * thread — from one story part plus its comment parts. Implemented by the pro
30
+ * review module; the free engine has no implementation and reports an empty
31
+ * queue.
32
+ *
33
+ * @public
34
+ */
35
+ type CollectReviewItems = (input: ReviewModelInput) => readonly ReviewItem[];
36
+ /**
37
+ * What a review module contributes: the queue derivation, and the revision
38
+ * display modes the editor may enter beyond the free tier's final-state
39
+ * projection.
40
+ *
41
+ * @public
42
+ */
43
+ interface ReviewModuleContribution {
44
+ /**
45
+ * Display modes this module unlocks (the free engine renders `proposed` only).
46
+ *
47
+ * Currently DECLARATIVE: any registered review module restores the layout
48
+ * default (`all-markup`), and no runtime mode switch exists yet. The list is
49
+ * carried so the future `setRevisionDisplayMode` command can validate against
50
+ * it without a breaking module-shape change.
51
+ */
52
+ readonly displayModes: readonly RevisionDisplayMode[];
53
+ /** The review queue derivation. */
54
+ readonly collectReviewItems: CollectReviewItems;
55
+ /**
56
+ * Revisions wholly inside one paragraph — for the conservative local review
57
+ * patch after a text-local body edit.
58
+ */
59
+ readonly revisionItemsOfParagraph: (part: OoxmlPart, paragraphId: string) => readonly ReviewRevisionItem[];
60
+ }
61
+ /**
62
+ * One registered capability module. Registration is construction-time
63
+ * (`createDocxEditor({ modules })`) and immutable for the instance's lifetime.
64
+ *
65
+ * @public
66
+ */
67
+ interface EditorModule {
68
+ /** Diagnostic identity (`'review'`, `'custom-nodes'`); not a dispatch key. */
69
+ readonly id: string;
70
+ /** Review capability: queue derivation, commands gate, display modes. */
71
+ readonly review?: ReviewModuleContribution;
72
+ /**
73
+ * Custom inline node definitions. Reserved: the definition shape lands with
74
+ * the custom-nodes lane; the registry carries them opaquely until then.
75
+ */
76
+ readonly customNodes?: readonly unknown[];
77
+ }
78
+ /**
79
+ * The resolved registry the editor instance holds: at most one review
80
+ * contribution (first registration wins), all custom node definitions in
81
+ * registration order.
82
+ */
83
+ interface EditorModuleRegistry {
84
+ readonly review: ReviewModuleContribution | null;
85
+ readonly customNodes: readonly unknown[];
86
+ }
87
+ /** Resolve construction-time modules into the registry the instance dispatches over. */
88
+ declare function resolveEditorModules(modules: readonly EditorModule[] | undefined): EditorModuleRegistry;
89
+
90
+ export { type CollectReviewItems, type EditorModule, type EditorModuleRegistry, OoxmlPart, ReviewItem, ReviewModelInput, type ReviewModuleContribution, ReviewRevisionItem, RevisionDisplayMode, resolveEditorModules };
@@ -0,0 +1,90 @@
1
+ import { e as OoxmlPart } from '../ooxml-tree-BU0e3DVi.js';
2
+ export { R as RevisionAddress } from '../tree-op-types-CwOeiaQ8.js';
3
+ import { R as RevisionDisplayMode } from '../revision-projection-DHAkcD_L.js';
4
+ import { R as ReviewModelInput, a as ReviewItem, b as ReviewRevisionItem } from '../review-support-Fy3vdIea.js';
5
+ export { C as CommentRecord, c as ReviewCommentItem, d as ReviewCustomItem, e as ReviewPosition, f as ReviewRange, g as ReviewRevisionKind } from '../review-support-Fy3vdIea.js';
6
+
7
+ /**
8
+ * `@docx-editor.dev/core/contracts/modules` — the `EditorModule` seam.
9
+ *
10
+ * How a paid or optional capability contributes to the engine without the free tier importing
11
+ * it: the review module and custom nodes both arrive through here, and their absence leaves the
12
+ * corresponding chrome disabled with the engine's own reason.
13
+ *
14
+ * NOT a plugin system. The shape is closed: every contribution point is named
15
+ * here, core iterates registered modules at its existing dispatch points, and
16
+ * core never imports a capability package. A capability absent from this file
17
+ * is not extendable from outside — deliberately, so the one-pipeline principle
18
+ * survives the packaging boundary.
19
+ * The free engine behaves identically with an empty registry: documents
20
+ * round-trip losslessly, revisions render in their final-state projection, and
21
+ * the review chrome slots stay disabled with the engine's own reason.
22
+ *
23
+ * @packageDocumentation
24
+ * @public
25
+ */
26
+
27
+ /**
28
+ * Derives the review queue — every pending revision decision and comment
29
+ * thread — from one story part plus its comment parts. Implemented by the pro
30
+ * review module; the free engine has no implementation and reports an empty
31
+ * queue.
32
+ *
33
+ * @public
34
+ */
35
+ type CollectReviewItems = (input: ReviewModelInput) => readonly ReviewItem[];
36
+ /**
37
+ * What a review module contributes: the queue derivation, and the revision
38
+ * display modes the editor may enter beyond the free tier's final-state
39
+ * projection.
40
+ *
41
+ * @public
42
+ */
43
+ interface ReviewModuleContribution {
44
+ /**
45
+ * Display modes this module unlocks (the free engine renders `proposed` only).
46
+ *
47
+ * Currently DECLARATIVE: any registered review module restores the layout
48
+ * default (`all-markup`), and no runtime mode switch exists yet. The list is
49
+ * carried so the future `setRevisionDisplayMode` command can validate against
50
+ * it without a breaking module-shape change.
51
+ */
52
+ readonly displayModes: readonly RevisionDisplayMode[];
53
+ /** The review queue derivation. */
54
+ readonly collectReviewItems: CollectReviewItems;
55
+ /**
56
+ * Revisions wholly inside one paragraph — for the conservative local review
57
+ * patch after a text-local body edit.
58
+ */
59
+ readonly revisionItemsOfParagraph: (part: OoxmlPart, paragraphId: string) => readonly ReviewRevisionItem[];
60
+ }
61
+ /**
62
+ * One registered capability module. Registration is construction-time
63
+ * (`createDocxEditor({ modules })`) and immutable for the instance's lifetime.
64
+ *
65
+ * @public
66
+ */
67
+ interface EditorModule {
68
+ /** Diagnostic identity (`'review'`, `'custom-nodes'`); not a dispatch key. */
69
+ readonly id: string;
70
+ /** Review capability: queue derivation, commands gate, display modes. */
71
+ readonly review?: ReviewModuleContribution;
72
+ /**
73
+ * Custom inline node definitions. Reserved: the definition shape lands with
74
+ * the custom-nodes lane; the registry carries them opaquely until then.
75
+ */
76
+ readonly customNodes?: readonly unknown[];
77
+ }
78
+ /**
79
+ * The resolved registry the editor instance holds: at most one review
80
+ * contribution (first registration wins), all custom node definitions in
81
+ * registration order.
82
+ */
83
+ interface EditorModuleRegistry {
84
+ readonly review: ReviewModuleContribution | null;
85
+ readonly customNodes: readonly unknown[];
86
+ }
87
+ /** Resolve construction-time modules into the registry the instance dispatches over. */
88
+ declare function resolveEditorModules(modules: readonly EditorModule[] | undefined): EditorModuleRegistry;
89
+
90
+ export { type CollectReviewItems, type EditorModule, type EditorModuleRegistry, OoxmlPart, ReviewItem, ReviewModelInput, type ReviewModuleContribution, ReviewRevisionItem, RevisionDisplayMode, resolveEditorModules };
@@ -0,0 +1 @@
1
+ export{a as resolveEditorModules}from'../chunk-HR7K3W6A.js';
@@ -0,0 +1 @@
1
+ 'use strict';
@@ -0,0 +1,452 @@
1
+ /**
2
+ * Shared types for the `@docx-editor.dev/core` contract. Type-only, zero runtime.
3
+ *
4
+ * `@docx-editor.dev/core/contracts/types` re-exports this module verbatim, through
5
+ * `types-barrel.ts`. There is no `@docx-editor.dev/core/types` subpath.
6
+ */
7
+ /**
8
+ * The LLM- and JSON-facing address for a piece of a document.
9
+ *
10
+ * `paraId` is the 8-hex `w14:paraId`, matched case-insensitively. `search` is a
11
+ * phrase that must match EXACTLY ONCE inside that paragraph; ambiguous or
12
+ * missing matches fail with `'ambiguous'` / `'notFound'` rather than falling
13
+ * back to first-match.
14
+ *
15
+ * Offset-based addressing was tried and abandoned: an agent cannot compute a
16
+ * character offset it has not seen, and offsets do not survive concurrent
17
+ * edits. Do not reintroduce `{ blockId, offset }`.
18
+ */
19
+ interface DocAnchor {
20
+ paraId: string;
21
+ search?: string;
22
+ /** Opt-in disambiguation. Omit to require uniqueness. */
23
+ occurrence?: number;
24
+ }
25
+ /** Structural addressing for content the paraId map cannot reach. */
26
+ interface DocLocation {
27
+ container: ContainerRef;
28
+ /** Block indices, descending into tables and content controls. */
29
+ path: number[];
30
+ offset?: number;
31
+ }
32
+ /**
33
+ * Which STORY a location belongs to.
34
+ *
35
+ * The body is one container; every header, footer and note is another. A path alone is
36
+ * ambiguous without it, because block index 0 exists in every story a document has.
37
+ */
38
+ type ContainerRef = {
39
+ part: 'body';
40
+ } | {
41
+ part: 'header' | 'footer';
42
+ rId: string;
43
+ } | {
44
+ part: 'footnote' | 'endnote';
45
+ noteId: number;
46
+ };
47
+ /**
48
+ * Anything an operation can be pointed at: a paragraph-relative {@link DocAnchor}, a structural
49
+ * {@link DocLocation}, or a {@link DocRange} spanning two of them.
50
+ */
51
+ type DocTarget = DocAnchor | DocLocation | DocRange;
52
+ /** A span between two positions. The endpoints may be addressed either way, independently. */
53
+ interface DocRange {
54
+ from: DocAnchor | DocLocation;
55
+ to: DocAnchor | DocLocation;
56
+ }
57
+ /**
58
+ * Every write returns this rather than `boolean`.
59
+ *
60
+ * A bare boolean cannot distinguish "no-op" from "target not found" from
61
+ * "content control is locked", and the editor layer already throws eight
62
+ * distinct ContentControl error classes that a boolean would flatten.
63
+ */
64
+ type ExecResult = {
65
+ ok: true;
66
+ changed: boolean;
67
+ } | {
68
+ ok: false;
69
+ code: ExecErrorCode;
70
+ reason: string;
71
+ target?: DocTarget;
72
+ };
73
+ /**
74
+ * Why a write was refused, as a value to branch on.
75
+ *
76
+ * Deliberately finer-grained than a boolean: "no-op", "target not found" and "content control is
77
+ * locked" are different outcomes, and a caller retrying the first should not retry the third.
78
+ */
79
+ type ExecErrorCode = 'notFound' | 'ambiguous' | 'locked' | 'bound' | 'typeMismatch' | 'kindMismatch' | 'outOfBounds' | 'unsupported' | 'invalidArgs';
80
+ /**
81
+ * A parsed .docx.
82
+ *
83
+ * NOT JSON-round-trippable: it holds `Map`s and `Date`s, plus an internal
84
+ * side-table of verbatim XML used for lossless round-tripping. Use `toJSON` /
85
+ * `fromJSON` before sending it over JSON-RPC or handing it to a model.
86
+ */
87
+ interface DocxDocument {
88
+ readonly body: DocumentBody;
89
+ readonly styles: StyleDefinitions;
90
+ readonly theme?: Theme;
91
+ readonly comments: readonly DocComment[];
92
+ readonly revisions: readonly Revision[];
93
+ }
94
+ /** The main story: its blocks in reading order, plus the sections derived from them. */
95
+ interface DocumentBody {
96
+ readonly content: readonly Block[];
97
+ /**
98
+ * Derived, not stored: recomputed on read from section-break markers and
99
+ * section inheritance. Never treat it as a spreadable field.
100
+ */
101
+ readonly sections: readonly Section[];
102
+ }
103
+ /** The JSON-safe projection of a document. */
104
+ interface DocxDocumentJSON {
105
+ readonly [key: string]: unknown;
106
+ }
107
+ /** One section: the page it lays out on, and the header/footer stories it declares. */
108
+ interface Section {
109
+ readonly properties: SectionProperties;
110
+ readonly headers: HeaderFooterSet;
111
+ readonly footers: HeaderFooterSet;
112
+ }
113
+ /**
114
+ * A section's three header (or footer) variants, each a relationship id.
115
+ *
116
+ * All optional: a variant a section does not declare inherits the previous section's, and one
117
+ * absent everywhere means the document simply has none.
118
+ */
119
+ interface HeaderFooterSet {
120
+ readonly default?: string;
121
+ readonly first?: string;
122
+ readonly even?: string;
123
+ }
124
+ /** Anything that can sit at block level in a story. Discriminate on `kind`. */
125
+ type Block = Paragraph | Table | ContentControl;
126
+ /** One paragraph: its runs, the style it names, and its list membership. */
127
+ interface Paragraph {
128
+ readonly kind: 'paragraph';
129
+ /** `w14:paraId`. The stable handle `DocAnchor` addresses. */
130
+ readonly paraId?: string;
131
+ readonly runs: readonly Run[];
132
+ readonly styleId?: string;
133
+ readonly numbering?: NumberingRef;
134
+ }
135
+ /** A stretch of text sharing one set of character properties. */
136
+ interface Run {
137
+ readonly text: string;
138
+ readonly formatting?: RunFormatting;
139
+ /** Set when the run carries a tracked change. Unique only within its part. */
140
+ readonly revisionId?: number;
141
+ }
142
+ /**
143
+ * Character formatting, and — at selection level — the paragraph properties a toolbar reads
144
+ * alongside it.
145
+ *
146
+ * One type serves both roles so a toolbar reads alignment, style and script state from the same
147
+ * object as bold and italic. On a {@link Run} the selection-level fields stay absent: a run has
148
+ * no alignment or paragraph style of its own.
149
+ */
150
+ interface RunFormatting {
151
+ readonly bold?: boolean;
152
+ readonly italic?: boolean;
153
+ readonly underline?: boolean;
154
+ readonly strike?: boolean;
155
+ readonly color?: ColorValue;
156
+ readonly highlight?: string;
157
+ readonly fontFamily?: string;
158
+ readonly fontSizePt?: number;
159
+ readonly superscript?: boolean;
160
+ readonly subscript?: boolean;
161
+ /** Paragraph alignment at the selection. `both` is OOXML's spelling of justify. */
162
+ readonly alignment?: 'left' | 'center' | 'right' | 'both';
163
+ /** Paragraph style id (`w:pStyle`) at the selection. */
164
+ readonly styleId?: string;
165
+ /**
166
+ * Line spacing at the selection, in the unit its rule implies — LINES for `multiple`,
167
+ * points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a
168
+ * control can show what it reads and send back what it shows. Absent when the
169
+ * selection's paragraphs disagree or state no line spacing.
170
+ */
171
+ readonly lineSpacing?: {
172
+ readonly rule: 'multiple' | 'exact' | 'atLeast';
173
+ readonly value: number;
174
+ };
175
+ /** Space above and below the paragraph at the selection, in points. */
176
+ readonly spaceBeforePt?: number;
177
+ readonly spaceAfterPt?: number;
178
+ /**
179
+ * The EFFECTIVE paragraph indent at the selection — cascade and numbering merge
180
+ * included, so a numbered item that authors no `w:ind` reports the indent its list
181
+ * definition gives it. Absent when nothing is loaded, or when the selection is inside a
182
+ * table (see {@link IndentFormatting}).
183
+ */
184
+ readonly indent?: IndentFormatting;
185
+ }
186
+ /**
187
+ * Indent at the selection, in twips.
188
+ *
189
+ * Unlike every other field here, this does NOT go absent when the selection's paragraphs
190
+ * disagree. A ruler has to draw its handles somewhere, and Word draws them at the FIRST
191
+ * selected paragraph's values — Select All is the commonest indent gesture, and hiding the
192
+ * handles for it would be worse than showing one paragraph's truth. The values are
193
+ * therefore always the first touched paragraph's, and {@link mixed} records per field
194
+ * whether the rest agree.
195
+ *
196
+ * `firstLine` is ONE SIGNED offset: negative is a hanging indent. OOXML spells it as two
197
+ * mutually exclusive attributes and this collapses them hanging-wins (§17.3.1.12), which
198
+ * is the model Word itself keeps.
199
+ *
200
+ * Absent inside a table. The value would be correct there, but it is measured from the
201
+ * cell's content edge while a ruler is drawn against the page's margin, and the ruler does
202
+ * not know the cell.
203
+ */
204
+ interface IndentFormatting {
205
+ /** Left indent, signed. Negative pulls text into the margin, as Word allows. */
206
+ readonly left: number;
207
+ /** Right indent, signed. */
208
+ readonly right: number;
209
+ /** First-line offset from {@link left}, signed. Negative is a hanging indent. */
210
+ readonly firstLine: number;
211
+ /** Per field, whether the selection's paragraphs disagree about it. */
212
+ readonly mixed: {
213
+ readonly left: boolean;
214
+ readonly right: boolean;
215
+ readonly firstLine: boolean;
216
+ };
217
+ }
218
+ /** A table: its rows, and the table style they resolve through. */
219
+ interface Table {
220
+ readonly kind: 'table';
221
+ readonly rows: readonly TableRow[];
222
+ readonly styleId?: string;
223
+ }
224
+ /** One table row. Cell count may vary between rows: `colSpan` and vertical merges reshape it. */
225
+ interface TableRow {
226
+ readonly cells: readonly TableCell[];
227
+ }
228
+ /**
229
+ * One cell. Its `content` is ordinary blocks, so a cell may hold paragraphs, nested tables and
230
+ * content controls alike.
231
+ */
232
+ interface TableCell {
233
+ readonly content: readonly Block[];
234
+ /** Vertical merge span. Absent means 1. */
235
+ readonly rowSpan?: number;
236
+ /** `w:gridSpan`. Absent means 1. */
237
+ readonly colSpan?: number;
238
+ }
239
+ /** Structured document tag (`w:sdt`). */
240
+ interface ContentControl {
241
+ readonly kind: 'contentControl';
242
+ readonly id: string;
243
+ readonly tag?: string;
244
+ readonly alias?: string;
245
+ readonly controlType: ContentControlType;
246
+ readonly locked?: boolean;
247
+ readonly content: readonly Block[];
248
+ }
249
+ /** Which kind of control a `w:sdt` is, and therefore what a value written into it must be. */
250
+ type ContentControlType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'repeatingSection';
251
+ /**
252
+ * Narrows a content-control query. Fields combine with AND; an empty filter matches every
253
+ * control.
254
+ */
255
+ interface ContentControlFilter {
256
+ readonly tag?: string;
257
+ readonly alias?: string;
258
+ readonly controlType?: ContentControlType;
259
+ }
260
+ /**
261
+ * A position in one story: a paragraph and a UTF-16 offset inside it.
262
+ *
263
+ * The same offset space the ops and the caret use, so an anchor read here can be handed
264
+ * straight back to a selection without re-deriving anything.
265
+ */
266
+ interface DocAnchorRange {
267
+ /** Canonical part name of the story the range lives in, e.g. `/word/document.xml`. */
268
+ readonly part: string;
269
+ readonly startParagraphId: string;
270
+ readonly startOffset: number;
271
+ /** May sit in a later paragraph: the range markers are independent elements. */
272
+ readonly endParagraphId: string;
273
+ readonly endOffset: number;
274
+ }
275
+ /**
276
+ * One comment or reply, as `comments.xml` records it.
277
+ *
278
+ * A reply is a comment with a `parentId`; OOXML gives replies no separate element, so the thread
279
+ * is reconstructed from that link rather than from nesting.
280
+ */
281
+ interface DocComment {
282
+ readonly id: string;
283
+ readonly author: string;
284
+ /**
285
+ * OPTIONAL, because `CT_Comment` makes `@w:date` optional and files omit it. A comment
286
+ * with no date is a comment, not a defect, and fabricating one is a content change.
287
+ */
288
+ readonly date?: string;
289
+ readonly text: string;
290
+ readonly parentId?: string;
291
+ readonly resolved?: boolean;
292
+ /**
293
+ * Where the comment is anchored, absent when the file gave it no usable range.
294
+ *
295
+ * A comment lives in `comments.xml` and is placed by markers in a STORY, so the story is
296
+ * part of the address: a comment anchored in a header belongs to a part the body never saw.
297
+ */
298
+ readonly anchor?: DocAnchorRange;
299
+ /**
300
+ * True when the file gave this comment no usable range — a reference with no markers, or a
301
+ * start with no end. Reported rather than dropped: a reviewer's remark vanishing silently
302
+ * is worse than one that says it lost its text.
303
+ */
304
+ readonly orphaned?: boolean;
305
+ }
306
+ /**
307
+ * What kind of decision a revision represents.
308
+ *
309
+ * Wider than insert/delete/format, and it has to be. `w:moveFrom`/`w:moveTo` are not a
310
+ * deletion and an insertion — resolving one half alone duplicates or loses the content;
311
+ * `w:pPr/w:rPr/w:ins|w:del` decorates no characters at all and merges paragraphs when
312
+ * resolved; a row or cell revision is structural. A reviewer shown only three kinds is a
313
+ * reviewer who never learns about the rest.
314
+ */
315
+ type RevisionType = 'insert' | 'delete'
316
+ /** A deletion and an insertion that are one edit: text typed over a selection. */
317
+ | 'replace' | 'moveFrom' | 'moveTo'
318
+ /** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
319
+ | 'format'
320
+ /** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
321
+ | 'paragraphMark'
322
+ /** A row, cell, section or grid revision. */
323
+ | 'structural';
324
+ /**
325
+ * One tracked change.
326
+ *
327
+ * Addressing needs BOTH `id` and `part`: `@w:id` is unique only within a part, so an id alone
328
+ * names two revisions in any package that has a header or a comments part.
329
+ */
330
+ interface Revision {
331
+ /** Numeric, and unique only WITHIN a part. Pair with `part` to address one. */
332
+ readonly id: number;
333
+ readonly type: RevisionType;
334
+ readonly author: string;
335
+ /**
336
+ * OPTIONAL. `CT_TrackChange` requires `@w:id` and `@w:author` and makes `@w:date`
337
+ * optional, and producers that omit it are ordinary. Requiring it here forced either a
338
+ * fabricated date — a content change — or dropping the revision from the list.
339
+ */
340
+ readonly date?: string;
341
+ /**
342
+ * REQUIRED, and a canonical PART NAME rather than a three-value enum.
343
+ *
344
+ * `@w:id` is unique only within a part, so an address without one names two revisions in a
345
+ * package that has both. The enum could not express the parts revisions actually occur in:
346
+ * `header3.xml`, `footer1.xml`, `comments.xml`, and `styles.xml`, which carries
347
+ * `w:pPrChange` inside style definitions with ids that collide with `document.xml`.
348
+ */
349
+ readonly part: string;
350
+ }
351
+ /** `w:sectPr`: the page a section lays out on. Twips throughout, as the file stores them. */
352
+ interface SectionProperties {
353
+ readonly pageSize: {
354
+ widthTwips: number;
355
+ heightTwips: number;
356
+ };
357
+ readonly margins: PageMargins;
358
+ readonly columns?: {
359
+ count: number;
360
+ gapTwips: number;
361
+ };
362
+ /** `w:titlePg` — whether the section's first page takes the `first` header/footer variant. */
363
+ readonly titlePage?: boolean;
364
+ }
365
+ /** Page margins in twips. */
366
+ interface PageMargins {
367
+ readonly topTwips: number;
368
+ readonly rightTwips: number;
369
+ readonly bottomTwips: number;
370
+ readonly leftTwips: number;
371
+ }
372
+ /**
373
+ * `styles.xml`, split by the three style families that address separately.
374
+ *
375
+ * Keyed by style ID rather than by the name a reader sees, because the ID is what a paragraph or
376
+ * run actually references.
377
+ */
378
+ interface StyleDefinitions {
379
+ readonly paragraph: ReadonlyMap<string, StyleDefinition>;
380
+ readonly character: ReadonlyMap<string, StyleDefinition>;
381
+ readonly table: ReadonlyMap<string, StyleDefinition>;
382
+ }
383
+ /** One style: the ID content references, the name a reader sees, and its inheritance link. */
384
+ interface StyleDefinition {
385
+ readonly id: string;
386
+ readonly name: string;
387
+ /** `w:basedOn` — the style this one inherits from. Absent at the root of a chain. */
388
+ readonly basedOn?: string;
389
+ }
390
+ /** A paragraph's list membership: which `numbering.xml` definition, and at which level. */
391
+ interface NumberingRef {
392
+ readonly numId: string;
393
+ /** Zero-based. OOXML numbering has nine levels, 0 through 8. */
394
+ readonly level: number;
395
+ }
396
+ /**
397
+ * A colour as the FILE expresses it, not as a resolved RGB string.
398
+ *
399
+ * A theme colour stays a theme reference — slot plus tint or shade — so that changing the theme
400
+ * repaints the document the way Word does. Flattening to hex at read time would freeze the
401
+ * resolved value and break that link. `auto` is Word's "let the renderer decide", usually black
402
+ * on white.
403
+ */
404
+ type ColorValue = {
405
+ readonly kind: 'hex';
406
+ readonly value: string;
407
+ } | {
408
+ readonly kind: 'theme';
409
+ readonly slot: string;
410
+ readonly tint?: number;
411
+ readonly shade?: number;
412
+ } | {
413
+ readonly kind: 'auto';
414
+ };
415
+ /** `theme1.xml` — what a {@link ColorValue} of kind `theme` resolves against. */
416
+ interface Theme {
417
+ readonly colorScheme: ThemeColorScheme;
418
+ readonly fontScheme?: Record<string, string>;
419
+ }
420
+ /** Theme colour slots (`accent1`, `dk1`, `lt2`, …) to hex. */
421
+ type ThemeColorScheme = Readonly<Record<string, string>>;
422
+ /** A watermark, which OOXML expresses as either text or an image — never both meaningfully. */
423
+ interface Watermark {
424
+ readonly text?: string;
425
+ readonly imageData?: Uint8Array;
426
+ }
427
+ /** A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch. */
428
+ interface Extent {
429
+ readonly widthEmu: number;
430
+ readonly heightEmu: number;
431
+ }
432
+ /** A font the document names, and whether its bytes travel inside the package. */
433
+ interface FontDefinition {
434
+ readonly family: string;
435
+ readonly embedded: boolean;
436
+ }
437
+ /** An axis-aligned rectangle in points, the unit layout works in throughout. */
438
+ interface Rect {
439
+ readonly x: number;
440
+ readonly y: number;
441
+ readonly width: number;
442
+ readonly height: number;
443
+ }
444
+ /** A position in points. */
445
+ interface Point {
446
+ readonly x: number;
447
+ readonly y: number;
448
+ }
449
+ /** What every subscription returns. Calling it twice is safe. */
450
+ type Unsubscribe = () => void;
451
+
452
+ export type { Block, ColorValue, ContainerRef, ContentControl, ContentControlFilter, ContentControlType, DocAnchor, DocAnchorRange, DocComment, DocLocation, DocRange, DocTarget, DocumentBody, DocxDocument, DocxDocumentJSON, ExecErrorCode, ExecResult, Extent, FontDefinition, HeaderFooterSet, IndentFormatting, NumberingRef, PageMargins, Paragraph, Point, Rect, Revision, RevisionType, Run, RunFormatting, Section, SectionProperties, StyleDefinition, StyleDefinitions, Table, TableCell, TableRow, Theme, ThemeColorScheme, Unsubscribe, Watermark };