@superdoc/sdk 2.15.1-next.5 → 2.16.0-next.10

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 CHANGED
@@ -60,6 +60,71 @@ is not supported for Liveblocks or the standalone document host.
60
60
 
61
61
  See the [Node.js SDK guide](https://docs.superdoc.dev/agents/automation/node-sdk) for a complete workflow.
62
62
 
63
+ ## Tracked comparison with exact-file review
64
+
65
+ The SDK's `diff.capture` and `diff.compare` describe a snapshot comparison. A
66
+ blocked tracked `diff.apply` cannot turn that snapshot into a complete review
67
+ proposal: the host must provide the exact base and target DOCX bytes, a durable
68
+ review store, a document ID, and an authenticated actor. For a Node host using
69
+ the V2 document runtime, `runTrackedComparisonReview` connects those steps:
70
+
71
+ ```js
72
+ import { readFile } from 'node:fs/promises';
73
+ import { createSuperDocClient, runTrackedComparisonReview } from '@superdoc/sdk';
74
+ import {
75
+ createDocumentProposalManager,
76
+ createFileDocumentReviewStore,
77
+ openVersionedDocumentReviewSession,
78
+ } from '@superdoc/docx-engine/document-runtime';
79
+
80
+ const baseBytes = new Uint8Array(await readFile(basePath));
81
+ const targetBytes = new Uint8Array(await readFile(targetPath));
82
+ const actor = authenticatedUser.name; // Set by the host's authentication layer.
83
+ const store = createFileDocumentReviewStore(durableReviewDirectory);
84
+ const manager = createDocumentProposalManager(store);
85
+ if (!(await store.read(documentId))) {
86
+ const initial = await manager.initialize({ documentId, bytes: baseBytes, savePolicy: 'suggest-only' });
87
+ if (initial.kind !== 'initialized' && initial.kind !== 'stale') throw new Error(initial.kind);
88
+ }
89
+
90
+ const session = await openVersionedDocumentReviewSession({ store, documentId, actor });
91
+ const client = createSuperDocClient({
92
+ user: { name: actor },
93
+ requestTimeoutMs: 120_000,
94
+ env: { SUPERDOC_SDK_DOCUMENT_HOST_BIN: 'embedded' },
95
+ });
96
+ try {
97
+ const { diff, comparisonError, result } = await runTrackedComparisonReview({
98
+ client, baseBytes, targetBytes, documentId, actor,
99
+ currentReviewDocument: (id) => manager.current(id),
100
+ reviewSession: session,
101
+ options: { timeoutMs: 120_000 },
102
+ });
103
+ console.log(diff?.applyEligibility?.tracked, comparisonError);
104
+ if (result.kind === 'prepared') {
105
+ const preview = await session.preview(result.id);
106
+ // Present the whole-document proposal and its exact base/target files to a reviewer.
107
+ // Call session.decide(result.id, 'accept' or 'reject') after their decision.
108
+ } else if (result.kind !== 'native-revisions-applied') {
109
+ throw new Error(`Tracked review did not proceed: ${result.kind}`);
110
+ }
111
+ // manager.current(documentId) supplies export bytes; manager.history(documentId) supplies audit events.
112
+ } finally {
113
+ await client.dispose();
114
+ await session.close();
115
+ }
116
+ ```
117
+
118
+ The helper stages private copies of the exact bytes for SDK capture and compare,
119
+ checks the store's current base and the review session's version, document, and
120
+ actor binding, then calls the versioned session's `applyTarget` in tracked mode.
121
+ If SDK import or comparison is unavailable, `comparisonError` explains why
122
+ `diff` is null and exact-file review still runs.
123
+ That session chooses native Word revisions only after proving accept and reject
124
+ endpoints; other supported changes become one whole-document proposal. A stale
125
+ base or invalid DOCX returns a refusal without a partial apply. The host owns
126
+ authorization, durable storage, reviewer presentation, and decisions.
127
+
63
128
  ## Agent execution evidence
64
129
 
65
130
  The core preset's `agent_apply`, `agent_verify`, and supported named actions
@@ -213,6 +213,7 @@ function createDocApi(runtime) {
213
213
  },
214
214
  selection: {
215
215
  current: (params = {}, options) => runtime.invoke(contract.CONTRACT.operations["doc.selection.current"], params, options),
216
+ extractOoxml: (params = {}, options) => runtime.invoke(contract.CONTRACT.operations["doc.selection.extractOoxml"], params, options),
216
217
  },
217
218
  mutations: {
218
219
  preview: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.mutations.preview"], params, options),
@@ -347,6 +348,7 @@ function createDocApi(runtime) {
347
348
  },
348
349
  },
349
350
  watermarks: {
351
+ apply: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.apply"], params, options),
350
352
  list: (params = {}, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.list"], params, options),
351
353
  insert: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.insert"], params, options),
352
354
  replace: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.replace"], params, options),
@@ -785,6 +787,7 @@ function createBoundDocApi(runtime) {
785
787
  },
786
788
  selection: {
787
789
  current: (params = {}, options) => runtime.invoke(contract.CONTRACT.operations["doc.selection.current"], params, options),
790
+ extractOoxml: (params = {}, options) => runtime.invoke(contract.CONTRACT.operations["doc.selection.extractOoxml"], params, options),
788
791
  },
789
792
  mutations: {
790
793
  preview: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.mutations.preview"], params, options),
@@ -919,6 +922,7 @@ function createBoundDocApi(runtime) {
919
922
  },
920
923
  },
921
924
  watermarks: {
925
+ apply: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.apply"], params, options),
922
926
  list: (params = {}, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.list"], params, options),
923
927
  insert: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.insert"], params, options),
924
928
  replace: (params, options) => runtime.invoke(contract.CONTRACT.operations["doc.watermarks.replace"], params, options),