superdoc 2.18.0-next.1 → 2.18.0-next.11

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/superdoc.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./chunks/rolldown-runtime-74VwNCz7.cjs");
3
3
  const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
4
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-D9JWPXRh.cjs");
4
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-BwM3I7-G.cjs");
5
5
  const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
6
6
  const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
7
7
  const require_jszip = require("./chunks/jszip-D8mAFF-r.cjs");
@@ -316,7 +316,7 @@ var shuffleArray = (array) => {
316
316
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
317
317
  function getSuperdocVersion() {
318
318
  try {
319
- return "2.18.0-next.1";
319
+ return "2.18.0-next.11";
320
320
  } catch {
321
321
  return "unknown";
322
322
  }
@@ -22372,7 +22372,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22372
22372
  if (!payload) return;
22373
22373
  clearV2EditorFailure(payload.documentId ?? null);
22374
22374
  clearV2MutationRejectionNotifications(payload.documentId ?? null);
22375
- 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;
22375
+ const { host, mount, documentId, capabilities, editCommands, bindEditShortcuts, bindSessionShortcuts, commentsAdapter, trackedChangesAdapter, contextMenu, documentApi, documentMutationReadiness, documentApiUnavailableReason, pageMetrics, pageLayout, pageFurniture, presence, lock, connection, collaborationProvider, fonts, replaceFile, upgradeToCollaboration, documentOpenToken } = payload;
22376
22376
  documentOpenTelemetry?.trackDocumentOpen(documentOpenToken ?? null, documentId ?? null);
22377
22377
  const saveV2Bytes = createV2SaveQueue(async (saveOptions = {}) => {
22378
22378
  if (!host || typeof host.save !== "function") throw new Error("v2-editor: save unavailable");
@@ -22649,6 +22649,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22649
22649
  pageFurniture: pageFurniture ?? null,
22650
22650
  presence: presence ?? null,
22651
22651
  lock: lock ?? null,
22652
+ connection: connection ?? null,
22652
22653
  provider: collaborationProvider ?? null,
22653
22654
  reviewWindow: {
22654
22655
  getDiagnostics: () => v2ReviewWindowController.getDiagnostics(),
@@ -22696,7 +22697,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22696
22697
  bindSessionShortcuts,
22697
22698
  documentApi
22698
22699
  });
22699
- if (resolveDocumentV2Collaboration(getDocument(documentId)).state === "valid") onEditorCollaborationReady({ editor: facade });
22700
+ if (collaborationProvider && resolveDocumentV2Collaboration(getDocument(documentId)).state === "valid") onEditorCollaborationReady({ editor: facade });
22700
22701
  if (pageMetrics && pageLayout) syncV2RulerActiveEditor();
22701
22702
  const commentsModuleEnabled = proxy.$superdoc.config.modules?.comments !== false;
22702
22703
  if (commentsAdapter && commentsModuleEnabled) commentsStore.setV2CommentsAdapter?.(commentsAdapter);
@@ -24494,7 +24495,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24494
24495
  ], 38);
24495
24496
  };
24496
24497
  }
24497
- }, [["__scopeId", "data-v-4e56e5b9"]]);
24498
+ }, [["__scopeId", "data-v-9da02d58"]]);
24498
24499
  //#endregion
24499
24500
  //#region src/core/create-app.js
24500
24501
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -45370,6 +45371,14 @@ function contentControlSelectionKey(selection) {
45370
45371
  return null;
45371
45372
  }
45372
45373
  }
45374
+ function deriveCollaborationConnectionKind(snapshot, hasSyncedBefore) {
45375
+ switch (snapshot.state) {
45376
+ case "failed": return "failed";
45377
+ case "degraded": return snapshot.detail === "reconnecting" ? "reconnecting" : "lost";
45378
+ case "synced": return hasSyncedBefore ? "recovered" : "initial";
45379
+ default: return hasSyncedBefore ? "reconnecting" : "initial";
45380
+ }
45381
+ }
45373
45382
  function isV2ActiveEditorFacade(editor) {
45374
45383
  return Boolean(editor && typeof editor === "object" && editor.editorVersion === 2);
45375
45384
  }
@@ -45437,6 +45446,12 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
45437
45446
  #v2AwarenessUnsub;
45438
45447
  /** Unsubscribe handle for the v2 root-doc lock observer. */
45439
45448
  #v2LockUnsub;
45449
+ /** Unsubscribe handle for the v2 collaboration connection observer. */
45450
+ #v2ConnectionUnsub;
45451
+ /** Latest `collaboration-connection-change` payload, for late readers. */
45452
+ #v2ConnectionState;
45453
+ /** Whether the current collaboration room has completed a sync at least once. */
45454
+ #v2ConnectionHasSynced;
45440
45455
  /** Lock state captured before a local → v2 collaboration promotion remount. */
45441
45456
  #pendingV2LockSeed;
45442
45457
  #mountWrapper;
@@ -45528,6 +45543,9 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
45528
45543
  this.#abortUpgrade = null;
45529
45544
  this.#v2AwarenessUnsub = null;
45530
45545
  this.#v2LockUnsub = null;
45546
+ this.#v2ConnectionUnsub = null;
45547
+ this.#v2ConnectionState = null;
45548
+ this.#v2ConnectionHasSynced = false;
45531
45549
  this.#pendingV2LockSeed = null;
45532
45550
  this.#mountWrapper = null;
45533
45551
  this.#contentControlClickRoot = null;
@@ -45726,7 +45744,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
45726
45744
  this.config.colors = shuffleArray(this.config.colors);
45727
45745
  this.userColorMap = /* @__PURE__ */ new Map();
45728
45746
  this.colorIndex = 0;
45729
- this.version = "2.18.0-next.1";
45747
+ this.version = "2.18.0-next.11";
45730
45748
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
45731
45749
  this.superdocId = config.superdocId || require_uuid.v4();
45732
45750
  this.colors = this.config.colors ?? [];
@@ -45828,7 +45846,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
45828
45846
  return this.#diagnostics;
45829
45847
  }
45830
45848
  emit(event, ...args) {
45831
- if (event === "exception" || event === "document-replaced" || event === "ready" || event === "active-editor-change" || event === "collaboration-ready" || event === "locked") require_create_super_doc_ui.recordInteraction(this, event, () => args[0]);
45849
+ if (event === "exception" || event === "document-replaced" || event === "ready" || event === "active-editor-change" || event === "collaboration-ready" || event === "collaboration-connection-change" || event === "locked") require_create_super_doc_ui.recordInteraction(this, event, () => args[0]);
45832
45850
  return super.emit(event, ...args);
45833
45851
  }
45834
45852
  on(event, fn, context) {
@@ -46070,6 +46088,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46070
46088
  this.#onConfig("pdf:document-ready", this.config.onPdfDocumentReady);
46071
46089
  this.#onConfig("sidebar-toggle", this.config.onSidebarToggle);
46072
46090
  this.#onConfig("collaboration-ready", this.config.onCollaborationReady);
46091
+ this.#onConfig("collaboration-connection-change", this.config.onCollaborationConnectionChange);
46073
46092
  this.on("collaboration-ready", (payload) => this.#startV2CollaborationEventBridge(payload?.editor ?? null));
46074
46093
  this.#onConfig("editor-update", this.config.onEditorUpdate);
46075
46094
  this.#onConfig("tracked-changes:bulk-decision", this.config.onTrackedChangesBulkDecision);
@@ -46160,12 +46179,59 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46160
46179
  } catch {}
46161
46180
  this.#v2LockUnsub = null;
46162
46181
  }
46182
+ if (this.#v2ConnectionUnsub) {
46183
+ try {
46184
+ this.#v2ConnectionUnsub();
46185
+ } catch {}
46186
+ this.#v2ConnectionUnsub = null;
46187
+ }
46163
46188
  }
46164
46189
  #startV2CollaborationEventBridge(editor) {
46165
46190
  this.#stopV2CollaborationEventBridge();
46166
46191
  if (!isV2ActiveEditorFacade(editor)) return;
46167
46192
  this.#startV2AwarenessBridge(editor);
46168
46193
  this.#startV2LockBridge(editor);
46194
+ this.#startV2ConnectionBridge(editor);
46195
+ }
46196
+ #startV2ConnectionBridge(editor) {
46197
+ const connection = editor.connection;
46198
+ if (!connection || typeof connection.subscribe !== "function") return;
46199
+ const { documentId } = connection;
46200
+ if (this.#v2ConnectionState?.documentId !== documentId) {
46201
+ this.#v2ConnectionState = null;
46202
+ this.#v2ConnectionHasSynced = false;
46203
+ }
46204
+ const publish = (snapshot) => {
46205
+ if (this.#destroyed) return;
46206
+ const previous = this.#v2ConnectionState;
46207
+ if (previous && previous.state === snapshot.state && previous.detail === (snapshot.detail ?? null)) return;
46208
+ const payload = {
46209
+ documentId,
46210
+ state: snapshot.state,
46211
+ previousState: previous?.state ?? null,
46212
+ kind: deriveCollaborationConnectionKind(snapshot, this.#v2ConnectionHasSynced),
46213
+ detail: snapshot.detail ?? null,
46214
+ superdoc: this
46215
+ };
46216
+ this.#v2ConnectionState = payload;
46217
+ if (snapshot.state === "synced") this.#v2ConnectionHasSynced = true;
46218
+ this.emit("collaboration-connection-change", payload);
46219
+ };
46220
+ try {
46221
+ const initialSnapshot = connection.getSnapshot?.();
46222
+ if (initialSnapshot) publish(initialSnapshot);
46223
+ this.#v2ConnectionUnsub = connection.subscribe(publish);
46224
+ } catch (err) {
46225
+ console.warn("[SuperDoc] v2 connection bridge failed to subscribe", err);
46226
+ }
46227
+ }
46228
+ /**
46229
+ * Latest v2 collaboration connection change, or `null` when no v2
46230
+ * collaboration session has reported one. Same payload as the
46231
+ * `collaboration-connection-change` event.
46232
+ */
46233
+ getCollaborationConnectionState() {
46234
+ return this.#v2ConnectionState;
46169
46235
  }
46170
46236
  #startV2AwarenessBridge(editor) {
46171
46237
  const presence = editor.presence;
@@ -47911,21 +47977,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
47911
47977
  }));
47912
47978
  }
47913
47979
  /**
47914
- * Clean up collaboration resources owned only by a removed document.
47915
- *
47916
- * Shared instance-level providers/ydocs stay alive; `destroy()` remains the
47917
- * one place that tears down shell-wide collaboration state.
47918
- */
47919
- #cleanupRemovedDocumentCollaboration(removedDocument, remainingDocuments) {
47920
- const removedProvider = removedDocument.provider;
47921
- if (removedProvider && removedProvider !== this.provider && !remainingDocuments.some((doc) => doc.provider === removedProvider)) {
47922
- removedProvider.disconnect?.();
47923
- removedProvider.destroy?.();
47924
- }
47925
- const removedYDoc = removedDocument.ydoc;
47926
- if (removedYDoc && removedYDoc !== this.ydoc && !remainingDocuments.some((doc) => doc.ydoc === removedYDoc)) removedYDoc.destroy?.();
47927
- }
47928
- /**
47929
47980
  * Clean up collaboration resources (providers, ydocs, sockets)
47930
47981
  */
47931
47982
  #cleanupCollaboration() {
@@ -47942,11 +47993,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
47942
47993
  this.ydoc?.destroy();
47943
47994
  this.provider?.disconnect?.();
47944
47995
  this.provider?.destroy?.();
47945
- cfg.documents.forEach((doc) => {
47946
- doc.provider?.disconnect?.();
47947
- doc.provider?.destroy?.();
47948
- doc.ydoc?.destroy();
47949
- });
47950
47996
  }
47951
47997
  /**
47952
47998
  * Open a surface (dialog or floating) above the document content.
@@ -47980,9 +48026,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
47980
48026
  const activeDocumentId = getActiveEditorDocumentId(activeEditor);
47981
48027
  for (const runtime of this.#editorRuntimeRegistry.getAllByDocumentId(normalizedDocumentId)) this.#editorRuntimeRegistry.unregister(runtime.id);
47982
48028
  if (activeDocumentId === normalizedDocumentId && activeEditor !== null) this.#clearActiveEditorProjection();
47983
- const removedDocument = store.removeDocument(normalizedDocumentId);
47984
- if (!removedDocument) return false;
47985
- this.#cleanupRemovedDocumentCollaboration(removedDocument, store.documents);
48029
+ if (!store.removeDocument(normalizedDocumentId)) return false;
47986
48030
  await (0, vue.nextTick)();
47987
48031
  return true;
47988
48032
  }
@@ -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 getV2TrackedChangeMutationImpact, c as createInteractionHistory, i as applyV2CommentInvalidationFromMutation, l as recordInteraction, o as DOM_CLASS_NAMES, s as closeInteractionHistory, t as createSuperDocUI } from "./chunks/create-super-doc-ui-qTSa0PbD.es.js";
3
+ import { a as getV2TrackedChangeMutationImpact, c as createInteractionHistory, i as applyV2CommentInvalidationFromMutation, l as recordInteraction, o as DOM_CLASS_NAMES, s as closeInteractionHistory, t as createSuperDocUI } from "./chunks/create-super-doc-ui-Ci7OxbXV.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-next.1";
318
+ return "2.18.0-next.11";
319
319
  } catch {
320
320
  return "unknown";
321
321
  }
@@ -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, 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(),
@@ -22656,7 +22657,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22656
22657
  bindSessionShortcuts,
22657
22658
  documentApi
22658
22659
  });
22659
- if (resolveDocumentV2Collaboration(getDocument(documentId)).state === "valid") onEditorCollaborationReady({ editor: facade });
22660
+ if (collaborationProvider && resolveDocumentV2Collaboration(getDocument(documentId)).state === "valid") onEditorCollaborationReady({ editor: facade });
22660
22661
  if (pageMetrics && pageLayout) syncV2RulerActiveEditor();
22661
22662
  const commentsModuleEnabled = proxy.$superdoc.config.modules?.comments !== false;
22662
22663
  if (commentsAdapter && commentsModuleEnabled) commentsStore.setV2CommentsAdapter?.(commentsAdapter);
@@ -24454,7 +24455,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
24454
24455
  ], 38);
24455
24456
  };
24456
24457
  }
24457
- }, [["__scopeId", "data-v-4e56e5b9"]]);
24458
+ }, [["__scopeId", "data-v-9da02d58"]]);
24458
24459
  //#endregion
24459
24460
  //#region src/core/create-app.js
24460
24461
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -45301,6 +45302,14 @@ function contentControlSelectionKey(selection) {
45301
45302
  return null;
45302
45303
  }
45303
45304
  }
45305
+ function deriveCollaborationConnectionKind(snapshot, hasSyncedBefore) {
45306
+ switch (snapshot.state) {
45307
+ case "failed": return "failed";
45308
+ case "degraded": return snapshot.detail === "reconnecting" ? "reconnecting" : "lost";
45309
+ case "synced": return hasSyncedBefore ? "recovered" : "initial";
45310
+ default: return hasSyncedBefore ? "reconnecting" : "initial";
45311
+ }
45312
+ }
45304
45313
  function isV2ActiveEditorFacade(editor) {
45305
45314
  return Boolean(editor && typeof editor === "object" && editor.editorVersion === 2);
45306
45315
  }
@@ -45368,6 +45377,12 @@ var SuperDoc = class extends import_eventemitter3.default {
45368
45377
  #v2AwarenessUnsub;
45369
45378
  /** Unsubscribe handle for the v2 root-doc lock observer. */
45370
45379
  #v2LockUnsub;
45380
+ /** Unsubscribe handle for the v2 collaboration connection observer. */
45381
+ #v2ConnectionUnsub;
45382
+ /** Latest `collaboration-connection-change` payload, for late readers. */
45383
+ #v2ConnectionState;
45384
+ /** Whether the current collaboration room has completed a sync at least once. */
45385
+ #v2ConnectionHasSynced;
45371
45386
  /** Lock state captured before a local → v2 collaboration promotion remount. */
45372
45387
  #pendingV2LockSeed;
45373
45388
  #mountWrapper;
@@ -45459,6 +45474,9 @@ var SuperDoc = class extends import_eventemitter3.default {
45459
45474
  this.#abortUpgrade = null;
45460
45475
  this.#v2AwarenessUnsub = null;
45461
45476
  this.#v2LockUnsub = null;
45477
+ this.#v2ConnectionUnsub = null;
45478
+ this.#v2ConnectionState = null;
45479
+ this.#v2ConnectionHasSynced = false;
45462
45480
  this.#pendingV2LockSeed = null;
45463
45481
  this.#mountWrapper = null;
45464
45482
  this.#contentControlClickRoot = null;
@@ -45657,7 +45675,7 @@ var SuperDoc = class extends import_eventemitter3.default {
45657
45675
  this.config.colors = shuffleArray(this.config.colors);
45658
45676
  this.userColorMap = /* @__PURE__ */ new Map();
45659
45677
  this.colorIndex = 0;
45660
- this.version = "2.18.0-next.1";
45678
+ this.version = "2.18.0-next.11";
45661
45679
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
45662
45680
  this.superdocId = config.superdocId || v4();
45663
45681
  this.colors = this.config.colors ?? [];
@@ -45759,7 +45777,7 @@ var SuperDoc = class extends import_eventemitter3.default {
45759
45777
  return this.#diagnostics;
45760
45778
  }
45761
45779
  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]);
45780
+ 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
45781
  return super.emit(event, ...args);
45764
45782
  }
45765
45783
  on(event, fn, context) {
@@ -46001,6 +46019,7 @@ var SuperDoc = class extends import_eventemitter3.default {
46001
46019
  this.#onConfig("pdf:document-ready", this.config.onPdfDocumentReady);
46002
46020
  this.#onConfig("sidebar-toggle", this.config.onSidebarToggle);
46003
46021
  this.#onConfig("collaboration-ready", this.config.onCollaborationReady);
46022
+ this.#onConfig("collaboration-connection-change", this.config.onCollaborationConnectionChange);
46004
46023
  this.on("collaboration-ready", (payload) => this.#startV2CollaborationEventBridge(payload?.editor ?? null));
46005
46024
  this.#onConfig("editor-update", this.config.onEditorUpdate);
46006
46025
  this.#onConfig("tracked-changes:bulk-decision", this.config.onTrackedChangesBulkDecision);
@@ -46091,12 +46110,59 @@ var SuperDoc = class extends import_eventemitter3.default {
46091
46110
  } catch {}
46092
46111
  this.#v2LockUnsub = null;
46093
46112
  }
46113
+ if (this.#v2ConnectionUnsub) {
46114
+ try {
46115
+ this.#v2ConnectionUnsub();
46116
+ } catch {}
46117
+ this.#v2ConnectionUnsub = null;
46118
+ }
46094
46119
  }
46095
46120
  #startV2CollaborationEventBridge(editor) {
46096
46121
  this.#stopV2CollaborationEventBridge();
46097
46122
  if (!isV2ActiveEditorFacade(editor)) return;
46098
46123
  this.#startV2AwarenessBridge(editor);
46099
46124
  this.#startV2LockBridge(editor);
46125
+ this.#startV2ConnectionBridge(editor);
46126
+ }
46127
+ #startV2ConnectionBridge(editor) {
46128
+ const connection = editor.connection;
46129
+ if (!connection || typeof connection.subscribe !== "function") return;
46130
+ const { documentId } = connection;
46131
+ if (this.#v2ConnectionState?.documentId !== documentId) {
46132
+ this.#v2ConnectionState = null;
46133
+ this.#v2ConnectionHasSynced = false;
46134
+ }
46135
+ const publish = (snapshot) => {
46136
+ if (this.#destroyed) return;
46137
+ const previous = this.#v2ConnectionState;
46138
+ if (previous && previous.state === snapshot.state && previous.detail === (snapshot.detail ?? null)) return;
46139
+ const payload = {
46140
+ documentId,
46141
+ state: snapshot.state,
46142
+ previousState: previous?.state ?? null,
46143
+ kind: deriveCollaborationConnectionKind(snapshot, this.#v2ConnectionHasSynced),
46144
+ detail: snapshot.detail ?? null,
46145
+ superdoc: this
46146
+ };
46147
+ this.#v2ConnectionState = payload;
46148
+ if (snapshot.state === "synced") this.#v2ConnectionHasSynced = true;
46149
+ this.emit("collaboration-connection-change", payload);
46150
+ };
46151
+ try {
46152
+ const initialSnapshot = connection.getSnapshot?.();
46153
+ if (initialSnapshot) publish(initialSnapshot);
46154
+ this.#v2ConnectionUnsub = connection.subscribe(publish);
46155
+ } catch (err) {
46156
+ console.warn("[SuperDoc] v2 connection bridge failed to subscribe", err);
46157
+ }
46158
+ }
46159
+ /**
46160
+ * Latest v2 collaboration connection change, or `null` when no v2
46161
+ * collaboration session has reported one. Same payload as the
46162
+ * `collaboration-connection-change` event.
46163
+ */
46164
+ getCollaborationConnectionState() {
46165
+ return this.#v2ConnectionState;
46100
46166
  }
46101
46167
  #startV2AwarenessBridge(editor) {
46102
46168
  const presence = editor.presence;
@@ -47842,21 +47908,6 @@ var SuperDoc = class extends import_eventemitter3.default {
47842
47908
  }));
47843
47909
  }
47844
47910
  /**
47845
- * Clean up collaboration resources owned only by a removed document.
47846
- *
47847
- * Shared instance-level providers/ydocs stay alive; `destroy()` remains the
47848
- * one place that tears down shell-wide collaboration state.
47849
- */
47850
- #cleanupRemovedDocumentCollaboration(removedDocument, remainingDocuments) {
47851
- const removedProvider = removedDocument.provider;
47852
- if (removedProvider && removedProvider !== this.provider && !remainingDocuments.some((doc) => doc.provider === removedProvider)) {
47853
- removedProvider.disconnect?.();
47854
- removedProvider.destroy?.();
47855
- }
47856
- const removedYDoc = removedDocument.ydoc;
47857
- if (removedYDoc && removedYDoc !== this.ydoc && !remainingDocuments.some((doc) => doc.ydoc === removedYDoc)) removedYDoc.destroy?.();
47858
- }
47859
- /**
47860
47911
  * Clean up collaboration resources (providers, ydocs, sockets)
47861
47912
  */
47862
47913
  #cleanupCollaboration() {
@@ -47873,11 +47924,6 @@ var SuperDoc = class extends import_eventemitter3.default {
47873
47924
  this.ydoc?.destroy();
47874
47925
  this.provider?.disconnect?.();
47875
47926
  this.provider?.destroy?.();
47876
- cfg.documents.forEach((doc) => {
47877
- doc.provider?.disconnect?.();
47878
- doc.provider?.destroy?.();
47879
- doc.ydoc?.destroy();
47880
- });
47881
47927
  }
47882
47928
  /**
47883
47929
  * Open a surface (dialog or floating) above the document content.
@@ -47911,9 +47957,7 @@ var SuperDoc = class extends import_eventemitter3.default {
47911
47957
  const activeDocumentId = getActiveEditorDocumentId(activeEditor);
47912
47958
  for (const runtime of this.#editorRuntimeRegistry.getAllByDocumentId(normalizedDocumentId)) this.#editorRuntimeRegistry.unregister(runtime.id);
47913
47959
  if (activeDocumentId === normalizedDocumentId && activeEditor !== null) this.#clearActiveEditorProjection();
47914
- const removedDocument = store.removeDocument(normalizedDocumentId);
47915
- if (!removedDocument) return false;
47916
- this.#cleanupRemovedDocumentCollaboration(removedDocument, store.documents);
47960
+ if (!store.removeDocument(normalizedDocumentId)) return false;
47917
47961
  await nextTick();
47918
47962
  return true;
47919
47963
  }