kritzel-stencil 0.1.73 → 0.1.75

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 (188) hide show
  1. package/dist/cjs/index-Dc7LOVhs.js +2 -2
  2. package/dist/cjs/index.cjs.js +131 -86
  3. package/dist/cjs/{kritzel-active-users_41.cjs.entry.js → kritzel-active-users_42.cjs.entry.js} +593 -177
  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 +1 -1
  7. package/dist/cjs/{workspace.migrations-DcwqsqPC.js → workspace.migrations-DkmVO6dE.js} +164 -49
  8. package/dist/collection/classes/core/core.class.js +9 -1
  9. package/dist/collection/classes/core/store.class.js +20 -6
  10. package/dist/collection/classes/core/viewport.class.js +9 -3
  11. package/dist/collection/classes/handlers/selection.handler.js +15 -2
  12. package/dist/collection/classes/managers/anchor.manager.js +101 -44
  13. package/dist/collection/classes/objects/base-object.class.js +2 -0
  14. package/dist/collection/classes/objects/custom-element.class.js +1 -0
  15. package/dist/collection/classes/objects/group.class.js +1 -0
  16. package/dist/collection/classes/objects/image.class.js +1 -0
  17. package/dist/collection/classes/objects/line.class.js +1 -0
  18. package/dist/collection/classes/objects/path.class.js +1 -0
  19. package/dist/collection/classes/objects/selection-box.class.js +1 -0
  20. package/dist/collection/classes/objects/selection-group.class.js +13 -1
  21. package/dist/collection/classes/objects/shape.class.js +1 -0
  22. package/dist/collection/classes/objects/text.class.js +1 -0
  23. package/dist/collection/classes/providers/broadcast-sync-provider.class.js +5 -0
  24. package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js +120 -85
  25. package/dist/collection/classes/providers/indexeddb-sync-provider.class.js +5 -0
  26. package/dist/collection/classes/providers/websocket-sync-provider.class.js +5 -0
  27. package/dist/collection/classes/structures/app-state-map.structure.js +15 -4
  28. package/dist/collection/classes/structures/object-map.structure.js +85 -7
  29. package/dist/collection/classes/tools/brush-tool.class.js +4 -0
  30. package/dist/collection/classes/tools/line-tool.class.js +4 -0
  31. package/dist/collection/classes/tools/shape-tool.class.js +2 -0
  32. package/dist/collection/collection-manifest.json +3 -2
  33. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css +110 -0
  34. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +347 -0
  35. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
  36. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +3 -3
  37. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +150 -109
  38. package/dist/collection/components/shared/kritzel-avatar/kritzel-avatar.js +3 -3
  39. package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js +1 -1
  40. package/dist/collection/components/shared/kritzel-button/kritzel-button.js +2 -2
  41. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
  42. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
  43. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js +1 -1
  44. package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
  45. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
  46. package/dist/collection/components/shared/kritzel-input/kritzel-input.js +1 -1
  47. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.js +3 -3
  48. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
  49. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
  50. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.js +1 -1
  51. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.js +1 -1
  52. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
  53. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.js +1 -1
  54. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
  55. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
  56. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +2 -2
  57. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.js +1 -1
  58. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +1 -1
  59. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +5 -5
  60. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.js +1 -1
  61. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +1 -1
  62. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  63. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  64. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +1 -1
  65. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
  66. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
  67. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  68. package/dist/collection/constants/schema.constants.js +1 -1
  69. package/dist/collection/constants/version.js +1 -1
  70. package/dist/collection/interfaces/remote-cursor.interface.js +1 -0
  71. package/dist/collection/migrations/workspace.migrations.js +10 -1
  72. package/dist/components/index.d.ts +2 -0
  73. package/dist/components/index.js +1 -1
  74. package/dist/components/kritzel-active-users.js +1 -1
  75. package/dist/components/kritzel-avatar.js +1 -1
  76. package/dist/components/kritzel-awareness-cursors.d.ts +11 -0
  77. package/dist/components/kritzel-awareness-cursors.js +1 -0
  78. package/dist/components/kritzel-back-to-content.js +1 -1
  79. package/dist/components/kritzel-brush-style.js +1 -1
  80. package/dist/components/kritzel-button.js +1 -1
  81. package/dist/components/kritzel-color-palette.js +1 -1
  82. package/dist/components/kritzel-color.js +1 -1
  83. package/dist/components/kritzel-context-menu.js +1 -1
  84. package/dist/components/kritzel-controls.js +1 -1
  85. package/dist/components/kritzel-current-user-dialog.js +1 -1
  86. package/dist/components/kritzel-current-user.js +1 -1
  87. package/dist/components/kritzel-cursor-trail.js +1 -1
  88. package/dist/components/kritzel-dropdown.js +1 -1
  89. package/dist/components/kritzel-editor.js +1 -1
  90. package/dist/components/kritzel-engine.js +1 -1
  91. package/dist/components/kritzel-export.js +1 -1
  92. package/dist/components/kritzel-font-family.js +1 -1
  93. package/dist/components/kritzel-font-size.js +1 -1
  94. package/dist/components/kritzel-font.js +1 -1
  95. package/dist/components/kritzel-input.js +1 -1
  96. package/dist/components/kritzel-login-dialog.js +1 -1
  97. package/dist/components/kritzel-master-detail.js +1 -1
  98. package/dist/components/kritzel-menu-item.js +1 -1
  99. package/dist/components/kritzel-menu.js +1 -1
  100. package/dist/components/kritzel-more-menu.js +1 -1
  101. package/dist/components/kritzel-numeric-input.js +1 -1
  102. package/dist/components/kritzel-opacity-slider.js +1 -1
  103. package/dist/components/kritzel-portal.js +1 -1
  104. package/dist/components/kritzel-settings.js +1 -1
  105. package/dist/components/kritzel-share-dialog.js +1 -1
  106. package/dist/components/kritzel-slide-toggle.js +1 -1
  107. package/dist/components/kritzel-split-button.js +1 -1
  108. package/dist/components/kritzel-stroke-size.js +1 -1
  109. package/dist/components/kritzel-tool-config.js +1 -1
  110. package/dist/components/kritzel-tooltip.js +1 -1
  111. package/dist/components/kritzel-utility-panel.js +1 -1
  112. package/dist/components/kritzel-workspace-manager.js +1 -1
  113. package/dist/components/{p-Dp8idtVD.js → p-0kShCfeb.js} +1 -1
  114. package/dist/components/{p-B47JuZiD.js → p-2OYw6GJ7.js} +1 -1
  115. package/dist/components/p-7o2FWtFx.js +1 -0
  116. package/dist/components/{p-C5KuV1pK.js → p-BA0ayKqO.js} +1 -1
  117. package/dist/components/{p-NbNVTRk6.js → p-BEJQ2kP7.js} +1 -1
  118. package/dist/components/p-BSipRoFx.js +1 -0
  119. package/dist/components/{p-CDadAOMw.js → p-BeFUNGEI.js} +1 -1
  120. package/dist/components/{p-35nrk8s0.js → p-BiByyU2C.js} +1 -1
  121. package/dist/components/{p-CCAWSyDD.js → p-BiouZo1q.js} +1 -1
  122. package/dist/components/{p-CSExtYKI.js → p-ByR0VXeU.js} +1 -1
  123. package/dist/components/{p-1MGcXTLv.js → p-C1uR_ZNW.js} +1 -1
  124. package/dist/components/{p-x8PzaMuD.js → p-C69Stayh.js} +1 -1
  125. package/dist/components/{p-Ch0UlFwq.js → p-C7SBI_0T.js} +1 -1
  126. package/dist/components/{p-DEzfXrGX.js → p-CAIGuV2J.js} +1 -1
  127. package/dist/components/p-CJ2eHeoV.js +1 -0
  128. package/dist/components/p-CW-VyJgK.js +1 -0
  129. package/dist/components/{p-DW4ADV9w.js → p-CZhyKp-f.js} +1 -1
  130. package/dist/components/p-CsR4owzk.js +1 -0
  131. package/dist/components/{p-BG1IxseV.js → p-CsoDfhD5.js} +1 -1
  132. package/dist/components/{p-BgDhcDNw.js → p-D0MQFmqi.js} +1 -1
  133. package/dist/components/{p-DpFu5yAt.js → p-D1O7DxL4.js} +1 -1
  134. package/dist/components/{p-B5ouV8EQ.js → p-DRbG92F9.js} +1 -1
  135. package/dist/components/{p-C3eaM9TB.js → p-DS0xx1eT.js} +1 -1
  136. package/dist/components/{p-jx8VOz7S.js → p-DSzQ6H2j.js} +1 -1
  137. package/dist/components/{p-DsIlDGDO.js → p-DXjuuVq9.js} +1 -1
  138. package/dist/components/p-DXpYcAnT.js +1 -0
  139. package/dist/components/{p-DiFVw6IQ.js → p-Da46jw3N.js} +1 -1
  140. package/dist/components/{p-C6kZf91d.js → p-Dj_Qjga5.js} +1 -1
  141. package/dist/components/{p-Do0Q5-iC.js → p-DvIEvoZu.js} +1 -1
  142. package/dist/components/{p-CnVzLD5e.js → p-GYI7sDxr.js} +1 -1
  143. package/dist/components/{p-CcBM_ClD.js → p-HLbqRJGs.js} +1 -1
  144. package/dist/components/{p-VHyNcODZ.js → p-KQzWumjB.js} +1 -1
  145. package/dist/components/{p-VAkeZOZL.js → p-TyR-YTXm.js} +1 -1
  146. package/dist/components/p-WmxufeOo.js +9 -0
  147. package/dist/components/{p-CHtn5xr6.js → p-b4gyXoju.js} +1 -1
  148. package/dist/components/p-iRL0wQHQ.js +1 -0
  149. package/dist/components/{p-CqLaHE27.js → p-kj9wbLY8.js} +1 -1
  150. package/dist/components/{p-DaHq4iG1.js → p-xM-_OeRO.js} +1 -1
  151. package/dist/esm/index-MV-81ybv.js +2 -2
  152. package/dist/esm/index.js +132 -87
  153. package/dist/esm/{kritzel-active-users_41.entry.js → kritzel-active-users_42.entry.js} +593 -178
  154. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  155. package/dist/esm/loader.js +1 -1
  156. package/dist/esm/stencil.js +1 -1
  157. package/dist/esm/{workspace.migrations-BGixvB76.js → workspace.migrations-D48_Bqvh.js} +164 -49
  158. package/dist/stencil/index.esm.js +1 -1
  159. package/dist/stencil/p-0dbd9a2f.entry.js +9 -0
  160. package/dist/stencil/p-D48_Bqvh.js +1 -0
  161. package/dist/stencil/{p-016ad76a.entry.js → p-fc21e29c.entry.js} +1 -1
  162. package/dist/stencil/stencil.esm.js +1 -1
  163. package/dist/types/classes/core/store.class.d.ts +10 -2
  164. package/dist/types/classes/managers/anchor.manager.d.ts +4 -0
  165. package/dist/types/classes/objects/base-object.class.d.ts +1 -0
  166. package/dist/types/classes/objects/selection-group.class.d.ts +5 -0
  167. package/dist/types/classes/providers/broadcast-sync-provider.class.d.ts +2 -0
  168. package/dist/types/classes/providers/hocuspocus-sync-provider.class.d.ts +37 -1
  169. package/dist/types/classes/providers/indexeddb-sync-provider.class.d.ts +2 -0
  170. package/dist/types/classes/providers/websocket-sync-provider.class.d.ts +2 -0
  171. package/dist/types/classes/structures/object-map.structure.d.ts +38 -0
  172. package/dist/types/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.d.ts +26 -0
  173. package/dist/types/components.d.ts +39 -4
  174. package/dist/types/constants/schema.constants.d.ts +1 -1
  175. package/dist/types/constants/version.d.ts +1 -1
  176. package/dist/types/interfaces/object.interface.d.ts +1 -0
  177. package/dist/types/interfaces/remote-cursor.interface.d.ts +17 -0
  178. package/dist/types/interfaces/sync-provider.interface.d.ts +16 -0
  179. package/dist/types/interfaces/theme.interface.d.ts +7 -0
  180. package/package.json +1 -1
  181. package/dist/components/p-BvToKcu1.js +0 -1
  182. package/dist/components/p-By3NOY-k.js +0 -9
  183. package/dist/components/p-CNro30tB.js +0 -1
  184. package/dist/components/p-Duv3EM3w.js +0 -1
  185. package/dist/components/p-KFsLHwYm.js +0 -1
  186. package/dist/components/p-hCORwbZh.js +0 -1
  187. package/dist/stencil/p-67c79d75.entry.js +0 -9
  188. package/dist/stencil/p-BGixvB76.js +0 -1
@@ -132,10 +132,10 @@ var loadModule = (cmpMeta, hostRef, hmrVersionId) => {
132
132
  }
133
133
  switch(bundleId) {
134
134
 
135
- case 'kritzel-active-users_41.cjs':
135
+ case 'kritzel-active-users_42.cjs':
136
136
  return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(
137
137
  /* webpackMode: "lazy" */
138
- './kritzel-active-users_41.cjs.entry.js')); }).then(processMod, consoleError);
138
+ './kritzel-active-users_42.cjs.entry.js')); }).then(processMod, consoleError);
139
139
  case 'kritzel-brush-style.cjs':
140
140
  return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(
141
141
  /* webpackMode: "lazy" */
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var workspace_migrations = require('./workspace.migrations-DcwqsqPC.js');
3
+ var workspace_migrations = require('./workspace.migrations-DkmVO6dE.js');
4
4
  var Y = require('yjs');
5
5
  var yWebsocket = require('y-websocket');
6
6
  require('y-indexeddb');
@@ -360,6 +360,7 @@ const readVarUint = decoder => {
360
360
  * This is a lightweight alternative to y-webrtc for browser-tab-only sync
361
361
  */
362
362
  class BroadcastSyncProvider {
363
+ type = 'local';
363
364
  doc;
364
365
  channel;
365
366
  _synced = false;
@@ -441,6 +442,10 @@ class BroadcastSyncProvider {
441
442
  disconnect() {
442
443
  // BroadcastChannel doesn't have explicit disconnect
443
444
  }
445
+ async reconnect() {
446
+ this.disconnect();
447
+ return this.connect();
448
+ }
444
449
  destroy() {
445
450
  this.doc.off('update', this.handleDocUpdate);
446
451
  this.channel.close();
@@ -451,6 +456,7 @@ class BroadcastSyncProvider {
451
456
  * WebSocket sync provider for real-time collaboration
452
457
  */
453
458
  class WebSocketSyncProvider {
459
+ type = 'network';
454
460
  provider;
455
461
  isConnected = false;
456
462
  _quiet = false;
@@ -539,6 +545,10 @@ class WebSocketSyncProvider {
539
545
  }
540
546
  this.isConnected = false;
541
547
  }
548
+ async reconnect() {
549
+ this.disconnect();
550
+ return this.connect();
551
+ }
542
552
  destroy() {
543
553
  if (this.provider) {
544
554
  this.provider.destroy();
@@ -552,6 +562,7 @@ class WebSocketSyncProvider {
552
562
  * Supports multiplexing - multiple documents can share the same WebSocket connection
553
563
  */
554
564
  class HocuspocusSyncProvider {
565
+ type = 'network';
555
566
  provider;
556
567
  isConnected = false;
557
568
  isSynced = false;
@@ -559,16 +570,87 @@ class HocuspocusSyncProvider {
559
570
  isDestroyed = false;
560
571
  connectTimeout = null;
561
572
  pendingConnectReject = null;
573
+ connectionTimeoutMs;
574
+ _connectionStatus = 'disconnected';
575
+ visibilityHandler = null;
576
+ onlineHandler = null;
562
577
  get awareness() {
563
578
  return this.provider.awareness;
564
579
  }
580
+ get connectionStatus() {
581
+ return this._connectionStatus;
582
+ }
565
583
  // Static shared WebSocket instance for multiplexing
566
584
  static sharedWebSocketProvider = null;
567
585
  constructor(docName, doc, options) {
568
586
  const name = options?.name || docName;
569
587
  const url = options?.url || 'ws://localhost:1234';
588
+ this.connectionTimeoutMs = options?.connectionTimeout ?? 10000;
570
589
  // Use provided websocketProvider or the static shared one
571
590
  const websocketProvider = options?.websocketProvider || HocuspocusSyncProvider.sharedWebSocketProvider;
591
+ // Build reconnect config from options
592
+ const reconnectConfig = {};
593
+ if (options?.delay !== undefined)
594
+ reconnectConfig.delay = options.delay;
595
+ if (options?.factor !== undefined)
596
+ reconnectConfig.factor = options.factor;
597
+ if (options?.maxAttempts !== undefined)
598
+ reconnectConfig.maxAttempts = options.maxAttempts;
599
+ if (options?.minDelay !== undefined)
600
+ reconnectConfig.minDelay = options.minDelay;
601
+ if (options?.maxDelay !== undefined)
602
+ reconnectConfig.maxDelay = options.maxDelay;
603
+ const onConnect = () => {
604
+ if (this.isDestroyed) {
605
+ return;
606
+ }
607
+ this.isConnected = true;
608
+ this._connectionStatus = 'connected';
609
+ if (!options?.quiet) {
610
+ console.info(`Hocuspocus connected: ${name}`);
611
+ }
612
+ if (options?.onConnect) {
613
+ options.onConnect();
614
+ }
615
+ };
616
+ const onDisconnect = () => {
617
+ if (this.isDestroyed) {
618
+ return;
619
+ }
620
+ this.isConnected = false;
621
+ this.isSynced = false;
622
+ this._connectionStatus = 'disconnected';
623
+ if (!options?.quiet) {
624
+ console.info(`Hocuspocus disconnected: ${name}`);
625
+ }
626
+ if (options?.onDisconnect) {
627
+ options.onDisconnect();
628
+ }
629
+ };
630
+ const onSynced = () => {
631
+ if (this.isDestroyed) {
632
+ return;
633
+ }
634
+ this.isSynced = true;
635
+ this._connectionStatus = 'synced';
636
+ if (!options?.quiet) {
637
+ console.info(`Hocuspocus synced: ${name}`);
638
+ }
639
+ if (options?.onSynced) {
640
+ options.onSynced();
641
+ }
642
+ };
643
+ const onStatus = (data) => {
644
+ if (this.isDestroyed) {
645
+ return;
646
+ }
647
+ if (data.status === 'connecting') {
648
+ this._connectionStatus = 'connecting';
649
+ }
650
+ if (options?.onStatus) {
651
+ options.onStatus(data);
652
+ }
653
+ };
572
654
  if (websocketProvider) {
573
655
  // Multiplexing mode - use shared WebSocket connection
574
656
  this.usesSharedSocket = true;
@@ -577,48 +659,11 @@ class HocuspocusSyncProvider {
577
659
  name,
578
660
  document: doc,
579
661
  token: options?.token || null,
580
- onStatus: (data) => {
581
- if (options?.onStatus) {
582
- options.onStatus(data);
583
- }
584
- },
585
- onConnect: () => {
586
- if (this.isConnected || this.isDestroyed) {
587
- return;
588
- }
589
- this.isConnected = true;
590
- if (!options?.quiet) {
591
- console.info(`Hocuspocus connected: ${name}`);
592
- }
593
- if (options?.onConnect) {
594
- options.onConnect();
595
- }
596
- },
597
- onDisconnect: () => {
598
- if (this.isDestroyed || (!this.isConnected && !this.isSynced)) {
599
- return;
600
- }
601
- this.isConnected = false;
602
- this.isSynced = false;
603
- if (!options?.quiet) {
604
- console.info(`Hocuspocus disconnected: ${name}`);
605
- }
606
- if (options?.onDisconnect) {
607
- options.onDisconnect();
608
- }
609
- },
610
- onSynced: () => {
611
- if (this.isSynced || this.isDestroyed) {
612
- return;
613
- }
614
- this.isSynced = true;
615
- if (!options?.quiet) {
616
- console.info(`Hocuspocus synced: ${name}`);
617
- }
618
- if (options?.onSynced) {
619
- options.onSynced();
620
- }
621
- },
662
+ onStatus,
663
+ onConnect,
664
+ onDisconnect,
665
+ onSynced,
666
+ ...reconnectConfig,
622
667
  };
623
668
  // Add optional settings
624
669
  if (options?.forceSyncInterval !== undefined) {
@@ -643,48 +688,11 @@ class HocuspocusSyncProvider {
643
688
  document: doc,
644
689
  token: options?.token || null,
645
690
  autoConnect: false,
646
- onStatus: (data) => {
647
- if (options?.onStatus) {
648
- options.onStatus(data);
649
- }
650
- },
651
- onConnect: () => {
652
- if (this.isConnected || this.isDestroyed) {
653
- return;
654
- }
655
- this.isConnected = true;
656
- if (!options?.quiet) {
657
- console.info(`Hocuspocus connected: ${name}`);
658
- }
659
- if (options?.onConnect) {
660
- options.onConnect();
661
- }
662
- },
663
- onDisconnect: () => {
664
- if (this.isDestroyed || (!this.isConnected && !this.isSynced)) {
665
- return;
666
- }
667
- this.isConnected = false;
668
- this.isSynced = false;
669
- if (!options?.quiet) {
670
- console.info(`Hocuspocus disconnected: ${name}`);
671
- }
672
- if (options?.onDisconnect) {
673
- options.onDisconnect();
674
- }
675
- },
676
- onSynced: () => {
677
- if (this.isSynced || this.isDestroyed) {
678
- return;
679
- }
680
- this.isSynced = true;
681
- if (!options?.quiet) {
682
- console.info(`Hocuspocus synced: ${name}`);
683
- }
684
- if (options?.onSynced) {
685
- options.onSynced();
686
- }
687
- },
691
+ onStatus,
692
+ onConnect,
693
+ onDisconnect,
694
+ onSynced,
695
+ ...reconnectConfig,
688
696
  };
689
697
  // Add optional settings
690
698
  if (options?.forceSyncInterval !== undefined) {
@@ -701,6 +709,35 @@ class HocuspocusSyncProvider {
701
709
  console.info(`Hocuspocus Provider initialized: ${url}/${name}`);
702
710
  }
703
711
  }
712
+ this.setupBrowserEventListeners();
713
+ }
714
+ setupBrowserEventListeners() {
715
+ if (typeof document !== 'undefined') {
716
+ this.visibilityHandler = () => {
717
+ if (document.visibilityState === 'visible' && !this.isConnected && !this.isDestroyed) {
718
+ this.provider.connect();
719
+ }
720
+ };
721
+ document.addEventListener('visibilitychange', this.visibilityHandler);
722
+ }
723
+ if (typeof window !== 'undefined') {
724
+ this.onlineHandler = () => {
725
+ if (!this.isConnected && !this.isDestroyed) {
726
+ this.provider.connect();
727
+ }
728
+ };
729
+ window.addEventListener('online', this.onlineHandler);
730
+ }
731
+ }
732
+ removeBrowserEventListeners() {
733
+ if (this.visibilityHandler && typeof document !== 'undefined') {
734
+ document.removeEventListener('visibilitychange', this.visibilityHandler);
735
+ this.visibilityHandler = null;
736
+ }
737
+ if (this.onlineHandler && typeof window !== 'undefined') {
738
+ window.removeEventListener('online', this.onlineHandler);
739
+ this.onlineHandler = null;
740
+ }
704
741
  }
705
742
  /**
706
743
  * Create a shared WebSocket connection for multiplexing
@@ -763,6 +800,7 @@ class HocuspocusSyncProvider {
763
800
  if (this.isSynced || this.isDestroyed) {
764
801
  return;
765
802
  }
803
+ this._connectionStatus = 'connecting';
766
804
  return new Promise((resolve, reject) => {
767
805
  // Store reject function so we can cancel the connection if destroyed
768
806
  this.pendingConnectReject = reject;
@@ -770,7 +808,7 @@ class HocuspocusSyncProvider {
770
808
  this.pendingConnectReject = null;
771
809
  this.connectTimeout = null;
772
810
  reject(new Error('Hocuspocus connection timeout'));
773
- }, 10000); // 10 second timeout
811
+ }, this.connectionTimeoutMs);
774
812
  const syncHandler = () => {
775
813
  if (this.connectTimeout) {
776
814
  clearTimeout(this.connectTimeout);
@@ -800,6 +838,10 @@ class HocuspocusSyncProvider {
800
838
  }
801
839
  });
802
840
  }
841
+ async reconnect() {
842
+ this.disconnect();
843
+ return this.connect();
844
+ }
803
845
  disconnect() {
804
846
  // Cancel any pending connection attempt
805
847
  if (this.connectTimeout) {
@@ -820,6 +862,7 @@ class HocuspocusSyncProvider {
820
862
  }
821
863
  this.isConnected = false;
822
864
  this.isSynced = false;
865
+ this._connectionStatus = 'disconnected';
823
866
  }
824
867
  destroy() {
825
868
  // Mark as destroyed first to prevent any callbacks from doing work
@@ -832,11 +875,13 @@ class HocuspocusSyncProvider {
832
875
  if (this.pendingConnectReject) {
833
876
  this.pendingConnectReject = null; // Don't reject, just abandon the promise
834
877
  }
878
+ this.removeBrowserEventListeners();
835
879
  if (this.provider) {
836
880
  this.provider.destroy();
837
881
  }
838
882
  this.isConnected = false;
839
883
  this.isSynced = false;
884
+ this._connectionStatus = 'disconnected';
840
885
  }
841
886
  }
842
887