superdoc 2.4.0-next.2 → 2.4.0-next.4
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/dist/chunks/{create-super-doc-ui-DXdWuTzm.cjs → create-super-doc-ui-BHMQEL2y.cjs} +247 -25
- package/dist/chunks/{create-super-doc-ui-D4kk9AjM.es.js → create-super-doc-ui-Dli6Wq70.es.js} +247 -25
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +23 -23
- package/dist/style.layered.css +23 -23
- package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +1 -0
- package/dist/superdoc/src/helpers/v2-review-mutation-reconciler.d.ts +1 -1
- package/dist/superdoc/src/stores/comments-store.d.ts +100 -22
- package/dist/superdoc/src/stores/superdoc-store.d.ts +300 -66
- package/dist/superdoc.cjs +496 -45
- package/dist/superdoc.es.js +496 -45
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +37 -37
- package/package.json +2 -2
package/dist/chunks/{create-super-doc-ui-D4kk9AjM.es.js → create-super-doc-ui-Dli6Wq70.es.js}
RENAMED
|
@@ -115,14 +115,21 @@ function getV2TrackedChangeMutationImpact(event) {
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
for (const id of removedIds) upsertIds.delete(id);
|
|
118
|
-
|
|
118
|
+
const allResolved = readAllResolvedFact(event, payload);
|
|
119
|
+
if (upsertIds.size === 0 && removedIds.size === 0 && !allResolved) return null;
|
|
119
120
|
return {
|
|
120
121
|
upsertIds,
|
|
121
122
|
removedIds,
|
|
122
123
|
remappedPairs,
|
|
123
|
-
reconcileMode: event.origin === "history" ? "authoritative" : "targeted"
|
|
124
|
+
reconcileMode: event.origin === "history" ? "authoritative" : "targeted",
|
|
125
|
+
...allResolved ? { allResolved } : {}
|
|
124
126
|
};
|
|
125
127
|
}
|
|
128
|
+
function readAllResolvedFact(event, receipt) {
|
|
129
|
+
const fact = event?.trackedChangeAllResolved;
|
|
130
|
+
if (event?.origin === "history" || !fact || fact.schemaVersion !== 1 || fact.targetKind !== "all" || fact.decision !== "accept" && fact.decision !== "reject" || fact.remainingLogicalCount !== 0 || typeof fact.catalogRevision !== "string" || !fact.catalogRevision || typeof fact.sourceCoverageRevision !== "string" || !fact.sourceCoverageRevision || !Number.isSafeInteger(fact.logicalTargetCount) || fact.logicalTargetCount <= 0 || !Number.isSafeInteger(fact.physicalCarrierCount) || fact.physicalCarrierCount < fact.logicalTargetCount || typeof fact.txId !== "string" || fact.txId !== receipt.txId || typeof fact.documentEpoch !== "string" || !Number.isSafeInteger(fact.commitSequence) || typeof fact.packagePreviousRevision !== "string" || typeof fact.packageNextRevision !== "string" || fact.packagePreviousRevision === fact.packageNextRevision) return null;
|
|
131
|
+
return fact;
|
|
132
|
+
}
|
|
126
133
|
var normalizeIds = (values) => new Set(Array.from(values ?? []).filter((value) => typeof value === "string" && value.length > 0));
|
|
127
134
|
var itemId = (item) => {
|
|
128
135
|
if (typeof item?.id === "string" && item.id.length > 0) return item.id;
|
|
@@ -133,10 +140,20 @@ var itemId = (item) => {
|
|
|
133
140
|
var contextMatches = (left, right) => left?.adapter === right?.adapter && left?.documentId === right?.documentId && left?.editor === right?.editor && left?.reconcileToken === right?.reconcileToken;
|
|
134
141
|
function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onReconciled }) {
|
|
135
142
|
const pendingUpserts = /* @__PURE__ */ new Map();
|
|
143
|
+
let pendingAllResolved = null;
|
|
136
144
|
let sequence = 0;
|
|
137
145
|
let generation = 0;
|
|
138
146
|
let flushInFlight = null;
|
|
139
147
|
let flushRequested = false;
|
|
148
|
+
const settlementWaiters = [];
|
|
149
|
+
const resolveSettlementsThrough = (version, value) => {
|
|
150
|
+
for (let index = settlementWaiters.length - 1; index >= 0; index -= 1) {
|
|
151
|
+
const waiter = settlementWaiters[index];
|
|
152
|
+
if (waiter.generation !== generation || waiter.version > version) continue;
|
|
153
|
+
settlementWaiters.splice(index, 1);
|
|
154
|
+
waiter.resolve(value === true && waiter.requiresAllResolved ? pendingAllResolved == null : value);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
140
157
|
const isCurrent = (capturedGeneration, context) => generation === capturedGeneration && contextMatches(context, getContext());
|
|
141
158
|
const clearResolved = (ids, snapshot) => {
|
|
142
159
|
const clearedIds = /* @__PURE__ */ new Set();
|
|
@@ -150,6 +167,10 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
150
167
|
const readySnapshot = (reconcileMode) => new Map([...pendingUpserts].filter(([, entry]) => entry.ready === true && entry.reconcileMode === reconcileMode));
|
|
151
168
|
const markRenderGatedReady = () => {
|
|
152
169
|
let changed = false;
|
|
170
|
+
if (pendingAllResolved?.gate === "render" && !pendingAllResolved.ready) {
|
|
171
|
+
pendingAllResolved.ready = true;
|
|
172
|
+
changed = true;
|
|
173
|
+
}
|
|
153
174
|
for (const entry of pendingUpserts.values()) {
|
|
154
175
|
if (entry.gate !== "render" || entry.ready) continue;
|
|
155
176
|
entry.ready = true;
|
|
@@ -159,6 +180,10 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
159
180
|
};
|
|
160
181
|
const markEntriesReadyThrough = (maxVersion) => {
|
|
161
182
|
let changed = false;
|
|
183
|
+
if (pendingAllResolved && pendingAllResolved.version <= maxVersion && !pendingAllResolved.ready) {
|
|
184
|
+
pendingAllResolved.ready = true;
|
|
185
|
+
changed = true;
|
|
186
|
+
}
|
|
162
187
|
for (const entry of pendingUpserts.values()) {
|
|
163
188
|
if (entry.version > maxVersion || entry.ready) continue;
|
|
164
189
|
entry.ready = true;
|
|
@@ -209,14 +234,31 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
209
234
|
};
|
|
210
235
|
const flush = () => {
|
|
211
236
|
if (flushInFlight) return flushInFlight;
|
|
237
|
+
const allResolvedSnapshot = pendingAllResolved?.ready ? pendingAllResolved : null;
|
|
212
238
|
const targetedSnapshot = readySnapshot("targeted");
|
|
213
239
|
const authoritativeSnapshot = readySnapshot("authoritative");
|
|
214
|
-
if (targetedSnapshot.size === 0 && authoritativeSnapshot.size === 0) return null;
|
|
240
|
+
if (!allResolvedSnapshot && targetedSnapshot.size === 0 && authoritativeSnapshot.size === 0) return null;
|
|
215
241
|
const context = getContext();
|
|
216
242
|
if (!context?.adapter) return null;
|
|
217
243
|
flushRequested = false;
|
|
218
244
|
const capturedGeneration = generation;
|
|
219
245
|
flushInFlight = Promise.resolve().then(async () => {
|
|
246
|
+
if (allResolvedSnapshot) {
|
|
247
|
+
let result = null;
|
|
248
|
+
try {
|
|
249
|
+
result = await reconcile(context, {
|
|
250
|
+
upsertIds: /* @__PURE__ */ new Set(),
|
|
251
|
+
removedIds: /* @__PURE__ */ new Set(),
|
|
252
|
+
allResolved: allResolvedSnapshot.fact,
|
|
253
|
+
reconcileMode: "targeted"
|
|
254
|
+
});
|
|
255
|
+
} catch {}
|
|
256
|
+
if (!isCurrent(capturedGeneration, context)) return;
|
|
257
|
+
if (result?.ok === true) {
|
|
258
|
+
if (pendingAllResolved === allResolvedSnapshot) pendingAllResolved = null;
|
|
259
|
+
await notifyReconciled(context, /* @__PURE__ */ new Set(), result, true);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
220
262
|
if (authoritativeSnapshot.size > 0) await reconcileAuthoritativeSnapshot(context, authoritativeSnapshot, capturedGeneration).catch(() => void 0);
|
|
221
263
|
if (targetedSnapshot.size > 0) await reconcileTargetedSnapshot(context, targetedSnapshot, capturedGeneration).catch(() => void 0);
|
|
222
264
|
}).catch(() => {}).finally(() => {
|
|
@@ -227,6 +269,15 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
227
269
|
};
|
|
228
270
|
const enqueueWithGate = (impact, gate) => {
|
|
229
271
|
if (!impact) return;
|
|
272
|
+
if (impact.allResolved) {
|
|
273
|
+
pendingUpserts.clear();
|
|
274
|
+
pendingAllResolved = {
|
|
275
|
+
fact: impact.allResolved,
|
|
276
|
+
version: ++sequence,
|
|
277
|
+
gate,
|
|
278
|
+
ready: false
|
|
279
|
+
};
|
|
280
|
+
}
|
|
230
281
|
const reconcileMode = impact.reconcileMode === "authoritative" ? "authoritative" : "targeted";
|
|
231
282
|
const removedIds = normalizeIds(impact.removedIds);
|
|
232
283
|
const upsertIds = normalizeIds(impact.upsertIds);
|
|
@@ -241,7 +292,7 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
241
292
|
else pendingUpserts.delete(id);
|
|
242
293
|
}
|
|
243
294
|
const context = getContext();
|
|
244
|
-
if (removedIds.size > 0 && upsertIds.size === 0 && context?.adapter) try {
|
|
295
|
+
if (removedIds.size > 0 && upsertIds.size === 0 && context?.adapter && !impact.allResolved) try {
|
|
245
296
|
Promise.resolve(reconcile(context, {
|
|
246
297
|
upsertIds: /* @__PURE__ */ new Set(),
|
|
247
298
|
removedIds
|
|
@@ -268,20 +319,34 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
268
319
|
enqueueAfterPaint(impact, waitForPaint) {
|
|
269
320
|
if (!impact || typeof waitForPaint !== "function") {
|
|
270
321
|
enqueue(impact);
|
|
271
|
-
return;
|
|
322
|
+
return Promise.resolve(false);
|
|
272
323
|
}
|
|
273
324
|
enqueueWithGate(impact, "exact-paint");
|
|
274
325
|
const context = getContext();
|
|
275
|
-
if (!context?.adapter) return;
|
|
276
326
|
const capturedGeneration = generation;
|
|
277
327
|
const capturedSequence = sequence;
|
|
328
|
+
if (!context?.adapter) {
|
|
329
|
+
markEntriesReadyThrough(capturedSequence);
|
|
330
|
+
return Promise.resolve(false);
|
|
331
|
+
}
|
|
332
|
+
const completion = new Promise((resolve) => {
|
|
333
|
+
settlementWaiters.push({
|
|
334
|
+
generation: capturedGeneration,
|
|
335
|
+
version: capturedSequence,
|
|
336
|
+
requiresAllResolved: Boolean(impact.allResolved),
|
|
337
|
+
resolve
|
|
338
|
+
});
|
|
339
|
+
});
|
|
278
340
|
const impactedIds = new Set([...normalizeIds(impact.upsertIds), ...normalizeIds(impact.removedIds)]);
|
|
279
341
|
const capturedEntries = new Map([...impactedIds].flatMap((id) => {
|
|
280
342
|
const entry = pendingUpserts.get(id);
|
|
281
343
|
return entry ? [[id, entry]] : [];
|
|
282
344
|
}));
|
|
283
|
-
Promise.resolve().then(() => waitForPaint()).then(() => {
|
|
284
|
-
if (!isCurrent(capturedGeneration, context))
|
|
345
|
+
Promise.resolve().then(() => waitForPaint()).then(async () => {
|
|
346
|
+
if (!isCurrent(capturedGeneration, context)) {
|
|
347
|
+
resolveSettlementsThrough(capturedSequence, false);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
285
350
|
let madeReady = markRenderGatedReady();
|
|
286
351
|
if (markEntriesReadyThrough(capturedSequence)) madeReady = true;
|
|
287
352
|
for (const [id, entry] of capturedEntries) {
|
|
@@ -290,16 +355,35 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
290
355
|
entry.ready = true;
|
|
291
356
|
}
|
|
292
357
|
if (flushInFlight && (madeReady || capturedSequence > 0)) flushRequested = true;
|
|
293
|
-
|
|
358
|
+
const preceding = flushInFlight;
|
|
359
|
+
const pending = flush();
|
|
360
|
+
if (pending) await pending;
|
|
361
|
+
if (preceding) {
|
|
362
|
+
const followUp = flushInFlight;
|
|
363
|
+
if (followUp && followUp !== preceding) await followUp;
|
|
364
|
+
}
|
|
365
|
+
if (!isCurrent(capturedGeneration, context)) {
|
|
366
|
+
resolveSettlementsThrough(capturedSequence, false);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
resolveSettlementsThrough(capturedSequence, true);
|
|
294
370
|
}).catch(() => {
|
|
295
|
-
if (!isCurrent(capturedGeneration, context))
|
|
371
|
+
if (!isCurrent(capturedGeneration, context)) {
|
|
372
|
+
resolveSettlementsThrough(capturedSequence, false);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
296
375
|
for (const [id, entry] of capturedEntries) if (pendingUpserts.get(id) === entry) entry.gate = "render";
|
|
376
|
+
if (pendingAllResolved?.gate === "exact-paint") pendingAllResolved.gate = "render";
|
|
377
|
+
resolveSettlementsThrough(capturedSequence, false);
|
|
297
378
|
});
|
|
379
|
+
return completion;
|
|
298
380
|
},
|
|
299
381
|
onRender,
|
|
300
382
|
reset() {
|
|
383
|
+
for (const waiter of settlementWaiters.splice(0)) waiter.resolve(false);
|
|
301
384
|
generation += 1;
|
|
302
385
|
pendingUpserts.clear();
|
|
386
|
+
pendingAllResolved = null;
|
|
303
387
|
flushRequested = false;
|
|
304
388
|
},
|
|
305
389
|
getPendingIds() {
|
|
@@ -1494,6 +1578,30 @@ const INLINE_PROPERTY_REGISTRY = [
|
|
|
1494
1578
|
new Set(INLINE_PROPERTY_REGISTRY.map((entry) => entry.key));
|
|
1495
1579
|
const INLINE_PROPERTY_BY_KEY = Object.fromEntries(INLINE_PROPERTY_REGISTRY.map((entry) => [entry.key, entry]));
|
|
1496
1580
|
INLINE_PROPERTY_REGISTRY.filter((entry) => entry.storage === "mark").map((entry) => entry.key), INLINE_PROPERTY_REGISTRY.filter((entry) => entry.storage === "runAttribute").map((entry) => entry.key);
|
|
1581
|
+
var sharedUiTrackedChangesCatalogByHost = /* @__PURE__ */ new WeakMap();
|
|
1582
|
+
function acquireSharedUiTrackedChangesCatalog(host) {
|
|
1583
|
+
let state = sharedUiTrackedChangesCatalogByHost.get(host);
|
|
1584
|
+
if (!state) {
|
|
1585
|
+
state = {
|
|
1586
|
+
refCount: 0,
|
|
1587
|
+
generation: 0,
|
|
1588
|
+
abortController: new AbortController(),
|
|
1589
|
+
inFlight: null,
|
|
1590
|
+
activeMutationTokens: /* @__PURE__ */ new Set()
|
|
1591
|
+
};
|
|
1592
|
+
sharedUiTrackedChangesCatalogByHost.set(host, state);
|
|
1593
|
+
}
|
|
1594
|
+
state.refCount += 1;
|
|
1595
|
+
return state;
|
|
1596
|
+
}
|
|
1597
|
+
function releaseSharedUiTrackedChangesCatalog(host, state) {
|
|
1598
|
+
state.refCount = Math.max(0, state.refCount - 1);
|
|
1599
|
+
if (state.refCount > 0) return;
|
|
1600
|
+
state.abortController.abort("ui-controller-destroyed");
|
|
1601
|
+
state.inFlight = null;
|
|
1602
|
+
state.activeMutationTokens.clear();
|
|
1603
|
+
sharedUiTrackedChangesCatalogByHost.delete(host);
|
|
1604
|
+
}
|
|
1497
1605
|
var SUPERDOC_UI_REASON_VALUES = new Set(Object.values(SUPERDOC_UI_REASONS));
|
|
1498
1606
|
function coerceSuperDocUIReason(reason, fallback) {
|
|
1499
1607
|
return typeof reason === "string" && SUPERDOC_UI_REASON_VALUES.has(reason) ? reason : fallback;
|
|
@@ -1590,12 +1698,12 @@ const HEAVY_DOC_READ_POLICY = [
|
|
|
1590
1698
|
{
|
|
1591
1699
|
key: "trackChanges",
|
|
1592
1700
|
match: "exact",
|
|
1593
|
-
note: "audited: all-story tracked-changes
|
|
1701
|
+
note: "audited: shared all-story tracked-changes catalog; stale-served during load"
|
|
1594
1702
|
},
|
|
1595
1703
|
{
|
|
1596
1704
|
key: "trackChanges:all",
|
|
1597
1705
|
match: "exact",
|
|
1598
|
-
note: "audited: all-story
|
|
1706
|
+
note: "audited: current-token validation over the shared all-story catalog; consumers fail closed on non-ready"
|
|
1599
1707
|
},
|
|
1600
1708
|
{
|
|
1601
1709
|
key: "tables",
|
|
@@ -3054,6 +3162,63 @@ function createSuperDocUI(options) {
|
|
|
3054
3162
|
};
|
|
3055
3163
|
let documentMutationRevision = 0;
|
|
3056
3164
|
let reviewMutationToken = {};
|
|
3165
|
+
const uiTrackedChangesCatalogHost = options.superdoc;
|
|
3166
|
+
const uiTrackedChangesCatalogState = acquireSharedUiTrackedChangesCatalog(uiTrackedChangesCatalogHost);
|
|
3167
|
+
const supersedeUiTrackedChangesCatalogRead = () => {
|
|
3168
|
+
uiTrackedChangesCatalogState.abortController.abort("review-mutation-started");
|
|
3169
|
+
uiTrackedChangesCatalogState.inFlight = null;
|
|
3170
|
+
};
|
|
3171
|
+
const renewUiTrackedChangesCatalogRead = () => {
|
|
3172
|
+
uiTrackedChangesCatalogState.generation += 1;
|
|
3173
|
+
uiTrackedChangesCatalogState.abortController = new AbortController();
|
|
3174
|
+
uiTrackedChangesCatalogState.inFlight = null;
|
|
3175
|
+
};
|
|
3176
|
+
const beginUiReviewMutation = (token) => {
|
|
3177
|
+
const activeTokens = uiTrackedChangesCatalogState.activeMutationTokens;
|
|
3178
|
+
if (typeof token !== "string" || token.length === 0 || activeTokens.has(token)) return;
|
|
3179
|
+
const firstToken = activeTokens.size === 0;
|
|
3180
|
+
activeTokens.add(token);
|
|
3181
|
+
if (firstToken) supersedeUiTrackedChangesCatalogRead();
|
|
3182
|
+
};
|
|
3183
|
+
const settleUiReviewMutation = (token) => {
|
|
3184
|
+
const activeTokens = uiTrackedChangesCatalogState.activeMutationTokens;
|
|
3185
|
+
if (typeof token !== "string" || !activeTokens.delete(token)) return;
|
|
3186
|
+
if (activeTokens.size === 0) renewUiTrackedChangesCatalogRead();
|
|
3187
|
+
};
|
|
3188
|
+
const runUiTrackedChangesCatalogRead = (fallback) => {
|
|
3189
|
+
const v2TrackedChanges = getV2TrackedChanges();
|
|
3190
|
+
const listTrackedChanges = v2TrackedChanges?.listTrackedChanges;
|
|
3191
|
+
if (typeof listTrackedChanges !== "function") {
|
|
3192
|
+
if (getEditor()?.editorVersion === 2) return Promise.reject(/* @__PURE__ */ new Error("v2-tracked-changes-bridge-pending"));
|
|
3193
|
+
return fallback();
|
|
3194
|
+
}
|
|
3195
|
+
if (uiTrackedChangesCatalogState.activeMutationTokens.size > 0) return Promise.reject(/* @__PURE__ */ new Error("ui-review-catalog-superseded"));
|
|
3196
|
+
if ((getEditor()?.reviewHydration?.getDiagnostics?.())?.inFlight === true) return Promise.reject(/* @__PURE__ */ new Error("shell-review-hydration-in-flight"));
|
|
3197
|
+
const generation = uiTrackedChangesCatalogState.generation;
|
|
3198
|
+
const existing = uiTrackedChangesCatalogState.inFlight;
|
|
3199
|
+
if (existing?.generation === generation) return existing.promise;
|
|
3200
|
+
const signal = uiTrackedChangesCatalogState.abortController.signal;
|
|
3201
|
+
const validateResult = (result) => {
|
|
3202
|
+
if (signal.aborted || generation !== uiTrackedChangesCatalogState.generation || result?.reason === "review-hydration-superseded") throw new Error("ui-review-catalog-superseded");
|
|
3203
|
+
return result;
|
|
3204
|
+
};
|
|
3205
|
+
const rawResult = listTrackedChanges.call(v2TrackedChanges, {
|
|
3206
|
+
blocking: false,
|
|
3207
|
+
signal
|
|
3208
|
+
});
|
|
3209
|
+
if (!isPromiseLike(rawResult)) return validateResult(rawResult);
|
|
3210
|
+
const promise = Promise.resolve(rawResult).then(validateResult);
|
|
3211
|
+
uiTrackedChangesCatalogState.inFlight = {
|
|
3212
|
+
generation,
|
|
3213
|
+
promise
|
|
3214
|
+
};
|
|
3215
|
+
promise.then(() => {
|
|
3216
|
+
if (uiTrackedChangesCatalogState.inFlight?.promise === promise) uiTrackedChangesCatalogState.inFlight = null;
|
|
3217
|
+
}, () => {
|
|
3218
|
+
if (uiTrackedChangesCatalogState.inFlight?.promise === promise) uiTrackedChangesCatalogState.inFlight = null;
|
|
3219
|
+
});
|
|
3220
|
+
return promise;
|
|
3221
|
+
};
|
|
3057
3222
|
let authoritativeTrackChangesPendingToken = null;
|
|
3058
3223
|
let authoritativeTrackChangesRetryTimer = null;
|
|
3059
3224
|
let authoritativeTrackChangesFailureCount = 0;
|
|
@@ -3065,6 +3230,7 @@ function createSuperDocUI(options) {
|
|
|
3065
3230
|
let scheduleAuthoritativeTrackChangesRetry = (_reconcileToken) => void 0;
|
|
3066
3231
|
let postDecisionTrackChangesToken = null;
|
|
3067
3232
|
let postDecisionTrackChangeIds = /* @__PURE__ */ new Set();
|
|
3233
|
+
let allTrackedChangesResolvedToken = null;
|
|
3068
3234
|
let selectionEpoch = 0;
|
|
3069
3235
|
let lastCoordinatorEditor = null;
|
|
3070
3236
|
const contentToken = () => `${editorIdentityId(getEditor())}|m${documentMutationRevision}`;
|
|
@@ -3143,6 +3309,23 @@ function createSuperDocUI(options) {
|
|
|
3143
3309
|
};
|
|
3144
3310
|
notifyPostDecisionTrackChanges(receipt);
|
|
3145
3311
|
};
|
|
3312
|
+
const publishAllTrackedChangesResolved = (receipt) => {
|
|
3313
|
+
const previous = state.trackChanges;
|
|
3314
|
+
const changed = previous.items.length > 0 || previous.total !== 0 || previous.activeId !== null || previous.authors.length > 0;
|
|
3315
|
+
allTrackedChangesResolvedToken = contentToken();
|
|
3316
|
+
if (explicitActiveChange !== null) setExplicitActiveChange(null);
|
|
3317
|
+
state = {
|
|
3318
|
+
...state,
|
|
3319
|
+
trackChanges: {
|
|
3320
|
+
...previous,
|
|
3321
|
+
items: [],
|
|
3322
|
+
total: 0,
|
|
3323
|
+
activeId: null,
|
|
3324
|
+
authors: []
|
|
3325
|
+
}
|
|
3326
|
+
};
|
|
3327
|
+
if (changed) notifyPostDecisionTrackChanges(receipt);
|
|
3328
|
+
};
|
|
3146
3329
|
const markPostDecisionTrackChanges = (ids, receipt) => {
|
|
3147
3330
|
if (ids.size === 0) return;
|
|
3148
3331
|
const token = contentToken();
|
|
@@ -3821,6 +4004,7 @@ function createSuperDocUI(options) {
|
|
|
3821
4004
|
detachSourceLoading = null;
|
|
3822
4005
|
sourceLoadingSubscriptionHost = null;
|
|
3823
4006
|
clearPostDecisionTrackChanges();
|
|
4007
|
+
allTrackedChangesResolvedToken = null;
|
|
3824
4008
|
};
|
|
3825
4009
|
const invalidateDocumentContent = () => {
|
|
3826
4010
|
const carryAuthoritativeTrackChangesHold = authoritativeTrackChangesPendingToken !== null;
|
|
@@ -3828,6 +4012,15 @@ function createSuperDocUI(options) {
|
|
|
3828
4012
|
if (carryAuthoritativeTrackChangesHold) authoritativeTrackChangesPendingToken = contentToken();
|
|
3829
4013
|
clearPostDecisionTrackChanges();
|
|
3830
4014
|
};
|
|
4015
|
+
const invalidateAfterCommandSettlement = () => {
|
|
4016
|
+
const carryAllResolvedCatalog = allTrackedChangesResolvedToken === contentToken();
|
|
4017
|
+
invalidateDocumentContent();
|
|
4018
|
+
if (carryAllResolvedCatalog) {
|
|
4019
|
+
replaceTrackedChangeItemsInCache([]);
|
|
4020
|
+
allTrackedChangesResolvedToken = contentToken();
|
|
4021
|
+
}
|
|
4022
|
+
recompute();
|
|
4023
|
+
};
|
|
3831
4024
|
const insertText = (text) => {
|
|
3832
4025
|
if (typeof text !== "string" || text.length === 0) return failedReceipt("insertText requires a non-empty string.", "INVALID_INPUT");
|
|
3833
4026
|
if (readDocumentMode() === "viewing") return failedReceipt("The document is read-only.", "DOCUMENT_READONLY");
|
|
@@ -4031,7 +4224,17 @@ function createSuperDocUI(options) {
|
|
|
4031
4224
|
const { value, status } = authoritativeTrackChangesPendingToken === token ? {
|
|
4032
4225
|
value: heldEntry?.hasSettled ? heldEntry.value : null,
|
|
4033
4226
|
status: heldEntry?.hasSettled ? "stale" : "pending"
|
|
4034
|
-
} : readAsync("trackChanges:all", token, () =>
|
|
4227
|
+
} : readAsync("trackChanges:all", token, () => {
|
|
4228
|
+
if (!tcApi?.list) return void 0;
|
|
4229
|
+
const fallback = () => tcApi.list({ in: "all" });
|
|
4230
|
+
const bridgeOwnsCatalog = typeof getV2TrackedChanges()?.listTrackedChanges === "function";
|
|
4231
|
+
const shared = runUiTrackedChangesCatalogRead(fallback);
|
|
4232
|
+
if (!bridgeOwnsCatalog) return shared;
|
|
4233
|
+
return Promise.resolve(shared).then((raw) => {
|
|
4234
|
+
const record = isLooseObject(raw) ? raw : null;
|
|
4235
|
+
return (Array.isArray(record?.items) ? record.items : []).some((item) => readEntityStory(item) == null) ? fallback() : raw;
|
|
4236
|
+
});
|
|
4237
|
+
}, (raw) => {
|
|
4035
4238
|
return (raw && Array.isArray(raw.items) ? raw.items : []).map(projectTrackChangesItem).filter((item) => item != null);
|
|
4036
4239
|
});
|
|
4037
4240
|
return status === "ready" ? value : null;
|
|
@@ -4047,7 +4250,7 @@ function createSuperDocUI(options) {
|
|
|
4047
4250
|
value: heldEntry?.hasSettled ? heldEntry.value : null,
|
|
4048
4251
|
status: heldEntry?.hasSettled ? "stale" : "pending"
|
|
4049
4252
|
} : readAsync("trackChanges", token, () => {
|
|
4050
|
-
if (listTrackedChanges) return
|
|
4253
|
+
if (listTrackedChanges) return runUiTrackedChangesCatalogRead(() => tcApi?.list?.());
|
|
4051
4254
|
return tcApi?.list ? tcApi.list({ in: "all" }) : void 0;
|
|
4052
4255
|
}, (raw) => raw && Array.isArray(raw.items) ? raw.items : []);
|
|
4053
4256
|
const items = (value ?? []).map(projectTrackChangesItem).filter((item) => item != null).filter((item) => {
|
|
@@ -4070,7 +4273,7 @@ function createSuperDocUI(options) {
|
|
|
4070
4273
|
}
|
|
4071
4274
|
const publicIdItems = allStoryItems ?? items;
|
|
4072
4275
|
const selectionIdContext = buildStoryScopedTrackedChangeIdContext(publicIdItems, selectionStory(selection$1));
|
|
4073
|
-
const selectionActiveChangeIds = postDecisionIds ? selection$1.activeChangeIds.filter((id) => !postDecisionIds.has(id)) : selection$1.activeChangeIds;
|
|
4276
|
+
const selectionActiveChangeIds = allTrackedChangesResolvedToken === token ? [] : postDecisionIds ? selection$1.activeChangeIds.filter((id) => !postDecisionIds.has(id)) : selection$1.activeChangeIds;
|
|
4074
4277
|
const selectionPublicChangeIds = selectionActiveChangeIds.map((id) => selectionIdContext.toPublicId(id) ?? id);
|
|
4075
4278
|
const explicitActiveIdContext = explicitActiveChange?.story ? buildStoryScopedTrackedChangeIdContext(publicIdItems, explicitActiveChange.story) : buildTrackedChangeIdContext(publicIdItems);
|
|
4076
4279
|
const explicitActiveId = explicitActiveChange ? explicitActiveIdContext.toPublicId(explicitActiveChange.id) ?? explicitActiveChange.id : null;
|
|
@@ -5833,6 +6036,20 @@ function createSuperDocUI(options) {
|
|
|
5833
6036
|
try {
|
|
5834
6037
|
const off = next.subscribe((event) => {
|
|
5835
6038
|
const type = event?.type;
|
|
6039
|
+
if (type === "review-mutation:started") {
|
|
6040
|
+
beginUiReviewMutation(event.reviewMutation?.token);
|
|
6041
|
+
return;
|
|
6042
|
+
}
|
|
6043
|
+
if (type === "review-mutation:aborted") {
|
|
6044
|
+
settleUiReviewMutation(event.reviewMutation?.token);
|
|
6045
|
+
scheduleAsyncRefresh();
|
|
6046
|
+
return;
|
|
6047
|
+
}
|
|
6048
|
+
if (type === "mutation:rejected" && event.reviewMutation) {
|
|
6049
|
+
settleUiReviewMutation(event.reviewMutation.token);
|
|
6050
|
+
scheduleAsyncRefresh();
|
|
6051
|
+
}
|
|
6052
|
+
if (type === "mutation:committed" && event.reviewMutation) settleUiReviewMutation(event.reviewMutation.token);
|
|
5836
6053
|
if (type === "source:complete" || type === "source:signals-complete") {
|
|
5837
6054
|
if (authoritativeTrackChangesPendingToken !== null) {
|
|
5838
6055
|
clearAuthoritativeTrackChangesRetry();
|
|
@@ -5848,6 +6065,13 @@ function createSuperDocUI(options) {
|
|
|
5848
6065
|
if (type === "mutation:committed" || type === "save:completed" || type === "collaboration:remote-changed") {
|
|
5849
6066
|
const impact = type === "mutation:committed" ? getV2TrackedChangeMutationImpact(event) : null;
|
|
5850
6067
|
const supersedesPendingReviewReconcile = type === "mutation:committed" && reviewMutationReconciler.getPendingIds().size > 0;
|
|
6068
|
+
if (impact?.allResolved) {
|
|
6069
|
+
reviewMutationReconciler.reset();
|
|
6070
|
+
replaceTrackedChangeItemsInCache([]);
|
|
6071
|
+
authoritativeTrackChangesPendingToken = null;
|
|
6072
|
+
publishAllTrackedChangesResolved(event.receipt);
|
|
6073
|
+
return;
|
|
6074
|
+
}
|
|
5851
6075
|
if (impact?.removedIds.size) markPostDecisionTrackChanges(new Set(impact.removedIds), event.receipt);
|
|
5852
6076
|
const authoritativeHistoryImpact = impact?.reconcileMode === "authoritative" && impact.upsertIds.size > 0;
|
|
5853
6077
|
if (authoritativeHistoryImpact) {
|
|
@@ -6081,7 +6305,7 @@ function createSuperDocUI(options) {
|
|
|
6081
6305
|
}
|
|
6082
6306
|
function resolveTrackDecisionTarget(command, payload) {
|
|
6083
6307
|
if (command.scope === "all") return {
|
|
6084
|
-
target: {
|
|
6308
|
+
target: { kind: "all" },
|
|
6085
6309
|
changeId: null
|
|
6086
6310
|
};
|
|
6087
6311
|
if (typeof payload === "string" && payload.length > 0) return {
|
|
@@ -6327,13 +6551,11 @@ function createSuperDocUI(options) {
|
|
|
6327
6551
|
};
|
|
6328
6552
|
const finalizeCommandSettlement = (promise, onSettled) => promise.then((settled) => {
|
|
6329
6553
|
onSettled?.(settled);
|
|
6330
|
-
|
|
6331
|
-
recompute();
|
|
6554
|
+
invalidateAfterCommandSettlement();
|
|
6332
6555
|
return settled;
|
|
6333
6556
|
}, () => {
|
|
6334
6557
|
onSettled?.(false);
|
|
6335
|
-
|
|
6336
|
-
recompute();
|
|
6558
|
+
invalidateAfterCommandSettlement();
|
|
6337
6559
|
return false;
|
|
6338
6560
|
});
|
|
6339
6561
|
const settleCommandExecution = (result, onSettled) => {
|
|
@@ -6356,8 +6578,7 @@ function createSuperDocUI(options) {
|
|
|
6356
6578
|
}
|
|
6357
6579
|
onSettled?.(settled);
|
|
6358
6580
|
lastCommandSettlement = Promise.resolve(settled);
|
|
6359
|
-
|
|
6360
|
-
recompute();
|
|
6581
|
+
invalidateAfterCommandSettlement();
|
|
6361
6582
|
return settled;
|
|
6362
6583
|
};
|
|
6363
6584
|
const normalizeWorkflowReceipt = (value, fallback) => {
|
|
@@ -7953,8 +8174,8 @@ function createSuperDocUI(options) {
|
|
|
7953
8174
|
},
|
|
7954
8175
|
accept: (changeId) => executeTrackDecision("accept", changeId),
|
|
7955
8176
|
reject: (changeId) => executeTrackDecision("reject", changeId),
|
|
7956
|
-
acceptAll: () => executeTrackDecisionTarget("accept", {
|
|
7957
|
-
rejectAll: () => executeTrackDecisionTarget("reject", {
|
|
8177
|
+
acceptAll: () => executeTrackDecisionTarget("accept", { kind: "all" }, null),
|
|
8178
|
+
rejectAll: () => executeTrackDecisionTarget("reject", { kind: "all" }, null),
|
|
7958
8179
|
next: () => navigateTrackChange(1),
|
|
7959
8180
|
previous: () => navigateTrackChange(-1),
|
|
7960
8181
|
navigateNext: () => navigateAndScroll(1),
|
|
@@ -8108,7 +8329,7 @@ function createSuperDocUI(options) {
|
|
|
8108
8329
|
const callTrackDecisionTarget = (kind, target, changeId, story) => {
|
|
8109
8330
|
if (reviewMutationsAreReadOnly()) return false;
|
|
8110
8331
|
const tcApi = getDoc()?.trackChanges;
|
|
8111
|
-
const isAllTarget = target.scope === "all";
|
|
8332
|
+
const isAllTarget = target.kind === "all" || target.scope === "all";
|
|
8112
8333
|
const isRangeTarget = target.kind === "range";
|
|
8113
8334
|
const isMultiIdTarget = target.kind === "ids";
|
|
8114
8335
|
if (bulkTrackDecisionBlockedReason({
|
|
@@ -9158,6 +9379,7 @@ function createSuperDocUI(options) {
|
|
|
9158
9379
|
const destroy = () => {
|
|
9159
9380
|
if (disposed) return;
|
|
9160
9381
|
disposed = true;
|
|
9382
|
+
releaseSharedUiTrackedChangesCatalog(uiTrackedChangesCatalogHost, uiTrackedChangesCatalogState);
|
|
9161
9383
|
reviewMutationReconciler.reset();
|
|
9162
9384
|
clearAuthoritativeTrackChangesRetry();
|
|
9163
9385
|
if (foregroundAsyncRetryTimer) {
|
|
@@ -7,7 +7,7 @@ const COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
|
|
|
7
7
|
var PRIVATE_ENGINE_INFO = (0, __superdoc_docx_engine_collaboration_upgrade_engine.getCollaborationUpgradeEngineInfo)();
|
|
8
8
|
var ENGINE_INFO = Object.freeze({
|
|
9
9
|
...PRIVATE_ENGINE_INFO,
|
|
10
|
-
superdocVersion: "2.4.0-next.
|
|
10
|
+
superdocVersion: "2.4.0-next.4",
|
|
11
11
|
roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
|
|
12
12
|
supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
|
|
13
13
|
supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
|
|
@@ -6,7 +6,7 @@ const COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
|
|
|
6
6
|
var PRIVATE_ENGINE_INFO = getCollaborationUpgradeEngineInfo$1();
|
|
7
7
|
var ENGINE_INFO = Object.freeze({
|
|
8
8
|
...PRIVATE_ENGINE_INFO,
|
|
9
|
-
superdocVersion: "2.4.0-next.
|
|
9
|
+
superdocVersion: "2.4.0-next.4",
|
|
10
10
|
roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
|
|
11
11
|
supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
|
|
12
12
|
supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
|
package/dist/public/ui-react.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("../chunks/rolldown-runtime-1Y-nnZJ3.cjs");
|
|
3
|
-
const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-
|
|
3
|
+
const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-BHMQEL2y.cjs");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
var SuperDocUIContext = (0, react.createContext)(null);
|
|
6
6
|
function disposeOwnedUi(ref) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createSuperDocUI } from "../chunks/create-super-doc-ui-
|
|
1
|
+
import { t as createSuperDocUI } from "../chunks/create-super-doc-ui-Dli6Wq70.es.js";
|
|
2
2
|
import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
3
|
var SuperDocUIContext = createContext(null);
|
|
4
4
|
function disposeOwnedUi(ref) {
|
package/dist/public/ui.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-
|
|
2
|
+
const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-BHMQEL2y.cjs");
|
|
3
3
|
exports.BUILT_IN_COMMAND_IDS = require_create_super_doc_ui.BUILT_IN_COMMAND_IDS;
|
|
4
4
|
exports.createSuperDocUI = require_create_super_doc_ui.createSuperDocUI;
|
|
5
5
|
exports.shallowEqual = require_create_super_doc_ui.shallowEqual;
|
package/dist/public/ui.es.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as shallowEqual, r as BUILT_IN_COMMAND_IDS, t as createSuperDocUI } from "../chunks/create-super-doc-ui-
|
|
1
|
+
import { n as shallowEqual, r as BUILT_IN_COMMAND_IDS, t as createSuperDocUI } from "../chunks/create-super-doc-ui-Dli6Wq70.es.js";
|
|
2
2
|
export { BUILT_IN_COMMAND_IDS, createSuperDocUI, shallowEqual };
|