kritzel-stencil 0.1.76 → 0.1.78

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.
Files changed (128) hide show
  1. package/dist/cjs/{index-Dc7LOVhs.js → index-BRZ6e6oa.js} +1 -1
  2. package/dist/cjs/index.cjs.js +2 -330
  3. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +88 -50
  4. package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/stencil.cjs.js +2 -2
  7. package/dist/cjs/{workspace.migrations-DkmVO6dE.js → workspace.migrations-sUPrO23c.js} +378 -13
  8. package/dist/collection/classes/objects/selection-group.class.js +2 -0
  9. package/dist/collection/collection-manifest.json +1 -1
  10. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css +6 -1
  11. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +5 -2
  12. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +2 -0
  13. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +16 -6
  14. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +21 -0
  15. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +24 -10
  16. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.css +3 -0
  17. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +1 -0
  18. package/dist/collection/configs/default-engine-config.js +1 -0
  19. package/dist/collection/constants/version.js +1 -1
  20. package/dist/components/index.js +1 -1
  21. package/dist/components/kritzel-active-users.js +1 -1
  22. package/dist/components/kritzel-avatar.js +1 -1
  23. package/dist/components/kritzel-awareness-cursors.js +1 -1
  24. package/dist/components/kritzel-back-to-content.js +1 -1
  25. package/dist/components/kritzel-brush-style.js +1 -1
  26. package/dist/components/kritzel-button.js +1 -1
  27. package/dist/components/kritzel-color-palette.js +1 -1
  28. package/dist/components/kritzel-color.js +1 -1
  29. package/dist/components/kritzel-context-menu.js +1 -1
  30. package/dist/components/kritzel-controls.js +1 -1
  31. package/dist/components/kritzel-current-user-dialog.js +1 -1
  32. package/dist/components/kritzel-current-user.js +1 -1
  33. package/dist/components/kritzel-cursor-trail.js +1 -1
  34. package/dist/components/kritzel-dialog.js +1 -1
  35. package/dist/components/kritzel-dropdown.js +1 -1
  36. package/dist/components/kritzel-editor.js +1 -1
  37. package/dist/components/kritzel-engine.js +1 -1
  38. package/dist/components/kritzel-export.js +1 -1
  39. package/dist/components/kritzel-font-family.js +1 -1
  40. package/dist/components/kritzel-font-size.js +1 -1
  41. package/dist/components/kritzel-font.js +1 -1
  42. package/dist/components/kritzel-icon.js +1 -1
  43. package/dist/components/kritzel-input.js +1 -1
  44. package/dist/components/kritzel-line-endings.js +1 -1
  45. package/dist/components/kritzel-login-dialog.js +1 -1
  46. package/dist/components/kritzel-master-detail.js +1 -1
  47. package/dist/components/kritzel-menu-item.js +1 -1
  48. package/dist/components/kritzel-menu.js +1 -1
  49. package/dist/components/kritzel-more-menu.js +1 -1
  50. package/dist/components/kritzel-numeric-input.js +1 -1
  51. package/dist/components/kritzel-opacity-slider.js +1 -1
  52. package/dist/components/kritzel-pill-tabs.js +1 -1
  53. package/dist/components/kritzel-portal.js +1 -1
  54. package/dist/components/kritzel-settings.js +1 -1
  55. package/dist/components/kritzel-shape-fill.js +1 -1
  56. package/dist/components/kritzel-share-dialog.js +1 -1
  57. package/dist/components/kritzel-slide-toggle.js +1 -1
  58. package/dist/components/kritzel-split-button.js +1 -1
  59. package/dist/components/kritzel-stroke-size.js +1 -1
  60. package/dist/components/kritzel-tool-config.js +1 -1
  61. package/dist/components/kritzel-tooltip.js +1 -1
  62. package/dist/components/kritzel-utility-panel.js +1 -1
  63. package/dist/components/kritzel-workspace-manager.js +1 -1
  64. package/dist/components/{p-Dt-J69xt.js → p-53di1Zko.js} +1 -1
  65. package/dist/components/{p-DS0xx1eT.js → p-6NFl6EB2.js} +1 -1
  66. package/dist/components/{p-DSzQ6H2j.js → p-76W5pG2O.js} +1 -1
  67. package/dist/components/{p-DRbG92F9.js → p-BLsH_Oi0.js} +1 -1
  68. package/dist/components/p-Ban3OlgZ.js +9 -0
  69. package/dist/components/{p-CUkKKbnu.js → p-BrZ_gL8Q.js} +1 -1
  70. package/dist/components/{p-kj9wbLY8.js → p-BuI6Gkzg.js} +1 -1
  71. package/dist/components/{p-BeFUNGEI.js → p-BueaqfA2.js} +1 -1
  72. package/dist/components/{p-BiByyU2C.js → p-C2l9mZ1P.js} +1 -1
  73. package/dist/components/{p-CsR4owzk.js → p-C4fKLlrd.js} +1 -1
  74. package/dist/components/{p-BA0ayKqO.js → p-CBslLN3-.js} +1 -1
  75. package/dist/components/p-CHY71o5B.js +1 -0
  76. package/dist/components/{p-KQzWumjB.js → p-CI9Nbh-x.js} +1 -1
  77. package/dist/components/{p-CsoDfhD5.js → p-CN8IxBlU.js} +1 -1
  78. package/dist/components/{p-2OYw6GJ7.js → p-CWMFGEe0.js} +1 -1
  79. package/dist/components/{p-Dj_Qjga5.js → p-CYh7yV-K.js} +1 -1
  80. package/dist/components/{p-xM-_OeRO.js → p-Ck1dhpUQ.js} +1 -1
  81. package/dist/components/{p-b4gyXoju.js → p-Cns7qSKS.js} +1 -1
  82. package/dist/components/{p-C69Stayh.js → p-D14QNK3X.js} +1 -1
  83. package/dist/components/{p-iRL0wQHQ.js → p-D3pNw-SV.js} +1 -1
  84. package/dist/components/{p-BEJQ2kP7.js → p-D5IhryUR.js} +1 -1
  85. package/dist/components/{p-CZhyKp-f.js → p-D7yzmu1l.js} +1 -1
  86. package/dist/components/{p-HLbqRJGs.js → p-DDKjsXCe.js} +1 -1
  87. package/dist/components/{p-TyR-YTXm.js → p-DV7Z_qfa.js} +1 -1
  88. package/dist/components/{p-ByR0VXeU.js → p-DWsCbu01.js} +1 -1
  89. package/dist/components/{p-31FVoNWR.js → p-DaGZEV0R.js} +1 -1
  90. package/dist/components/{p-Da46jw3N.js → p-DkWWzVg8.js} +1 -1
  91. package/dist/components/{p-D1O7DxL4.js → p-Dr3-pKVg.js} +1 -1
  92. package/dist/components/{p-JdNoaqqb.js → p-Dte67BWd.js} +1 -1
  93. package/dist/components/{p-CHmi1QWx.js → p-DxzDda_J.js} +1 -1
  94. package/dist/components/{p-CAIGuV2J.js → p-KJ4dHzrS.js} +1 -1
  95. package/dist/components/{p-BiouZo1q.js → p-Lhyh6KeB.js} +1 -1
  96. package/dist/components/{p-CFhp1W9F.js → p-Md9Y-b3d.js} +1 -1
  97. package/dist/components/{p-C1uR_ZNW.js → p-ZC5YELQJ.js} +1 -1
  98. package/dist/components/{p-C7SBI_0T.js → p-ZQ2bKafG.js} +1 -1
  99. package/dist/components/{p-0kShCfeb.js → p-_QEHfsIk.js} +1 -1
  100. package/dist/components/{p-DXjuuVq9.js → p-gtQlsorg.js} +1 -1
  101. package/dist/components/{p-GYI7sDxr.js → p-l_YGO7RB.js} +1 -1
  102. package/dist/components/{p-DvIEvoZu.js → p-m1nVDC3G.js} +1 -1
  103. package/dist/components/{p-7o2FWtFx.js → p-pCC6t6BH.js} +1 -1
  104. package/dist/components/p-pGzF7PUB.js +1 -0
  105. package/dist/esm/{index-MV-81ybv.js → index-BbOHefEf.js} +1 -1
  106. package/dist/esm/index.js +2 -331
  107. package/dist/esm/kritzel-active-users_42.entry.js +88 -50
  108. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  109. package/dist/esm/loader.js +2 -2
  110. package/dist/esm/stencil.js +3 -3
  111. package/dist/esm/{workspace.migrations-D48_Bqvh.js → workspace.migrations-NhRgr2_H.js} +378 -12
  112. package/dist/stencil/index.esm.js +1 -1
  113. package/dist/stencil/p-4a4b38e4.entry.js +9 -0
  114. package/dist/stencil/{p-fc21e29c.entry.js → p-98238bf9.entry.js} +1 -1
  115. package/dist/stencil/p-NhRgr2_H.js +1 -0
  116. package/dist/stencil/stencil.esm.js +1 -1
  117. package/dist/types/classes/objects/selection-group.class.d.ts +1 -0
  118. package/dist/types/components.d.ts +4 -2
  119. package/dist/types/constants/version.d.ts +1 -1
  120. package/dist/types/interfaces/engine-state.interface.d.ts +1 -0
  121. package/package.json +2 -2
  122. package/dist/components/p-CJ2eHeoV.js +0 -1
  123. package/dist/components/p-jdYmu4SA.js +0 -9
  124. package/dist/components/p-xNwOWoiT.js +0 -1
  125. package/dist/stencil/p-775a7246.entry.js +0 -9
  126. package/dist/stencil/p-D48_Bqvh.js +0 -1
  127. /package/dist/components/{p-pebXO4LU.js → p-CGGiwvWZ.js} +0 -0
  128. /package/dist/stencil/{p-MV-81ybv.js → p-BbOHefEf.js} +0 -0
@@ -5032,7 +5032,8 @@ class ReplaceStep extends Step {
5032
5032
  return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
5033
5033
  }
5034
5034
  map(mapping) {
5035
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
5035
+ let to = mapping.mapResult(this.to, -1);
5036
+ let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
5036
5037
  if (from.deletedAcross && to.deletedAcross)
5037
5038
  return null;
5038
5039
  return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
@@ -5071,6 +5072,15 @@ class ReplaceStep extends Step {
5071
5072
  return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
5072
5073
  }
5073
5074
  }
5075
+ /**
5076
+ By default, for backwards compatibility, an inserting step
5077
+ mapped over an insertion at that same position fill move after
5078
+ the inserted content. In a collaborative editing situation, that
5079
+ can make redone insertions appear in unexpected places. You can
5080
+ set this to -1 to make such mapping keep the step before the
5081
+ insertion instead.
5082
+ */
5083
+ ReplaceStep.MAP_BIAS = 1;
5074
5084
  Step.jsonID("replace", ReplaceStep);
5075
5085
  /**
5076
5086
  Replace a part of the document with a slice of content, but
@@ -5988,6 +5998,26 @@ function replaceRangeWith(tr, from, to, node) {
5988
5998
  }
5989
5999
  function deleteRange(tr, from, to) {
5990
6000
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
6001
+ // When the deleted range spans from the start of one textblock to
6002
+ // the start of another one, move out of the start of both blocks.
6003
+ if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() &&
6004
+ $from.parentOffset == 0 && $to.parentOffset == 0) {
6005
+ let shared = $from.sharedDepth(to), isolated = false;
6006
+ for (let d = $from.depth; d > shared; d--)
6007
+ if ($from.node(d).type.spec.isolating)
6008
+ isolated = true;
6009
+ for (let d = $to.depth; d > shared; d--)
6010
+ if ($to.node(d).type.spec.isolating)
6011
+ isolated = true;
6012
+ if (!isolated) {
6013
+ for (let d = $from.depth; d > 0 && from == $from.start(d); d--)
6014
+ from = $from.before(d);
6015
+ for (let d = $to.depth; d > 0 && to == $to.start(d); d--)
6016
+ to = $to.before(d);
6017
+ $from = tr.doc.resolve(from);
6018
+ $to = tr.doc.resolve(to);
6019
+ }
6020
+ }
5991
6021
  let covered = coveredDepths($from, $to);
5992
6022
  for (let i = 0; i < covered.length; i++) {
5993
6023
  let depth = covered[i], last = i == covered.length - 1;
@@ -10756,8 +10786,8 @@ class MouseDown {
10756
10786
  this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null;
10757
10787
  let { selection } = view.state;
10758
10788
  if (event.button == 0 &&
10759
- targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
10760
- selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos)
10789
+ (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
10790
+ selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos))
10761
10791
  this.mightDrag = {
10762
10792
  node: targetNode,
10763
10793
  pos: targetPos,
@@ -11106,8 +11136,9 @@ class Dragging {
11106
11136
  }
11107
11137
  const dragCopyModifier = mac$3 ? "altKey" : "ctrlKey";
11108
11138
  function dragMoves(view, event) {
11109
- let moves = view.someProp("dragCopies", test => !test(event));
11110
- return moves != null ? moves : !event[dragCopyModifier];
11139
+ let copy;
11140
+ view.someProp("dragCopies", test => { copy = copy || test(event); });
11141
+ return copy != null ? !copy : !event[dragCopyModifier];
11111
11142
  }
11112
11143
  handlers.dragstart = (view, _event) => {
11113
11144
  let event = _event;
@@ -11134,7 +11165,7 @@ handlers.dragstart = (view, _event) => {
11134
11165
  if (!event.dataTransfer.files.length || !chrome || chrome_version > 120)
11135
11166
  event.dataTransfer.clearData();
11136
11167
  event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
11137
- // See https://github.com/ProseMirror/prosemirror/issues/1156
11168
+ // See https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1156
11138
11169
  event.dataTransfer.effectAllowed = "copyMove";
11139
11170
  if (!brokenClipboardAPI)
11140
11171
  event.dataTransfer.setData("text/plain", text);
@@ -12133,8 +12164,13 @@ class DOMObserver {
12133
12164
  for (let node of added)
12134
12165
  if (node.nodeName == "BR" && node.parentNode) {
12135
12166
  let after = node.nextSibling;
12136
- if (after && after.nodeType == 1 && after.contentEditable == "false")
12137
- node.parentNode.removeChild(node);
12167
+ while (after && after.nodeType == 1) {
12168
+ if (after.contentEditable == "false") {
12169
+ node.parentNode.removeChild(node);
12170
+ break;
12171
+ }
12172
+ after = after.firstChild;
12173
+ }
12138
12174
  }
12139
12175
  }
12140
12176
  else if (gecko && added.length) {
@@ -12754,7 +12790,7 @@ class EditorView {
12754
12790
  this.pluginViews = [];
12755
12791
  /**
12756
12792
  Holds `true` when a hack node is needed in Firefox to prevent the
12757
- [space is eaten issue](https://github.com/ProseMirror/prosemirror/issues/651)
12793
+ [space is eaten issue](https://code.haverbeke.berlin/prosemirror/prosemirror/issues/651)
12758
12794
  @internal
12759
12795
  */
12760
12796
  this.requiresGeckoHackNode = false;
@@ -12972,12 +13008,12 @@ class EditorView {
12972
13008
  }
12973
13009
  updateDraggedNode(dragging, prev) {
12974
13010
  let sel = dragging.node, found = -1;
12975
- if (this.state.doc.nodeAt(sel.from) == sel.node) {
13011
+ if (sel.from < this.state.doc.content.size && this.state.doc.nodeAt(sel.from) == sel.node) {
12976
13012
  found = sel.from;
12977
13013
  }
12978
13014
  else {
12979
13015
  let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size);
12980
- let moved = movedPos > 0 && this.state.doc.nodeAt(movedPos);
13016
+ let moved = movedPos > 0 && movedPos < this.state.doc.content.size && this.state.doc.nodeAt(movedPos);
12981
13017
  if (moved == sel.node)
12982
13018
  found = movedPos;
12983
13019
  }
@@ -18470,6 +18506,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18470
18506
  snapshotHeight = 0;
18471
18507
  snapshotTranslateX = 0;
18472
18508
  snapshotTranslateY = 0;
18509
+ clientId;
18473
18510
  minX;
18474
18511
  maxX;
18475
18512
  minY;
@@ -18542,6 +18579,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18542
18579
  object.id = object.generateId();
18543
18580
  object.workspaceId = core.store.state.activeWorkspace.id;
18544
18581
  object.userId = core.user?.id;
18582
+ object.clientId = core.store.state.objects?.localClientId ?? undefined;
18545
18583
  object.scale = core.store.state.scale;
18546
18584
  object.zIndex = 99999;
18547
18585
  // Initialize styling with theme-aware defaults
@@ -25202,6 +25240,334 @@ class HocuspocusProvider extends EventEmitter {
25202
25240
  }
25203
25241
  }
25204
25242
 
25243
+ /**
25244
+ * Hocuspocus sync provider for real-time collaboration
25245
+ * Supports multiplexing - multiple documents can share the same WebSocket connection
25246
+ */
25247
+ class HocuspocusSyncProvider {
25248
+ type = 'network';
25249
+ provider;
25250
+ isConnected = false;
25251
+ isSynced = false;
25252
+ usesSharedSocket = false;
25253
+ isDestroyed = false;
25254
+ connectTimeout = null;
25255
+ pendingConnectReject = null;
25256
+ connectionTimeoutMs;
25257
+ _connectionStatus = 'disconnected';
25258
+ visibilityHandler = null;
25259
+ onlineHandler = null;
25260
+ get awareness() {
25261
+ return this.provider.awareness;
25262
+ }
25263
+ get connectionStatus() {
25264
+ return this._connectionStatus;
25265
+ }
25266
+ // Static shared WebSocket instance for multiplexing
25267
+ static sharedWebSocketProvider = null;
25268
+ constructor(docName, doc, options) {
25269
+ const name = options?.name || docName;
25270
+ const url = options?.url || 'ws://localhost:1234';
25271
+ this.connectionTimeoutMs = options?.connectionTimeout ?? 10000;
25272
+ // Use provided websocketProvider or the static shared one
25273
+ const websocketProvider = options?.websocketProvider || HocuspocusSyncProvider.sharedWebSocketProvider;
25274
+ // Build reconnect config from options
25275
+ const reconnectConfig = {};
25276
+ if (options?.delay !== undefined)
25277
+ reconnectConfig.delay = options.delay;
25278
+ if (options?.factor !== undefined)
25279
+ reconnectConfig.factor = options.factor;
25280
+ if (options?.maxAttempts !== undefined)
25281
+ reconnectConfig.maxAttempts = options.maxAttempts;
25282
+ if (options?.minDelay !== undefined)
25283
+ reconnectConfig.minDelay = options.minDelay;
25284
+ if (options?.maxDelay !== undefined)
25285
+ reconnectConfig.maxDelay = options.maxDelay;
25286
+ const onConnect = () => {
25287
+ if (this.isDestroyed) {
25288
+ return;
25289
+ }
25290
+ this.isConnected = true;
25291
+ this._connectionStatus = 'connected';
25292
+ if (!options?.quiet) {
25293
+ console.info(`Hocuspocus connected: ${name}`);
25294
+ }
25295
+ if (options?.onConnect) {
25296
+ options.onConnect();
25297
+ }
25298
+ };
25299
+ const onDisconnect = () => {
25300
+ if (this.isDestroyed) {
25301
+ return;
25302
+ }
25303
+ this.isConnected = false;
25304
+ this.isSynced = false;
25305
+ this._connectionStatus = 'disconnected';
25306
+ if (!options?.quiet) {
25307
+ console.info(`Hocuspocus disconnected: ${name}`);
25308
+ }
25309
+ if (options?.onDisconnect) {
25310
+ options.onDisconnect();
25311
+ }
25312
+ };
25313
+ const onSynced = () => {
25314
+ if (this.isDestroyed) {
25315
+ return;
25316
+ }
25317
+ this.isSynced = true;
25318
+ this._connectionStatus = 'synced';
25319
+ if (!options?.quiet) {
25320
+ console.info(`Hocuspocus synced: ${name}`);
25321
+ }
25322
+ if (options?.onSynced) {
25323
+ options.onSynced();
25324
+ }
25325
+ };
25326
+ const onStatus = (data) => {
25327
+ if (this.isDestroyed) {
25328
+ return;
25329
+ }
25330
+ if (data.status === 'connecting') {
25331
+ this._connectionStatus = 'connecting';
25332
+ }
25333
+ if (options?.onStatus) {
25334
+ options.onStatus(data);
25335
+ }
25336
+ };
25337
+ if (websocketProvider) {
25338
+ // Multiplexing mode - use shared WebSocket connection
25339
+ this.usesSharedSocket = true;
25340
+ const config = {
25341
+ websocketProvider,
25342
+ name,
25343
+ document: doc,
25344
+ token: options?.token || null,
25345
+ onStatus,
25346
+ onConnect,
25347
+ onDisconnect,
25348
+ onSynced,
25349
+ ...reconnectConfig,
25350
+ };
25351
+ // Add optional settings
25352
+ if (options?.forceSyncInterval !== undefined) {
25353
+ config.forceSyncInterval = options.forceSyncInterval;
25354
+ }
25355
+ if (options?.onAuthenticationFailed) {
25356
+ config.onAuthenticationFailed = options.onAuthenticationFailed;
25357
+ }
25358
+ this.provider = new HocuspocusProvider(config);
25359
+ // Must call attach() explicitly when using shared socket
25360
+ this.provider.attach();
25361
+ if (!options?.quiet) {
25362
+ console.info(`Hocuspocus Provider initialized (multiplexed): ${name}`);
25363
+ }
25364
+ }
25365
+ else {
25366
+ // Standalone mode - create own WebSocket connection
25367
+ this.usesSharedSocket = false;
25368
+ const config = {
25369
+ url,
25370
+ name,
25371
+ document: doc,
25372
+ token: options?.token || null,
25373
+ autoConnect: false,
25374
+ onStatus,
25375
+ onConnect,
25376
+ onDisconnect,
25377
+ onSynced,
25378
+ ...reconnectConfig,
25379
+ };
25380
+ // Add optional settings
25381
+ if (options?.forceSyncInterval !== undefined) {
25382
+ config.forceSyncInterval = options.forceSyncInterval;
25383
+ }
25384
+ if (options?.onAuthenticationFailed) {
25385
+ config.onAuthenticationFailed = options.onAuthenticationFailed;
25386
+ }
25387
+ if (options?.WebSocketPolyfill) {
25388
+ config.WebSocketPolyfill = options.WebSocketPolyfill;
25389
+ }
25390
+ this.provider = new HocuspocusProvider(config);
25391
+ if (!options?.quiet) {
25392
+ console.info(`Hocuspocus Provider initialized: ${url}/${name}`);
25393
+ }
25394
+ }
25395
+ this.setupBrowserEventListeners();
25396
+ }
25397
+ setupBrowserEventListeners() {
25398
+ if (typeof document !== 'undefined') {
25399
+ this.visibilityHandler = () => {
25400
+ if (document.visibilityState === 'visible' && !this.isConnected && !this.isDestroyed) {
25401
+ this.provider.connect();
25402
+ }
25403
+ };
25404
+ document.addEventListener('visibilitychange', this.visibilityHandler);
25405
+ }
25406
+ if (typeof window !== 'undefined') {
25407
+ this.onlineHandler = () => {
25408
+ if (!this.isConnected && !this.isDestroyed) {
25409
+ this.provider.connect();
25410
+ }
25411
+ };
25412
+ window.addEventListener('online', this.onlineHandler);
25413
+ }
25414
+ }
25415
+ removeBrowserEventListeners() {
25416
+ if (this.visibilityHandler && typeof document !== 'undefined') {
25417
+ document.removeEventListener('visibilitychange', this.visibilityHandler);
25418
+ this.visibilityHandler = null;
25419
+ }
25420
+ if (this.onlineHandler && typeof window !== 'undefined') {
25421
+ window.removeEventListener('online', this.onlineHandler);
25422
+ this.onlineHandler = null;
25423
+ }
25424
+ }
25425
+ /**
25426
+ * Create a shared WebSocket connection for multiplexing
25427
+ * Call this once to create a shared connection that multiple providers can use
25428
+ */
25429
+ static createSharedWebSocket(options) {
25430
+ if (HocuspocusSyncProvider.sharedWebSocketProvider) {
25431
+ console.warn('Shared WebSocket already exists. Returning existing instance.');
25432
+ return HocuspocusSyncProvider.sharedWebSocketProvider;
25433
+ }
25434
+ const config = {
25435
+ url: options.url,
25436
+ };
25437
+ if (options.WebSocketPolyfill) {
25438
+ config.WebSocketPolyfill = options.WebSocketPolyfill;
25439
+ }
25440
+ if (options.onConnect) {
25441
+ config.onConnect = options.onConnect;
25442
+ }
25443
+ if (options.onDisconnect) {
25444
+ config.onDisconnect = options.onDisconnect;
25445
+ }
25446
+ if (options.onStatus) {
25447
+ config.onStatus = options.onStatus;
25448
+ }
25449
+ HocuspocusSyncProvider.sharedWebSocketProvider = new HocuspocusProviderWebsocket(config);
25450
+ console.info(`Shared Hocuspocus WebSocket created: ${options.url}`);
25451
+ return HocuspocusSyncProvider.sharedWebSocketProvider;
25452
+ }
25453
+ /**
25454
+ * Destroy the shared WebSocket connection
25455
+ * Call this when you're done with all multiplexed providers
25456
+ */
25457
+ static destroySharedWebSocket() {
25458
+ if (HocuspocusSyncProvider.sharedWebSocketProvider) {
25459
+ HocuspocusSyncProvider.sharedWebSocketProvider.destroy();
25460
+ HocuspocusSyncProvider.sharedWebSocketProvider = null;
25461
+ console.info('Shared Hocuspocus WebSocket destroyed');
25462
+ }
25463
+ }
25464
+ /**
25465
+ * Get the shared WebSocket provider instance (if it exists)
25466
+ */
25467
+ static getSharedWebSocket() {
25468
+ return HocuspocusSyncProvider.sharedWebSocketProvider;
25469
+ }
25470
+ /**
25471
+ * Static factory method for creating HocuspocusSyncProvider with configuration options
25472
+ * Returns a ProviderFactory that can be used in sync configuration
25473
+ */
25474
+ static with(options) {
25475
+ return {
25476
+ create: (docName, doc, runtimeOptions) => {
25477
+ const mergedOptions = runtimeOptions ? { ...options, ...runtimeOptions } : options;
25478
+ return new HocuspocusSyncProvider(docName, doc, mergedOptions);
25479
+ },
25480
+ };
25481
+ }
25482
+ async connect() {
25483
+ if (this.isSynced || this.isDestroyed) {
25484
+ return;
25485
+ }
25486
+ this._connectionStatus = 'connecting';
25487
+ return new Promise((resolve, reject) => {
25488
+ // Store reject function so we can cancel the connection if destroyed
25489
+ this.pendingConnectReject = reject;
25490
+ this.connectTimeout = setTimeout(() => {
25491
+ this.pendingConnectReject = null;
25492
+ this.connectTimeout = null;
25493
+ reject(new Error('Hocuspocus connection timeout'));
25494
+ }, this.connectionTimeoutMs);
25495
+ const syncHandler = () => {
25496
+ if (this.connectTimeout) {
25497
+ clearTimeout(this.connectTimeout);
25498
+ this.connectTimeout = null;
25499
+ }
25500
+ this.pendingConnectReject = null;
25501
+ this.provider.off('synced', syncHandler);
25502
+ if (!this.isDestroyed) {
25503
+ resolve();
25504
+ }
25505
+ };
25506
+ this.provider.on('synced', syncHandler);
25507
+ // If already synced, resolve immediately
25508
+ if (this.provider.isSynced) {
25509
+ if (this.connectTimeout) {
25510
+ clearTimeout(this.connectTimeout);
25511
+ this.connectTimeout = null;
25512
+ }
25513
+ this.pendingConnectReject = null;
25514
+ this.provider.off('synced', syncHandler);
25515
+ resolve();
25516
+ return;
25517
+ }
25518
+ // Connect if not already connected (standalone mode only)
25519
+ if (!this.isConnected && !this.usesSharedSocket) {
25520
+ this.provider.connect();
25521
+ }
25522
+ });
25523
+ }
25524
+ async reconnect() {
25525
+ this.disconnect();
25526
+ return this.connect();
25527
+ }
25528
+ disconnect() {
25529
+ // Cancel any pending connection attempt
25530
+ if (this.connectTimeout) {
25531
+ clearTimeout(this.connectTimeout);
25532
+ this.connectTimeout = null;
25533
+ }
25534
+ if (this.pendingConnectReject) {
25535
+ this.pendingConnectReject = null; // Don't reject, just abandon the promise
25536
+ }
25537
+ if (this.provider) {
25538
+ if (this.usesSharedSocket) {
25539
+ // Detach from shared socket instead of disconnecting
25540
+ this.provider.detach();
25541
+ }
25542
+ else {
25543
+ this.provider.disconnect();
25544
+ }
25545
+ }
25546
+ this.isConnected = false;
25547
+ this.isSynced = false;
25548
+ this._connectionStatus = 'disconnected';
25549
+ }
25550
+ destroy() {
25551
+ // Mark as destroyed first to prevent any callbacks from doing work
25552
+ this.isDestroyed = true;
25553
+ // Cancel any pending connection attempt
25554
+ if (this.connectTimeout) {
25555
+ clearTimeout(this.connectTimeout);
25556
+ this.connectTimeout = null;
25557
+ }
25558
+ if (this.pendingConnectReject) {
25559
+ this.pendingConnectReject = null; // Don't reject, just abandon the promise
25560
+ }
25561
+ this.removeBrowserEventListeners();
25562
+ if (this.provider) {
25563
+ this.provider.destroy();
25564
+ }
25565
+ this.isConnected = false;
25566
+ this.isSynced = false;
25567
+ this._connectionStatus = 'disconnected';
25568
+ }
25569
+ }
25570
+
25205
25571
  /** Current version of the workspace export format */
25206
25572
  const WORKSPACE_EXPORT_VERSION = '1.2.0';
25207
25573
  /**
@@ -26853,4 +27219,4 @@ const WORKSPACE_MIGRATIONS = [
26853
27219
  },
26854
27220
  ];
26855
27221
 
26856
- export { APP_STATE_MIGRATIONS as A, KritzelDevicesHelper as B, CURRENT_APP_STATE_SCHEMA_VERSION as C, DEFAULT_BRUSH_CONFIG as D, KritzelMouseButton as E, DEFAULT_COLOR_PALETTE as F, KritzelSelectionGroup as G, HocuspocusProvider as H, IndexedDBSyncProvider as I, KritzelSelectionBox as J, KritzelText as K, KritzelIconRegistry as L, KritzelKeyboardHelper as M, KritzelBaseHandler as N, KritzelToolRegistry as O, KritzelBaseObject as P, ObjectHelper as Q, KritzelClassHelper as R, ShapeType as S, KritzelEventHelper as T, KritzelBaseTool as U, WORKSPACE_EXPORT_VERSION as W, HocuspocusProviderWebsocket as a, KritzelPath as b, KritzelImage as c, KritzelLine as d, KritzelGroup as e, KritzelShape as f, KritzelBrushTool as g, KritzelLineTool as h, KritzelEraserTool as i, KritzelImageTool as j, KritzelTextTool as k, KritzelShapeTool as l, KritzelCursorHelper as m, KritzelSelectionTool as n, KritzelWorkspace as o, KritzelAnchorManager as p, KritzelThemeManager as q, DEFAULT_TEXT_CONFIG as r, DEFAULT_LINE_TOOL_CONFIG as s, lightTheme as t, darkTheme as u, KritzelAlignment as v, CURRENT_WORKSPACE_SCHEMA_VERSION as w, runMigrations as x, WORKSPACE_MIGRATIONS as y, KritzelColorHelper as z };
27222
+ export { APP_STATE_MIGRATIONS as A, KritzelMouseButton as B, CURRENT_APP_STATE_SCHEMA_VERSION as C, DEFAULT_BRUSH_CONFIG as D, DEFAULT_COLOR_PALETTE as E, KritzelSelectionGroup as F, KritzelSelectionBox as G, HocuspocusSyncProvider as H, IndexedDBSyncProvider as I, KritzelIconRegistry as J, KritzelText as K, KritzelKeyboardHelper as L, KritzelBaseHandler as M, KritzelToolRegistry as N, KritzelBaseObject as O, ObjectHelper as P, KritzelClassHelper as Q, KritzelEventHelper as R, ShapeType as S, KritzelBaseTool as T, WORKSPACE_EXPORT_VERSION as W, KritzelPath as a, KritzelImage as b, KritzelLine as c, KritzelGroup as d, KritzelShape as e, KritzelBrushTool as f, KritzelLineTool as g, KritzelEraserTool as h, KritzelImageTool as i, KritzelTextTool as j, KritzelShapeTool as k, KritzelCursorHelper as l, KritzelSelectionTool as m, KritzelWorkspace as n, KritzelAnchorManager as o, KritzelThemeManager as p, DEFAULT_TEXT_CONFIG as q, DEFAULT_LINE_TOOL_CONFIG as r, lightTheme as s, darkTheme as t, KritzelAlignment as u, CURRENT_WORKSPACE_SCHEMA_VERSION as v, runMigrations as w, WORKSPACE_MIGRATIONS as x, KritzelColorHelper as y, KritzelDevicesHelper as z };
@@ -1 +1 @@
1
- import{H as a,a as T}from"./p-D48_Bqvh.js";export{A as APP_STATE_MIGRATIONS,C as CURRENT_APP_STATE_SCHEMA_VERSION,w as CURRENT_WORKSPACE_SCHEMA_VERSION,D as DEFAULT_BRUSH_CONFIG,s as DEFAULT_LINE_TOOL_CONFIG,r as DEFAULT_TEXT_CONFIG,I as IndexedDBSyncProvider,v as KritzelAlignment,p as KritzelAnchorManager,g as KritzelBrushTool,m as KritzelCursorHelper,i as KritzelEraserTool,e as KritzelGroup,c as KritzelImage,j as KritzelImageTool,d as KritzelLine,h as KritzelLineTool,b as KritzelPath,n as KritzelSelectionTool,f as KritzelShape,l as KritzelShapeTool,K as KritzelText,k as KritzelTextTool,q as KritzelThemeManager,o as KritzelWorkspace,S as ShapeType,W as WORKSPACE_EXPORT_VERSION,y as WORKSPACE_MIGRATIONS,u as darkTheme,t as lightTheme,x as runMigrations}from"./p-D48_Bqvh.js";import*as E from"yjs";import{WebsocketProvider as _}from"y-websocket";import"y-indexeddb";const z=Math.floor,P=127,R=Number.MAX_SAFE_INTEGER;class H{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const U=()=>new H,O=t=>{const e=new Uint8Array((t=>{let e=t.cpos;for(let s=0;s<t.bufs.length;s++)e+=t.bufs[s].length;return e})(t));let s=0;for(let i=0;i<t.bufs.length;i++){const n=t.bufs[i];e.set(n,s),s+=n.length}return e.set(new Uint8Array(t.cbuf.buffer,0,t.cpos),s),e},N=(t,e)=>{const s=t.cbuf.length;t.cpos===s&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(2*s),t.cpos=0),t.cbuf[t.cpos++]=e},B=(t,e)=>{for(;e>P;)N(t,128|P&e),e=z(e/128);N(t,P&e)},L=(t,e)=>{B(t,e.byteLength),((t,e)=>{const s=t.cbuf.length,i=t.cpos,n=((t,e)=>t<e?t:e)(s-i,e.length),o=e.length-n;t.cbuf.set(e.subarray(0,n),i),t.cpos+=n,o>0&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(((t,e)=>t>e?t:e)(2*s,o)),t.cbuf.set(e.subarray(n)),t.cpos=o)})(t,e)},M=t=>new Error(t),$=M("Unexpected end of array"),F=M("Integer out of Range");class G{constructor(t){this.arr=t,this.pos=0}}const V=t=>((t,e)=>{const s=new Uint8Array(t.arr.buffer,t.pos+t.arr.byteOffset,e);return t.pos+=e,s})(t,X(t)),X=t=>{let e=0,s=1;const i=t.arr.length;for(;t.pos<i;){const i=t.arr[t.pos++];if(e+=(i&P)*s,s*=128,i<128)return e;if(e>R)throw F}throw $};class J{type="local";doc;channel;_synced=!1;constructor(t,e,s){this.doc=e,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(t,e)=>{if(e!==this){const e=U();B(e,0),L(e,t),this.channel.postMessage(O(e))}};handleMessage(t){const e=(s=new Uint8Array(t),new G(s));var s;switch(X(e)){case 0:const t=V(e);E.applyUpdate(this.doc,t,this);break;case 1:this.broadcastSync();break;case 2:const s=V(e),i=E.encodeStateAsUpdate(this.doc,s);if(i.length>0){const t=U();B(t,0),L(t,i),this.channel.postMessage(O(t))}}}broadcastSync(){const t=U();B(t,2),L(t,E.encodeStateVector(this.doc)),this.channel.postMessage(O(t))}async connect(){if(!this._synced)return new Promise((t=>{const e=()=>{this._synced?t():setTimeout(e,50)};e()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class Q{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(t,e,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||t;this.provider=new _(i,n,e,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new Q(e,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,e)=>{const s=setTimeout((()=>{e(new Error("WebSocket connection timeout"))}),1e4),i=({status:e})=>{"connected"===e&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class Y{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(t,e,s){const i=s?.name||t,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||Y.sharedWebSocketProvider,c={};void 0!==s?.delay&&(c.delay=s.delay),void 0!==s?.factor&&(c.factor=s.factor),void 0!==s?.maxAttempts&&(c.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(c.minDelay=s.minDelay),void 0!==s?.maxDelay&&(c.maxDelay=s.maxDelay);const r=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info(`Hocuspocus connected: ${i}`),s?.onConnect&&s.onConnect())},h=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info(`Hocuspocus disconnected: ${i}`),s?.onDisconnect&&s.onDisconnect())},l=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info(`Hocuspocus synced: ${i}`),s?.onSynced&&s.onSynced())},u=t=>{this.isDestroyed||("connecting"===t.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(t))};if(o){this.usesSharedSocket=!0;const t={websocketProvider:o,name:i,document:e,token:s?.token||null,onStatus:u,onConnect:r,onDisconnect:h,onSynced:l,...c};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new a(t),this.provider.attach(),s?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:n,name:i,document:e,token:s?.token||null,autoConnect:!1,onStatus:u,onConnect:r,onDisconnect:h,onSynced:l,...c};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(t.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new a(t),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(t){if(Y.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),Y.sharedWebSocketProvider;const e={url:t.url};return t.WebSocketPolyfill&&(e.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(e.onConnect=t.onConnect),t.onDisconnect&&(e.onDisconnect=t.onDisconnect),t.onStatus&&(e.onStatus=t.onStatus),Y.sharedWebSocketProvider=new T(e),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),Y.sharedWebSocketProvider}static destroySharedWebSocket(){Y.sharedWebSocketProvider&&(Y.sharedWebSocketProvider.destroy(),Y.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return Y.sharedWebSocketProvider}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new Y(e,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((t,e)=>{this.pendingConnectReject=e,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,e(new Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||t()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void t();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}export{J as BroadcastSyncProvider,Y as HocuspocusSyncProvider,Q as WebSocketSyncProvider}
1
+ export{A as APP_STATE_MIGRATIONS,C as CURRENT_APP_STATE_SCHEMA_VERSION,v as CURRENT_WORKSPACE_SCHEMA_VERSION,D as DEFAULT_BRUSH_CONFIG,r as DEFAULT_LINE_TOOL_CONFIG,q as DEFAULT_TEXT_CONFIG,H as HocuspocusSyncProvider,I as IndexedDBSyncProvider,u as KritzelAlignment,o as KritzelAnchorManager,f as KritzelBrushTool,l as KritzelCursorHelper,h as KritzelEraserTool,d as KritzelGroup,b as KritzelImage,i as KritzelImageTool,c as KritzelLine,g as KritzelLineTool,a as KritzelPath,m as KritzelSelectionTool,e as KritzelShape,k as KritzelShapeTool,K as KritzelText,j as KritzelTextTool,p as KritzelThemeManager,n as KritzelWorkspace,S as ShapeType,W as WORKSPACE_EXPORT_VERSION,x as WORKSPACE_MIGRATIONS,t as darkTheme,s as lightTheme,w as runMigrations}from"./p-NhRgr2_H.js";import*as T from"yjs";import{WebsocketProvider as y}from"y-websocket";import"y-indexeddb";const E=Math.floor,_=127,z=Number.MAX_SAFE_INTEGER;class P{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const R=()=>new P,U=t=>{const s=new Uint8Array((t=>{let s=t.cpos;for(let e=0;e<t.bufs.length;e++)s+=t.bufs[e].length;return s})(t));let e=0;for(let i=0;i<t.bufs.length;i++){const r=t.bufs[i];s.set(r,e),e+=r.length}return s.set(new Uint8Array(t.cbuf.buffer,0,t.cpos),e),s},O=(t,s)=>{const e=t.cbuf.length;t.cpos===e&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(2*e),t.cpos=0),t.cbuf[t.cpos++]=s},N=(t,s)=>{for(;s>_;)O(t,128|_&s),s=E(s/128);O(t,_&s)},M=(t,s)=>{N(t,s.byteLength),((t,s)=>{const e=t.cbuf.length,i=t.cpos,r=((t,s)=>t<s?t:s)(e-i,s.length),n=s.length-r;t.cbuf.set(s.subarray(0,r),i),t.cpos+=r,n>0&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(((t,s)=>t>s?t:s)(2*e,n)),t.cbuf.set(s.subarray(r)),t.cpos=n)})(t,s)},L=t=>new Error(t),B=L("Unexpected end of array"),F=L("Integer out of Range");class G{constructor(t){this.arr=t,this.pos=0}}const V=t=>((t,s)=>{const e=new Uint8Array(t.arr.buffer,t.pos+t.arr.byteOffset,s);return t.pos+=s,e})(t,$(t)),$=t=>{let s=0,e=1;const i=t.arr.length;for(;t.pos<i;){const i=t.arr[t.pos++];if(s+=(i&_)*e,e*=128,i<128)return s;if(s>z)throw F}throw B};class X{type="local";doc;channel;_synced=!1;constructor(t,s,e){this.doc=s,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),e?.quiet||console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(t,s)=>{if(s!==this){const s=R();N(s,0),M(s,t),this.channel.postMessage(U(s))}};handleMessage(t){const s=(e=new Uint8Array(t),new G(e));var e;switch($(s)){case 0:const t=V(s);T.applyUpdate(this.doc,t,this);break;case 1:this.broadcastSync();break;case 2:const e=V(s),i=T.encodeStateAsUpdate(this.doc,e);if(i.length>0){const t=R();N(t,0),M(t,i),this.channel.postMessage(U(t))}}}broadcastSync(){const t=R();N(t,2),M(t,T.encodeStateVector(this.doc)),this.channel.postMessage(U(t))}async connect(){if(!this._synced)return new Promise((t=>{const s=()=>{this._synced?t():setTimeout(s,50)};s()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class J{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(t,s,e){const i=e?.url||"ws://localhost:1234",r=e?.roomName||t;this.provider=new y(i,r,s,{params:e?.params,protocols:e?.protocols,WebSocketPolyfill:e?.WebSocketPolyfill,awareness:e?.awareness,maxBackoffTime:e?.maxBackoffTime,disableBc:!0}),this._quiet=e?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${r}`)}static with(t){return{create:(s,e,i)=>{const r=i?{...t,...i}:t;return new J(s,e,r)}}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,s)=>{const e=setTimeout((()=>{s(new Error("WebSocket connection timeout"))}),1e4),i=({status:s})=>{"connected"===s&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}export{X as BroadcastSyncProvider,J as WebSocketSyncProvider}