superdoc 2.18.0-next.9 → 2.18.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/dist/chunks/{create-super-doc-ui-D9JWPXRh.cjs → create-super-doc-ui-wDvhW9Tz.cjs} +996 -912
- package/dist/chunks/{create-super-doc-ui-qTSa0PbD.es.js → create-super-doc-ui-wKzxrztu.es.js} +982 -910
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/diff/diff.types.d.ts +1 -1
- package/dist/document-api/src/images/images.types.d.ts +2 -0
- package/dist/document-api/src/types/clipboard.d.ts +24 -1
- package/dist/layout-engine/contracts/src/index.d.ts +4 -0
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui-vue.cjs +1 -1
- package/dist/public/ui-vue.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +22 -22
- package/dist/style.layered.css +22 -22
- package/dist/superdoc/src/core/SuperDoc.d.ts +10 -3
- package/dist/superdoc/src/core/types/index.d.ts +37 -0
- package/dist/superdoc/src/internal/toolbar/built-in/LinkInput.vue.d.ts +4 -4
- package/dist/superdoc/src/public/index.d.cts +10 -0
- package/dist/superdoc/src/public/index.d.ts +5 -0
- package/dist/superdoc/src/public/ui/create-super-doc-ui.d.ts +9 -1
- package/dist/superdoc.cjs +232 -104
- package/dist/superdoc.es.js +232 -104
- 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/superdoc.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
|
|
2
2
|
import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as applyV2CommentInvalidationFromMutation, c as DOM_CLASS_NAMES, d as recordInteraction, l as closeInteractionHistory, n as executeFirstPartyCommandAsync, o as getV2TrackedChangeMutationImpact, r as registerFirstPartyCommandMutation, t as createSuperDocUI, u as createInteractionHistory } from "./chunks/create-super-doc-ui-wKzxrztu.es.js";
|
|
4
4
|
import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
|
|
5
5
|
import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
|
|
6
6
|
import { a as init_dist$1, i as global, n as init_dist$2, o as Buffer, r as process$1, s as init_dist, t as require_jszip_min } from "./chunks/jszip-BzJ3CyxR.es.js";
|
|
@@ -315,7 +315,7 @@ var shuffleArray = (array) => {
|
|
|
315
315
|
var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
|
|
316
316
|
function getSuperdocVersion() {
|
|
317
317
|
try {
|
|
318
|
-
return "2.18.0
|
|
318
|
+
return "2.18.0";
|
|
319
319
|
} catch {
|
|
320
320
|
return "unknown";
|
|
321
321
|
}
|
|
@@ -14970,6 +14970,79 @@ function useViewportFit({ getSuperdoc, superdocContainerWidth, isReady, activeZo
|
|
|
14970
14970
|
return { evaluateViewport };
|
|
14971
14971
|
}
|
|
14972
14972
|
//#endregion
|
|
14973
|
+
//#region ../layout-engine/contracts/src/author-colors.ts
|
|
14974
|
+
/**
|
|
14975
|
+
* Curated, high-contrast fallback palette. Used when neither `overrides` nor
|
|
14976
|
+
* `resolve` produces a color so imported/discovered authors the host did not
|
|
14977
|
+
* configure ahead of time still get a stable, distinct color.
|
|
14978
|
+
*/
|
|
14979
|
+
var FALLBACK_PALETTE = [
|
|
14980
|
+
"#1f6feb",
|
|
14981
|
+
"#d1242f",
|
|
14982
|
+
"#8250df",
|
|
14983
|
+
"#bf3989",
|
|
14984
|
+
"#1a7f37",
|
|
14985
|
+
"#9a6700",
|
|
14986
|
+
"#bc4c00",
|
|
14987
|
+
"#0969da",
|
|
14988
|
+
"#cf222e",
|
|
14989
|
+
"#6639ba",
|
|
14990
|
+
"#116329",
|
|
14991
|
+
"#7d4e00"
|
|
14992
|
+
];
|
|
14993
|
+
/** Stable identity string for an author (used for hashing + dedupe). */
|
|
14994
|
+
var authorIdentityKey = (author) => {
|
|
14995
|
+
if (!author) return "";
|
|
14996
|
+
return `${typeof author.name === "string" ? author.name : ""} ${typeof author.email === "string" ? author.email : ""}`;
|
|
14997
|
+
};
|
|
14998
|
+
/** Deterministic 32-bit FNV-1a hash of a string. */
|
|
14999
|
+
var hashString = (value) => {
|
|
15000
|
+
let hash = 2166136261;
|
|
15001
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
15002
|
+
hash ^= value.charCodeAt(i);
|
|
15003
|
+
hash = Math.imul(hash, 16777619);
|
|
15004
|
+
}
|
|
15005
|
+
return hash >>> 0;
|
|
15006
|
+
};
|
|
15007
|
+
/**
|
|
15008
|
+
* Deterministic fallback color derived from the author identity. The same
|
|
15009
|
+
* identity always maps to the same palette entry, so colors stay stable across
|
|
15010
|
+
* reloads and across the paint / snapshot surfaces.
|
|
15011
|
+
*/
|
|
15012
|
+
var fallbackAuthorColor = (author) => {
|
|
15013
|
+
return FALLBACK_PALETTE[hashString(authorIdentityKey(author)) % FALLBACK_PALETTE.length];
|
|
15014
|
+
};
|
|
15015
|
+
var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
15016
|
+
/**
|
|
15017
|
+
* Composes the host `authorColors` config into a single resolver.
|
|
15018
|
+
*
|
|
15019
|
+
* Resolution order per author:
|
|
15020
|
+
* 1. `overrides` by identity — `email` first, then `name` (exact match).
|
|
15021
|
+
* 2. `resolve(author)`.
|
|
15022
|
+
* 3. A deterministic fallback color from the author identity.
|
|
15023
|
+
*
|
|
15024
|
+
* Returns `undefined` when colors are disabled (`enabled === false`) or no
|
|
15025
|
+
* config was provided, so callers can leave the existing default palette in
|
|
15026
|
+
* place by simply not threading a resolver.
|
|
15027
|
+
*/
|
|
15028
|
+
var composeAuthorColorResolver = (config) => {
|
|
15029
|
+
if (!config || config.enabled === false) return void 0;
|
|
15030
|
+
const overrides = config.overrides && typeof config.overrides === "object" ? config.overrides : void 0;
|
|
15031
|
+
const resolve = typeof config.resolve === "function" ? config.resolve : void 0;
|
|
15032
|
+
return (author) => {
|
|
15033
|
+
const safeAuthor = author ?? {};
|
|
15034
|
+
if (overrides) {
|
|
15035
|
+
if (isNonEmptyString(safeAuthor.email) && isNonEmptyString(overrides[safeAuthor.email])) return overrides[safeAuthor.email];
|
|
15036
|
+
if (isNonEmptyString(safeAuthor.name) && isNonEmptyString(overrides[safeAuthor.name])) return overrides[safeAuthor.name];
|
|
15037
|
+
}
|
|
15038
|
+
if (resolve) try {
|
|
15039
|
+
const resolved = resolve(safeAuthor);
|
|
15040
|
+
if (isNonEmptyString(resolved)) return resolved;
|
|
15041
|
+
} catch {}
|
|
15042
|
+
return fallbackAuthorColor(safeAuthor);
|
|
15043
|
+
};
|
|
15044
|
+
};
|
|
15045
|
+
//#endregion
|
|
14973
15046
|
//#region src/components/CommentsLayer/floating-comment-positioning.js
|
|
14974
15047
|
var isPersistentReviewSidebarItem = (comment) => {
|
|
14975
15048
|
return Boolean(comment?.trackedChange);
|
|
@@ -16378,79 +16451,6 @@ var WhiteboardLayer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
16378
16451
|
}
|
|
16379
16452
|
}, [["__scopeId", "data-v-54546c3d"]]);
|
|
16380
16453
|
//#endregion
|
|
16381
|
-
//#region ../layout-engine/contracts/src/author-colors.ts
|
|
16382
|
-
/**
|
|
16383
|
-
* Curated, high-contrast fallback palette. Used when neither `overrides` nor
|
|
16384
|
-
* `resolve` produces a color so imported/discovered authors the host did not
|
|
16385
|
-
* configure ahead of time still get a stable, distinct color.
|
|
16386
|
-
*/
|
|
16387
|
-
var FALLBACK_PALETTE = [
|
|
16388
|
-
"#1f6feb",
|
|
16389
|
-
"#d1242f",
|
|
16390
|
-
"#8250df",
|
|
16391
|
-
"#bf3989",
|
|
16392
|
-
"#1a7f37",
|
|
16393
|
-
"#9a6700",
|
|
16394
|
-
"#bc4c00",
|
|
16395
|
-
"#0969da",
|
|
16396
|
-
"#cf222e",
|
|
16397
|
-
"#6639ba",
|
|
16398
|
-
"#116329",
|
|
16399
|
-
"#7d4e00"
|
|
16400
|
-
];
|
|
16401
|
-
/** Stable identity string for an author (used for hashing + dedupe). */
|
|
16402
|
-
var authorIdentityKey = (author) => {
|
|
16403
|
-
if (!author) return "";
|
|
16404
|
-
return `${typeof author.name === "string" ? author.name : ""} ${typeof author.email === "string" ? author.email : ""}`;
|
|
16405
|
-
};
|
|
16406
|
-
/** Deterministic 32-bit FNV-1a hash of a string. */
|
|
16407
|
-
var hashString = (value) => {
|
|
16408
|
-
let hash = 2166136261;
|
|
16409
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
16410
|
-
hash ^= value.charCodeAt(i);
|
|
16411
|
-
hash = Math.imul(hash, 16777619);
|
|
16412
|
-
}
|
|
16413
|
-
return hash >>> 0;
|
|
16414
|
-
};
|
|
16415
|
-
/**
|
|
16416
|
-
* Deterministic fallback color derived from the author identity. The same
|
|
16417
|
-
* identity always maps to the same palette entry, so colors stay stable across
|
|
16418
|
-
* reloads and across the paint / snapshot surfaces.
|
|
16419
|
-
*/
|
|
16420
|
-
var fallbackAuthorColor = (author) => {
|
|
16421
|
-
return FALLBACK_PALETTE[hashString(authorIdentityKey(author)) % FALLBACK_PALETTE.length];
|
|
16422
|
-
};
|
|
16423
|
-
var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
16424
|
-
/**
|
|
16425
|
-
* Composes the host `authorColors` config into a single resolver.
|
|
16426
|
-
*
|
|
16427
|
-
* Resolution order per author:
|
|
16428
|
-
* 1. `overrides` by identity — `email` first, then `name` (exact match).
|
|
16429
|
-
* 2. `resolve(author)`.
|
|
16430
|
-
* 3. A deterministic fallback color from the author identity.
|
|
16431
|
-
*
|
|
16432
|
-
* Returns `undefined` when colors are disabled (`enabled === false`) or no
|
|
16433
|
-
* config was provided, so callers can leave the existing default palette in
|
|
16434
|
-
* place by simply not threading a resolver.
|
|
16435
|
-
*/
|
|
16436
|
-
var composeAuthorColorResolver = (config) => {
|
|
16437
|
-
if (!config || config.enabled === false) return void 0;
|
|
16438
|
-
const overrides = config.overrides && typeof config.overrides === "object" ? config.overrides : void 0;
|
|
16439
|
-
const resolve = typeof config.resolve === "function" ? config.resolve : void 0;
|
|
16440
|
-
return (author) => {
|
|
16441
|
-
const safeAuthor = author ?? {};
|
|
16442
|
-
if (overrides) {
|
|
16443
|
-
if (isNonEmptyString(safeAuthor.email) && isNonEmptyString(overrides[safeAuthor.email])) return overrides[safeAuthor.email];
|
|
16444
|
-
if (isNonEmptyString(safeAuthor.name) && isNonEmptyString(overrides[safeAuthor.name])) return overrides[safeAuthor.name];
|
|
16445
|
-
}
|
|
16446
|
-
if (resolve) try {
|
|
16447
|
-
const resolved = resolve(safeAuthor);
|
|
16448
|
-
if (isNonEmptyString(resolved)) return resolved;
|
|
16449
|
-
} catch {}
|
|
16450
|
-
return fallbackAuthorColor(safeAuthor);
|
|
16451
|
-
};
|
|
16452
|
-
};
|
|
16453
|
-
//#endregion
|
|
16454
16454
|
//#region src/components/HtmlViewer/HtmlViewer.vue
|
|
16455
16455
|
var _hoisted_1$20 = { class: "superdoc-html-viewer" };
|
|
16456
16456
|
var _hoisted_2$16 = { class: "superdoc-html-viewer__document" };
|
|
@@ -22131,7 +22131,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
22131
22131
|
executeAsync: (commandId, payload) => {
|
|
22132
22132
|
const ui = getSuperDocUI();
|
|
22133
22133
|
if (!ui) return Promise.resolve(UNAVAILABLE_COMMAND_RESULT);
|
|
22134
|
-
return ui
|
|
22134
|
+
return executeFirstPartyCommandAsync(ui, commandId, payload);
|
|
22135
22135
|
},
|
|
22136
22136
|
getState: (commandId) => getSuperDocUI()?.commands.get(commandId).getState() ?? UNAVAILABLE_COMMAND_STATE
|
|
22137
22137
|
},
|
|
@@ -22332,7 +22332,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
22332
22332
|
if (!payload) return;
|
|
22333
22333
|
clearV2EditorFailure(payload.documentId ?? null);
|
|
22334
22334
|
clearV2MutationRejectionNotifications(payload.documentId ?? null);
|
|
22335
|
-
const { host, mount, documentId, capabilities, editCommands, bindEditShortcuts, bindSessionShortcuts, commentsAdapter, trackedChangesAdapter, contextMenu, documentApi, documentMutationReadiness, documentApiUnavailableReason, pageMetrics, pageLayout, pageFurniture, presence, lock, collaborationProvider, fonts, replaceFile, upgradeToCollaboration, documentOpenToken } = payload;
|
|
22335
|
+
const { host, firstPartyCommandMutation, mount, documentId, capabilities, editCommands, bindEditShortcuts, bindSessionShortcuts, commentsAdapter, trackedChangesAdapter, contextMenu, documentApi, documentMutationReadiness, documentApiUnavailableReason, pageMetrics, pageLayout, pageFurniture, presence, lock, connection, collaborationProvider, fonts, replaceFile, upgradeToCollaboration, documentOpenToken } = payload;
|
|
22336
22336
|
documentOpenTelemetry?.trackDocumentOpen(documentOpenToken ?? null, documentId ?? null);
|
|
22337
22337
|
const saveV2Bytes = createV2SaveQueue(async (saveOptions = {}) => {
|
|
22338
22338
|
if (!host || typeof host.save !== "function") throw new Error("v2-editor: save unavailable");
|
|
@@ -22609,6 +22609,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
22609
22609
|
pageFurniture: pageFurniture ?? null,
|
|
22610
22610
|
presence: presence ?? null,
|
|
22611
22611
|
lock: lock ?? null,
|
|
22612
|
+
connection: connection ?? null,
|
|
22612
22613
|
provider: collaborationProvider ?? null,
|
|
22613
22614
|
reviewWindow: {
|
|
22614
22615
|
getDiagnostics: () => v2ReviewWindowController.getDiagnostics(),
|
|
@@ -22647,6 +22648,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
22647
22648
|
if (doc) doc.provider = provider;
|
|
22648
22649
|
}
|
|
22649
22650
|
proxy.$superdoc.broadcastEditorCreate(facade);
|
|
22651
|
+
if (host && firstPartyCommandMutation) registerFirstPartyCommandMutation(proxy.$superdoc, host, firstPartyCommandMutation);
|
|
22650
22652
|
installV2CommandShortcutBinding({
|
|
22651
22653
|
documentId,
|
|
22652
22654
|
bindEditShortcuts
|
|
@@ -23207,7 +23209,8 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
23207
23209
|
case "collaboration-room-corrupt": return "SuperDoc v2 found a structurally invalid collaboration room. No changes were made.";
|
|
23208
23210
|
case "collaboration-v2-room-missing": return "SuperDoc v2 could not find a committed v2 collaboration room. No changes were made. Use roomMode: \"create\" only when creating a new room.";
|
|
23209
23211
|
case "collaboration-v2-room-already-exists": return "SuperDoc v2 was asked to create a collaboration room that already exists. Use roomMode: \"join\" to open it.";
|
|
23210
|
-
case "collaboration-v2-room-initializing": return "The SuperDoc v2 collaboration room
|
|
23212
|
+
case "collaboration-v2-room-initializing": return "The SuperDoc v2 collaboration room has not completed initialization. This open attempt did not modify it.";
|
|
23213
|
+
case "collaboration-v2-room-bootstrap-stalled": return "The SuperDoc v2 collaboration room bootstrap appears stalled. This open attempt did not modify it. Preserve the room data if a create retry cannot recover it.";
|
|
23211
23214
|
case "collaboration-open-intent-invalid": return "SuperDoc v2 received an invalid collaboration room mode. No provider was connected.";
|
|
23212
23215
|
case "collaboration-config-invalid": return "SuperDoc v2 received an invalid collaboration configuration. No provider was connected.";
|
|
23213
23216
|
default: return "SuperDoc could not load the document editor.";
|
|
@@ -23234,7 +23237,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
23234
23237
|
...workerFailure ? { workerFailure } : {},
|
|
23235
23238
|
reason
|
|
23236
23239
|
};
|
|
23237
|
-
if (reason === "collaboration-v1-config-unsupported" || reason === "collaboration-room-format-unsupported" || reason === "collaboration-room-format-conflict" || reason === "collaboration-room-corrupt" || reason === "collaboration-v2-room-missing" || reason === "collaboration-v2-room-already-exists" || reason === "collaboration-v2-room-initializing" || reason === "collaboration-open-intent-invalid" || reason === "collaboration-config-invalid") console.warn(`[SuperDoc] ${message}`, logContext);
|
|
23240
|
+
if (reason === "collaboration-v1-config-unsupported" || reason === "collaboration-room-format-unsupported" || reason === "collaboration-room-format-conflict" || reason === "collaboration-room-corrupt" || reason === "collaboration-v2-room-missing" || reason === "collaboration-v2-room-already-exists" || reason === "collaboration-v2-room-initializing" || reason === "collaboration-v2-room-bootstrap-stalled" || reason === "collaboration-open-intent-invalid" || reason === "collaboration-config-invalid") console.warn(`[SuperDoc] ${message}`, logContext);
|
|
23238
23241
|
else console.error(`[SuperDoc] ${message}`, logContext);
|
|
23239
23242
|
proxy.$superdoc.emit("exception", collaborationException ?? {
|
|
23240
23243
|
error: new Error(message),
|
|
@@ -24454,7 +24457,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
|
|
|
24454
24457
|
], 38);
|
|
24455
24458
|
};
|
|
24456
24459
|
}
|
|
24457
|
-
}, [["__scopeId", "data-v-
|
|
24460
|
+
}, [["__scopeId", "data-v-77e0209a"]]);
|
|
24458
24461
|
//#endregion
|
|
24459
24462
|
//#region src/core/create-app.js
|
|
24460
24463
|
var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
|
|
@@ -44298,7 +44301,7 @@ function executeCommand(ui, commandId, argument, options = {}) {
|
|
|
44298
44301
|
if (typeof ui.commands.has === "function" && !ui.commands.has(commandId)) return false;
|
|
44299
44302
|
const execute = typeof ui.commands.executeAsync === "function" ? ui.commands.executeAsync : ui.commands.execute;
|
|
44300
44303
|
if (typeof execute !== "function") return false;
|
|
44301
|
-
const result = argument === void 0 ? execute.call(ui.commands, commandId) : execute.call(ui.commands, commandId, argument);
|
|
44304
|
+
const result = options.firstParty ? executeFirstPartyCommandAsync(ui, commandId, argument) : argument === void 0 ? execute.call(ui.commands, commandId) : execute.call(ui.commands, commandId, argument);
|
|
44302
44305
|
const reportFailure = (settled) => {
|
|
44303
44306
|
if (!options.reportUnhandled || settled !== false) return;
|
|
44304
44307
|
options.onError?.(/* @__PURE__ */ new Error(`[superdoc toolbar] Command "${commandId}" did not run. Check that it is enabled and has the required input.`));
|
|
@@ -44946,6 +44949,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
44946
44949
|
const name = item?.name?.value;
|
|
44947
44950
|
if (!name) return false;
|
|
44948
44951
|
const callbacks = {
|
|
44952
|
+
firstParty: true,
|
|
44949
44953
|
onSettled: () => this.updateToolbarState(),
|
|
44950
44954
|
onError: (error) => this.#emitCommandException(error, name)
|
|
44951
44955
|
};
|
|
@@ -44974,6 +44978,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
44974
44978
|
onPick: async (file) => {
|
|
44975
44979
|
const src = await resolveImageSrc(file, this.superdoc?.config?.handleImageUpload);
|
|
44976
44980
|
executeCommand(this.ui, "image", { src }, {
|
|
44981
|
+
firstParty: true,
|
|
44977
44982
|
onSettled: () => this.updateToolbarState(),
|
|
44978
44983
|
onError: (error) => this.#emitCommandException(error, "image")
|
|
44979
44984
|
});
|
|
@@ -45301,6 +45306,14 @@ function contentControlSelectionKey(selection) {
|
|
|
45301
45306
|
return null;
|
|
45302
45307
|
}
|
|
45303
45308
|
}
|
|
45309
|
+
function deriveCollaborationConnectionKind(snapshot, hasSyncedBefore) {
|
|
45310
|
+
switch (snapshot.state) {
|
|
45311
|
+
case "failed": return "failed";
|
|
45312
|
+
case "degraded": return snapshot.detail === "reconnecting" ? "reconnecting" : "lost";
|
|
45313
|
+
case "synced": return hasSyncedBefore ? "recovered" : "initial";
|
|
45314
|
+
default: return hasSyncedBefore ? "reconnecting" : "initial";
|
|
45315
|
+
}
|
|
45316
|
+
}
|
|
45304
45317
|
function isV2ActiveEditorFacade(editor) {
|
|
45305
45318
|
return Boolean(editor && typeof editor === "object" && editor.editorVersion === 2);
|
|
45306
45319
|
}
|
|
@@ -45357,6 +45370,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
45357
45370
|
#destroyed;
|
|
45358
45371
|
#diagnostics;
|
|
45359
45372
|
#isUpgrading;
|
|
45373
|
+
#pendingUpgrade;
|
|
45360
45374
|
/** Aborts an in-flight upgrade (sync wait or ready wait). */
|
|
45361
45375
|
#abortUpgrade;
|
|
45362
45376
|
/**
|
|
@@ -45368,6 +45382,12 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
45368
45382
|
#v2AwarenessUnsub;
|
|
45369
45383
|
/** Unsubscribe handle for the v2 root-doc lock observer. */
|
|
45370
45384
|
#v2LockUnsub;
|
|
45385
|
+
/** Unsubscribe handle for the v2 collaboration connection observer. */
|
|
45386
|
+
#v2ConnectionUnsub;
|
|
45387
|
+
/** Latest `collaboration-connection-change` payload, for late readers. */
|
|
45388
|
+
#v2ConnectionState;
|
|
45389
|
+
/** Whether the current collaboration room has completed a sync at least once. */
|
|
45390
|
+
#v2ConnectionHasSynced;
|
|
45371
45391
|
/** Lock state captured before a local → v2 collaboration promotion remount. */
|
|
45372
45392
|
#pendingV2LockSeed;
|
|
45373
45393
|
#mountWrapper;
|
|
@@ -45456,9 +45476,13 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
45456
45476
|
super();
|
|
45457
45477
|
this.#destroyed = false;
|
|
45458
45478
|
this.#isUpgrading = false;
|
|
45479
|
+
this.#pendingUpgrade = null;
|
|
45459
45480
|
this.#abortUpgrade = null;
|
|
45460
45481
|
this.#v2AwarenessUnsub = null;
|
|
45461
45482
|
this.#v2LockUnsub = null;
|
|
45483
|
+
this.#v2ConnectionUnsub = null;
|
|
45484
|
+
this.#v2ConnectionState = null;
|
|
45485
|
+
this.#v2ConnectionHasSynced = false;
|
|
45462
45486
|
this.#pendingV2LockSeed = null;
|
|
45463
45487
|
this.#mountWrapper = null;
|
|
45464
45488
|
this.#contentControlClickRoot = null;
|
|
@@ -45657,7 +45681,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
45657
45681
|
this.config.colors = shuffleArray(this.config.colors);
|
|
45658
45682
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
45659
45683
|
this.colorIndex = 0;
|
|
45660
|
-
this.version = "2.18.0
|
|
45684
|
+
this.version = "2.18.0";
|
|
45661
45685
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
45662
45686
|
this.superdocId = config.superdocId || v4();
|
|
45663
45687
|
this.colors = this.config.colors ?? [];
|
|
@@ -45759,7 +45783,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
45759
45783
|
return this.#diagnostics;
|
|
45760
45784
|
}
|
|
45761
45785
|
emit(event, ...args) {
|
|
45762
|
-
if (event === "exception" || event === "document-replaced" || event === "ready" || event === "active-editor-change" || event === "collaboration-ready" || event === "locked") recordInteraction(this, event, () => args[0]);
|
|
45786
|
+
if (event === "exception" || event === "document-replaced" || event === "ready" || event === "active-editor-change" || event === "collaboration-ready" || event === "collaboration-connection-change" || event === "locked") recordInteraction(this, event, () => args[0]);
|
|
45763
45787
|
return super.emit(event, ...args);
|
|
45764
45788
|
}
|
|
45765
45789
|
on(event, fn, context) {
|
|
@@ -46001,6 +46025,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
46001
46025
|
this.#onConfig("pdf:document-ready", this.config.onPdfDocumentReady);
|
|
46002
46026
|
this.#onConfig("sidebar-toggle", this.config.onSidebarToggle);
|
|
46003
46027
|
this.#onConfig("collaboration-ready", this.config.onCollaborationReady);
|
|
46028
|
+
this.#onConfig("collaboration-connection-change", this.config.onCollaborationConnectionChange);
|
|
46004
46029
|
this.on("collaboration-ready", (payload) => this.#startV2CollaborationEventBridge(payload?.editor ?? null));
|
|
46005
46030
|
this.#onConfig("editor-update", this.config.onEditorUpdate);
|
|
46006
46031
|
this.#onConfig("tracked-changes:bulk-decision", this.config.onTrackedChangesBulkDecision);
|
|
@@ -46091,12 +46116,59 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
46091
46116
|
} catch {}
|
|
46092
46117
|
this.#v2LockUnsub = null;
|
|
46093
46118
|
}
|
|
46119
|
+
if (this.#v2ConnectionUnsub) {
|
|
46120
|
+
try {
|
|
46121
|
+
this.#v2ConnectionUnsub();
|
|
46122
|
+
} catch {}
|
|
46123
|
+
this.#v2ConnectionUnsub = null;
|
|
46124
|
+
}
|
|
46094
46125
|
}
|
|
46095
46126
|
#startV2CollaborationEventBridge(editor) {
|
|
46096
46127
|
this.#stopV2CollaborationEventBridge();
|
|
46097
46128
|
if (!isV2ActiveEditorFacade(editor)) return;
|
|
46098
46129
|
this.#startV2AwarenessBridge(editor);
|
|
46099
46130
|
this.#startV2LockBridge(editor);
|
|
46131
|
+
this.#startV2ConnectionBridge(editor);
|
|
46132
|
+
}
|
|
46133
|
+
#startV2ConnectionBridge(editor) {
|
|
46134
|
+
const connection = editor.connection;
|
|
46135
|
+
if (!connection || typeof connection.subscribe !== "function") return;
|
|
46136
|
+
const { documentId } = connection;
|
|
46137
|
+
if (this.#v2ConnectionState?.documentId !== documentId) {
|
|
46138
|
+
this.#v2ConnectionState = null;
|
|
46139
|
+
this.#v2ConnectionHasSynced = false;
|
|
46140
|
+
}
|
|
46141
|
+
const publish = (snapshot) => {
|
|
46142
|
+
if (this.#destroyed) return;
|
|
46143
|
+
const previous = this.#v2ConnectionState;
|
|
46144
|
+
if (previous && previous.state === snapshot.state && previous.detail === (snapshot.detail ?? null)) return;
|
|
46145
|
+
const payload = {
|
|
46146
|
+
documentId,
|
|
46147
|
+
state: snapshot.state,
|
|
46148
|
+
previousState: previous?.state ?? null,
|
|
46149
|
+
kind: deriveCollaborationConnectionKind(snapshot, this.#v2ConnectionHasSynced),
|
|
46150
|
+
detail: snapshot.detail ?? null,
|
|
46151
|
+
superdoc: this
|
|
46152
|
+
};
|
|
46153
|
+
this.#v2ConnectionState = payload;
|
|
46154
|
+
if (snapshot.state === "synced") this.#v2ConnectionHasSynced = true;
|
|
46155
|
+
this.emit("collaboration-connection-change", payload);
|
|
46156
|
+
};
|
|
46157
|
+
try {
|
|
46158
|
+
const initialSnapshot = connection.getSnapshot?.();
|
|
46159
|
+
if (initialSnapshot) publish(initialSnapshot);
|
|
46160
|
+
this.#v2ConnectionUnsub = connection.subscribe(publish);
|
|
46161
|
+
} catch (err) {
|
|
46162
|
+
console.warn("[SuperDoc] v2 connection bridge failed to subscribe", err);
|
|
46163
|
+
}
|
|
46164
|
+
}
|
|
46165
|
+
/**
|
|
46166
|
+
* Latest v2 collaboration connection change, or `null` when no v2
|
|
46167
|
+
* collaboration session has reported one. Same payload as the
|
|
46168
|
+
* `collaboration-connection-change` event.
|
|
46169
|
+
*/
|
|
46170
|
+
getCollaborationConnectionState() {
|
|
46171
|
+
return this.#v2ConnectionState;
|
|
46100
46172
|
}
|
|
46101
46173
|
#startV2AwarenessBridge(editor) {
|
|
46102
46174
|
const presence = editor.presence;
|
|
@@ -46184,29 +46256,78 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
46184
46256
|
* - A supported v2 single-doc `v2Collaboration` target
|
|
46185
46257
|
* - Create-and-upgrade only (no merge semantics)
|
|
46186
46258
|
*
|
|
46187
|
-
* @returns
|
|
46259
|
+
* @returns The attached room and document once the collaborative runtime is ready
|
|
46188
46260
|
*/
|
|
46189
46261
|
async upgradeToCollaboration(options) {
|
|
46262
|
+
if (this.#pendingUpgrade) {
|
|
46263
|
+
const { target } = this.#resolveCollaborationUpgradeTarget(options);
|
|
46264
|
+
if (this.#sameUpgradeTarget(target, this.#pendingUpgrade.target)) return this.#pendingUpgrade.promise;
|
|
46265
|
+
throw Object.assign(/* @__PURE__ */ new Error("SuperDoc: a different collaboration target is already upgrading"), { code: "collaboration-upgrade-target-conflict" });
|
|
46266
|
+
}
|
|
46190
46267
|
const { target } = this.#validateUpgradePrerequisites(options);
|
|
46191
46268
|
this.#isUpgrading = true;
|
|
46192
|
-
|
|
46193
|
-
const localSource = await this.#captureCurrentDocxSourceForUpgrade();
|
|
46194
|
-
const rollback = this.#snapshotV2UpgradeState();
|
|
46195
|
-
const lockSeed = this.#snapshotV2LockSeed();
|
|
46196
|
-
this.#assertNotDestroyed();
|
|
46269
|
+
const operation = (async () => {
|
|
46197
46270
|
try {
|
|
46198
|
-
|
|
46199
|
-
const
|
|
46200
|
-
this.#
|
|
46201
|
-
this.#
|
|
46202
|
-
|
|
46203
|
-
|
|
46204
|
-
|
|
46205
|
-
|
|
46206
|
-
|
|
46207
|
-
|
|
46208
|
-
|
|
46209
|
-
|
|
46271
|
+
const localSource = await this.#captureCurrentDocxSourceForUpgrade();
|
|
46272
|
+
const rollback = this.#snapshotV2UpgradeState();
|
|
46273
|
+
const lockSeed = this.#snapshotV2LockSeed();
|
|
46274
|
+
this.#assertNotDestroyed();
|
|
46275
|
+
try {
|
|
46276
|
+
this.#pendingV2LockSeed = lockSeed;
|
|
46277
|
+
const promotion = await this.#promoteSingleDocumentToV2Collaboration(target, localSource);
|
|
46278
|
+
this.#finalizeSingleDocumentV2Collaboration(promotion, target);
|
|
46279
|
+
this.#pendingV2LockSeed = null;
|
|
46280
|
+
const attachedDocumentId = this.activeEditor?.options?.documentId;
|
|
46281
|
+
const attachedRoomId = promotion.configDoc.v2Collaboration?.documentId;
|
|
46282
|
+
if (typeof attachedDocumentId !== "string" || attachedDocumentId !== promotion.configDoc.id || typeof attachedRoomId !== "string" || attachedRoomId !== target.documentId) throw new Error("SuperDoc: collaboration upgrade did not attach the expected room and document");
|
|
46283
|
+
return {
|
|
46284
|
+
roomId: attachedRoomId,
|
|
46285
|
+
documentId: attachedDocumentId
|
|
46286
|
+
};
|
|
46287
|
+
} catch (err) {
|
|
46288
|
+
this.#rollbackV2UpgradeState(rollback);
|
|
46289
|
+
throw err;
|
|
46290
|
+
}
|
|
46291
|
+
} finally {
|
|
46292
|
+
this.#abortUpgrade = null;
|
|
46293
|
+
this.#isUpgrading = false;
|
|
46294
|
+
this.#pendingUpgrade = null;
|
|
46295
|
+
}
|
|
46296
|
+
})();
|
|
46297
|
+
this.#pendingUpgrade = {
|
|
46298
|
+
target,
|
|
46299
|
+
promise: operation
|
|
46300
|
+
};
|
|
46301
|
+
return operation;
|
|
46302
|
+
}
|
|
46303
|
+
#sameUpgradeTarget(left, right) {
|
|
46304
|
+
if (left.token !== right.token) return false;
|
|
46305
|
+
const seen = /* @__PURE__ */ new WeakMap();
|
|
46306
|
+
const sameValue = (first, second) => {
|
|
46307
|
+
if (Object.is(first, second)) return true;
|
|
46308
|
+
if (!first || !second || typeof first !== "object" || typeof second !== "object") return false;
|
|
46309
|
+
if (Object.getPrototypeOf(first) !== Object.getPrototypeOf(second)) return false;
|
|
46310
|
+
if (seen.has(first)) return seen.get(first) === second;
|
|
46311
|
+
seen.set(first, second);
|
|
46312
|
+
if (first instanceof Date && second instanceof Date) return first.getTime() === second.getTime();
|
|
46313
|
+
if (first instanceof RegExp && second instanceof RegExp) return first.source === second.source && first.flags === second.flags;
|
|
46314
|
+
if (first instanceof ArrayBuffer && second instanceof ArrayBuffer) return sameValue(Array.from(new Uint8Array(first)), Array.from(new Uint8Array(second)));
|
|
46315
|
+
if (ArrayBuffer.isView(first) && ArrayBuffer.isView(second)) return first.constructor === second.constructor && sameValue(Array.from(new Uint8Array(first.buffer, first.byteOffset, first.byteLength)), Array.from(new Uint8Array(second.buffer, second.byteOffset, second.byteLength)));
|
|
46316
|
+
if (first instanceof Map && second instanceof Map) return first.size === second.size && sameValue(Array.from(first.entries()), Array.from(second.entries()));
|
|
46317
|
+
if (first instanceof Set && second instanceof Set) return first.size === second.size && sameValue(Array.from(first.values()), Array.from(second.values()));
|
|
46318
|
+
if (Array.isArray(first) && Array.isArray(second)) return first.length === second.length && first.every((value, index) => sameValue(value, second[index]));
|
|
46319
|
+
if (Object.getPrototypeOf(first) !== Object.prototype && Object.getPrototypeOf(first) !== null) return false;
|
|
46320
|
+
const keys = Object.keys(first).sort();
|
|
46321
|
+
const otherKeys = Object.keys(second).sort();
|
|
46322
|
+
return keys.length === otherKeys.length && keys.every((key, index) => key === otherKeys[index] && sameValue(first[key], second[key]));
|
|
46323
|
+
};
|
|
46324
|
+
return sameValue({
|
|
46325
|
+
...left,
|
|
46326
|
+
token: void 0
|
|
46327
|
+
}, {
|
|
46328
|
+
...right,
|
|
46329
|
+
token: void 0
|
|
46330
|
+
});
|
|
46210
46331
|
}
|
|
46211
46332
|
#snapshotV2LockSeed() {
|
|
46212
46333
|
return {
|
|
@@ -46533,9 +46654,13 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
46533
46654
|
if (docxDocs.length > 1) throw new Error("SuperDoc: upgradeToCollaboration() only supports a single DOCX document");
|
|
46534
46655
|
if (cfg.documents.length !== docxDocs.length) throw new Error("SuperDoc: upgradeToCollaboration() only supports single-DOCX instances");
|
|
46535
46656
|
if (!isV2ActiveEditorFacade(this.#resolveSourceEditor())) throw new Error("SuperDoc: upgradeToCollaboration() requires a ready v2 DOCX editor");
|
|
46536
|
-
const
|
|
46537
|
-
const mountedDocumentId = configDoc.id;
|
|
46657
|
+
const mountedDocumentId = docxDocs[0].id;
|
|
46538
46658
|
if (typeof mountedDocumentId !== "string" || mountedDocumentId.length === 0) throw new Error("SuperDoc: source document is missing its mounted document identity");
|
|
46659
|
+
return this.#resolveCollaborationUpgradeTarget(options);
|
|
46660
|
+
}
|
|
46661
|
+
#resolveCollaborationUpgradeTarget(options) {
|
|
46662
|
+
const cfg = this.config;
|
|
46663
|
+
const configDoc = cfg.documents.find((doc) => doc.type === DOCX);
|
|
46539
46664
|
const collaborationModule = cfg.modules?.collaboration;
|
|
46540
46665
|
const legacyCollaboration = options.ydoc || options.provider ? {
|
|
46541
46666
|
ydoc: options.ydoc,
|
|
@@ -46551,7 +46676,10 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
46551
46676
|
...typeof window !== "undefined" ? { authEndpointBaseUrl: window.location.href } : {}
|
|
46552
46677
|
});
|
|
46553
46678
|
if (!resolution.ok) throw new Error(`SuperDoc: upgradeToCollaboration() ${resolution.reason}: ${resolution.message}`);
|
|
46554
|
-
return { target:
|
|
46679
|
+
return { target: {
|
|
46680
|
+
...resolution.target,
|
|
46681
|
+
roomMode: "create"
|
|
46682
|
+
} };
|
|
46555
46683
|
}
|
|
46556
46684
|
#unwrapMaybeRef(value) {
|
|
46557
46685
|
if (value && typeof value === "object" && "value" in value) return value.value;
|