@ansonlai/docx-redline-js 0.4.0 → 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.
- package/AGENTS.md +589 -287
- package/ARCHITECTURE.md +215 -9
- package/CHANGELOG.md +319 -0
- package/README.md +604 -360
- package/adapters/config.js +45 -43
- package/bin/docx-redline.js +3 -0
- package/core/list-targeting.js +101 -110
- package/core/paragraph-targeting.js +501 -61
- package/core/paragraph-text.js +209 -0
- package/core/revision-cloning.js +38 -0
- package/core/types.js +64 -10
- package/core/word-xml.js +43 -15
- package/dist/docx-redline-js.esm.js +2849 -466
- package/dist/docx-redline-js.esm.js.map +4 -4
- package/dist/docx-redline-js.esm.min.js +87 -76
- package/dist/docx-redline-js.esm.min.js.map +4 -4
- package/docs/TESTING.md +342 -23
- package/docs/plans/2026-09-05-structural-revisions-and-fidelity-oracles.md +1669 -0
- package/docs/plans/completed/2026-09-01-performance-and-complexity-reduction.md +669 -0
- package/docs/plans/completed/2026-09-03-agent-friendly-document-workflows.md +427 -0
- package/docs/plans/completed/2026-09-04-comment-anchor-and-cli-reliability.md +519 -0
- package/docs/plans/completed/PERFORMANCE-CONSOLIDATION.md +69 -0
- package/docs/plans/completed/structural-revision-capability-matrix.md +115 -0
- package/docs/schemas/document-operations.schema.json +109 -0
- package/docs/test-comparison-dashboard.html +4250 -7
- package/engine/formatting-removal.js +11 -2
- package/engine/oxml-engine.js +491 -336
- package/engine/reconstruction-mode.js +15 -14
- package/engine/reconstruction-writer.js +247 -142
- package/engine/route-selection.js +35 -0
- package/engine/rpr-helpers.js +334 -35
- package/engine/run-builders.js +239 -196
- package/engine/surgical-diff-application.js +222 -37
- package/engine/surgical-mode.js +134 -6
- package/engine/surgical-spans.js +52 -1
- package/engine/table-cell-context.js +3 -6
- package/engine/table-mode.js +1 -1
- package/index.d.ts +234 -6
- package/index.js +24 -1
- package/node/cli.js +317 -0
- package/node/docx-document.js +302 -0
- package/node/index.d.ts +31 -0
- package/node/index.js +2 -0
- package/node/zip-archive.js +52 -0
- package/orchestration/list-markdown.js +10 -16
- package/orchestration/list-parsing.js +7 -12
- package/orchestration/list-structural-fallback.js +21 -10
- package/package.json +24 -3
- package/pipeline/content-analysis.js +12 -17
- package/pipeline/ingestion-export.js +3 -31
- package/pipeline/ingestion-paragraph.js +10 -5
- package/pipeline/list-generation.js +150 -55
- package/pipeline/list-markers.js +70 -3
- package/pipeline/serialization.js +4 -2
- package/pipeline/structured-content.js +160 -0
- package/scripts/apply_changes.mjs +27 -0
- package/scripts/benchmark-operation-session.mjs +137 -0
- package/scripts/benchmark-targeting-browser.html +74 -0
- package/scripts/benchmark-targeting-hot-paths.mjs +67 -0
- package/scripts/benchmark-test-runner.mjs +59 -0
- package/scripts/build-test-dashboard.mjs +23 -0
- package/scripts/export-lane1-fixtures.mjs +380 -0
- package/scripts/export-reredline-stress-fixtures.mjs +317 -0
- package/scripts/export-validation-fixtures.mjs +1 -1
- package/scripts/extract_text.mjs +7 -0
- package/scripts/generate-paragraph-boundary-fixtures.ps1 +215 -0
- package/scripts/generate-test-dashboard.mjs +362 -11
- package/scripts/lib/word-coverage-catalogue.mjs +6 -2
- package/scripts/profile-route-selection.mjs +19 -0
- package/scripts/render-agenda-multilevel.mjs +0 -5
- package/scripts/render-multilevel-cases.mjs +0 -1
- package/scripts/run-tests.mjs +107 -35
- package/scripts/word-com-corpus-suite.ps1 +3 -0
- package/scripts/word-com-differential.ps1 +64 -4
- package/scripts/word-com-suite.ps1 +3 -0
- package/services/batch-operation-orchestrator.js +494 -0
- package/services/capture-engine.js +226 -0
- package/services/comment-builders.js +23 -6
- package/services/comment-engine.js +108 -47
- package/services/comment-locator.js +187 -82
- package/services/comment-replies.js +95 -0
- package/services/document-inspection.js +258 -0
- package/services/document-operation-applier.js +372 -0
- package/services/document-operation-contract.js +323 -0
- package/services/document-operation-mutations.js +1733 -0
- package/services/document-operation-session.js +258 -0
- package/services/numbering-service.js +14 -5
- package/services/operation-heuristics.js +173 -0
- package/services/operation-preflight.js +366 -0
- package/services/receipt-collector.js +288 -0
- package/services/revision-comment-management.js +37 -5
- package/services/revision-token.js +290 -0
- package/services/standalone-docx-plumbing.js +123 -8
- package/services/standalone-operation-runner.d.ts +296 -0
- package/services/standalone-operation-runner.js +10 -1455
- package/services/table-reconciliation.js +15 -6
- package/docs/VALIDATION.md +0 -183
- package/docs/WORD-MANUAL-REVIEW.md +0 -138
- package/docs/plans/2026-09-01-performance-and-complexity-reduction.md +0 -210
- /package/docs/plans/{2026-08-30-reliability-testing-improvements.md → completed/2026-08-30-reliability-testing-improvements.md} +0 -0
package/index.d.ts
CHANGED
|
@@ -1,10 +1,61 @@
|
|
|
1
1
|
export type OoxmlSourceType = 'package' | 'document' | 'fragment';
|
|
2
2
|
export type RedlineStatus = 'ok' | 'no-op' | 'error';
|
|
3
|
-
export type ExistingRevisionsPolicy = 'reject-input' | 'accept-all-first' | 'accept-all-first-keep-normalized';
|
|
3
|
+
export type ExistingRevisionsPolicy = 'merge-same-author' | 'reject-input' | 'accept-all-first' | 'accept-all-first-keep-normalized';
|
|
4
|
+
export type RevisionView = 'accepted' | 'rejected';
|
|
5
|
+
|
|
6
|
+
export interface RevisionTextSegment {
|
|
7
|
+
text: string;
|
|
8
|
+
kind: 'baseline' | 'insertion' | 'deletion' | 'move_from' | 'move_to';
|
|
9
|
+
author?: string;
|
|
10
|
+
revisionId?: string;
|
|
11
|
+
acceptedStart: number | null;
|
|
12
|
+
rejectedStart: number | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
import type { InsertionAffinity } from './services/standalone-operation-runner.js';
|
|
16
|
+
|
|
17
|
+
export type {
|
|
18
|
+
BatchOperationItemResult,
|
|
19
|
+
CommentDocumentOperation,
|
|
20
|
+
CommentReplyDocumentOperation,
|
|
21
|
+
DeleteDocumentOperation,
|
|
22
|
+
DocumentOperation,
|
|
23
|
+
DocumentOperationBatchResult,
|
|
24
|
+
HighlightDocumentOperation,
|
|
25
|
+
InsertionAffinity,
|
|
26
|
+
OperationConflict,
|
|
27
|
+
OperationDependencyPlan,
|
|
28
|
+
OperationPreflightItemResult,
|
|
29
|
+
OperationPreflightResult,
|
|
30
|
+
ParagraphTargetDescriptor,
|
|
31
|
+
RedlineDocumentOperation,
|
|
32
|
+
ResolvedCommentAnchor,
|
|
33
|
+
ResolvedDocumentTarget,
|
|
34
|
+
StandaloneRunnerOptions
|
|
35
|
+
} from './services/standalone-operation-runner.js';
|
|
4
36
|
|
|
5
37
|
export interface RedlineError {
|
|
6
|
-
code:
|
|
38
|
+
code:
|
|
39
|
+
| 'PARSE_ERROR'
|
|
40
|
+
| 'TARGET_NOT_FOUND'
|
|
41
|
+
| 'EXISTING_REVISIONS'
|
|
42
|
+
| 'DIFF_TOKEN_LIMIT'
|
|
43
|
+
| 'UNSUPPORTED_REVISION_VIEW_MUTATION'
|
|
44
|
+
| 'UNSUPPORTED_INSERTION_AFFINITY'
|
|
45
|
+
| 'UNSAFE_PARAGRAPH_BOUNDARY'
|
|
46
|
+
| 'TARGET_INDEX_MISMATCH'
|
|
47
|
+
| 'REVISION_MISMATCH'
|
|
48
|
+
| 'REVISION_TOKEN_SCOPE_MISMATCH'
|
|
49
|
+
| 'INVALID_REVISION_TOKEN'
|
|
50
|
+
| 'DUPLICATE_CAPTURE_KEY'
|
|
51
|
+
| 'CAPTURE_NOT_FOUND'
|
|
52
|
+
| 'CAPTURE_DEPENDENCY_CYCLE'
|
|
53
|
+
| 'AMBIGUOUS_CAPTURE_SELECTION'
|
|
54
|
+
| 'CAPTURE_STALE'
|
|
55
|
+
| string;
|
|
7
56
|
message: string;
|
|
57
|
+
commentIds?: string[];
|
|
58
|
+
comments?: Array<{ id: string; author: string; text: string }>;
|
|
8
59
|
}
|
|
9
60
|
|
|
10
61
|
export interface RedlineOptions {
|
|
@@ -14,6 +65,9 @@ export interface RedlineOptions {
|
|
|
14
65
|
existingRevisions?: ExistingRevisionsPolicy;
|
|
15
66
|
removeFormatting?: boolean;
|
|
16
67
|
sanitizeInput?: boolean;
|
|
68
|
+
structuredContent?: boolean;
|
|
69
|
+
pairReplacements?: boolean;
|
|
70
|
+
insertionAffinity?: InsertionAffinity;
|
|
17
71
|
[key: string]: unknown;
|
|
18
72
|
}
|
|
19
73
|
|
|
@@ -78,6 +132,28 @@ export interface IngestionTextResult {
|
|
|
78
132
|
warnings?: string[];
|
|
79
133
|
}
|
|
80
134
|
|
|
135
|
+
export interface ParagraphTargetCandidate {
|
|
136
|
+
paragraph: Element;
|
|
137
|
+
index: number;
|
|
138
|
+
inTable: boolean;
|
|
139
|
+
paragraphId: string | null;
|
|
140
|
+
fingerprint: string | null;
|
|
141
|
+
text: string;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface ParagraphTargetResolution {
|
|
145
|
+
paragraph: Element;
|
|
146
|
+
resolvedBy:
|
|
147
|
+
| 'ref'
|
|
148
|
+
| 'paragraph_id'
|
|
149
|
+
| 'occurrence'
|
|
150
|
+
| 'fingerprint'
|
|
151
|
+
| 'strict_text'
|
|
152
|
+
| 'fuzzy_text'
|
|
153
|
+
| 'strict_text_after_ref_drift'
|
|
154
|
+
| 'fuzzy_text_after_ref_drift';
|
|
155
|
+
}
|
|
156
|
+
|
|
81
157
|
export interface XmlProvider {
|
|
82
158
|
DOMParser: typeof DOMParser;
|
|
83
159
|
XMLSerializer: typeof XMLSerializer;
|
|
@@ -94,6 +170,7 @@ export interface DocumentOperationResult {
|
|
|
94
170
|
hasChanges: boolean;
|
|
95
171
|
numberingXml?: string | null;
|
|
96
172
|
commentsXml?: string | null;
|
|
173
|
+
commentsExtendedXml?: string | null;
|
|
97
174
|
warnings?: string[];
|
|
98
175
|
status?: RedlineStatus;
|
|
99
176
|
error?: RedlineError;
|
|
@@ -128,10 +205,86 @@ export function reconcileMarkdownTableOoxml(
|
|
|
128
205
|
options?: RedlineOptions
|
|
129
206
|
): Promise<TableReconciliationResult>;
|
|
130
207
|
|
|
208
|
+
export interface StructuredContentIssue {
|
|
209
|
+
severity: 'error' | 'warning';
|
|
210
|
+
code: string;
|
|
211
|
+
line: number;
|
|
212
|
+
message: string;
|
|
213
|
+
}
|
|
214
|
+
export interface StructuredContentBlock {
|
|
215
|
+
type: 'heading' | 'paragraph' | 'list' | 'table';
|
|
216
|
+
markdown: string;
|
|
217
|
+
text?: string;
|
|
218
|
+
level?: number;
|
|
219
|
+
items?: number;
|
|
220
|
+
columns?: number;
|
|
221
|
+
rows?: number;
|
|
222
|
+
hasHeader?: boolean;
|
|
223
|
+
}
|
|
224
|
+
export interface StructuredContentAnalysis {
|
|
225
|
+
valid: boolean;
|
|
226
|
+
normalizedMarkdown: string;
|
|
227
|
+
blocks: StructuredContentBlock[];
|
|
228
|
+
issues: StructuredContentIssue[];
|
|
229
|
+
counts: Record<'heading' | 'paragraph' | 'list' | 'table', number>;
|
|
230
|
+
requiresStructuredContent: boolean;
|
|
231
|
+
}
|
|
232
|
+
export function analyzeStructuredContent(markdown: string): StructuredContentAnalysis;
|
|
233
|
+
export function planStructuredReplacement(
|
|
234
|
+
target: string | import('./services/standalone-operation-runner.js').ParagraphTargetDescriptor,
|
|
235
|
+
markdown: string,
|
|
236
|
+
options?: { author?: string; generateRedlines?: boolean; existingRevisions?: ExistingRevisionsPolicy }
|
|
237
|
+
): StructuredContentAnalysis & { operation: import('./services/standalone-operation-runner.js').RedlineDocumentOperation | null };
|
|
238
|
+
|
|
131
239
|
export function ingestWordOoxmlToPlainText(oxml: string): string;
|
|
132
240
|
export function ingestWordOoxmlToMarkdown(oxml: string): string;
|
|
133
241
|
export function ingestWordOoxmlToPlainTextResult(oxml: unknown): IngestionTextResult;
|
|
134
242
|
export function ingestWordOoxmlToMarkdownResult(oxml: unknown): IngestionTextResult;
|
|
243
|
+
export function extractCanonicalParagraphText(paragraph: Element | null | undefined, options?: { revisionView?: 'accepted' | 'rejected' | 'current' }): string;
|
|
244
|
+
export function extractParagraphRevisionSegments(paragraph: Element | null | undefined, options?: { mergeRuns?: boolean; [key: string]: unknown }): RevisionTextSegment[];
|
|
245
|
+
export function readCanonicalRunText(run: Element, options?: { revisionView?: 'accepted' | 'rejected' | 'current'; boundary?: Element | null }): string;
|
|
246
|
+
export function isNodeVisibleInRevisionView(node: Node, boundary?: Node | null, revisionView?: 'accepted' | 'rejected' | 'current'): boolean;
|
|
247
|
+
export function containsTrackedChanges(xmlDoc: Document | Element | null | undefined): boolean;
|
|
248
|
+
export function getTrackedChangeAuthors(xmlDocOrElement: Document | Element | null | undefined): string[];
|
|
249
|
+
|
|
250
|
+
export interface InspectedParagraph {
|
|
251
|
+
index: number; ref: string; paragraphId: string | null; fingerprint: string | null;
|
|
252
|
+
text: string; exactText: string; excerpt: string; inTable: boolean;
|
|
253
|
+
humanReference: string; styleId: string | null;
|
|
254
|
+
table: { tableIndex: number; rowIndex: number; cellIndex: number } | null;
|
|
255
|
+
structuralReferences: Array<{ type: 'footnote' | 'endnote' | 'comment'; id: string | null }>;
|
|
256
|
+
headingLevel: number | null; nearestHeading: { level: number; text: string } | null;
|
|
257
|
+
list: { numId: string; level: number; label: string | null; format: string | null } | null;
|
|
258
|
+
hasRevisions: boolean; revisionAuthors: string[]; commentIds: string[];
|
|
259
|
+
segments: RevisionTextSegment[];
|
|
260
|
+
}
|
|
261
|
+
export interface RevisionToken {
|
|
262
|
+
algorithm: 'sha256';
|
|
263
|
+
version: 1;
|
|
264
|
+
scope: 'document-parts' | 'package';
|
|
265
|
+
value: string;
|
|
266
|
+
coveredParts?: string[];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface InspectedComment { id: string; author: string | null; date: string | null; text: string; paraId?: string | null; parentParaId?: string; parentCommentId?: string | null; done?: boolean; paragraphIndex?: number; targetRef?: string; anchoredText?: string; }
|
|
270
|
+
export interface DocumentInspectionOptions { revisionView?: 'accepted' | 'rejected' | 'current'; excerptLength?: number; revisedOnly?: boolean; inTable?: boolean; skipEmpty?: boolean; search?: string; indexes?: number[]; range?: { start: number; end: number } | [number, number]; digestFn?: (bytes: Uint8Array) => string; }
|
|
271
|
+
export interface DocumentInspectionResult {
|
|
272
|
+
status: 'ok' | 'error'; paragraphs: InspectedParagraph[]; comments: InspectedComment[];
|
|
273
|
+
revisionAuthors?: string[]; commentAuthors?: string[]; counts?: { paragraphs: number; comments: number; revisedParagraphs: number };
|
|
274
|
+
revisionToken?: RevisionToken | null;
|
|
275
|
+
coveredParts?: string[];
|
|
276
|
+
warnings: string[]; error?: RedlineError;
|
|
277
|
+
}
|
|
278
|
+
export function inspectDocumentParts(parts: { documentXml: string; commentsXml?: string | null; commentsExtendedXml?: string | null; numberingXml?: string | null; stylesXml?: string | null; parts?: Map<string, unknown>; additionalParts?: Record<string, unknown> }, options?: DocumentInspectionOptions): DocumentInspectionResult;
|
|
279
|
+
export function buildRevisionTokenFraming(options: { scope: string; entries?: unknown }): { framing: Uint8Array; scope: string; version: number; coveredParts: string[] };
|
|
280
|
+
export function computeRevisionToken(options: { scope: string; entries?: unknown; digestFn?: (bytes: Uint8Array) => Promise<string> }): Promise<RevisionToken>;
|
|
281
|
+
export function computeRevisionTokenSync(options: { scope: string; entries?: unknown; digestFn: (bytes: Uint8Array) => string }): RevisionToken;
|
|
282
|
+
export function computeDocumentPartsRevisionToken(parts: unknown, options?: { digestFn?: (bytes: Uint8Array) => Promise<string> }): Promise<RevisionToken>;
|
|
283
|
+
export function validateRevisionToken(token: unknown): { valid: boolean; error?: { code: string; message: string } };
|
|
284
|
+
export function areRevisionTokensEqual(a: string, b: string): boolean;
|
|
285
|
+
export function normalizeOpcEntryName(name: string): string;
|
|
286
|
+
export function extractDocumentPartsEntries(parts: unknown): Array<{ name: string; payload: unknown }>;
|
|
287
|
+
|
|
135
288
|
export function ingestOoxml(oxml: string): unknown;
|
|
136
289
|
export function preprocessMarkdown(text: string): { cleanText: string; formatHints: unknown[] };
|
|
137
290
|
export function serializeToOoxml(runModel: unknown[], pPrXml?: string | null, formatHints?: unknown[], options?: Record<string, unknown>): string;
|
|
@@ -139,6 +292,7 @@ export function wrapInDocumentFragment(rawOoxml: string, options?: Record<string
|
|
|
139
292
|
|
|
140
293
|
export function injectCommentsIntoOoxml(oxml: string, comments: unknown[], options?: Record<string, unknown>): unknown;
|
|
141
294
|
export function injectCommentsIntoPackage(packageXml: string, comments: unknown[], options?: Record<string, unknown>): unknown;
|
|
295
|
+
export function applyCommentReplyToParts(options: { commentsXml: string; commentsExtendedXml?: string | null; parentCommentId: string | number; commentId: string | number; commentContent: string; author: string; date?: string }): { status: 'ok' | 'error'; hasChanges?: boolean; commentsXml?: string; commentsExtendedXml?: string; commentsXmlMode?: 'replace'; commentsExtendedXmlMode?: 'replace'; parentCommentId?: string; paraId?: string; parentParaId?: string; error?: RedlineError };
|
|
142
296
|
export function acceptTrackedChangesInOoxml(oxml: string, options?: RevisionFilterOptions): AcceptTrackedChangesResult;
|
|
143
297
|
export function rejectTrackedChangesInOoxml(oxml: string, options?: RevisionFilterOptions): RejectTrackedChangesResult;
|
|
144
298
|
export function deleteCommentsByAuthorInOoxml(oxml: string, options?: RevisionFilterOptions): DeleteCommentsResult;
|
|
@@ -174,6 +328,7 @@ export function extractReplacementNodesFromOoxml(oxml: string): unknown;
|
|
|
174
328
|
export function validateDocxPackage(zip: unknown): Promise<unknown> | unknown;
|
|
175
329
|
export function ensureNumberingArtifactsInZip(zip: unknown, numberingXml: string): Promise<unknown> | unknown;
|
|
176
330
|
export function ensureCommentsArtifactsInZip(zip: unknown, commentsXml: string): Promise<unknown> | unknown;
|
|
331
|
+
export function ensureCommentsExtendedArtifactsInZip(zip: unknown, commentsExtendedXml: string): Promise<unknown> | unknown;
|
|
177
332
|
export function createDynamicNumberingIdState(numberingXml?: string): unknown;
|
|
178
333
|
|
|
179
334
|
export function parseOoxml(ooxml: string): Document | null;
|
|
@@ -231,6 +386,8 @@ export function enforceListBindingOnParagraphNodes(nodes: Node[], options?: Reco
|
|
|
231
386
|
export function stripSingleLineListMarkerPrefix(text: string): string;
|
|
232
387
|
|
|
233
388
|
export function getParagraphText(paragraph: Element | null | undefined): string;
|
|
389
|
+
export function getParagraphId(paragraph: Element | null | undefined): string | null;
|
|
390
|
+
export function createParagraphFingerprint(paragraph: Element | null | undefined): string | null;
|
|
234
391
|
export function getDocumentParagraphNodes(xmlDoc: Document | Element | null | undefined): Element[];
|
|
235
392
|
export function normalizeWhitespaceForTargeting(text: string): string;
|
|
236
393
|
export function isMarkdownTableText(text: string): boolean;
|
|
@@ -241,10 +398,23 @@ export function findContainingWordElement(node: Node | null, localName: string):
|
|
|
241
398
|
export function findParagraphByReference(xmlDoc: Document | Element, reference: unknown): Element | null;
|
|
242
399
|
export function findParagraphByStrictText(xmlDoc: Document | Element, text: string): Element | null;
|
|
243
400
|
export function findParagraphByBestTextMatch(xmlDoc: Document | Element, text: string): Element | null;
|
|
244
|
-
export function
|
|
245
|
-
export function
|
|
246
|
-
export function
|
|
247
|
-
|
|
401
|
+
export function findStrictTargetCandidates(xmlDoc: Document | Element, text: string): ParagraphTargetCandidate[];
|
|
402
|
+
export function resolveTargetParagraph(xmlDoc: Document | Element, options?: Record<string, unknown>): ParagraphTargetResolution;
|
|
403
|
+
export function buildTargetReferenceSnapshot(xmlDoc: Document | Element): Map<number, {
|
|
404
|
+
text: string;
|
|
405
|
+
normalizedText: string;
|
|
406
|
+
inTable: boolean;
|
|
407
|
+
}>;
|
|
408
|
+
export function resolveTargetParagraphWithSnapshot(
|
|
409
|
+
xmlDoc: Document | Element,
|
|
410
|
+
options?: Record<string, unknown>
|
|
411
|
+
): ParagraphTargetResolution;
|
|
412
|
+
export function resolveParagraphRangeByRefs(
|
|
413
|
+
xmlDoc: Document | Element,
|
|
414
|
+
startRef: string | number | null,
|
|
415
|
+
endRef: string | number | null,
|
|
416
|
+
options?: Record<string, unknown>
|
|
417
|
+
): Element[] | null;
|
|
248
418
|
export function extractParagraphIdFromOoxml(oxml: string): string | null;
|
|
249
419
|
|
|
250
420
|
export function getParagraphListInfo(paragraph: Element): Record<string, unknown> | null;
|
|
@@ -262,3 +432,61 @@ export function insertBodyElementBeforeSectPr(body: Element, element: Element):
|
|
|
262
432
|
export function normalizeBodySectionOrderStandalone(documentXml: string): string;
|
|
263
433
|
export function sanitizeNestedParagraphsInTables(documentXml: string): string;
|
|
264
434
|
export function getPackagePartName(part: unknown): string | null;
|
|
435
|
+
|
|
436
|
+
export interface MutationReceiptRevisionItem {
|
|
437
|
+
id: string;
|
|
438
|
+
kind: 'ins' | 'del' | 'move_from' | 'move_to' | 'rPrChange' | 'pPrChange' | 'structural';
|
|
439
|
+
partName: string;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export interface MutationReceipt {
|
|
443
|
+
operationIndex: number;
|
|
444
|
+
operationId?: string;
|
|
445
|
+
attemptedDisposition: 'applied' | 'no_change' | 'refused' | 'not_attempted';
|
|
446
|
+
finalDisposition: 'applied' | 'no_change' | 'refused' | 'rolled_back' | 'not_attempted';
|
|
447
|
+
committed: boolean;
|
|
448
|
+
authorUsed?: string;
|
|
449
|
+
revisionItems: MutationReceiptRevisionItem[];
|
|
450
|
+
commentIds: string[];
|
|
451
|
+
numberingIds: string[];
|
|
452
|
+
relationshipIds: string[];
|
|
453
|
+
affectedTargets: unknown[];
|
|
454
|
+
warnings: string[];
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export class ReceiptCollector {
|
|
458
|
+
constructor();
|
|
459
|
+
beginOperation(operationIndex: number, operationId?: string | null, authorUsed?: string | null): void;
|
|
460
|
+
recordRevision(id: string | number, kind?: string, partName?: string): void;
|
|
461
|
+
recordComment(id: string | number, partName?: string): void;
|
|
462
|
+
recordNumbering(id: string | number, partName?: string): void;
|
|
463
|
+
recordRelationship(id: string | number, partName?: string): void;
|
|
464
|
+
recordAffectedTarget(target: unknown): void;
|
|
465
|
+
recordWarning(warning: unknown): void;
|
|
466
|
+
commitOperation(disposition?: string): MutationReceipt | null;
|
|
467
|
+
abortOperation(disposition?: string): MutationReceipt | null;
|
|
468
|
+
createSavepoint(): unknown;
|
|
469
|
+
restoreSavepoint(savepoint: unknown): void;
|
|
470
|
+
clear(): void;
|
|
471
|
+
markRolledBack(): void;
|
|
472
|
+
getReceipts(): MutationReceipt[];
|
|
473
|
+
getCurrentReceipt(): MutationReceipt | null;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export function createEmptyReceipt(
|
|
477
|
+
operationIndex: number,
|
|
478
|
+
operationId?: string | null,
|
|
479
|
+
authorUsed?: string | null,
|
|
480
|
+
disposition?: 'applied' | 'no_change' | 'refused' | 'not_attempted'
|
|
481
|
+
): MutationReceipt;
|
|
482
|
+
|
|
483
|
+
export function reconcileReceiptsAgainstOutput(
|
|
484
|
+
parts: {
|
|
485
|
+
documentXml: string;
|
|
486
|
+
commentsXml?: string | null;
|
|
487
|
+
numberingXml?: string | null;
|
|
488
|
+
numberingXmlParts?: string[];
|
|
489
|
+
relationshipsXml?: string | null;
|
|
490
|
+
},
|
|
491
|
+
receipts: MutationReceipt[]
|
|
492
|
+
): { valid: boolean; error?: { code: string; message: string } };
|
package/index.js
CHANGED
|
@@ -21,8 +21,9 @@ import {
|
|
|
21
21
|
executeSingleLineListStructuralFallback
|
|
22
22
|
} from './orchestration/list-structural-fallback.js';
|
|
23
23
|
import { withOoxmlSourceType } from './core/word-xml.js';
|
|
24
|
-
export { containsTrackedChanges } from './core/word-xml.js';
|
|
24
|
+
export { containsTrackedChanges, getTrackedChangeAuthors } from './core/word-xml.js';
|
|
25
25
|
export { validateRedlineOoxml } from './core/redline-validation.js';
|
|
26
|
+
export { analyzeStructuredContent, planStructuredReplacement } from './pipeline/structured-content.js';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Standalone-safe redline wrapper.
|
|
@@ -237,6 +238,18 @@ export {
|
|
|
237
238
|
ingestWordOoxmlToPlainTextResult,
|
|
238
239
|
ingestWordOoxmlToMarkdownResult
|
|
239
240
|
} from './pipeline/ingestion-export.js';
|
|
241
|
+
export { extractCanonicalParagraphText, readCanonicalRunText, isNodeVisibleInRevisionView, extractParagraphRevisionSegments } from './core/paragraph-text.js';
|
|
242
|
+
export { inspectDocumentParts } from './services/document-inspection.js';
|
|
243
|
+
export {
|
|
244
|
+
buildRevisionTokenFraming,
|
|
245
|
+
computeRevisionToken,
|
|
246
|
+
computeRevisionTokenSync,
|
|
247
|
+
computeDocumentPartsRevisionToken,
|
|
248
|
+
validateRevisionToken,
|
|
249
|
+
areRevisionTokensEqual,
|
|
250
|
+
normalizeOpcEntryName,
|
|
251
|
+
extractDocumentPartsEntries
|
|
252
|
+
} from './services/revision-token.js';
|
|
240
253
|
export { preprocessMarkdown } from './pipeline/markdown-processor.js';
|
|
241
254
|
export { serializeToOoxml, wrapInDocumentFragment } from './pipeline/serialization.js';
|
|
242
255
|
|
|
@@ -247,6 +260,7 @@ export {
|
|
|
247
260
|
buildCommentElement,
|
|
248
261
|
buildCommentsPartXml
|
|
249
262
|
} from './services/comment-engine.js';
|
|
263
|
+
export { applyCommentReplyToParts } from './services/comment-replies.js';
|
|
250
264
|
export {
|
|
251
265
|
acceptTrackedChangesInOoxml,
|
|
252
266
|
rejectTrackedChangesInOoxml,
|
|
@@ -272,6 +286,7 @@ export {
|
|
|
272
286
|
extractReplacementNodesFromOoxml,
|
|
273
287
|
ensureNumberingArtifactsInZip,
|
|
274
288
|
ensureCommentsArtifactsInZip,
|
|
289
|
+
ensureCommentsExtendedArtifactsInZip,
|
|
275
290
|
validateDocxPackage
|
|
276
291
|
} from './services/standalone-docx-plumbing.js';
|
|
277
292
|
export { buildReconciliationPlan, RoutePlanKind, normalizeContentEscapesForRouting } from './orchestration/route-plan.js';
|
|
@@ -293,6 +308,8 @@ export { extractParagraphIdFromOoxml } from './core/ooxml-identifiers.js';
|
|
|
293
308
|
export {
|
|
294
309
|
WORD_MAIN_NS,
|
|
295
310
|
getParagraphText,
|
|
311
|
+
getParagraphId,
|
|
312
|
+
createParagraphFingerprint,
|
|
296
313
|
getDocumentParagraphNodes,
|
|
297
314
|
normalizeWhitespaceForTargeting,
|
|
298
315
|
isMarkdownTableText,
|
|
@@ -303,6 +320,7 @@ export {
|
|
|
303
320
|
findParagraphByReference,
|
|
304
321
|
findParagraphByStrictText,
|
|
305
322
|
findParagraphByBestTextMatch,
|
|
323
|
+
findStrictTargetCandidates,
|
|
306
324
|
resolveTargetParagraph,
|
|
307
325
|
buildTargetReferenceSnapshot,
|
|
308
326
|
resolveTargetParagraphWithSnapshot
|
|
@@ -315,3 +333,8 @@ export {
|
|
|
315
333
|
planListInsertionOnlyEdit,
|
|
316
334
|
stripRedundantLeadingListMarkers
|
|
317
335
|
} from './core/list-targeting.js';
|
|
336
|
+
export {
|
|
337
|
+
ReceiptCollector,
|
|
338
|
+
createEmptyReceipt,
|
|
339
|
+
reconcileReceiptsAgainstOutput
|
|
340
|
+
} from './services/receipt-collector.js';
|