@docx-editor.dev/core 0.0.1 → 2.1.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.
- package/LICENSE +201 -0
- package/README.md +91 -2
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/dist/automation.cjs +1 -0
- package/dist/automation.d.cts +74 -0
- package/dist/automation.d.ts +74 -0
- package/dist/automation.js +1 -0
- package/dist/binding.cjs +1 -0
- package/dist/binding.d.cts +88 -0
- package/dist/binding.d.ts +88 -0
- package/dist/binding.js +1 -0
- package/dist/chunk-2DTQDAN7.js +2 -0
- package/dist/chunk-3JKQE4QJ.cjs +2 -0
- package/dist/chunk-4WWEDTTE.js +2 -0
- package/dist/chunk-6WIIHJFY.js +1 -0
- package/dist/chunk-7VQ7YLW3.cjs +1 -0
- package/dist/chunk-BS554B6D.cjs +2 -0
- package/dist/chunk-BZK64YU3.cjs +10 -0
- package/dist/chunk-CZFUMACF.cjs +12 -0
- package/dist/chunk-GQQOL4PV.js +1 -0
- package/dist/chunk-HBL3NNH5.cjs +1 -0
- package/dist/chunk-JQFDLZXQ.cjs +2 -0
- package/dist/chunk-O2WQY7IT.cjs +5 -0
- package/dist/chunk-PC76F2HR.cjs +1 -0
- package/dist/chunk-QRAUDDVY.js +2 -0
- package/dist/chunk-REZUWYB7.js +1 -0
- package/dist/chunk-STCITBJK.js +12 -0
- package/dist/chunk-TBBXCC7D.js +5 -0
- package/dist/chunk-TSXT537P.cjs +12 -0
- package/dist/chunk-WOGYVM3W.js +12 -0
- package/dist/chunk-Y7TA7TPF.js +10 -0
- package/dist/content-control-walk-CbTqHq6O.d.cts +56 -0
- package/dist/content-control-walk-D06GijR0.d.ts +56 -0
- package/dist/contracts/document.cjs +1 -0
- package/dist/contracts/document.d.cts +246 -0
- package/dist/contracts/document.d.ts +246 -0
- package/dist/contracts/document.js +0 -0
- package/dist/contracts/editor.cjs +1 -0
- package/dist/contracts/editor.d.cts +11 -0
- package/dist/contracts/editor.d.ts +11 -0
- package/dist/contracts/editor.js +1 -0
- package/dist/contracts/interaction.cjs +1 -0
- package/dist/contracts/interaction.d.cts +11 -0
- package/dist/contracts/interaction.d.ts +11 -0
- package/dist/contracts/interaction.js +0 -0
- package/dist/contracts/modules.cjs +1 -0
- package/dist/contracts/modules.d.cts +117 -0
- package/dist/contracts/modules.d.ts +117 -0
- package/dist/contracts/modules.js +1 -0
- package/dist/contracts/types.cjs +1 -0
- package/dist/contracts/types.d.cts +452 -0
- package/dist/contracts/types.d.ts +452 -0
- package/dist/contracts/types.js +0 -0
- package/dist/custom-node-writes-YqISlSRl.d.cts +885 -0
- package/dist/custom-node-writes-ttKuYd0M.d.ts +885 -0
- package/dist/editor-B93PggnR.d.cts +1690 -0
- package/dist/editor-CFsSrxGR.d.ts +1690 -0
- package/dist/editor.cjs +1 -0
- package/dist/editor.css +7106 -0
- package/dist/editor.d.cts +271 -0
- package/dist/editor.d.ts +271 -0
- package/dist/editor.js +1 -0
- package/dist/hf-references-BdjsQNE_.d.ts +71 -0
- package/dist/hf-references-CgEOSw3i.d.cts +71 -0
- package/dist/image-resources-C_YnqPhn.d.ts +203 -0
- package/dist/image-resources-DwpNnTg3.d.cts +203 -0
- package/dist/index-BjZelfWL.d.cts +2532 -0
- package/dist/index-DP1yJJ3R.d.ts +2532 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +1 -0
- package/dist/layout.cjs +1 -0
- package/dist/layout.d.cts +2366 -0
- package/dist/layout.d.ts +2366 -0
- package/dist/layout.js +1 -0
- package/dist/note-nodes-BPSTVDMr.d.ts +108 -0
- package/dist/note-nodes-C6DLxlvj.d.cts +108 -0
- package/dist/ooxml-package-CR5us6ad.d.cts +354 -0
- package/dist/ooxml-package-D_CtywTW.d.ts +354 -0
- package/dist/ooxml-tree-BU0e3DVi.d.cts +871 -0
- package/dist/ooxml-tree-BU0e3DVi.d.ts +871 -0
- package/dist/output.cjs +1 -0
- package/dist/output.d.cts +158 -0
- package/dist/output.d.ts +158 -0
- package/dist/output.js +1 -0
- package/dist/protocol-BWVA3Q1p.d.ts +1255 -0
- package/dist/protocol-FAz_nPm_.d.cts +1255 -0
- package/dist/review-reads-CsoXSvUg.d.ts +401 -0
- package/dist/review-reads-qW0jvdF1.d.cts +401 -0
- package/dist/review-support-D64Wu236.d.cts +358 -0
- package/dist/review-support-nsLXC9jf.d.ts +358 -0
- package/dist/revision-projection-72ZApe-g.d.cts +84 -0
- package/dist/revision-projection-DHAkcD_L.d.ts +84 -0
- package/dist/semantic-cell-selection-D_8RbPII.d.ts +427 -0
- package/dist/semantic-cell-selection-DwLB71fF.d.cts +427 -0
- package/dist/semantic-interaction-CXH2wFqi.d.ts +187 -0
- package/dist/semantic-interaction-DqcEonqD.d.cts +187 -0
- package/dist/semantic-paint-drawings-B5Wk2so5.d.ts +21 -0
- package/dist/semantic-paint-drawings-x8g44lD_.d.cts +21 -0
- package/dist/semantic-records-COVFW5aS.d.cts +1505 -0
- package/dist/semantic-records-zTC0_1zi.d.ts +1505 -0
- package/dist/shaped-measurer-AFnFxoot.d.cts +613 -0
- package/dist/shaped-measurer-CZXL-a6v.d.ts +613 -0
- package/dist/store.cjs +1 -0
- package/dist/store.d.cts +2153 -0
- package/dist/store.d.ts +2153 -0
- package/dist/store.js +1 -0
- package/dist/tree-op-types-DWLCllG7.d.ts +1486 -0
- package/dist/tree-op-types-UOXlRUqQ.d.cts +1486 -0
- package/dist/tree-session-BtVFXsF6.d.ts +580 -0
- package/dist/tree-session-DxIOHUOD.d.cts +580 -0
- package/dist/tree-store-B1lEkdXc.d.cts +273 -0
- package/dist/tree-store-BscFPB7x.d.ts +273 -0
- package/package.json +110 -8
- package/index.js +0 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { e as OoxmlPart } from './ooxml-tree-BU0e3DVi.cjs';
|
|
2
|
+
import { O as OoxmlPackage } from './ooxml-package-CR5us6ad.cjs';
|
|
3
|
+
import { I as ImpactClass, T as TreeDocOp, a as TreeOpRejection } from './tree-op-types-UOXlRUqQ.cjs';
|
|
4
|
+
|
|
5
|
+
/** A selection the caller wants restored when an entry is undone or redone. */
|
|
6
|
+
/** A selection captured with a transaction, so undo restores where the caret was. */
|
|
7
|
+
interface SelectionMark {
|
|
8
|
+
readonly paragraphId: string;
|
|
9
|
+
readonly start: number;
|
|
10
|
+
readonly end: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Which editable story a ModelChange came from.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors `EditorScope` for body and header/footer — `{ kind: 'headerFooter'; rId }` —
|
|
16
|
+
* so package-aware mutation and the public scope contract stay one vocabulary. Body
|
|
17
|
+
* commits omit `rId`; header/footer commits carry the relationship id that addressed
|
|
18
|
+
* the part. Notes parts use `{ kind: 'notesPart'; noteKind }` (one store per part).
|
|
19
|
+
*/
|
|
20
|
+
/** Which story a transaction targets: the body, a header/footer part, or a notes part. */
|
|
21
|
+
type TreeStoryRef = {
|
|
22
|
+
readonly kind: 'body';
|
|
23
|
+
readonly partName: string;
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: 'headerFooter';
|
|
26
|
+
readonly partName: string;
|
|
27
|
+
readonly rId: string;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: 'notesPart';
|
|
30
|
+
readonly partName: string;
|
|
31
|
+
readonly noteKind: 'footnote' | 'endnote';
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* What one committed transaction changed: the revision, the ids touched, and the impact class.
|
|
35
|
+
*
|
|
36
|
+
* The ids are what let layout and paint re-do only the affected blocks instead of the document.
|
|
37
|
+
*/
|
|
38
|
+
interface TreeModelChange {
|
|
39
|
+
readonly change: 'model-change';
|
|
40
|
+
readonly fromRevision: number;
|
|
41
|
+
readonly toRevision: number;
|
|
42
|
+
readonly commitId: string;
|
|
43
|
+
readonly origin: string;
|
|
44
|
+
readonly dirty: readonly string[];
|
|
45
|
+
readonly created: readonly string[];
|
|
46
|
+
readonly deleted: readonly string[];
|
|
47
|
+
readonly splitJoin: readonly ({
|
|
48
|
+
readonly split: {
|
|
49
|
+
readonly from: string;
|
|
50
|
+
readonly tail: string;
|
|
51
|
+
};
|
|
52
|
+
} | {
|
|
53
|
+
readonly join: {
|
|
54
|
+
readonly kept: string;
|
|
55
|
+
readonly removed: string;
|
|
56
|
+
};
|
|
57
|
+
})[];
|
|
58
|
+
readonly dependencyKeys: readonly string[];
|
|
59
|
+
/** The widest impact among the transaction's ops — what layout must scope to. */
|
|
60
|
+
readonly impact: ImpactClass;
|
|
61
|
+
/**
|
|
62
|
+
* Story that published this change. Absent on body-only store publishes that predate
|
|
63
|
+
* package-aware targeting; `TreePackageStore` always sets it.
|
|
64
|
+
*/
|
|
65
|
+
readonly story?: TreeStoryRef;
|
|
66
|
+
/**
|
|
67
|
+
* Committed collapsed caret for this transaction, when one exists.
|
|
68
|
+
* Matches history `selectionAfter` when that mark is collapsed; absent for explicit
|
|
69
|
+
* null, non-collapsed explicit selection, or when no caret was committed.
|
|
70
|
+
*/
|
|
71
|
+
readonly caret?: SelectionMark;
|
|
72
|
+
}
|
|
73
|
+
/** Whether a transaction committed, or the typed reason it was refused. */
|
|
74
|
+
type TransactResult = {
|
|
75
|
+
readonly ok: true;
|
|
76
|
+
readonly change: TreeModelChange | null;
|
|
77
|
+
} | {
|
|
78
|
+
readonly ok: false;
|
|
79
|
+
readonly reason: TreeOpRejection;
|
|
80
|
+
readonly detail?: string;
|
|
81
|
+
};
|
|
82
|
+
/** What a transaction body is handed: the working tree, and the means to stage ops against it. */
|
|
83
|
+
interface TransactionContext {
|
|
84
|
+
/** Stage one op against the STORY part. Returns false once the transaction has failed. */
|
|
85
|
+
apply(op: TreeDocOp): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Stage one op against a named part.
|
|
88
|
+
*
|
|
89
|
+
* A comment body lives in `comments.xml` and is edited by the same ops that edit the story,
|
|
90
|
+
* so this is `apply` with the target named rather than a second vocabulary.
|
|
91
|
+
*/
|
|
92
|
+
applyTo(partName: string, op: TreeDocOp): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Stage a whole-package edit: a new part, a relationship, a content-type override.
|
|
95
|
+
*
|
|
96
|
+
* The edit is a pure function of the working package, so a rejected transaction discards it
|
|
97
|
+
* with everything else. Returning the SAME package is a no-op, not a failure — a primitive
|
|
98
|
+
* that finds nothing to do says so that way.
|
|
99
|
+
*/
|
|
100
|
+
applyPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): boolean;
|
|
101
|
+
/** The selection to restore when this entry is undone. */
|
|
102
|
+
selectionBefore(selection: SelectionMark | null): void;
|
|
103
|
+
/** The selection to restore when this entry is redone. */
|
|
104
|
+
selectionAfter(selection: SelectionMark | null): void;
|
|
105
|
+
}
|
|
106
|
+
/** How one transaction behaves: its story scope, its attribution, and its selection marks. */
|
|
107
|
+
interface TransactOptions {
|
|
108
|
+
readonly origin?: string;
|
|
109
|
+
/**
|
|
110
|
+
* A COMMAND is one user intent that may need several ops (a toolbar click applying a
|
|
111
|
+
* property across a multi-run selection). It is still exactly one history entry, which is
|
|
112
|
+
* the same rule a plain transaction follows — the option exists to say so explicitly at
|
|
113
|
+
* the call site rather than leaving it implied.
|
|
114
|
+
*/
|
|
115
|
+
readonly scope?: 'transaction' | 'command';
|
|
116
|
+
/**
|
|
117
|
+
* Floor on the published impact. Header/footer story edits use `global` so every page
|
|
118
|
+
* sharing the part invalidates rather than keeping stale furniture.
|
|
119
|
+
*/
|
|
120
|
+
readonly minimumImpact?: ImpactClass;
|
|
121
|
+
/** Story identity stamped onto the published ModelChange (package-aware targeting). */
|
|
122
|
+
readonly story?: TreeStoryRef;
|
|
123
|
+
}
|
|
124
|
+
interface HistoryEntry {
|
|
125
|
+
/**
|
|
126
|
+
* The whole package as it was, not just the story part.
|
|
127
|
+
*
|
|
128
|
+
* Affordable for the same reason a part snapshot was: parts are immutable and deep-frozen, so
|
|
129
|
+
* a package snapshot is a Map of references and every part the transaction did not touch is
|
|
130
|
+
* object-identical to the one before it. Undo stays a pointer swap, and it now reverses every
|
|
131
|
+
* part one intent wrote rather than only the story.
|
|
132
|
+
*/
|
|
133
|
+
readonly pkg: OoxmlPackage;
|
|
134
|
+
readonly revision: number;
|
|
135
|
+
readonly selectionBefore: SelectionMark | null;
|
|
136
|
+
readonly selectionAfter: SelectionMark | null;
|
|
137
|
+
}
|
|
138
|
+
/** How a store is constructed: its limits, its history depth, and its identity source. */
|
|
139
|
+
interface TreeDocumentStoreOptions {
|
|
140
|
+
/** Bound on retained history entries. Oldest entries drop first. */
|
|
141
|
+
readonly historyLimit?: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Opaque document+history checkpoint for package-coordinator rollback.
|
|
145
|
+
* Used when a story mutation may promote to a package undo unit (note-ref cascade).
|
|
146
|
+
*/
|
|
147
|
+
/** A restorable point in history — one entry of the intent-scoped undo stack. */
|
|
148
|
+
interface TreeDocumentCheckpoint {
|
|
149
|
+
/**
|
|
150
|
+
* The whole package, not one part. The store owns the package so a transaction spanning
|
|
151
|
+
* several parts is one publication — a checkpoint of only the story part could not roll
|
|
152
|
+
* back the comment or numbering part the same transaction wrote.
|
|
153
|
+
*/
|
|
154
|
+
readonly pkg: OoxmlPackage;
|
|
155
|
+
readonly revision: number;
|
|
156
|
+
readonly undoStack: readonly HistoryEntry[];
|
|
157
|
+
readonly redoStack: readonly HistoryEntry[];
|
|
158
|
+
readonly composition: {
|
|
159
|
+
readonly entry: HistoryEntry;
|
|
160
|
+
readonly committed: boolean;
|
|
161
|
+
} | null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The document store: one transaction is one atomic publication and one history entry.
|
|
165
|
+
*
|
|
166
|
+
* `apply` STAGES ops against a working part and nothing is visible until `transact` returns, so a
|
|
167
|
+
* batch rejected halfway leaves the revision, the tree, the indexes and every subscriber exactly
|
|
168
|
+
* as they were. That all-or-nothing property is what lets a caller compose ops without having to
|
|
169
|
+
* reason about partial application.
|
|
170
|
+
*/
|
|
171
|
+
declare class TreeDocumentStore {
|
|
172
|
+
private current;
|
|
173
|
+
/** The part `apply` targets and `part` returns: the story this store is editing. */
|
|
174
|
+
private readonly storyPartName;
|
|
175
|
+
private rev;
|
|
176
|
+
private commitCounter;
|
|
177
|
+
private readonly undoStack;
|
|
178
|
+
private readonly redoStack;
|
|
179
|
+
private readonly subscribers;
|
|
180
|
+
private readonly historyLimit;
|
|
181
|
+
/** Package-aware story tag applied to publishes (including undo/redo). */
|
|
182
|
+
private storyRef;
|
|
183
|
+
/** Open composition, if any. While set, transactions extend one entry (task 5.5). */
|
|
184
|
+
private composition;
|
|
185
|
+
/**
|
|
186
|
+
* Open a store over a package, editing the named story part.
|
|
187
|
+
*
|
|
188
|
+
* A bare part is accepted and wrapped in a single-part package, so callers that never open a
|
|
189
|
+
* real package — tests, headless tooling — are unaffected by the widening.
|
|
190
|
+
*/
|
|
191
|
+
constructor(source: OoxmlPart | OoxmlPackage, storyPartNameOrOptions?: string | TreeDocumentStoreOptions, maybeOptions?: TreeDocumentStoreOptions);
|
|
192
|
+
/**
|
|
193
|
+
* Stamp story identity onto subsequent publishes for this store (including undo/redo).
|
|
194
|
+
* Used by the package coordinator so history navigation keeps the same scope tag.
|
|
195
|
+
*/
|
|
196
|
+
setStoryRef(story: TreeStoryRef | null): void;
|
|
197
|
+
/** The story part being edited. Unchanged for every caller that predates the widening. */
|
|
198
|
+
get part(): OoxmlPart;
|
|
199
|
+
/** Every part, including the ones a multi-part transaction wrote. */
|
|
200
|
+
get package(): OoxmlPackage;
|
|
201
|
+
get revision(): number;
|
|
202
|
+
get canUndo(): boolean;
|
|
203
|
+
get canRedo(): boolean;
|
|
204
|
+
/** Retained entries — the unit `undo()` reverses, so tests can assert grouping. */
|
|
205
|
+
get historyDepth(): number;
|
|
206
|
+
get compositionActive(): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Replace the package OUTSIDE the transaction and history lanes.
|
|
209
|
+
*
|
|
210
|
+
* For package writes that are not a user intent and publish no revision: grafting
|
|
211
|
+
* `numbering.xml` into a document that never had one, which the caller performs as a
|
|
212
|
+
* precondition of the list op that follows. Those edits were previously kept in a package
|
|
213
|
+
* variable beside the store, which meant two owners of one value and, predictably, two
|
|
214
|
+
* values — a graft written to one and a save read from the other.
|
|
215
|
+
*
|
|
216
|
+
* Deliberately narrow and deliberately awkward to reach for: anything a user did belongs in
|
|
217
|
+
* `transact`, where it gets a revision, an undo entry and the invariant checks.
|
|
218
|
+
*/
|
|
219
|
+
graftPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): void;
|
|
220
|
+
/**
|
|
221
|
+
* Replace the current part without recording history, but advance the revision so
|
|
222
|
+
* revision-keyed projections cannot survive a package snapshot install.
|
|
223
|
+
*/
|
|
224
|
+
replacePart(part: OoxmlPart): void;
|
|
225
|
+
/**
|
|
226
|
+
* Snapshot part, revision, and undo/redo stacks so the package coordinator can roll
|
|
227
|
+
* back a story transaction that fails after commit (e.g. note-reference cascade) or
|
|
228
|
+
* discard a local history entry when promoting to a package undo unit.
|
|
229
|
+
*/
|
|
230
|
+
checkpoint(): TreeDocumentCheckpoint;
|
|
231
|
+
/** Full restore — part, revision, history stacks, and composition. */
|
|
232
|
+
restoreCheckpoint(checkpoint: TreeDocumentCheckpoint): void;
|
|
233
|
+
/**
|
|
234
|
+
* Restore undo/redo stacks only, keeping the current part and revision.
|
|
235
|
+
* Used when a story mutation is promoted to a package history pointer so the local
|
|
236
|
+
* orphan entry does not steal a later undo.
|
|
237
|
+
*/
|
|
238
|
+
restoreHistoryStacks(checkpoint: TreeDocumentCheckpoint): void;
|
|
239
|
+
subscribe(listener: (change: TreeModelChange) => void): () => void;
|
|
240
|
+
/**
|
|
241
|
+
* Run one atomic transaction.
|
|
242
|
+
*
|
|
243
|
+
* Ops are staged against a working copy. On the first rejection the whole transaction is
|
|
244
|
+
* abandoned: no revision, no history entry, no notification. On success exactly one
|
|
245
|
+
* revision is published and exactly one history entry is recorded — unless a composition
|
|
246
|
+
* is open, in which case the entry already exists and this transaction joins it.
|
|
247
|
+
*/
|
|
248
|
+
transact(build: (ctx: TransactionContext) => void, options?: TransactOptions): TransactResult;
|
|
249
|
+
/**
|
|
250
|
+
* Open one history entry for an IME composition.
|
|
251
|
+
*
|
|
252
|
+
* Everything committed until `endComposition` collapses into this single entry, which is
|
|
253
|
+
* what makes a composed word one undo step rather than one per intermediate transaction.
|
|
254
|
+
*/
|
|
255
|
+
beginComposition(selectionBefore?: SelectionMark | null): void;
|
|
256
|
+
/** Close the composition, recording its entry only if anything actually committed. */
|
|
257
|
+
endComposition(): void;
|
|
258
|
+
/**
|
|
259
|
+
* Cancel an open composition without recording an entry, leaving whatever it committed
|
|
260
|
+
* in place. An IME cancel is not an undo request; the caller decides what to revert.
|
|
261
|
+
*/
|
|
262
|
+
cancelComposition(): void;
|
|
263
|
+
undo(): TreeModelChange | null;
|
|
264
|
+
redo(): TreeModelChange | null;
|
|
265
|
+
/** The selection to restore for the entry `undo()` would reverse next. */
|
|
266
|
+
selectionForUndo(): SelectionMark | null;
|
|
267
|
+
/** The selection to restore for the entry `redo()` would reapply next. */
|
|
268
|
+
selectionForRedo(): SelectionMark | null;
|
|
269
|
+
private pushUndo;
|
|
270
|
+
private publish;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export { type SelectionMark as S, type TreeModelChange as T, type TreeStoryRef as a, TreeDocumentStore as b, type TransactionContext as c, type TransactOptions as d, type TreeDocumentCheckpoint as e, type TreeDocumentStoreOptions as f, type TransactResult as g };
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { e as OoxmlPart } from './ooxml-tree-BU0e3DVi.js';
|
|
2
|
+
import { O as OoxmlPackage } from './ooxml-package-D_CtywTW.js';
|
|
3
|
+
import { I as ImpactClass, T as TreeDocOp, a as TreeOpRejection } from './tree-op-types-DWLCllG7.js';
|
|
4
|
+
|
|
5
|
+
/** A selection the caller wants restored when an entry is undone or redone. */
|
|
6
|
+
/** A selection captured with a transaction, so undo restores where the caret was. */
|
|
7
|
+
interface SelectionMark {
|
|
8
|
+
readonly paragraphId: string;
|
|
9
|
+
readonly start: number;
|
|
10
|
+
readonly end: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Which editable story a ModelChange came from.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors `EditorScope` for body and header/footer — `{ kind: 'headerFooter'; rId }` —
|
|
16
|
+
* so package-aware mutation and the public scope contract stay one vocabulary. Body
|
|
17
|
+
* commits omit `rId`; header/footer commits carry the relationship id that addressed
|
|
18
|
+
* the part. Notes parts use `{ kind: 'notesPart'; noteKind }` (one store per part).
|
|
19
|
+
*/
|
|
20
|
+
/** Which story a transaction targets: the body, a header/footer part, or a notes part. */
|
|
21
|
+
type TreeStoryRef = {
|
|
22
|
+
readonly kind: 'body';
|
|
23
|
+
readonly partName: string;
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: 'headerFooter';
|
|
26
|
+
readonly partName: string;
|
|
27
|
+
readonly rId: string;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: 'notesPart';
|
|
30
|
+
readonly partName: string;
|
|
31
|
+
readonly noteKind: 'footnote' | 'endnote';
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* What one committed transaction changed: the revision, the ids touched, and the impact class.
|
|
35
|
+
*
|
|
36
|
+
* The ids are what let layout and paint re-do only the affected blocks instead of the document.
|
|
37
|
+
*/
|
|
38
|
+
interface TreeModelChange {
|
|
39
|
+
readonly change: 'model-change';
|
|
40
|
+
readonly fromRevision: number;
|
|
41
|
+
readonly toRevision: number;
|
|
42
|
+
readonly commitId: string;
|
|
43
|
+
readonly origin: string;
|
|
44
|
+
readonly dirty: readonly string[];
|
|
45
|
+
readonly created: readonly string[];
|
|
46
|
+
readonly deleted: readonly string[];
|
|
47
|
+
readonly splitJoin: readonly ({
|
|
48
|
+
readonly split: {
|
|
49
|
+
readonly from: string;
|
|
50
|
+
readonly tail: string;
|
|
51
|
+
};
|
|
52
|
+
} | {
|
|
53
|
+
readonly join: {
|
|
54
|
+
readonly kept: string;
|
|
55
|
+
readonly removed: string;
|
|
56
|
+
};
|
|
57
|
+
})[];
|
|
58
|
+
readonly dependencyKeys: readonly string[];
|
|
59
|
+
/** The widest impact among the transaction's ops — what layout must scope to. */
|
|
60
|
+
readonly impact: ImpactClass;
|
|
61
|
+
/**
|
|
62
|
+
* Story that published this change. Absent on body-only store publishes that predate
|
|
63
|
+
* package-aware targeting; `TreePackageStore` always sets it.
|
|
64
|
+
*/
|
|
65
|
+
readonly story?: TreeStoryRef;
|
|
66
|
+
/**
|
|
67
|
+
* Committed collapsed caret for this transaction, when one exists.
|
|
68
|
+
* Matches history `selectionAfter` when that mark is collapsed; absent for explicit
|
|
69
|
+
* null, non-collapsed explicit selection, or when no caret was committed.
|
|
70
|
+
*/
|
|
71
|
+
readonly caret?: SelectionMark;
|
|
72
|
+
}
|
|
73
|
+
/** Whether a transaction committed, or the typed reason it was refused. */
|
|
74
|
+
type TransactResult = {
|
|
75
|
+
readonly ok: true;
|
|
76
|
+
readonly change: TreeModelChange | null;
|
|
77
|
+
} | {
|
|
78
|
+
readonly ok: false;
|
|
79
|
+
readonly reason: TreeOpRejection;
|
|
80
|
+
readonly detail?: string;
|
|
81
|
+
};
|
|
82
|
+
/** What a transaction body is handed: the working tree, and the means to stage ops against it. */
|
|
83
|
+
interface TransactionContext {
|
|
84
|
+
/** Stage one op against the STORY part. Returns false once the transaction has failed. */
|
|
85
|
+
apply(op: TreeDocOp): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Stage one op against a named part.
|
|
88
|
+
*
|
|
89
|
+
* A comment body lives in `comments.xml` and is edited by the same ops that edit the story,
|
|
90
|
+
* so this is `apply` with the target named rather than a second vocabulary.
|
|
91
|
+
*/
|
|
92
|
+
applyTo(partName: string, op: TreeDocOp): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Stage a whole-package edit: a new part, a relationship, a content-type override.
|
|
95
|
+
*
|
|
96
|
+
* The edit is a pure function of the working package, so a rejected transaction discards it
|
|
97
|
+
* with everything else. Returning the SAME package is a no-op, not a failure — a primitive
|
|
98
|
+
* that finds nothing to do says so that way.
|
|
99
|
+
*/
|
|
100
|
+
applyPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): boolean;
|
|
101
|
+
/** The selection to restore when this entry is undone. */
|
|
102
|
+
selectionBefore(selection: SelectionMark | null): void;
|
|
103
|
+
/** The selection to restore when this entry is redone. */
|
|
104
|
+
selectionAfter(selection: SelectionMark | null): void;
|
|
105
|
+
}
|
|
106
|
+
/** How one transaction behaves: its story scope, its attribution, and its selection marks. */
|
|
107
|
+
interface TransactOptions {
|
|
108
|
+
readonly origin?: string;
|
|
109
|
+
/**
|
|
110
|
+
* A COMMAND is one user intent that may need several ops (a toolbar click applying a
|
|
111
|
+
* property across a multi-run selection). It is still exactly one history entry, which is
|
|
112
|
+
* the same rule a plain transaction follows — the option exists to say so explicitly at
|
|
113
|
+
* the call site rather than leaving it implied.
|
|
114
|
+
*/
|
|
115
|
+
readonly scope?: 'transaction' | 'command';
|
|
116
|
+
/**
|
|
117
|
+
* Floor on the published impact. Header/footer story edits use `global` so every page
|
|
118
|
+
* sharing the part invalidates rather than keeping stale furniture.
|
|
119
|
+
*/
|
|
120
|
+
readonly minimumImpact?: ImpactClass;
|
|
121
|
+
/** Story identity stamped onto the published ModelChange (package-aware targeting). */
|
|
122
|
+
readonly story?: TreeStoryRef;
|
|
123
|
+
}
|
|
124
|
+
interface HistoryEntry {
|
|
125
|
+
/**
|
|
126
|
+
* The whole package as it was, not just the story part.
|
|
127
|
+
*
|
|
128
|
+
* Affordable for the same reason a part snapshot was: parts are immutable and deep-frozen, so
|
|
129
|
+
* a package snapshot is a Map of references and every part the transaction did not touch is
|
|
130
|
+
* object-identical to the one before it. Undo stays a pointer swap, and it now reverses every
|
|
131
|
+
* part one intent wrote rather than only the story.
|
|
132
|
+
*/
|
|
133
|
+
readonly pkg: OoxmlPackage;
|
|
134
|
+
readonly revision: number;
|
|
135
|
+
readonly selectionBefore: SelectionMark | null;
|
|
136
|
+
readonly selectionAfter: SelectionMark | null;
|
|
137
|
+
}
|
|
138
|
+
/** How a store is constructed: its limits, its history depth, and its identity source. */
|
|
139
|
+
interface TreeDocumentStoreOptions {
|
|
140
|
+
/** Bound on retained history entries. Oldest entries drop first. */
|
|
141
|
+
readonly historyLimit?: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Opaque document+history checkpoint for package-coordinator rollback.
|
|
145
|
+
* Used when a story mutation may promote to a package undo unit (note-ref cascade).
|
|
146
|
+
*/
|
|
147
|
+
/** A restorable point in history — one entry of the intent-scoped undo stack. */
|
|
148
|
+
interface TreeDocumentCheckpoint {
|
|
149
|
+
/**
|
|
150
|
+
* The whole package, not one part. The store owns the package so a transaction spanning
|
|
151
|
+
* several parts is one publication — a checkpoint of only the story part could not roll
|
|
152
|
+
* back the comment or numbering part the same transaction wrote.
|
|
153
|
+
*/
|
|
154
|
+
readonly pkg: OoxmlPackage;
|
|
155
|
+
readonly revision: number;
|
|
156
|
+
readonly undoStack: readonly HistoryEntry[];
|
|
157
|
+
readonly redoStack: readonly HistoryEntry[];
|
|
158
|
+
readonly composition: {
|
|
159
|
+
readonly entry: HistoryEntry;
|
|
160
|
+
readonly committed: boolean;
|
|
161
|
+
} | null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The document store: one transaction is one atomic publication and one history entry.
|
|
165
|
+
*
|
|
166
|
+
* `apply` STAGES ops against a working part and nothing is visible until `transact` returns, so a
|
|
167
|
+
* batch rejected halfway leaves the revision, the tree, the indexes and every subscriber exactly
|
|
168
|
+
* as they were. That all-or-nothing property is what lets a caller compose ops without having to
|
|
169
|
+
* reason about partial application.
|
|
170
|
+
*/
|
|
171
|
+
declare class TreeDocumentStore {
|
|
172
|
+
private current;
|
|
173
|
+
/** The part `apply` targets and `part` returns: the story this store is editing. */
|
|
174
|
+
private readonly storyPartName;
|
|
175
|
+
private rev;
|
|
176
|
+
private commitCounter;
|
|
177
|
+
private readonly undoStack;
|
|
178
|
+
private readonly redoStack;
|
|
179
|
+
private readonly subscribers;
|
|
180
|
+
private readonly historyLimit;
|
|
181
|
+
/** Package-aware story tag applied to publishes (including undo/redo). */
|
|
182
|
+
private storyRef;
|
|
183
|
+
/** Open composition, if any. While set, transactions extend one entry (task 5.5). */
|
|
184
|
+
private composition;
|
|
185
|
+
/**
|
|
186
|
+
* Open a store over a package, editing the named story part.
|
|
187
|
+
*
|
|
188
|
+
* A bare part is accepted and wrapped in a single-part package, so callers that never open a
|
|
189
|
+
* real package — tests, headless tooling — are unaffected by the widening.
|
|
190
|
+
*/
|
|
191
|
+
constructor(source: OoxmlPart | OoxmlPackage, storyPartNameOrOptions?: string | TreeDocumentStoreOptions, maybeOptions?: TreeDocumentStoreOptions);
|
|
192
|
+
/**
|
|
193
|
+
* Stamp story identity onto subsequent publishes for this store (including undo/redo).
|
|
194
|
+
* Used by the package coordinator so history navigation keeps the same scope tag.
|
|
195
|
+
*/
|
|
196
|
+
setStoryRef(story: TreeStoryRef | null): void;
|
|
197
|
+
/** The story part being edited. Unchanged for every caller that predates the widening. */
|
|
198
|
+
get part(): OoxmlPart;
|
|
199
|
+
/** Every part, including the ones a multi-part transaction wrote. */
|
|
200
|
+
get package(): OoxmlPackage;
|
|
201
|
+
get revision(): number;
|
|
202
|
+
get canUndo(): boolean;
|
|
203
|
+
get canRedo(): boolean;
|
|
204
|
+
/** Retained entries — the unit `undo()` reverses, so tests can assert grouping. */
|
|
205
|
+
get historyDepth(): number;
|
|
206
|
+
get compositionActive(): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Replace the package OUTSIDE the transaction and history lanes.
|
|
209
|
+
*
|
|
210
|
+
* For package writes that are not a user intent and publish no revision: grafting
|
|
211
|
+
* `numbering.xml` into a document that never had one, which the caller performs as a
|
|
212
|
+
* precondition of the list op that follows. Those edits were previously kept in a package
|
|
213
|
+
* variable beside the store, which meant two owners of one value and, predictably, two
|
|
214
|
+
* values — a graft written to one and a save read from the other.
|
|
215
|
+
*
|
|
216
|
+
* Deliberately narrow and deliberately awkward to reach for: anything a user did belongs in
|
|
217
|
+
* `transact`, where it gets a revision, an undo entry and the invariant checks.
|
|
218
|
+
*/
|
|
219
|
+
graftPackage(edit: (pkg: OoxmlPackage) => OoxmlPackage): void;
|
|
220
|
+
/**
|
|
221
|
+
* Replace the current part without recording history, but advance the revision so
|
|
222
|
+
* revision-keyed projections cannot survive a package snapshot install.
|
|
223
|
+
*/
|
|
224
|
+
replacePart(part: OoxmlPart): void;
|
|
225
|
+
/**
|
|
226
|
+
* Snapshot part, revision, and undo/redo stacks so the package coordinator can roll
|
|
227
|
+
* back a story transaction that fails after commit (e.g. note-reference cascade) or
|
|
228
|
+
* discard a local history entry when promoting to a package undo unit.
|
|
229
|
+
*/
|
|
230
|
+
checkpoint(): TreeDocumentCheckpoint;
|
|
231
|
+
/** Full restore — part, revision, history stacks, and composition. */
|
|
232
|
+
restoreCheckpoint(checkpoint: TreeDocumentCheckpoint): void;
|
|
233
|
+
/**
|
|
234
|
+
* Restore undo/redo stacks only, keeping the current part and revision.
|
|
235
|
+
* Used when a story mutation is promoted to a package history pointer so the local
|
|
236
|
+
* orphan entry does not steal a later undo.
|
|
237
|
+
*/
|
|
238
|
+
restoreHistoryStacks(checkpoint: TreeDocumentCheckpoint): void;
|
|
239
|
+
subscribe(listener: (change: TreeModelChange) => void): () => void;
|
|
240
|
+
/**
|
|
241
|
+
* Run one atomic transaction.
|
|
242
|
+
*
|
|
243
|
+
* Ops are staged against a working copy. On the first rejection the whole transaction is
|
|
244
|
+
* abandoned: no revision, no history entry, no notification. On success exactly one
|
|
245
|
+
* revision is published and exactly one history entry is recorded — unless a composition
|
|
246
|
+
* is open, in which case the entry already exists and this transaction joins it.
|
|
247
|
+
*/
|
|
248
|
+
transact(build: (ctx: TransactionContext) => void, options?: TransactOptions): TransactResult;
|
|
249
|
+
/**
|
|
250
|
+
* Open one history entry for an IME composition.
|
|
251
|
+
*
|
|
252
|
+
* Everything committed until `endComposition` collapses into this single entry, which is
|
|
253
|
+
* what makes a composed word one undo step rather than one per intermediate transaction.
|
|
254
|
+
*/
|
|
255
|
+
beginComposition(selectionBefore?: SelectionMark | null): void;
|
|
256
|
+
/** Close the composition, recording its entry only if anything actually committed. */
|
|
257
|
+
endComposition(): void;
|
|
258
|
+
/**
|
|
259
|
+
* Cancel an open composition without recording an entry, leaving whatever it committed
|
|
260
|
+
* in place. An IME cancel is not an undo request; the caller decides what to revert.
|
|
261
|
+
*/
|
|
262
|
+
cancelComposition(): void;
|
|
263
|
+
undo(): TreeModelChange | null;
|
|
264
|
+
redo(): TreeModelChange | null;
|
|
265
|
+
/** The selection to restore for the entry `undo()` would reverse next. */
|
|
266
|
+
selectionForUndo(): SelectionMark | null;
|
|
267
|
+
/** The selection to restore for the entry `redo()` would reapply next. */
|
|
268
|
+
selectionForRedo(): SelectionMark | null;
|
|
269
|
+
private pushUndo;
|
|
270
|
+
private publish;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export { type SelectionMark as S, type TreeModelChange as T, type TreeStoryRef as a, TreeDocumentStore as b, type TransactionContext as c, type TransactOptions as d, type TreeDocumentCheckpoint as e, type TreeDocumentStoreOptions as f, type TransactResult as g };
|
package/package.json
CHANGED
|
@@ -1,17 +1,119 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docx-editor.dev/core",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Framework-agnostic core for
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Framework-agnostic core for docx-editor.dev: OOXML parse/serialize, the canonical document tree, layout and paint, and the Editor contract the adapters render.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"require": "./dist/index.cjs"
|
|
11
|
+
},
|
|
12
|
+
"./automation": {
|
|
13
|
+
"types": "./dist/automation.d.ts",
|
|
14
|
+
"import": "./dist/automation.js",
|
|
15
|
+
"require": "./dist/automation.cjs"
|
|
16
|
+
},
|
|
17
|
+
"./binding": {
|
|
18
|
+
"types": "./dist/binding.d.ts",
|
|
19
|
+
"import": "./dist/binding.js",
|
|
20
|
+
"require": "./dist/binding.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./contracts/editor": {
|
|
23
|
+
"types": "./dist/contracts/editor.d.ts",
|
|
24
|
+
"import": "./dist/contracts/editor.js",
|
|
25
|
+
"require": "./dist/contracts/editor.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./contracts/document": {
|
|
28
|
+
"types": "./dist/contracts/document.d.ts",
|
|
29
|
+
"import": "./dist/contracts/document.js",
|
|
30
|
+
"require": "./dist/contracts/document.cjs"
|
|
31
|
+
},
|
|
32
|
+
"./contracts/interaction": {
|
|
33
|
+
"types": "./dist/contracts/interaction.d.ts",
|
|
34
|
+
"import": "./dist/contracts/interaction.js",
|
|
35
|
+
"require": "./dist/contracts/interaction.cjs"
|
|
36
|
+
},
|
|
37
|
+
"./contracts/modules": {
|
|
38
|
+
"types": "./dist/contracts/modules.d.ts",
|
|
39
|
+
"import": "./dist/contracts/modules.js",
|
|
40
|
+
"require": "./dist/contracts/modules.cjs"
|
|
41
|
+
},
|
|
42
|
+
"./contracts/types": {
|
|
43
|
+
"types": "./dist/contracts/types.d.ts",
|
|
44
|
+
"import": "./dist/contracts/types.js",
|
|
45
|
+
"require": "./dist/contracts/types.cjs"
|
|
46
|
+
},
|
|
47
|
+
"./layout": {
|
|
48
|
+
"types": "./dist/layout.d.ts",
|
|
49
|
+
"import": "./dist/layout.js",
|
|
50
|
+
"require": "./dist/layout.cjs"
|
|
51
|
+
},
|
|
52
|
+
"./output": {
|
|
53
|
+
"types": "./dist/output.d.ts",
|
|
54
|
+
"import": "./dist/output.js",
|
|
55
|
+
"require": "./dist/output.cjs"
|
|
56
|
+
},
|
|
57
|
+
"./store": {
|
|
58
|
+
"types": "./dist/store.d.ts",
|
|
59
|
+
"import": "./dist/store.js",
|
|
60
|
+
"require": "./dist/store.cjs"
|
|
61
|
+
},
|
|
62
|
+
"./editor": {
|
|
63
|
+
"types": "./dist/editor.d.ts",
|
|
64
|
+
"import": "./dist/editor.js",
|
|
65
|
+
"require": "./dist/editor.cjs"
|
|
66
|
+
},
|
|
67
|
+
"./styles/editor.css": "./dist/editor.css",
|
|
68
|
+
"./package.json": "./package.json"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsup && node ../../scripts/build-core-styles.mjs",
|
|
72
|
+
"typecheck": "tsc --noEmit"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"autoprefixer": "^10.4.17",
|
|
76
|
+
"postcss": "^8.4.33",
|
|
77
|
+
"tailwindcss": "^3.4.1",
|
|
78
|
+
"tailwindcss-animate": "^1.0.7",
|
|
79
|
+
"typescript": "^5.3.3"
|
|
80
|
+
},
|
|
5
81
|
"license": "Apache-2.0",
|
|
6
|
-
"main": "index.js",
|
|
7
82
|
"repository": {
|
|
8
83
|
"type": "git",
|
|
9
84
|
"url": "https://github.com/eigenpal/docx-editor.git",
|
|
10
85
|
"directory": "packages/core"
|
|
11
86
|
},
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
87
|
+
"dependencies": {
|
|
88
|
+
"@docx-editor.dev/i18n": "^2.1.0",
|
|
89
|
+
"bidi-js": "1.0.3",
|
|
90
|
+
"emf-converter": "2.0.2",
|
|
91
|
+
"fast-xml-parser": "^5.10.1",
|
|
92
|
+
"fflate": "^0.8.2",
|
|
93
|
+
"harfbuzzjs": "1.4.0",
|
|
94
|
+
"prosemirror-commands": "^1.7.1",
|
|
95
|
+
"prosemirror-keymap": "^1.2.3",
|
|
96
|
+
"prosemirror-model": "^1.25.4",
|
|
97
|
+
"prosemirror-state": "^1.4.4",
|
|
98
|
+
"prosemirror-view": "^1.41.8",
|
|
99
|
+
"utif2": "4.1.0"
|
|
100
|
+
},
|
|
101
|
+
"peerDependencies": {
|
|
102
|
+
"pdf-lib": "^1.17.1",
|
|
103
|
+
"yjs": "^13.6.0"
|
|
104
|
+
},
|
|
105
|
+
"peerDependenciesMeta": {
|
|
106
|
+
"pdf-lib": {
|
|
107
|
+
"optional": true
|
|
108
|
+
},
|
|
109
|
+
"yjs": {
|
|
110
|
+
"optional": true
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"files": [
|
|
114
|
+
"dist",
|
|
115
|
+
"!dist/metafile-*.json",
|
|
116
|
+
"README.md",
|
|
117
|
+
"THIRD_PARTY_NOTICES.md"
|
|
118
|
+
]
|
|
17
119
|
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {};
|