docxodus 12.4.1 → 12.6.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/README.md +83 -4
- package/dist/core.d.ts +17 -24
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +44 -221
- package/dist/core.js.map +1 -1
- package/dist/docxodus.worker.js +303 -7
- package/dist/docxodus.worker.js.map +1 -1
- package/dist/editor-reconcile.d.ts +5 -0
- package/dist/editor-reconcile.d.ts.map +1 -1
- package/dist/editor-reconcile.js.map +1 -1
- package/dist/editor.bundle.js +157 -15
- package/dist/editor.d.ts +44 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +209 -22
- package/dist/editor.js.map +1 -1
- package/dist/embed.bundle.js +589 -218
- package/dist/embed.d.ts +1 -1
- package/dist/embed.iife.js +589 -218
- package/dist/embed.js +1 -1
- package/dist/export-assets.json +29 -29
- package/dist/export-browser.bundle.js +109 -4
- package/dist/external-annotation-wire.d.ts +19 -0
- package/dist/external-annotation-wire.d.ts.map +1 -0
- package/dist/external-annotation-wire.js +139 -0
- package/dist/external-annotation-wire.js.map +1 -0
- package/dist/session.bundle.js +276 -8
- package/dist/session.d.ts +66 -13
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +245 -8
- package/dist/session.js.map +1 -1
- package/dist/types.d.ts +389 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/verification-request.d.ts +9 -0
- package/dist/verification-request.d.ts.map +1 -0
- package/dist/verification-request.js +37 -0
- package/dist/verification-request.js.map +1 -0
- package/dist/wasm/_framework/DocumentFormat.OpenXml.Framework.wasm +0 -0
- package/dist/wasm/_framework/DocumentFormat.OpenXml.Framework.wasm.br +0 -0
- package/dist/wasm/_framework/DocumentFormat.OpenXml.wasm +0 -0
- package/dist/wasm/_framework/DocumentFormat.OpenXml.wasm.br +0 -0
- package/dist/wasm/_framework/Docxodus.wasm +0 -0
- package/dist/wasm/_framework/Docxodus.wasm.br +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm.br +0 -0
- package/dist/wasm/_framework/System.IO.Compression.wasm +0 -0
- package/dist/wasm/_framework/System.IO.Compression.wasm.br +0 -0
- package/dist/wasm/_framework/System.IO.Packaging.wasm +0 -0
- package/dist/wasm/_framework/System.IO.Packaging.wasm.br +0 -0
- package/dist/wasm/_framework/System.Linq.Expressions.wasm +0 -0
- package/dist/wasm/_framework/System.Linq.Expressions.wasm.br +0 -0
- package/dist/wasm/_framework/System.Memory.wasm +0 -0
- package/dist/wasm/_framework/System.Memory.wasm.br +0 -0
- package/dist/wasm/_framework/System.Private.CoreLib.wasm +0 -0
- package/dist/wasm/_framework/System.Private.CoreLib.wasm.br +0 -0
- package/dist/wasm/_framework/System.Private.Uri.wasm +0 -0
- package/dist/wasm/_framework/System.Private.Uri.wasm.br +0 -0
- package/dist/wasm/_framework/System.Private.Xml.Linq.wasm +0 -0
- package/dist/wasm/_framework/System.Private.Xml.Linq.wasm.br +0 -0
- package/dist/wasm/_framework/System.Private.Xml.wasm +0 -0
- package/dist/wasm/_framework/System.Private.Xml.wasm.br +0 -0
- package/dist/wasm/_framework/System.Runtime.InteropServices.JavaScript.wasm +0 -0
- package/dist/wasm/_framework/System.Runtime.InteropServices.JavaScript.wasm.br +0 -0
- package/dist/wasm/_framework/System.Security.Cryptography.wasm +0 -0
- package/dist/wasm/_framework/System.Security.Cryptography.wasm.br +0 -0
- package/dist/wasm/_framework/System.Text.Encodings.Web.wasm +0 -0
- package/dist/wasm/_framework/System.Text.Encodings.Web.wasm.br +0 -0
- package/dist/wasm/_framework/System.Text.Json.wasm +0 -0
- package/dist/wasm/_framework/System.Text.Json.wasm.br +0 -0
- package/dist/wasm/_framework/dotnet.boot.js +18 -18
- package/dist/wasm/_framework/dotnet.boot.js.br +0 -0
- package/dist/wasm/_framework/dotnet.native.wasm +0 -0
- package/dist/wasm/_framework/dotnet.native.wasm.br +0 -0
- package/dist/worker-proxy.bundle.js +109 -4
- package/dist/worker-proxy.d.ts +29 -3
- package/dist/worker-proxy.d.ts.map +1 -1
- package/dist/worker-proxy.js +62 -2
- package/dist/worker-proxy.js.map +1 -1
- package/package.json +3 -2
package/dist/embed.iife.js
CHANGED
|
@@ -199,6 +199,7 @@ var Docxodus = (() => {
|
|
|
199
199
|
generateAnnotationVisibilityCss: () => generateAnnotationVisibilityCss,
|
|
200
200
|
generatePackageManifest: () => generatePackageManifest,
|
|
201
201
|
getAnnotations: () => getAnnotations,
|
|
202
|
+
getComments: () => getComments,
|
|
202
203
|
getDocumentMetadata: () => getDocumentMetadata,
|
|
203
204
|
getDocumentStructure: () => getDocumentStructure,
|
|
204
205
|
getParagraphs: () => getParagraphs,
|
|
@@ -251,6 +252,37 @@ var Docxodus = (() => {
|
|
|
251
252
|
wasmBasePath: () => wasmBasePath
|
|
252
253
|
});
|
|
253
254
|
|
|
255
|
+
// src/verification-request.ts
|
|
256
|
+
function serializeVerificationRequest(request) {
|
|
257
|
+
if (request === null || typeof request !== "object" || Array.isArray(request)) {
|
|
258
|
+
throw new RangeError("a verification request must be an object");
|
|
259
|
+
}
|
|
260
|
+
const { companionArtifacts, ...rest } = request;
|
|
261
|
+
const wire = { ...rest };
|
|
262
|
+
if (companionArtifacts !== void 0) {
|
|
263
|
+
wire.companionArtifacts = companionArtifacts.map(encodeCompanion);
|
|
264
|
+
}
|
|
265
|
+
return JSON.stringify(wire);
|
|
266
|
+
}
|
|
267
|
+
function encodeCompanion(artifact) {
|
|
268
|
+
const { bytes, ...rest } = artifact;
|
|
269
|
+
const wire = { ...rest };
|
|
270
|
+
if (bytes !== void 0) wire.bytesB64 = bytesToBase64(bytes);
|
|
271
|
+
return wire;
|
|
272
|
+
}
|
|
273
|
+
function bytesToBase64(bytes) {
|
|
274
|
+
if (typeof btoa === "function") {
|
|
275
|
+
let binary = "";
|
|
276
|
+
const chunkSize = 32768;
|
|
277
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
278
|
+
const chunk = bytes.subarray(i, i + chunkSize);
|
|
279
|
+
binary += String.fromCharCode.apply(null, chunk);
|
|
280
|
+
}
|
|
281
|
+
return btoa(binary);
|
|
282
|
+
}
|
|
283
|
+
return Buffer.from(bytes).toString("base64");
|
|
284
|
+
}
|
|
285
|
+
|
|
254
286
|
// src/types.ts
|
|
255
287
|
var ProjectionScopes = /* @__PURE__ */ ((ProjectionScopes2) => {
|
|
256
288
|
ProjectionScopes2[ProjectionScopes2["Body"] = 1] = "Body";
|
|
@@ -520,9 +552,23 @@ var Docxodus = (() => {
|
|
|
520
552
|
modified: after.filter((_, index) => modified[index])
|
|
521
553
|
};
|
|
522
554
|
}
|
|
555
|
+
var BATCH_REPLAY_CAVEATS = {
|
|
556
|
+
revisionDates: "Tracked-revision date attributes may use the execution clock; compare revision ids, authors, types, text, and anchors across separate executions.",
|
|
557
|
+
commentDates: "Comment date attributes may be generated from the execution clock; supply dates explicitly when byte-identical replay is required.",
|
|
558
|
+
annotationMetadata: "Auto-generated annotation ids or creation timestamps are execution metadata; supply id and created explicitly when byte-identical replay is required.",
|
|
559
|
+
createdAnchors: "Created anchors and related OOXML ids may be generated independently on replay; preview/apply equivalence is semantic and packageHash or anchor ids may differ."
|
|
560
|
+
};
|
|
561
|
+
var BATCH_REPLAY_CAVEAT_TEXTS = new Set(Object.values(BATCH_REPLAY_CAVEATS));
|
|
562
|
+
var RETAINED_PREVIEW_RECEIPTS = 8;
|
|
523
563
|
var DocxSession = class _DocxSession {
|
|
524
564
|
/** @internal */
|
|
525
565
|
constructor(handle, wasm) {
|
|
566
|
+
/**
|
|
567
|
+
* The receipts this client composed for previews it retained, keyed by previewId. The host
|
|
568
|
+
* keeps the package and the binding; the step receipts live only here, so a commit can return
|
|
569
|
+
* the previewed steps and change sets without the host re-parsing a client-composed result.
|
|
570
|
+
*/
|
|
571
|
+
this.retainedPreviewReceipts = /* @__PURE__ */ new Map();
|
|
526
572
|
// ─── Raw escape hatch ────────────────────────────────────────────────
|
|
527
573
|
this.raw = {
|
|
528
574
|
getXml: (anchorId) => this.wasm.RawGetXml(this.handle, anchorId),
|
|
@@ -587,10 +633,152 @@ var Docxodus = (() => {
|
|
|
587
633
|
* Execute synchronous mutations atomically by default. Atomic success is one undo/version
|
|
588
634
|
* unit; any failed or thrown step restores the exact package and history checkpoint.
|
|
589
635
|
*/
|
|
590
|
-
executeBatch(steps, mode = "atomic") {
|
|
636
|
+
executeBatch(steps, mode = "atomic", transaction) {
|
|
591
637
|
if (mode !== "atomic" && mode !== "best_effort") {
|
|
592
638
|
throw new RangeError(`unknown mutation batch mode: ${String(mode)}`);
|
|
593
639
|
}
|
|
640
|
+
if (transaction === void 0) return this.recorded(steps, mode, void 0, () => this.runBatch(steps, mode));
|
|
641
|
+
return this.runTransactional(
|
|
642
|
+
transaction,
|
|
643
|
+
mode,
|
|
644
|
+
(identity) => this.recorded(steps, mode, identity, () => this.runBatch(steps, mode))
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* What the session's host-owned delivery evidence recorder holds (issue #748). `enabled` is
|
|
649
|
+
* false, with the reason, unless the session was opened with `captureDeliveryEvidence`.
|
|
650
|
+
*/
|
|
651
|
+
getDeliveryEvidenceStatus() {
|
|
652
|
+
if (!this.wasm.GetDeliveryEvidenceStatus) {
|
|
653
|
+
throw new Error("This WASM bundle predates delivery evidence; rebuild docxodus.");
|
|
654
|
+
}
|
|
655
|
+
return JSON.parse(this.wasm.GetDeliveryEvidenceStatus(this.handle));
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Build the receipt-bearing delivery of this session through the shared bundle service: the
|
|
659
|
+
* clean current package (`final-docx`), the source-to-delivered semantic delta, and the change
|
|
660
|
+
* receipt (`change-receipt`) minted from the captured evidence — verifiable with
|
|
661
|
+
* `verifyDeliveryReceipt` against the returned artifact bytes. A history that cannot be
|
|
662
|
+
* attested yields an `incomplete` bundle whose receipt artifact carries the reason, and
|
|
663
|
+
* `evidence.unavailableReason` says why.
|
|
664
|
+
*/
|
|
665
|
+
buildDeliveryReceipt(options) {
|
|
666
|
+
if (!this.wasm.BuildDeliveryReceipt) {
|
|
667
|
+
throw new Error("This WASM bundle predates delivery evidence; rebuild docxodus.");
|
|
668
|
+
}
|
|
669
|
+
const wire = JSON.parse(this.wasm.BuildDeliveryReceipt(this.handle, JSON.stringify(options ?? {})));
|
|
670
|
+
const decode = (base64) => Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
|
671
|
+
return {
|
|
672
|
+
status: wire.status,
|
|
673
|
+
verified: wire.verified,
|
|
674
|
+
manifest: wire.manifest,
|
|
675
|
+
manifestBytes: decode(wire.manifestBytes),
|
|
676
|
+
artifacts: wire.artifacts.map((artifact) => {
|
|
677
|
+
const { bytes, ...rest } = artifact;
|
|
678
|
+
return bytes === void 0 ? rest : { ...rest, bytes: decode(bytes) };
|
|
679
|
+
}),
|
|
680
|
+
...wire.evidence ? { evidence: wire.evidence } : {}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Describe a batch to the session's delivery evidence recorder before running it, and hand
|
|
685
|
+
* it the step results afterwards, so the version steps the batch produced are recorded under
|
|
686
|
+
* this description rather than as unlabeled mutations. A bundle without the recorder, or a
|
|
687
|
+
* session not capturing evidence, simply runs the batch.
|
|
688
|
+
*/
|
|
689
|
+
recorded(steps, mode, identity, run) {
|
|
690
|
+
if (!this.wasm.BeginDeliveryEvidence || !this.wasm.CompleteDeliveryEvidence || !this.wasm.AbandonDeliveryEvidence) {
|
|
691
|
+
return run();
|
|
692
|
+
}
|
|
693
|
+
const described = this.wasm.BeginDeliveryEvidence(
|
|
694
|
+
this.handle,
|
|
695
|
+
JSON.stringify(steps.map((step) => step.args === void 0 ? { tool: step.tool, action: step.action } : { tool: step.tool, action: step.action, args: step.args })),
|
|
696
|
+
mode,
|
|
697
|
+
identity ? JSON.stringify({ transactionId: identity.transactionId, requestFingerprint: identity.requestFingerprint }) : ""
|
|
698
|
+
);
|
|
699
|
+
if (!described) return run();
|
|
700
|
+
let result;
|
|
701
|
+
try {
|
|
702
|
+
result = run();
|
|
703
|
+
return result;
|
|
704
|
+
} finally {
|
|
705
|
+
if (result) this.wasm.CompleteDeliveryEvidence(this.handle, JSON.stringify(result.steps));
|
|
706
|
+
else this.wasm.AbandonDeliveryEvidence(this.handle);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Make a preview retained by {@link previewBatch} (`retain: true`) the live document exactly
|
|
711
|
+
* as previewed: the previewed package is restored byte-for-byte as one undo step, so the
|
|
712
|
+
* generated anchor ids, timestamps and `packageHash` are exactly those the preview reported.
|
|
713
|
+
* The commit is guarded — it refuses with `preview_stale`, editing nothing, when the session's
|
|
714
|
+
* version, package content, tracked-changes mode or revision author moved since the preview,
|
|
715
|
+
* and with `preview_not_found` once the preview expired, was evicted, or was already
|
|
716
|
+
* committed. A `transaction` makes a retry after a lost response safe, as for
|
|
717
|
+
* {@link executeBatch}.
|
|
718
|
+
*/
|
|
719
|
+
commitPreview(previewId, transaction) {
|
|
720
|
+
if (!this.wasm.CommitPreview) {
|
|
721
|
+
throw new Error("This WASM bundle predates retained previews; rebuild docxodus.");
|
|
722
|
+
}
|
|
723
|
+
const commit = () => {
|
|
724
|
+
const envelope = JSON.parse(this.wasm.CommitPreview(this.handle, previewId));
|
|
725
|
+
if (!envelope.success) {
|
|
726
|
+
if (envelope.failure?.error.code === "preview_not_found") this.retainedPreviewReceipts.delete(previewId);
|
|
727
|
+
return envelope;
|
|
728
|
+
}
|
|
729
|
+
const receipt = this.retainedPreviewReceipts.get(previewId);
|
|
730
|
+
this.retainedPreviewReceipts.delete(previewId);
|
|
731
|
+
if (!receipt) return envelope;
|
|
732
|
+
return {
|
|
733
|
+
...receipt,
|
|
734
|
+
preview: false,
|
|
735
|
+
html: null,
|
|
736
|
+
baseVersion: envelope.baseVersion,
|
|
737
|
+
resultVersion: envelope.resultVersion,
|
|
738
|
+
packageHash: envelope.packageHash,
|
|
739
|
+
warnings: receipt.warnings.filter((warning) => !BATCH_REPLAY_CAVEAT_TEXTS.has(warning)),
|
|
740
|
+
retention: envelope.retention
|
|
741
|
+
};
|
|
742
|
+
};
|
|
743
|
+
if (transaction === void 0) return commit();
|
|
744
|
+
return this.runTransactional(transaction, "atomic", () => commit());
|
|
745
|
+
}
|
|
746
|
+
runTransactional(transaction, mode, body) {
|
|
747
|
+
if (!this.wasm.BeginMutationTransaction || !this.wasm.CompleteMutationTransaction || !this.wasm.AbandonMutationTransaction) {
|
|
748
|
+
throw new Error("This WASM bundle predates mutation transactions; rebuild docxodus.");
|
|
749
|
+
}
|
|
750
|
+
if (typeof transaction.transactionId !== "string") {
|
|
751
|
+
throw new RangeError("transactionId must be a string");
|
|
752
|
+
}
|
|
753
|
+
if (transaction.request === null || typeof transaction.request !== "object" || Array.isArray(transaction.request)) {
|
|
754
|
+
throw new RangeError("a mutation transaction needs a request object describing the batch");
|
|
755
|
+
}
|
|
756
|
+
const decision = JSON.parse(this.wasm.BeginMutationTransaction(
|
|
757
|
+
this.handle,
|
|
758
|
+
transaction.transactionId,
|
|
759
|
+
JSON.stringify({ ...transaction.request, mode })
|
|
760
|
+
));
|
|
761
|
+
if (decision.response !== null) {
|
|
762
|
+
return JSON.parse(decision.response);
|
|
763
|
+
}
|
|
764
|
+
let completed = false;
|
|
765
|
+
try {
|
|
766
|
+
const result = {
|
|
767
|
+
...body(decision.transaction),
|
|
768
|
+
transaction: decision.transaction
|
|
769
|
+
};
|
|
770
|
+
this.wasm.CompleteMutationTransaction(
|
|
771
|
+
this.handle,
|
|
772
|
+
transaction.transactionId,
|
|
773
|
+
JSON.stringify(result)
|
|
774
|
+
);
|
|
775
|
+
completed = true;
|
|
776
|
+
return result;
|
|
777
|
+
} finally {
|
|
778
|
+
if (!completed) this.wasm.AbandonMutationTransaction(this.handle, transaction.transactionId);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
runBatch(steps, mode) {
|
|
594
782
|
const baseVersion = this.getVersion();
|
|
595
783
|
const observationWarnings = [];
|
|
596
784
|
const inspect = (label, read, fallback) => {
|
|
@@ -628,16 +816,16 @@ var Docxodus = (() => {
|
|
|
628
816
|
);
|
|
629
817
|
const warnings = [...observationWarnings];
|
|
630
818
|
if ([...revisionChanges.added, ...revisionChanges.modified].some((revision) => revision.date !== void 0 && revision.date !== null)) {
|
|
631
|
-
warnings.push(
|
|
819
|
+
warnings.push(BATCH_REPLAY_CAVEATS.revisionDates);
|
|
632
820
|
}
|
|
633
821
|
if ([...commentChanges.added, ...commentChanges.modified].some((comment) => comment.date !== void 0 && comment.date !== null)) {
|
|
634
|
-
warnings.push(
|
|
822
|
+
warnings.push(BATCH_REPLAY_CAVEATS.commentDates);
|
|
635
823
|
}
|
|
636
824
|
if (annotationChanges.added.some((annotation) => annotation.created !== void 0 && annotation.created !== null)) {
|
|
637
|
-
warnings.push(
|
|
825
|
+
warnings.push(BATCH_REPLAY_CAVEATS.annotationMetadata);
|
|
638
826
|
}
|
|
639
827
|
if (result.steps.some((step) => step.results.some((edit) => edit.created.length > 0))) {
|
|
640
|
-
warnings.push(
|
|
828
|
+
warnings.push(BATCH_REPLAY_CAVEATS.createdAnchors);
|
|
641
829
|
}
|
|
642
830
|
if (mode === "best_effort" && !result.success) {
|
|
643
831
|
warnings.push("Best-effort execution retains every successful step despite later failures.");
|
|
@@ -861,7 +1049,27 @@ var Docxodus = (() => {
|
|
|
861
1049
|
} catch (error) {
|
|
862
1050
|
warnings.push(`Preview HTML could not be generated: ${error instanceof Error ? error.message : String(error)}`);
|
|
863
1051
|
}
|
|
864
|
-
|
|
1052
|
+
let retention;
|
|
1053
|
+
if (options?.retain) {
|
|
1054
|
+
if (!this.wasm.RetainPreview) {
|
|
1055
|
+
throw new Error("This WASM bundle predates retained previews; rebuild docxodus.");
|
|
1056
|
+
}
|
|
1057
|
+
if (!result.success) {
|
|
1058
|
+
warnings.push("The preview did not succeed, so it was not retained for commit.");
|
|
1059
|
+
} else {
|
|
1060
|
+
const retained = JSON.parse(this.wasm.RetainPreview(shadow.handle));
|
|
1061
|
+
warnings.push(...retained.warnings);
|
|
1062
|
+
retention = retained.retention ?? void 0;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
const preview = retention ? { ...result, preview: true, warnings, html, retention } : { ...result, preview: true, warnings, html };
|
|
1066
|
+
if (retention) {
|
|
1067
|
+
if (this.retainedPreviewReceipts.size >= RETAINED_PREVIEW_RECEIPTS) {
|
|
1068
|
+
this.retainedPreviewReceipts.delete(this.retainedPreviewReceipts.keys().next().value);
|
|
1069
|
+
}
|
|
1070
|
+
this.retainedPreviewReceipts.set(retention.previewId, { ...preview, html: null });
|
|
1071
|
+
}
|
|
1072
|
+
return preview;
|
|
865
1073
|
} finally {
|
|
866
1074
|
shadow.close();
|
|
867
1075
|
}
|
|
@@ -1440,6 +1648,18 @@ var Docxodus = (() => {
|
|
|
1440
1648
|
imageBytesToBase64(bytes)
|
|
1441
1649
|
));
|
|
1442
1650
|
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Convert an external linked picture into an embedded one using bytes the caller fetched;
|
|
1653
|
+
* the engine never reaches the network itself. Refused for pictures that already embed
|
|
1654
|
+
* their media — see `ImageOccurrence.operations`.
|
|
1655
|
+
*/
|
|
1656
|
+
embedLinkedImage(imageId, bytes) {
|
|
1657
|
+
return JSON.parse(this.wasm.EmbedLinkedImage(
|
|
1658
|
+
this.handle,
|
|
1659
|
+
imageId,
|
|
1660
|
+
imageBytesToBase64(bytes)
|
|
1661
|
+
));
|
|
1662
|
+
}
|
|
1443
1663
|
setImageDimensions(imageId, dimensions) {
|
|
1444
1664
|
return JSON.parse(this.wasm.SetImageDimensions(
|
|
1445
1665
|
this.handle,
|
|
@@ -1570,6 +1790,28 @@ var Docxodus = (() => {
|
|
|
1570
1790
|
listRevisions() {
|
|
1571
1791
|
return JSON.parse(this.wasm.ListRevisions(this.handle));
|
|
1572
1792
|
}
|
|
1793
|
+
/**
|
|
1794
|
+
* The explicit repairs the registry offers for entries it refuses to resolve (issues
|
|
1795
|
+
* #754–#758): which carriers are defective, whether a unique repair exists, and what it
|
|
1796
|
+
* would do. Read-only; listing, accept and reject never repair.
|
|
1797
|
+
*/
|
|
1798
|
+
listRevisionRepairs() {
|
|
1799
|
+
if (!this.wasm.ListRevisionRepairs) {
|
|
1800
|
+
throw new Error("This WASM bundle predates revision repairs; rebuild docxodus.");
|
|
1801
|
+
}
|
|
1802
|
+
return JSON.parse(this.wasm.ListRevisionRepairs(this.handle));
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
* Perform requested repairs atomically as one undo step. A kind the registry did not offer,
|
|
1806
|
+
* a non-repairable proposal, or a wrap-as-deletion without author and date refuses the whole
|
|
1807
|
+
* call (`revision_repair_rejected`) with nothing mutated. Repaired entries get new ids.
|
|
1808
|
+
*/
|
|
1809
|
+
repairRevisions(repairs) {
|
|
1810
|
+
if (!this.wasm.RepairRevisions) {
|
|
1811
|
+
throw new Error("This WASM bundle predates revision repairs; rebuild docxodus.");
|
|
1812
|
+
}
|
|
1813
|
+
return JSON.parse(this.wasm.RepairRevisions(this.handle, JSON.stringify(repairs)));
|
|
1814
|
+
}
|
|
1573
1815
|
/** Accept ONE revision by the id {@link listRevisions} reported — insertions keep
|
|
1574
1816
|
* their content, deletions are carried out, a move materializes at its destination,
|
|
1575
1817
|
* a format change keeps the new properties. Undoable. */
|
|
@@ -1723,8 +1965,25 @@ var Docxodus = (() => {
|
|
|
1723
1965
|
* `enclosingAnchor.id` + `span.{start,length}`, so identical needles in the
|
|
1724
1966
|
* same paragraph (the template-fill case where five `[___]` placeholders
|
|
1725
1967
|
* each get a different value) don't collide.
|
|
1968
|
+
*
|
|
1969
|
+
* Pass `format` to replace text and format exactly the replacement atomically, with one
|
|
1970
|
+
* undo/version unit. This interactive path returns an ordinary EditResult and avoids the
|
|
1971
|
+
* package checkpoint/hash required by executeBatch's receipt. Empty replacements only delete.
|
|
1726
1972
|
*/
|
|
1727
|
-
replaceMatch(match, replace) {
|
|
1973
|
+
replaceMatch(match, replace, format) {
|
|
1974
|
+
if (format !== void 0) {
|
|
1975
|
+
if (!this.wasm.ReplaceTextAtSpanWithFormat) {
|
|
1976
|
+
throw new Error("This WASM bundle predates atomic text-plus-format edits; rebuild docxodus.");
|
|
1977
|
+
}
|
|
1978
|
+
return JSON.parse(this.wasm.ReplaceTextAtSpanWithFormat(
|
|
1979
|
+
this.handle,
|
|
1980
|
+
match.enclosingAnchor.id,
|
|
1981
|
+
match.span.start,
|
|
1982
|
+
match.span.length,
|
|
1983
|
+
replace,
|
|
1984
|
+
JSON.stringify(format)
|
|
1985
|
+
));
|
|
1986
|
+
}
|
|
1728
1987
|
return JSON.parse(
|
|
1729
1988
|
this.wasm.ReplaceTextAtSpan(this.handle, match.enclosingAnchor.id, match.span.start, match.span.length, replace)
|
|
1730
1989
|
);
|
|
@@ -1927,7 +2186,16 @@ var Docxodus = (() => {
|
|
|
1927
2186
|
* With initial projection capture enabled (the default), exact opening bytes are the
|
|
1928
2187
|
* baseline used for dispositions and semantic/package deltas.
|
|
1929
2188
|
*/
|
|
1930
|
-
verifyDeliverable() {
|
|
2189
|
+
verifyDeliverable(request) {
|
|
2190
|
+
if (request !== void 0) {
|
|
2191
|
+
if (!this.wasm.VerifyDeliverableWithRequest) {
|
|
2192
|
+
throw new Error("This WASM bundle predates full verification requests; rebuild docxodus.");
|
|
2193
|
+
}
|
|
2194
|
+
return JSON.parse(this.wasm.VerifyDeliverableWithRequest(
|
|
2195
|
+
this.handle,
|
|
2196
|
+
serializeVerificationRequest(request)
|
|
2197
|
+
));
|
|
2198
|
+
}
|
|
1931
2199
|
return JSON.parse(
|
|
1932
2200
|
this.wasm.VerifyDeliverable(this.handle)
|
|
1933
2201
|
);
|
|
@@ -2156,6 +2424,7 @@ var Docxodus = (() => {
|
|
|
2156
2424
|
return this.wasm.Save(this.handle);
|
|
2157
2425
|
}
|
|
2158
2426
|
close() {
|
|
2427
|
+
this.retainedPreviewReceipts.clear();
|
|
2159
2428
|
this.wasm.CloseSession(this.handle);
|
|
2160
2429
|
}
|
|
2161
2430
|
// TypeScript 5.2+ disposable protocol
|
|
@@ -2176,6 +2445,129 @@ var Docxodus = (() => {
|
|
|
2176
2445
|
return new DocxSession(handle, bridge);
|
|
2177
2446
|
}
|
|
2178
2447
|
|
|
2448
|
+
// src/external-annotation-wire.ts
|
|
2449
|
+
function readPawlsPage(p) {
|
|
2450
|
+
return {
|
|
2451
|
+
page: {
|
|
2452
|
+
width: p.Page?.Width ?? p.page?.width,
|
|
2453
|
+
height: p.Page?.Height ?? p.page?.height,
|
|
2454
|
+
index: p.Page?.Index ?? p.page?.index
|
|
2455
|
+
},
|
|
2456
|
+
tokens: (p.Tokens || p.tokens || []).map((t) => ({
|
|
2457
|
+
x: t.X ?? t.x,
|
|
2458
|
+
y: t.Y ?? t.y,
|
|
2459
|
+
width: t.Width ?? t.width,
|
|
2460
|
+
height: t.Height ?? t.height,
|
|
2461
|
+
text: t.Text ?? t.text
|
|
2462
|
+
}))
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2465
|
+
function readAnnotationJson(json) {
|
|
2466
|
+
if (!json) return void 0;
|
|
2467
|
+
if (json.Start !== void 0 || json.start !== void 0) {
|
|
2468
|
+
return {
|
|
2469
|
+
id: json.Id ?? json.id,
|
|
2470
|
+
start: json.Start ?? json.start,
|
|
2471
|
+
end: json.End ?? json.end,
|
|
2472
|
+
text: json.Text ?? json.text
|
|
2473
|
+
};
|
|
2474
|
+
}
|
|
2475
|
+
const result = {};
|
|
2476
|
+
for (const [key, value] of Object.entries(json)) {
|
|
2477
|
+
const v = value;
|
|
2478
|
+
result[key] = {
|
|
2479
|
+
bounds: {
|
|
2480
|
+
top: v.Bounds?.Top ?? v.bounds?.top,
|
|
2481
|
+
bottom: v.Bounds?.Bottom ?? v.bounds?.bottom,
|
|
2482
|
+
left: v.Bounds?.Left ?? v.bounds?.left,
|
|
2483
|
+
right: v.Bounds?.Right ?? v.bounds?.right
|
|
2484
|
+
},
|
|
2485
|
+
tokensJsons: (v.TokensJsons || v.tokensJsons || []).map((t) => ({
|
|
2486
|
+
pageIndex: t.PageIndex ?? t.pageIndex,
|
|
2487
|
+
tokenIndex: t.TokenIndex ?? t.tokenIndex
|
|
2488
|
+
})),
|
|
2489
|
+
rawText: v.RawText ?? v.rawText
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
return result;
|
|
2493
|
+
}
|
|
2494
|
+
function readAnnotation(a) {
|
|
2495
|
+
return {
|
|
2496
|
+
id: a.Id ?? a.id,
|
|
2497
|
+
annotationLabel: a.AnnotationLabel ?? a.annotationLabel,
|
|
2498
|
+
rawText: a.RawText ?? a.rawText,
|
|
2499
|
+
page: a.Page ?? a.page,
|
|
2500
|
+
annotationJson: readAnnotationJson(a.AnnotationJson ?? a.annotationJson),
|
|
2501
|
+
parentId: a.ParentId ?? a.parentId,
|
|
2502
|
+
annotationType: a.AnnotationType ?? a.annotationType,
|
|
2503
|
+
structural: a.Structural ?? a.structural
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
function readRelationship(r) {
|
|
2507
|
+
return {
|
|
2508
|
+
id: r.Id ?? r.id,
|
|
2509
|
+
relationshipLabel: r.RelationshipLabel ?? r.relationshipLabel,
|
|
2510
|
+
sourceAnnotationIds: r.SourceAnnotationIds ?? r.sourceAnnotationIds ?? [],
|
|
2511
|
+
targetAnnotationIds: r.TargetAnnotationIds ?? r.targetAnnotationIds ?? [],
|
|
2512
|
+
structural: r.Structural ?? r.structural
|
|
2513
|
+
};
|
|
2514
|
+
}
|
|
2515
|
+
function readLabel(l) {
|
|
2516
|
+
return {
|
|
2517
|
+
id: l.Id ?? l.id,
|
|
2518
|
+
color: l.Color ?? l.color,
|
|
2519
|
+
description: l.Description ?? l.description ?? "",
|
|
2520
|
+
icon: l.Icon ?? l.icon ?? "",
|
|
2521
|
+
text: l.Text ?? l.text,
|
|
2522
|
+
labelType: l.LabelType ?? l.labelType ?? "text"
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2525
|
+
function readLabels(raw) {
|
|
2526
|
+
const labels = {};
|
|
2527
|
+
for (const [key, value] of Object.entries(raw || {})) labels[key] = readLabel(value);
|
|
2528
|
+
return labels;
|
|
2529
|
+
}
|
|
2530
|
+
function readOpenContractExport(parsed) {
|
|
2531
|
+
return {
|
|
2532
|
+
title: parsed.Title ?? parsed.title,
|
|
2533
|
+
content: parsed.Content ?? parsed.content,
|
|
2534
|
+
description: parsed.Description ?? parsed.description,
|
|
2535
|
+
pageCount: parsed.PageCount ?? parsed.pageCount,
|
|
2536
|
+
pawlsFileContent: (parsed.PawlsFileContent || parsed.pawlsFileContent || []).map(readPawlsPage),
|
|
2537
|
+
docLabels: parsed.DocLabels ?? parsed.docLabels ?? [],
|
|
2538
|
+
labelledText: (parsed.LabelledText || parsed.labelledText || []).map(readAnnotation),
|
|
2539
|
+
relationships: (parsed.Relationships || parsed.relationships)?.map(readRelationship)
|
|
2540
|
+
};
|
|
2541
|
+
}
|
|
2542
|
+
function readExternalAnnotationSet(parsed) {
|
|
2543
|
+
return {
|
|
2544
|
+
documentId: parsed.DocumentId ?? parsed.documentId,
|
|
2545
|
+
documentHash: parsed.DocumentHash ?? parsed.documentHash,
|
|
2546
|
+
createdAt: parsed.CreatedAt ?? parsed.createdAt,
|
|
2547
|
+
updatedAt: parsed.UpdatedAt ?? parsed.updatedAt,
|
|
2548
|
+
version: parsed.Version ?? parsed.version,
|
|
2549
|
+
...readOpenContractExport(parsed),
|
|
2550
|
+
textLabels: readLabels(parsed.TextLabels || parsed.textLabels),
|
|
2551
|
+
docLabelDefinitions: readLabels(parsed.DocLabelDefinitions || parsed.docLabelDefinitions)
|
|
2552
|
+
};
|
|
2553
|
+
}
|
|
2554
|
+
function readExternalAnnotationValidation(parsed) {
|
|
2555
|
+
return {
|
|
2556
|
+
isValid: parsed.IsValid ?? parsed.isValid,
|
|
2557
|
+
hashMismatch: parsed.HashMismatch ?? parsed.hashMismatch,
|
|
2558
|
+
issues: (parsed.Issues || parsed.issues || []).map((i) => ({
|
|
2559
|
+
annotationId: i.AnnotationId ?? i.annotationId,
|
|
2560
|
+
issueType: i.IssueType ?? i.issueType,
|
|
2561
|
+
description: i.Description ?? i.description,
|
|
2562
|
+
expectedText: i.ExpectedText ?? i.expectedText,
|
|
2563
|
+
actualText: i.ActualText ?? i.actualText
|
|
2564
|
+
}))
|
|
2565
|
+
};
|
|
2566
|
+
}
|
|
2567
|
+
function readProjectedHtml(parsed) {
|
|
2568
|
+
return parsed.Html ?? parsed.html;
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2179
2571
|
// src/history.ts
|
|
2180
2572
|
var MAX_HISTORY_ARCHIVE_BYTES = 64 * 1024 * 1024;
|
|
2181
2573
|
var DocxHistoryError = class extends Error {
|
|
@@ -6565,11 +6957,21 @@ Your current draft and all later versions will be kept.`);
|
|
|
6565
6957
|
exports.DocumentConverter.GeneratePackageManifest(bytes)
|
|
6566
6958
|
);
|
|
6567
6959
|
}
|
|
6568
|
-
async function verifyDeliverable(document2, baseline) {
|
|
6960
|
+
async function verifyDeliverable(document2, baseline, request) {
|
|
6569
6961
|
const exports = ensureInitialized();
|
|
6570
6962
|
const bytes = await toBytes(document2);
|
|
6571
6963
|
const baselineBytes = baseline === void 0 ? void 0 : await toBytes(baseline);
|
|
6572
6964
|
await yieldToMain();
|
|
6965
|
+
if (request !== void 0) {
|
|
6966
|
+
const requestJson = serializeVerificationRequest(request);
|
|
6967
|
+
const converter = exports.DocumentConverter;
|
|
6968
|
+
if (!converter.VerifyDeliverableWithRequest || !converter.VerifyDeliverableWithBaselineAndRequest) {
|
|
6969
|
+
throw new Error("This WASM bundle predates full verification requests; rebuild docxodus.");
|
|
6970
|
+
}
|
|
6971
|
+
return JSON.parse(
|
|
6972
|
+
baselineBytes === void 0 ? converter.VerifyDeliverableWithRequest(bytes, requestJson) : converter.VerifyDeliverableWithBaselineAndRequest(baselineBytes, bytes, requestJson)
|
|
6973
|
+
);
|
|
6974
|
+
}
|
|
6573
6975
|
return JSON.parse(
|
|
6574
6976
|
baselineBytes === void 0 ? exports.DocumentConverter.VerifyDeliverable(bytes) : exports.DocumentConverter.VerifyDeliverableWithBaseline(
|
|
6575
6977
|
baselineBytes,
|
|
@@ -6583,7 +6985,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
6583
6985
|
Object.fromEntries(
|
|
6584
6986
|
Object.entries(artifacts).map(([artifactId, bytes]) => [
|
|
6585
6987
|
artifactId,
|
|
6586
|
-
|
|
6988
|
+
bytesToBase642(bytes)
|
|
6587
6989
|
])
|
|
6588
6990
|
)
|
|
6589
6991
|
);
|
|
@@ -6748,6 +7150,16 @@ Your current draft and all later versions will be kept.`);
|
|
|
6748
7150
|
}
|
|
6749
7151
|
return JSON.parse(result);
|
|
6750
7152
|
}
|
|
7153
|
+
async function getComments(document2) {
|
|
7154
|
+
const exports = ensureInitialized();
|
|
7155
|
+
const bytes = await toBytes(document2);
|
|
7156
|
+
await yieldToMain();
|
|
7157
|
+
const result = exports.DocumentComparer.GetCommentsJson(bytes);
|
|
7158
|
+
if (isErrorResponse(result)) {
|
|
7159
|
+
throw new Error(`Failed to get comments: ${parseError(result).error}`);
|
|
7160
|
+
}
|
|
7161
|
+
return JSON.parse(result);
|
|
7162
|
+
}
|
|
6751
7163
|
function docxDiffSettingsJson(settings) {
|
|
6752
7164
|
return settings ? JSON.stringify(settings) : "";
|
|
6753
7165
|
}
|
|
@@ -6814,7 +7226,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
6814
7226
|
const bytes = await toBytes(candidates[i].document);
|
|
6815
7227
|
payload.push({
|
|
6816
7228
|
name: candidates[i].name ?? String(i),
|
|
6817
|
-
docB64:
|
|
7229
|
+
docB64: bytesToBase642(bytes)
|
|
6818
7230
|
});
|
|
6819
7231
|
}
|
|
6820
7232
|
await yieldToMain();
|
|
@@ -6890,7 +7302,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
6890
7302
|
}
|
|
6891
7303
|
return result;
|
|
6892
7304
|
}
|
|
6893
|
-
function
|
|
7305
|
+
function bytesToBase642(bytes) {
|
|
6894
7306
|
if (typeof btoa === "function") {
|
|
6895
7307
|
let binary = "";
|
|
6896
7308
|
const chunkSize = 32768;
|
|
@@ -6906,7 +7318,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
6906
7318
|
const arr = await Promise.all(
|
|
6907
7319
|
reviewers.map(async (r) => ({
|
|
6908
7320
|
author: r.author,
|
|
6909
|
-
docB64:
|
|
7321
|
+
docB64: bytesToBase642(await toBytes(r.document))
|
|
6910
7322
|
}))
|
|
6911
7323
|
);
|
|
6912
7324
|
return JSON.stringify(arr);
|
|
@@ -7216,77 +7628,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7216
7628
|
const error = parseError(result);
|
|
7217
7629
|
throw new Error(`Failed to export to OpenContract format: ${error.error}`);
|
|
7218
7630
|
}
|
|
7219
|
-
|
|
7220
|
-
const convertPawlsPage = (p) => ({
|
|
7221
|
-
page: {
|
|
7222
|
-
width: p.Page?.Width ?? p.page?.width,
|
|
7223
|
-
height: p.Page?.Height ?? p.page?.height,
|
|
7224
|
-
index: p.Page?.Index ?? p.page?.index
|
|
7225
|
-
},
|
|
7226
|
-
tokens: (p.Tokens || p.tokens || []).map((t) => ({
|
|
7227
|
-
x: t.X ?? t.x,
|
|
7228
|
-
y: t.Y ?? t.y,
|
|
7229
|
-
width: t.Width ?? t.width,
|
|
7230
|
-
height: t.Height ?? t.height,
|
|
7231
|
-
text: t.Text ?? t.text
|
|
7232
|
-
}))
|
|
7233
|
-
});
|
|
7234
|
-
const convertAnnotation = (a) => ({
|
|
7235
|
-
id: a.Id ?? a.id,
|
|
7236
|
-
annotationLabel: a.AnnotationLabel ?? a.annotationLabel,
|
|
7237
|
-
rawText: a.RawText ?? a.rawText,
|
|
7238
|
-
page: a.Page ?? a.page,
|
|
7239
|
-
annotationJson: convertAnnotationJson(a.AnnotationJson ?? a.annotationJson),
|
|
7240
|
-
parentId: a.ParentId ?? a.parentId,
|
|
7241
|
-
annotationType: a.AnnotationType ?? a.annotationType,
|
|
7242
|
-
structural: a.Structural ?? a.structural
|
|
7243
|
-
});
|
|
7244
|
-
const convertAnnotationJson = (json) => {
|
|
7245
|
-
if (!json) return void 0;
|
|
7246
|
-
if (json.Start !== void 0 || json.start !== void 0) {
|
|
7247
|
-
return {
|
|
7248
|
-
id: json.Id ?? json.id,
|
|
7249
|
-
start: json.Start ?? json.start,
|
|
7250
|
-
end: json.End ?? json.end,
|
|
7251
|
-
text: json.Text ?? json.text
|
|
7252
|
-
};
|
|
7253
|
-
}
|
|
7254
|
-
const result2 = {};
|
|
7255
|
-
for (const [key, value] of Object.entries(json)) {
|
|
7256
|
-
const v = value;
|
|
7257
|
-
result2[key] = {
|
|
7258
|
-
bounds: {
|
|
7259
|
-
top: v.Bounds?.Top ?? v.bounds?.top,
|
|
7260
|
-
bottom: v.Bounds?.Bottom ?? v.bounds?.bottom,
|
|
7261
|
-
left: v.Bounds?.Left ?? v.bounds?.left,
|
|
7262
|
-
right: v.Bounds?.Right ?? v.bounds?.right
|
|
7263
|
-
},
|
|
7264
|
-
tokensJsons: (v.TokensJsons || v.tokensJsons || []).map((t) => ({
|
|
7265
|
-
pageIndex: t.PageIndex ?? t.pageIndex,
|
|
7266
|
-
tokenIndex: t.TokenIndex ?? t.tokenIndex
|
|
7267
|
-
})),
|
|
7268
|
-
rawText: v.RawText ?? v.rawText
|
|
7269
|
-
};
|
|
7270
|
-
}
|
|
7271
|
-
return result2;
|
|
7272
|
-
};
|
|
7273
|
-
const convertRelationship = (r) => ({
|
|
7274
|
-
id: r.Id ?? r.id,
|
|
7275
|
-
relationshipLabel: r.RelationshipLabel ?? r.relationshipLabel,
|
|
7276
|
-
sourceAnnotationIds: r.SourceAnnotationIds ?? r.sourceAnnotationIds ?? [],
|
|
7277
|
-
targetAnnotationIds: r.TargetAnnotationIds ?? r.targetAnnotationIds ?? [],
|
|
7278
|
-
structural: r.Structural ?? r.structural
|
|
7279
|
-
});
|
|
7280
|
-
return {
|
|
7281
|
-
title: parsed.Title ?? parsed.title,
|
|
7282
|
-
content: parsed.Content ?? parsed.content,
|
|
7283
|
-
description: parsed.Description ?? parsed.description,
|
|
7284
|
-
pageCount: parsed.PageCount ?? parsed.pageCount,
|
|
7285
|
-
pawlsFileContent: (parsed.PawlsFileContent || parsed.pawlsFileContent || []).map(convertPawlsPage),
|
|
7286
|
-
docLabels: parsed.DocLabels ?? parsed.docLabels ?? [],
|
|
7287
|
-
labelledText: (parsed.LabelledText || parsed.labelledText || []).map(convertAnnotation),
|
|
7288
|
-
relationships: (parsed.Relationships || parsed.relationships)?.map(convertRelationship)
|
|
7289
|
-
};
|
|
7631
|
+
return readOpenContractExport(JSON.parse(result));
|
|
7290
7632
|
}
|
|
7291
7633
|
async function convertWmlToMarkdown(document2, settings = {}) {
|
|
7292
7634
|
const exports = ensureInitialized();
|
|
@@ -7392,8 +7734,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7392
7734
|
const error = parseError(result);
|
|
7393
7735
|
throw new Error(`Failed to create external annotation set: ${error.error}`);
|
|
7394
7736
|
}
|
|
7395
|
-
|
|
7396
|
-
return convertExternalAnnotationSet(parsed);
|
|
7737
|
+
return readExternalAnnotationSet(JSON.parse(result));
|
|
7397
7738
|
}
|
|
7398
7739
|
async function validateExternalAnnotations(document2, annotationSet) {
|
|
7399
7740
|
const exports = ensureInitialized();
|
|
@@ -7405,18 +7746,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7405
7746
|
const error = parseError(result);
|
|
7406
7747
|
throw new Error(`Failed to validate external annotations: ${error.error}`);
|
|
7407
7748
|
}
|
|
7408
|
-
|
|
7409
|
-
return {
|
|
7410
|
-
isValid: parsed.IsValid ?? parsed.isValid,
|
|
7411
|
-
hashMismatch: parsed.HashMismatch ?? parsed.hashMismatch,
|
|
7412
|
-
issues: (parsed.Issues || parsed.issues || []).map((i) => ({
|
|
7413
|
-
annotationId: i.AnnotationId ?? i.annotationId,
|
|
7414
|
-
issueType: i.IssueType ?? i.issueType,
|
|
7415
|
-
description: i.Description ?? i.description,
|
|
7416
|
-
expectedText: i.ExpectedText ?? i.expectedText,
|
|
7417
|
-
actualText: i.ActualText ?? i.actualText
|
|
7418
|
-
}))
|
|
7419
|
-
};
|
|
7749
|
+
return readExternalAnnotationValidation(JSON.parse(result));
|
|
7420
7750
|
}
|
|
7421
7751
|
async function convertDocxToHtmlWithExternalAnnotations(document2, annotationSet, conversionOptions, projectionOptions) {
|
|
7422
7752
|
const exports = ensureInitialized();
|
|
@@ -7437,8 +7767,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7437
7767
|
const error = parseError(result);
|
|
7438
7768
|
throw new Error(`Failed to convert with external annotations: ${error.error}`);
|
|
7439
7769
|
}
|
|
7440
|
-
|
|
7441
|
-
return parsed.Html ?? parsed.html;
|
|
7770
|
+
return readProjectedHtml(JSON.parse(result));
|
|
7442
7771
|
}
|
|
7443
7772
|
async function searchTextOffsets(document2, searchText, maxResults = 100) {
|
|
7444
7773
|
const exports = ensureInitialized();
|
|
@@ -7506,103 +7835,6 @@ Your current draft and all later versions will be kept.`);
|
|
|
7506
7835
|
}
|
|
7507
7836
|
return results;
|
|
7508
7837
|
}
|
|
7509
|
-
function convertExternalAnnotationSet(parsed) {
|
|
7510
|
-
const convertLabel = (l) => ({
|
|
7511
|
-
id: l.Id ?? l.id,
|
|
7512
|
-
color: l.Color ?? l.color,
|
|
7513
|
-
description: l.Description ?? l.description ?? "",
|
|
7514
|
-
icon: l.Icon ?? l.icon ?? "",
|
|
7515
|
-
text: l.Text ?? l.text,
|
|
7516
|
-
labelType: l.LabelType ?? l.labelType ?? "text"
|
|
7517
|
-
});
|
|
7518
|
-
const convertPawlsPage = (p) => ({
|
|
7519
|
-
page: {
|
|
7520
|
-
width: p.Page?.Width ?? p.page?.width,
|
|
7521
|
-
height: p.Page?.Height ?? p.page?.height,
|
|
7522
|
-
index: p.Page?.Index ?? p.page?.index
|
|
7523
|
-
},
|
|
7524
|
-
tokens: (p.Tokens || p.tokens || []).map((t) => ({
|
|
7525
|
-
x: t.X ?? t.x,
|
|
7526
|
-
y: t.Y ?? t.y,
|
|
7527
|
-
width: t.Width ?? t.width,
|
|
7528
|
-
height: t.Height ?? t.height,
|
|
7529
|
-
text: t.Text ?? t.text
|
|
7530
|
-
}))
|
|
7531
|
-
});
|
|
7532
|
-
const convertAnnotation = (a) => ({
|
|
7533
|
-
id: a.Id ?? a.id,
|
|
7534
|
-
annotationLabel: a.AnnotationLabel ?? a.annotationLabel,
|
|
7535
|
-
rawText: a.RawText ?? a.rawText,
|
|
7536
|
-
page: a.Page ?? a.page,
|
|
7537
|
-
annotationJson: convertAnnotationJson(a.AnnotationJson ?? a.annotationJson),
|
|
7538
|
-
parentId: a.ParentId ?? a.parentId,
|
|
7539
|
-
annotationType: a.AnnotationType ?? a.annotationType,
|
|
7540
|
-
structural: a.Structural ?? a.structural
|
|
7541
|
-
});
|
|
7542
|
-
const convertAnnotationJson = (json) => {
|
|
7543
|
-
if (!json) return void 0;
|
|
7544
|
-
if (json.Start !== void 0 || json.start !== void 0) {
|
|
7545
|
-
return {
|
|
7546
|
-
id: json.Id ?? json.id,
|
|
7547
|
-
start: json.Start ?? json.start,
|
|
7548
|
-
end: json.End ?? json.end,
|
|
7549
|
-
text: json.Text ?? json.text
|
|
7550
|
-
};
|
|
7551
|
-
}
|
|
7552
|
-
const result = {};
|
|
7553
|
-
for (const [key, value] of Object.entries(json)) {
|
|
7554
|
-
const v = value;
|
|
7555
|
-
result[key] = {
|
|
7556
|
-
bounds: {
|
|
7557
|
-
top: v.Bounds?.Top ?? v.bounds?.top,
|
|
7558
|
-
bottom: v.Bounds?.Bottom ?? v.bounds?.bottom,
|
|
7559
|
-
left: v.Bounds?.Left ?? v.bounds?.left,
|
|
7560
|
-
right: v.Bounds?.Right ?? v.bounds?.right
|
|
7561
|
-
},
|
|
7562
|
-
tokensJsons: (v.TokensJsons || v.tokensJsons || []).map((t) => ({
|
|
7563
|
-
pageIndex: t.PageIndex ?? t.pageIndex,
|
|
7564
|
-
tokenIndex: t.TokenIndex ?? t.tokenIndex
|
|
7565
|
-
})),
|
|
7566
|
-
rawText: v.RawText ?? v.rawText
|
|
7567
|
-
};
|
|
7568
|
-
}
|
|
7569
|
-
return result;
|
|
7570
|
-
};
|
|
7571
|
-
const convertRelationship = (r) => ({
|
|
7572
|
-
id: r.Id ?? r.id,
|
|
7573
|
-
relationshipLabel: r.RelationshipLabel ?? r.relationshipLabel,
|
|
7574
|
-
sourceAnnotationIds: r.SourceAnnotationIds ?? r.sourceAnnotationIds ?? [],
|
|
7575
|
-
targetAnnotationIds: r.TargetAnnotationIds ?? r.targetAnnotationIds ?? [],
|
|
7576
|
-
structural: r.Structural ?? r.structural
|
|
7577
|
-
});
|
|
7578
|
-
const textLabels = {};
|
|
7579
|
-
const rawTextLabels = parsed.TextLabels || parsed.textLabels || {};
|
|
7580
|
-
for (const [key, value] of Object.entries(rawTextLabels)) {
|
|
7581
|
-
textLabels[key] = convertLabel(value);
|
|
7582
|
-
}
|
|
7583
|
-
const docLabelDefinitions = {};
|
|
7584
|
-
const rawDocLabelDefs = parsed.DocLabelDefinitions || parsed.docLabelDefinitions || {};
|
|
7585
|
-
for (const [key, value] of Object.entries(rawDocLabelDefs)) {
|
|
7586
|
-
docLabelDefinitions[key] = convertLabel(value);
|
|
7587
|
-
}
|
|
7588
|
-
return {
|
|
7589
|
-
documentId: parsed.DocumentId ?? parsed.documentId,
|
|
7590
|
-
documentHash: parsed.DocumentHash ?? parsed.documentHash,
|
|
7591
|
-
createdAt: parsed.CreatedAt ?? parsed.createdAt,
|
|
7592
|
-
updatedAt: parsed.UpdatedAt ?? parsed.updatedAt,
|
|
7593
|
-
version: parsed.Version ?? parsed.version,
|
|
7594
|
-
title: parsed.Title ?? parsed.title,
|
|
7595
|
-
content: parsed.Content ?? parsed.content,
|
|
7596
|
-
description: parsed.Description ?? parsed.description,
|
|
7597
|
-
pageCount: parsed.PageCount ?? parsed.pageCount,
|
|
7598
|
-
pawlsFileContent: (parsed.PawlsFileContent || parsed.pawlsFileContent || []).map(convertPawlsPage),
|
|
7599
|
-
docLabels: parsed.DocLabels ?? parsed.docLabels ?? [],
|
|
7600
|
-
labelledText: (parsed.LabelledText || parsed.labelledText || []).map(convertAnnotation),
|
|
7601
|
-
relationships: (parsed.Relationships || parsed.relationships)?.map(convertRelationship),
|
|
7602
|
-
textLabels,
|
|
7603
|
-
docLabelDefinitions
|
|
7604
|
-
};
|
|
7605
|
-
}
|
|
7606
7838
|
async function projectAnnotationsOntoHtml(html, annotationSet, projectionOptions) {
|
|
7607
7839
|
const exports = ensureInitialized();
|
|
7608
7840
|
await yieldToMain();
|
|
@@ -7617,8 +7849,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7617
7849
|
const error = parseError(result);
|
|
7618
7850
|
throw new Error(`Failed to project annotations: ${error.error}`);
|
|
7619
7851
|
}
|
|
7620
|
-
|
|
7621
|
-
return parsed.Html ?? parsed.html;
|
|
7852
|
+
return readProjectedHtml(JSON.parse(result));
|
|
7622
7853
|
}
|
|
7623
7854
|
async function addAnnotationToHtml(html, annotation, label, projectionOptions) {
|
|
7624
7855
|
const exports = ensureInitialized();
|
|
@@ -7636,8 +7867,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7636
7867
|
const error = parseError(result);
|
|
7637
7868
|
throw new Error(`Failed to add annotation to HTML: ${error.error}`);
|
|
7638
7869
|
}
|
|
7639
|
-
|
|
7640
|
-
return parsed.Html ?? parsed.html;
|
|
7870
|
+
return readProjectedHtml(JSON.parse(result));
|
|
7641
7871
|
}
|
|
7642
7872
|
async function removeAnnotationFromHtml(html, annotationId, cssClassPrefix) {
|
|
7643
7873
|
const exports = ensureInitialized();
|
|
@@ -7651,8 +7881,7 @@ Your current draft and all later versions will be kept.`);
|
|
|
7651
7881
|
const error = parseError(result);
|
|
7652
7882
|
throw new Error(`Failed to remove annotation from HTML: ${error.error}`);
|
|
7653
7883
|
}
|
|
7654
|
-
|
|
7655
|
-
return parsed.Html ?? parsed.html;
|
|
7884
|
+
return readProjectedHtml(JSON.parse(result));
|
|
7656
7885
|
}
|
|
7657
7886
|
async function generateAnnotationVisibilityCss(hiddenLabelIds, cssClassPrefix) {
|
|
7658
7887
|
const exports = ensureInitialized();
|
|
@@ -11819,6 +12048,16 @@ span.comment-highlight.docx-comment-active { background: hsl(var(--docx-comment-
|
|
|
11819
12048
|
`;
|
|
11820
12049
|
(doc.head ?? doc.documentElement).appendChild(style);
|
|
11821
12050
|
}
|
|
12051
|
+
var CHROME_CARRIER_ANCHOR = "chrome-carrier";
|
|
12052
|
+
function yieldToEventLoop() {
|
|
12053
|
+
return new Promise((resolve) => {
|
|
12054
|
+
const settle = () => {
|
|
12055
|
+
setTimeout(resolve, 0);
|
|
12056
|
+
};
|
|
12057
|
+
if (typeof requestAnimationFrame === "function") requestAnimationFrame(settle);
|
|
12058
|
+
else settle();
|
|
12059
|
+
});
|
|
12060
|
+
}
|
|
11822
12061
|
function trackedChangeWireName(mode) {
|
|
11823
12062
|
if (mode === 1 /* RenderInline */) return "render_inline";
|
|
11824
12063
|
if (mode === 2 /* StripDeletions */) return "strip_deletions";
|
|
@@ -12486,7 +12725,64 @@ span.comment-highlight.docx-comment-active { background: hsl(var(--docx-comment-
|
|
|
12486
12725
|
}
|
|
12487
12726
|
/** Open a document, render it into `container`, and wire up editing. */
|
|
12488
12727
|
static open(container, bytes, exports, options = {}) {
|
|
12489
|
-
const opts =
|
|
12728
|
+
const opts = _DocxEditor.resolveOptions(options);
|
|
12729
|
+
const editor = _DocxEditor.openSession(container, bytes, exports, opts);
|
|
12730
|
+
try {
|
|
12731
|
+
editor.refreshAnchorMap();
|
|
12732
|
+
if (opts.headerFooter) editor.createRegion();
|
|
12733
|
+
const fullHtml = editor.renderFullHtml(bytes);
|
|
12734
|
+
if (opts.paginated) editor.mountPaginated(fullHtml);
|
|
12735
|
+
else editor.mountHtml(fullHtml);
|
|
12736
|
+
editor.finishMount();
|
|
12737
|
+
return editor;
|
|
12738
|
+
} catch (error) {
|
|
12739
|
+
editor.close();
|
|
12740
|
+
throw error;
|
|
12741
|
+
}
|
|
12742
|
+
}
|
|
12743
|
+
/**
|
|
12744
|
+
* Open a document without holding the main thread for the whole mount (issue #776).
|
|
12745
|
+
*
|
|
12746
|
+
* {@link open} renders and wires the entire document in one synchronous task, which on a
|
|
12747
|
+
* long document is the largest single block of a reading-and-editing session. This variant
|
|
12748
|
+
* pays only the session open up front, then mounts the document in windows of body units,
|
|
12749
|
+
* yielding to the event loop between them: the chrome — stylesheet, section wrappers with
|
|
12750
|
+
* their page geometry, footnote and endnote sections — comes from one cheap engine render
|
|
12751
|
+
* that sees no body content, and each window from the engine's block renderer, which lays
|
|
12752
|
+
* units out exactly as the full render does (the plan's border-box grouping is never split).
|
|
12753
|
+
* The DOM that results is the one {@link open} produces; blocks already mounted are editable
|
|
12754
|
+
* while later windows are still landing, and edits made meanwhile are honoured because every
|
|
12755
|
+
* window renders from the live session.
|
|
12756
|
+
*
|
|
12757
|
+
* Paginated mounts assemble the windows off-screen and paginate once at the end, since
|
|
12758
|
+
* pagination is a one-shot flow over the whole document; the main thread is still free
|
|
12759
|
+
* between windows, and `onProgress` lets a host show the fill.
|
|
12760
|
+
*
|
|
12761
|
+
* A bundle that predates the windowed renders mounts synchronously, exactly like {@link open}.
|
|
12762
|
+
*/
|
|
12763
|
+
static async openAsync(container, bytes, exports, options = {}) {
|
|
12764
|
+
const bridge = exports.DocxSessionBridge;
|
|
12765
|
+
if (typeof bridge.RenderEditorChromeHtml !== "function" || typeof bridge.RenderEditorRangeHtml !== "function" || typeof bridge.ListRenderedBlocks !== "function") {
|
|
12766
|
+
return _DocxEditor.open(container, bytes, exports, options);
|
|
12767
|
+
}
|
|
12768
|
+
const opts = _DocxEditor.resolveOptions(options);
|
|
12769
|
+
const editor = _DocxEditor.openSession(container, bytes, exports, opts);
|
|
12770
|
+
try {
|
|
12771
|
+
editor.refreshAnchorMap();
|
|
12772
|
+
if (opts.headerFooter) editor.createRegion();
|
|
12773
|
+
await editor.mountWindowed(
|
|
12774
|
+
Math.max(1, Math.floor(options.windowSize ?? 24)),
|
|
12775
|
+
options.onProgress
|
|
12776
|
+
);
|
|
12777
|
+
editor.finishMount();
|
|
12778
|
+
return editor;
|
|
12779
|
+
} catch (error) {
|
|
12780
|
+
editor.close();
|
|
12781
|
+
throw error;
|
|
12782
|
+
}
|
|
12783
|
+
}
|
|
12784
|
+
static resolveOptions(options) {
|
|
12785
|
+
return {
|
|
12490
12786
|
cssPrefix: options.cssPrefix ?? "docx-",
|
|
12491
12787
|
fabricateClasses: options.fabricateClasses ?? false,
|
|
12492
12788
|
editable: options.editable ?? true,
|
|
@@ -12505,25 +12801,100 @@ span.comment-highlight.docx-comment-active { background: hsl(var(--docx-comment-
|
|
|
12505
12801
|
onStoryChange: options.onStoryChange,
|
|
12506
12802
|
onCommentsChange: options.onCommentsChange
|
|
12507
12803
|
};
|
|
12804
|
+
}
|
|
12805
|
+
static openSession(container, bytes, exports, opts) {
|
|
12508
12806
|
const handle = exports.DocxSessionBridge.OpenSession(bytes, JSON.stringify({
|
|
12509
12807
|
emitMarkdownPatch: false,
|
|
12510
12808
|
trackedChanges: trackedChangeWireName(opts.trackedChanges),
|
|
12511
12809
|
revisionAuthor: opts.revisionAuthor
|
|
12512
12810
|
}));
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12811
|
+
return new _DocxEditor(container, exports, handle, opts);
|
|
12812
|
+
}
|
|
12813
|
+
/** The steps every mount ends with once the body is in the DOM. */
|
|
12814
|
+
finishMount() {
|
|
12815
|
+
this.syncRegionToBody();
|
|
12816
|
+
this.setupBlockDrag();
|
|
12817
|
+
if (this.options.comments) this.createGutter();
|
|
12818
|
+
}
|
|
12819
|
+
/**
|
|
12820
|
+
* The windowed mount behind {@link openAsync}: chrome first, then body units in plan order,
|
|
12821
|
+
* a group-aligned window per task. See {@link openAsync} for the contract.
|
|
12822
|
+
*/
|
|
12823
|
+
async mountWindowed(windowSize, onProgress) {
|
|
12824
|
+
const bridge = this.exports.DocxSessionBridge;
|
|
12825
|
+
const profile = JSON.stringify({ ...JSON.parse(this.editorRenderProfile()), stampAnchors: true });
|
|
12826
|
+
const chrome = bridge.RenderEditorChromeHtml(this.handle, profile);
|
|
12827
|
+
if (chrome.trimStart().startsWith("{")) {
|
|
12828
|
+
throw new Error(JSON.parse(chrome).error ?? "chrome render failed");
|
|
12829
|
+
}
|
|
12830
|
+
const parsed = new DOMParser().parseFromString(chrome, "text/html");
|
|
12831
|
+
parsed.body.querySelectorAll(`[data-section-index] > [data-anchor="${CHROME_CARRIER_ANCHOR}"]`).forEach((el) => el.remove());
|
|
12832
|
+
const styles = Array.from(parsed.querySelectorAll("style")).map((s) => s.outerHTML).join("");
|
|
12833
|
+
const flow = document.createElement("div");
|
|
12834
|
+
flow.className = "docx-body-flow";
|
|
12835
|
+
flow.innerHTML = parsed.body.innerHTML;
|
|
12836
|
+
const hosts = /* @__PURE__ */ new Map();
|
|
12837
|
+
flow.querySelectorAll("[data-section-index]").forEach((el) => hosts.set(Number(el.getAttribute("data-section-index")), el));
|
|
12838
|
+
const attachNow = !this.options.paginated;
|
|
12839
|
+
const wireNow = attachNow && this.options.editable;
|
|
12840
|
+
if (wireNow) this.wireBlocks(flow);
|
|
12841
|
+
if (attachNow) {
|
|
12842
|
+
this.region?.detachPages();
|
|
12843
|
+
this.container.innerHTML = styles;
|
|
12844
|
+
this.readoptGutter();
|
|
12845
|
+
this.container.appendChild(flow);
|
|
12846
|
+
this.editRoot = flow;
|
|
12847
|
+
}
|
|
12848
|
+
const plan = JSON.parse(this.renderPlanJson());
|
|
12849
|
+
if (plan.error) throw new Error(plan.error);
|
|
12850
|
+
const units = plan.body;
|
|
12851
|
+
const sectionOf = new Map(units.map((u) => [unidOf(u.id), u.section ?? 0]));
|
|
12852
|
+
const mounted = /* @__PURE__ */ new Set();
|
|
12853
|
+
const place = (el, sameHostAs) => {
|
|
12854
|
+
el.removeAttribute("xmlns");
|
|
12855
|
+
const unit = el.hasAttribute("data-anchor") ? el : el.querySelector("[data-anchor]");
|
|
12856
|
+
const unid = unit?.getAttribute("data-anchor") ?? "";
|
|
12857
|
+
const host = sameHostAs ?? hosts.get(sectionOf.get(unid) ?? 0) ?? hosts.values().next().value ?? flow;
|
|
12858
|
+
host.insertBefore(el, host.querySelector(":scope > section.endnotes"));
|
|
12859
|
+
if (wireNow) {
|
|
12860
|
+
if (el.hasAttribute("data-anchor")) this.wireBlock(el);
|
|
12861
|
+
this.wireBlocks(el);
|
|
12862
|
+
}
|
|
12863
|
+
unit && mounted.add(unid);
|
|
12864
|
+
el.querySelectorAll("[data-anchor]").forEach((n) => mounted.add(n.getAttribute("data-anchor")));
|
|
12865
|
+
return host;
|
|
12866
|
+
};
|
|
12867
|
+
for (let start2 = 0; start2 < units.length; ) {
|
|
12868
|
+
let end = Math.min(start2 + windowSize, units.length);
|
|
12869
|
+
while (end < units.length && units[end].group !== void 0 && units[end].group === units[end - 1].group) end++;
|
|
12870
|
+
const window2 = units.slice(start2, end);
|
|
12871
|
+
const rendered = JSON.parse(bridge.RenderEditorRangeHtml(
|
|
12872
|
+
this.handle,
|
|
12873
|
+
JSON.stringify(window2.map((u) => u.id)),
|
|
12874
|
+
profile
|
|
12875
|
+
));
|
|
12876
|
+
if (!Array.isArray(rendered)) throw new Error(rendered.error ?? "window render failed");
|
|
12877
|
+
for (const html of rendered) {
|
|
12878
|
+
let host;
|
|
12879
|
+
for (const el of Array.from(new DOMParser().parseFromString(html, "text/html").body.children)) {
|
|
12880
|
+
host = place(el, host);
|
|
12881
|
+
}
|
|
12882
|
+
}
|
|
12883
|
+
for (const unit of window2) {
|
|
12884
|
+
if (mounted.has(unidOf(unit.id))) continue;
|
|
12885
|
+
const el = this.renderInto(unit.id);
|
|
12886
|
+
if (el) place(el);
|
|
12887
|
+
}
|
|
12888
|
+
start2 = end;
|
|
12889
|
+
onProgress?.(start2, units.length);
|
|
12890
|
+
if (start2 < units.length) await yieldToEventLoop();
|
|
12891
|
+
}
|
|
12892
|
+
if (attachNow) {
|
|
12893
|
+
this.stampPlanState();
|
|
12894
|
+
if (this.region) this.dockBands(flow);
|
|
12895
|
+
this.viewport.attach(flow, true);
|
|
12896
|
+
} else {
|
|
12897
|
+
this.mountPaginated(parsed.head.innerHTML + flow.innerHTML);
|
|
12527
12898
|
}
|
|
12528
12899
|
}
|
|
12529
12900
|
/**
|