kritzel-stencil 0.1.46 → 0.1.47

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 (30) hide show
  1. package/dist/cjs/index.cjs.js +39 -9
  2. package/dist/cjs/kritzel-active-users_38.cjs.entry.js +40 -14
  3. package/dist/collection/classes/providers/broadcast-sync-provider.class.js +3 -1
  4. package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js +21 -2
  5. package/dist/collection/classes/providers/websocket-sync-provider.class.js +15 -6
  6. package/dist/collection/classes/structures/app-state-map.structure.js +3 -2
  7. package/dist/collection/classes/structures/object-map.structure.js +3 -2
  8. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +1 -2
  9. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +30 -6
  10. package/dist/collection/configs/default-engine-config.js +2 -1
  11. package/dist/collection/constants/version.js +1 -1
  12. package/dist/components/index.js +1 -1
  13. package/dist/components/kritzel-editor.js +1 -1
  14. package/dist/components/kritzel-engine.js +1 -1
  15. package/dist/components/kritzel-settings.js +1 -1
  16. package/dist/components/{p-Dn3QBIRf.js → p-DbRfuRFb.js} +2 -2
  17. package/dist/components/{p-B6QKNHJJ.js → p-Twjj9gUr.js} +1 -1
  18. package/dist/esm/index.js +39 -9
  19. package/dist/esm/kritzel-active-users_38.entry.js +40 -14
  20. package/dist/stencil/index.esm.js +1 -1
  21. package/dist/stencil/p-fd4ec8dc.entry.js +9 -0
  22. package/dist/stencil/stencil.esm.js +1 -1
  23. package/dist/types/classes/providers/broadcast-sync-provider.class.d.ts +3 -1
  24. package/dist/types/classes/providers/websocket-sync-provider.class.d.ts +5 -0
  25. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +3 -0
  26. package/dist/types/constants/version.d.ts +1 -1
  27. package/dist/types/interfaces/debug-info.interface.d.ts +1 -0
  28. package/dist/types/interfaces/sync-provider.interface.d.ts +3 -1
  29. package/package.json +1 -1
  30. package/dist/stencil/p-676eac95.entry.js +0 -9
@@ -378,7 +378,9 @@ class BroadcastSyncProvider {
378
378
  setTimeout(() => {
379
379
  this._synced = true;
380
380
  }, 100);
381
- console.info(`BroadcastChannel Provider initialized: ${docName}`);
381
+ if (!_options?.quiet) {
382
+ console.info(`BroadcastChannel Provider initialized: ${docName}`);
383
+ }
382
384
  }
383
385
  handleDocUpdate = (update, origin) => {
384
386
  // Don't broadcast updates that came from other tabs (to prevent loops)
@@ -451,6 +453,7 @@ class BroadcastSyncProvider {
451
453
  class WebSocketSyncProvider {
452
454
  provider;
453
455
  isConnected = false;
456
+ _quiet = false;
454
457
  constructor(docName, doc, options) {
455
458
  const url = options?.url || 'ws://localhost:1234';
456
459
  const roomName = options?.roomName || docName;
@@ -462,8 +465,11 @@ class WebSocketSyncProvider {
462
465
  maxBackoffTime: options?.maxBackoffTime,
463
466
  disableBc: true,
464
467
  });
468
+ this._quiet = options?.quiet ?? false;
465
469
  this.setupEventListeners();
466
- console.info(`WebSocket Provider initialized: ${url}/${roomName}`);
470
+ if (!this._quiet) {
471
+ console.info(`WebSocket Provider initialized: ${url}/${roomName}`);
472
+ }
467
473
  }
468
474
  /**
469
475
  * Static factory method for creating WebSocketSyncProvider with configuration options
@@ -471,8 +477,9 @@ class WebSocketSyncProvider {
471
477
  */
472
478
  static with(options) {
473
479
  return {
474
- create: (docName, doc) => {
475
- return new WebSocketSyncProvider(docName, doc, options);
480
+ create: (docName, doc, runtimeOptions) => {
481
+ const mergedOptions = runtimeOptions ? { ...options, ...runtimeOptions } : options;
482
+ return new WebSocketSyncProvider(docName, doc, mergedOptions);
476
483
  },
477
484
  };
478
485
  }
@@ -480,15 +487,19 @@ class WebSocketSyncProvider {
480
487
  this.provider.on('status', ({ status }) => {
481
488
  if (status === 'connected') {
482
489
  this.isConnected = true;
483
- console.info('WebSocket connected');
490
+ if (!this._quiet) {
491
+ console.info('WebSocket connected');
492
+ }
484
493
  }
485
494
  else if (status === 'disconnected') {
486
495
  this.isConnected = false;
487
- console.info('WebSocket disconnected');
496
+ if (!this._quiet) {
497
+ console.info('WebSocket disconnected');
498
+ }
488
499
  }
489
500
  });
490
501
  this.provider.on('sync', (synced) => {
491
- if (synced) {
502
+ if (synced && !this._quiet) {
492
503
  console.info('WebSocket synced');
493
504
  }
494
505
  });
@@ -3362,6 +3373,9 @@ class HocuspocusSyncProvider {
3362
3373
  document: doc,
3363
3374
  token: options?.token || null,
3364
3375
  onConnect: () => {
3376
+ if (this.isConnected) {
3377
+ return;
3378
+ }
3365
3379
  this.isConnected = true;
3366
3380
  if (!options?.quiet) {
3367
3381
  console.info(`Hocuspocus connected: ${name}`);
@@ -3371,6 +3385,9 @@ class HocuspocusSyncProvider {
3371
3385
  }
3372
3386
  },
3373
3387
  onDisconnect: () => {
3388
+ if (!this.isConnected && !this.isSynced) {
3389
+ return;
3390
+ }
3374
3391
  this.isConnected = false;
3375
3392
  this.isSynced = false;
3376
3393
  if (!options?.quiet) {
@@ -3381,6 +3398,9 @@ class HocuspocusSyncProvider {
3381
3398
  }
3382
3399
  },
3383
3400
  onSynced: () => {
3401
+ if (this.isSynced) {
3402
+ return;
3403
+ }
3384
3404
  this.isSynced = true;
3385
3405
  if (!options?.quiet) {
3386
3406
  console.info(`Hocuspocus synced: ${name}`);
@@ -3416,6 +3436,9 @@ class HocuspocusSyncProvider {
3416
3436
  document: doc,
3417
3437
  token: options?.token || null,
3418
3438
  onConnect: () => {
3439
+ if (this.isConnected) {
3440
+ return;
3441
+ }
3419
3442
  this.isConnected = true;
3420
3443
  if (!options?.quiet) {
3421
3444
  console.info(`Hocuspocus connected: ${name}`);
@@ -3425,6 +3448,9 @@ class HocuspocusSyncProvider {
3425
3448
  }
3426
3449
  },
3427
3450
  onDisconnect: () => {
3451
+ if (!this.isConnected && !this.isSynced) {
3452
+ return;
3453
+ }
3428
3454
  this.isConnected = false;
3429
3455
  this.isSynced = false;
3430
3456
  if (!options?.quiet) {
@@ -3435,6 +3461,9 @@ class HocuspocusSyncProvider {
3435
3461
  }
3436
3462
  },
3437
3463
  onSynced: () => {
3464
+ if (this.isSynced) {
3465
+ return;
3466
+ }
3438
3467
  this.isSynced = true;
3439
3468
  if (!options?.quiet) {
3440
3469
  console.info(`Hocuspocus synced: ${name}`);
@@ -3514,8 +3543,9 @@ class HocuspocusSyncProvider {
3514
3543
  */
3515
3544
  static with(options) {
3516
3545
  return {
3517
- create: (docName, doc) => {
3518
- return new HocuspocusSyncProvider(docName, doc, options);
3546
+ create: (docName, doc, runtimeOptions) => {
3547
+ const mergedOptions = runtimeOptions ? { ...options, ...runtimeOptions } : options;
3548
+ return new HocuspocusSyncProvider(docName, doc, mergedOptions);
3519
3549
  },
3520
3550
  };
3521
3551
  }
@@ -1991,7 +1991,6 @@ const KritzelEditor = class {
1991
1991
  this.registerCustomSvgIcons();
1992
1992
  this.listenForMobileKeyboard();
1993
1993
  this.setOsSpecificCssVariables();
1994
- console.log('loaded editor');
1995
1994
  }
1996
1995
  async checkIsReady() {
1997
1996
  await customElements.whenDefined('kritzel-editor');
@@ -2184,7 +2183,7 @@ const KritzelEditor = class {
2184
2183
  }
2185
2184
  }
2186
2185
  render() {
2187
- return (index.h(index.Host, { key: '496c072de4cb9d0998b4b93d41b6f34d2594336f' }, index.h("div", { key: '61640aefd176f9d2056c55658121754bf656d7a8', class: "top-left-buttons" }, index.h("kritzel-workspace-manager", { key: 'ad017b4dadf7edae048fd69d40d89bef07fad6f4', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), index.h("kritzel-back-to-content", { key: '65c24099b16c6f009f133709cc82e53e3689b2d9', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), index.h("kritzel-engine", { key: 'c2fc4b7e0b91f748fd4fbc3a34d5d5f9f67e5bfe', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event) }), index.h("kritzel-controls", { key: '5caefbd8d401d9a056f9d2ce67d72d86f7fc63c1', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), index.h("div", { key: 'e52903a9bfa8ed18e5897a8cb5789be9416aab85', class: "top-right-buttons" }, index.h("kritzel-settings", { key: 'd2a9153401a6da7d12e334b0b11227e258f31a65', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), index.h("kritzel-export", { key: 'b72e97833be9fe13a630f055e48530924336813b', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: (event) => this.engineRef.downloadAsJson(event.detail) }), index.h("kritzel-active-users", { key: '2c2c994023eda91cc3f30e8341d1c854d0673a2a', users: this.activeUsers }), index.h("kritzel-current-user", { key: 'e650e21eed5f3136727b92b521fa4afa09d7d66a', user: this.user, onItemSelect: event => this.handleCurrentUserItemSelect(event) }), index.h("kritzel-more-menu", { key: '543e84bcbd99cbf9d101c346d571ec6a1d6db1fd', onItemSelect: event => this.handleMoreMenuItemSelect(event) }), index.h("kritzel-share-dialog", { key: '3ed56d1dbaff240a7fa90331bb2244dd836ff7f3', ref: el => (this.shareDialogRef = el), linkShare: this.currentLinkShare, workspaceId: this.activeWorkspace?.id, onToggleLinkShare: this.handleToggleLinkShare, onPermissionChange: this.handleSharePermissionChange }))));
2186
+ return (index.h(index.Host, { key: '90a91249e483f27f52c6677483793a00e78e7488' }, index.h("div", { key: 'be2392052be658194bc00c029abe883ce3fb4a79', class: "top-left-buttons" }, index.h("kritzel-workspace-manager", { key: '3e0a4004dccbada37f1008c77ac143e453714db5', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), index.h("kritzel-back-to-content", { key: 'f6d11f6e0bc0a0be10bab2c5757fadd18d0a305c', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), index.h("kritzel-engine", { key: 'a5720d2e7d7a2e257f17fd0e68a53d33b4bef711', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event) }), index.h("kritzel-controls", { key: '1324b903ea3cc8296467465a9524b812e65dd627', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), index.h("div", { key: '7b535fd7cd96bf64f64011b7cc30f8bd471b3bb6', class: "top-right-buttons" }, index.h("kritzel-settings", { key: '483995f3e3b81a381828d9dd0d2e25afb8a48966', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), index.h("kritzel-export", { key: '8697a908a01a0cf6143b3822c232afd047e389a5', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: (event) => this.engineRef.downloadAsJson(event.detail) }), index.h("kritzel-active-users", { key: '85a54896088999df529e70d524c775e92dcf5e6b', users: this.activeUsers }), index.h("kritzel-current-user", { key: 'cbcd428a95c2ab260f5fe175e75bbf9018de5c21', user: this.user, onItemSelect: event => this.handleCurrentUserItemSelect(event) }), index.h("kritzel-more-menu", { key: '972cc8721173cb2ed8ba448d9690e31e0a9321e1', onItemSelect: event => this.handleMoreMenuItemSelect(event) }), index.h("kritzel-share-dialog", { key: '3c5e325ca58af4f5c09e25bf8e059471f5e178d1', ref: el => (this.shareDialogRef = el), linkShare: this.currentLinkShare, workspaceId: this.activeWorkspace?.id, onToggleLinkShare: this.handleToggleLinkShare, onPermissionChange: this.handleSharePermissionChange }))));
2188
2187
  }
2189
2188
  static get watchers() { return {
2190
2189
  "isEngineReady": [{
@@ -20512,7 +20511,8 @@ const DEFAULT_ENGINE_CONFIG = {
20512
20511
  skipContextMenu: false,
20513
20512
  debugInfo: {
20514
20513
  showObjectInfo: false,
20515
- showViewportInfo: false
20514
+ showViewportInfo: false,
20515
+ showSyncProviderInfo: false
20516
20516
  },
20517
20517
  host: null,
20518
20518
  pointerX: 0,
@@ -20968,16 +20968,17 @@ class KritzelObjectMap {
20968
20968
  const docName = core.editorId ? `kritzel-workspace-${core.editorId}-${workspaceId}` : `kritzel-workspace-${workspaceId}`;
20969
20969
  const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
20970
20970
  // Instantiate providers from configuration
20971
+ const quiet = !core.store.state.debugInfo.showSyncProviderInfo;
20971
20972
  for (const providerConfig of finalConfig.providers) {
20972
20973
  let provider;
20973
20974
  // Check if it's a class constructor or a factory
20974
20975
  if (typeof providerConfig === 'function') {
20975
20976
  // It's a class constructor
20976
- provider = new providerConfig(docName, this._ydoc);
20977
+ provider = new providerConfig(docName, this._ydoc, { quiet });
20977
20978
  }
20978
20979
  else {
20979
20980
  // It's a factory with a create method
20980
- provider = providerConfig.create(docName, this._ydoc);
20981
+ provider = providerConfig.create(docName, this._ydoc, { quiet });
20981
20982
  }
20982
20983
  this._providers.push(provider);
20983
20984
  }
@@ -21781,16 +21782,17 @@ class KritzelAppStateMap {
21781
21782
  const docName = core.editorId ? `kritzel-app-state-${core.editorId}` : 'kritzel-app-state';
21782
21783
  const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
21783
21784
  // Instantiate providers from configuration
21785
+ const quiet = !core.store.state.debugInfo.showSyncProviderInfo;
21784
21786
  for (const providerConfig of finalConfig.providers) {
21785
21787
  let provider;
21786
21788
  // Check if it's a class constructor or a factory
21787
21789
  if (typeof providerConfig === 'function') {
21788
21790
  // It's a class constructor
21789
- provider = new providerConfig(docName, this._ydoc);
21791
+ provider = new providerConfig(docName, this._ydoc, { quiet });
21790
21792
  }
21791
21793
  else {
21792
21794
  // It's a factory with a create method
21793
- provider = providerConfig.create(docName, this._ydoc);
21795
+ provider = providerConfig.create(docName, this._ydoc, { quiet });
21794
21796
  }
21795
21797
  this._providers.push(provider);
21796
21798
  }
@@ -24657,7 +24659,7 @@ const KritzelEngine = class {
24657
24659
  return;
24658
24660
  }
24659
24661
  this.core.beforeWorkspaceChange();
24660
- await this.core.initializeWorkspace(newWorkspace);
24662
+ await this.initializeWorkspaceIfNeeded(newWorkspace);
24661
24663
  this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
24662
24664
  }
24663
24665
  /** Optional unique identifier for namespacing storage keys across multiple editor instances. */
@@ -25730,6 +25732,8 @@ const KritzelEngine = class {
25730
25732
  _isYjsInitialized = false;
25731
25733
  _isResolvingActiveWorkspaceId = false;
25732
25734
  _stateChangeListenersRegistered = false;
25735
+ _workspaceInitializationPromise = null;
25736
+ _workspaceInitializationTargetKey = null;
25733
25737
  get isSelecting() {
25734
25738
  return this.core.store.state.activeTool instanceof alignment_enum.KritzelSelectionTool && this.core.store.state.isSelecting;
25735
25739
  }
@@ -25791,7 +25795,6 @@ const KritzelEngine = class {
25791
25795
  this.core.store.state.isReady = true;
25792
25796
  this.isEngineReady.emit(this.core.store.state);
25793
25797
  }
25794
- console.log('loaded engine');
25795
25798
  }
25796
25799
  async initializeSyncAndWorkspace() {
25797
25800
  // Set sync configuration if provided
@@ -25806,17 +25809,17 @@ const KritzelEngine = class {
25806
25809
  if (this.activeWorkspaceId) {
25807
25810
  const startupWorkspace = this.core.getWorkspaces().find(ws => ws.id === this.activeWorkspaceId);
25808
25811
  if (startupWorkspace) {
25809
- await this.core.initializeWorkspace(startupWorkspace);
25812
+ await this.initializeWorkspaceIfNeeded(startupWorkspace);
25810
25813
  }
25811
25814
  else {
25812
25815
  // When a specific workspace ID is requested, do not create a fallback workspace.
25813
- await this.core.initializeWorkspace(undefined, { skipFallbackCreation: true });
25816
+ await this.initializeWorkspaceIfNeeded(undefined, { skipFallbackCreation: true });
25814
25817
  }
25815
25818
  }
25816
25819
  else {
25817
25820
  // Resolve startup workspace, preferring explicit workspace object when provided.
25818
25821
  const startupWorkspace = this.resolveStartupWorkspace();
25819
- await this.core.initializeWorkspace(startupWorkspace);
25822
+ await this.initializeWorkspaceIfNeeded(startupWorkspace);
25820
25823
  }
25821
25824
  // Emit initial active workspace once startup initialization has completed
25822
25825
  const initialActiveWorkspace = this.core.store.state.activeWorkspace;
@@ -25868,9 +25871,32 @@ const KritzelEngine = class {
25868
25871
  return;
25869
25872
  }
25870
25873
  this.core.beforeWorkspaceChange();
25871
- await this.core.initializeWorkspace(workspace);
25874
+ await this.initializeWorkspaceIfNeeded(workspace);
25872
25875
  this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
25873
25876
  }
25877
+ async initializeWorkspaceIfNeeded(workspace, options) {
25878
+ const targetWorkspaceId = workspace?.id ?? null;
25879
+ const targetKey = targetWorkspaceId ?? (options?.skipFallbackCreation ? '__NO_FALLBACK__' : '__AUTO__');
25880
+ if (targetWorkspaceId && this.core.store.state.activeWorkspace?.id === targetWorkspaceId) {
25881
+ return;
25882
+ }
25883
+ if (this._workspaceInitializationPromise && this._workspaceInitializationTargetKey === targetKey) {
25884
+ await this._workspaceInitializationPromise;
25885
+ return;
25886
+ }
25887
+ const initializationPromise = this.core.initializeWorkspace(workspace, options);
25888
+ this._workspaceInitializationPromise = initializationPromise;
25889
+ this._workspaceInitializationTargetKey = targetKey;
25890
+ try {
25891
+ await initializationPromise;
25892
+ }
25893
+ finally {
25894
+ if (this._workspaceInitializationPromise === initializationPromise) {
25895
+ this._workspaceInitializationPromise = null;
25896
+ this._workspaceInitializationTargetKey = null;
25897
+ }
25898
+ }
25899
+ }
25874
25900
  emitObjectsChange() {
25875
25901
  const objects = this.core.store.allObjects;
25876
25902
  const undoState = this.core.store.state.objects.undoState;
@@ -27488,7 +27514,7 @@ const KritzelPortal = class {
27488
27514
  * This file is auto-generated by the version bump scripts.
27489
27515
  * Do not modify manually.
27490
27516
  */
27491
- const KRITZEL_VERSION = '0.1.46';
27517
+ const KRITZEL_VERSION = '0.1.47';
27492
27518
 
27493
27519
  const kritzelSettingsCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}`;
27494
27520
 
@@ -24,7 +24,9 @@ export class BroadcastSyncProvider {
24
24
  setTimeout(() => {
25
25
  this._synced = true;
26
26
  }, 100);
27
- console.info(`BroadcastChannel Provider initialized: ${docName}`);
27
+ if (!_options?.quiet) {
28
+ console.info(`BroadcastChannel Provider initialized: ${docName}`);
29
+ }
28
30
  }
29
31
  handleDocUpdate = (update, origin) => {
30
32
  // Don't broadcast updates that came from other tabs (to prevent loops)
@@ -24,6 +24,9 @@ export class HocuspocusSyncProvider {
24
24
  document: doc,
25
25
  token: options?.token || null,
26
26
  onConnect: () => {
27
+ if (this.isConnected) {
28
+ return;
29
+ }
27
30
  this.isConnected = true;
28
31
  if (!options?.quiet) {
29
32
  console.info(`Hocuspocus connected: ${name}`);
@@ -33,6 +36,9 @@ export class HocuspocusSyncProvider {
33
36
  }
34
37
  },
35
38
  onDisconnect: () => {
39
+ if (!this.isConnected && !this.isSynced) {
40
+ return;
41
+ }
36
42
  this.isConnected = false;
37
43
  this.isSynced = false;
38
44
  if (!options?.quiet) {
@@ -43,6 +49,9 @@ export class HocuspocusSyncProvider {
43
49
  }
44
50
  },
45
51
  onSynced: () => {
52
+ if (this.isSynced) {
53
+ return;
54
+ }
46
55
  this.isSynced = true;
47
56
  if (!options?.quiet) {
48
57
  console.info(`Hocuspocus synced: ${name}`);
@@ -78,6 +87,9 @@ export class HocuspocusSyncProvider {
78
87
  document: doc,
79
88
  token: options?.token || null,
80
89
  onConnect: () => {
90
+ if (this.isConnected) {
91
+ return;
92
+ }
81
93
  this.isConnected = true;
82
94
  if (!options?.quiet) {
83
95
  console.info(`Hocuspocus connected: ${name}`);
@@ -87,6 +99,9 @@ export class HocuspocusSyncProvider {
87
99
  }
88
100
  },
89
101
  onDisconnect: () => {
102
+ if (!this.isConnected && !this.isSynced) {
103
+ return;
104
+ }
90
105
  this.isConnected = false;
91
106
  this.isSynced = false;
92
107
  if (!options?.quiet) {
@@ -97,6 +112,9 @@ export class HocuspocusSyncProvider {
97
112
  }
98
113
  },
99
114
  onSynced: () => {
115
+ if (this.isSynced) {
116
+ return;
117
+ }
100
118
  this.isSynced = true;
101
119
  if (!options?.quiet) {
102
120
  console.info(`Hocuspocus synced: ${name}`);
@@ -176,8 +194,9 @@ export class HocuspocusSyncProvider {
176
194
  */
177
195
  static with(options) {
178
196
  return {
179
- create: (docName, doc) => {
180
- return new HocuspocusSyncProvider(docName, doc, options);
197
+ create: (docName, doc, runtimeOptions) => {
198
+ const mergedOptions = runtimeOptions ? { ...options, ...runtimeOptions } : options;
199
+ return new HocuspocusSyncProvider(docName, doc, mergedOptions);
181
200
  },
182
201
  };
183
202
  }
@@ -5,6 +5,7 @@ import { WebsocketProvider } from "y-websocket";
5
5
  export class WebSocketSyncProvider {
6
6
  provider;
7
7
  isConnected = false;
8
+ _quiet = false;
8
9
  constructor(docName, doc, options) {
9
10
  const url = options?.url || 'ws://localhost:1234';
10
11
  const roomName = options?.roomName || docName;
@@ -16,8 +17,11 @@ export class WebSocketSyncProvider {
16
17
  maxBackoffTime: options?.maxBackoffTime,
17
18
  disableBc: true,
18
19
  });
20
+ this._quiet = options?.quiet ?? false;
19
21
  this.setupEventListeners();
20
- console.info(`WebSocket Provider initialized: ${url}/${roomName}`);
22
+ if (!this._quiet) {
23
+ console.info(`WebSocket Provider initialized: ${url}/${roomName}`);
24
+ }
21
25
  }
22
26
  /**
23
27
  * Static factory method for creating WebSocketSyncProvider with configuration options
@@ -25,8 +29,9 @@ export class WebSocketSyncProvider {
25
29
  */
26
30
  static with(options) {
27
31
  return {
28
- create: (docName, doc) => {
29
- return new WebSocketSyncProvider(docName, doc, options);
32
+ create: (docName, doc, runtimeOptions) => {
33
+ const mergedOptions = runtimeOptions ? { ...options, ...runtimeOptions } : options;
34
+ return new WebSocketSyncProvider(docName, doc, mergedOptions);
30
35
  },
31
36
  };
32
37
  }
@@ -34,15 +39,19 @@ export class WebSocketSyncProvider {
34
39
  this.provider.on('status', ({ status }) => {
35
40
  if (status === 'connected') {
36
41
  this.isConnected = true;
37
- console.info('WebSocket connected');
42
+ if (!this._quiet) {
43
+ console.info('WebSocket connected');
44
+ }
38
45
  }
39
46
  else if (status === 'disconnected') {
40
47
  this.isConnected = false;
41
- console.info('WebSocket disconnected');
48
+ if (!this._quiet) {
49
+ console.info('WebSocket disconnected');
50
+ }
42
51
  }
43
52
  });
44
53
  this.provider.on('sync', (synced) => {
45
- if (synced) {
54
+ if (synced && !this._quiet) {
46
55
  console.info('WebSocket synced');
47
56
  }
48
57
  });
@@ -52,16 +52,17 @@ export class KritzelAppStateMap {
52
52
  const docName = core.editorId ? `kritzel-app-state-${core.editorId}` : 'kritzel-app-state';
53
53
  const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
54
54
  // Instantiate providers from configuration
55
+ const quiet = !core.store.state.debugInfo.showSyncProviderInfo;
55
56
  for (const providerConfig of finalConfig.providers) {
56
57
  let provider;
57
58
  // Check if it's a class constructor or a factory
58
59
  if (typeof providerConfig === 'function') {
59
60
  // It's a class constructor
60
- provider = new providerConfig(docName, this._ydoc);
61
+ provider = new providerConfig(docName, this._ydoc, { quiet });
61
62
  }
62
63
  else {
63
64
  // It's a factory with a create method
64
- provider = providerConfig.create(docName, this._ydoc);
65
+ provider = providerConfig.create(docName, this._ydoc, { quiet });
65
66
  }
66
67
  this._providers.push(provider);
67
68
  }
@@ -107,16 +107,17 @@ export class KritzelObjectMap {
107
107
  const docName = core.editorId ? `kritzel-workspace-${core.editorId}-${workspaceId}` : `kritzel-workspace-${workspaceId}`;
108
108
  const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
109
109
  // Instantiate providers from configuration
110
+ const quiet = !core.store.state.debugInfo.showSyncProviderInfo;
110
111
  for (const providerConfig of finalConfig.providers) {
111
112
  let provider;
112
113
  // Check if it's a class constructor or a factory
113
114
  if (typeof providerConfig === 'function') {
114
115
  // It's a class constructor
115
- provider = new providerConfig(docName, this._ydoc);
116
+ provider = new providerConfig(docName, this._ydoc, { quiet });
116
117
  }
117
118
  else {
118
119
  // It's a factory with a create method
119
- provider = providerConfig.create(docName, this._ydoc);
120
+ provider = providerConfig.create(docName, this._ydoc, { quiet });
120
121
  }
121
122
  this._providers.push(provider);
122
123
  }
@@ -429,7 +429,6 @@ export class KritzelEditor {
429
429
  this.registerCustomSvgIcons();
430
430
  this.listenForMobileKeyboard();
431
431
  this.setOsSpecificCssVariables();
432
- console.log('loaded editor');
433
432
  }
434
433
  async checkIsReady() {
435
434
  await customElements.whenDefined('kritzel-editor');
@@ -622,7 +621,7 @@ export class KritzelEditor {
622
621
  }
623
622
  }
624
623
  render() {
625
- return (h(Host, { key: '496c072de4cb9d0998b4b93d41b6f34d2594336f' }, h("div", { key: '61640aefd176f9d2056c55658121754bf656d7a8', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'ad017b4dadf7edae048fd69d40d89bef07fad6f4', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: '65c24099b16c6f009f133709cc82e53e3689b2d9', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: 'c2fc4b7e0b91f748fd4fbc3a34d5d5f9f67e5bfe', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event) }), h("kritzel-controls", { key: '5caefbd8d401d9a056f9d2ce67d72d86f7fc63c1', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e52903a9bfa8ed18e5897a8cb5789be9416aab85', class: "top-right-buttons" }, h("kritzel-settings", { key: 'd2a9153401a6da7d12e334b0b11227e258f31a65', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'b72e97833be9fe13a630f055e48530924336813b', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: (event) => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '2c2c994023eda91cc3f30e8341d1c854d0673a2a', users: this.activeUsers }), h("kritzel-current-user", { key: 'e650e21eed5f3136727b92b521fa4afa09d7d66a', user: this.user, onItemSelect: event => this.handleCurrentUserItemSelect(event) }), h("kritzel-more-menu", { key: '543e84bcbd99cbf9d101c346d571ec6a1d6db1fd', onItemSelect: event => this.handleMoreMenuItemSelect(event) }), h("kritzel-share-dialog", { key: '3ed56d1dbaff240a7fa90331bb2244dd836ff7f3', ref: el => (this.shareDialogRef = el), linkShare: this.currentLinkShare, workspaceId: this.activeWorkspace?.id, onToggleLinkShare: this.handleToggleLinkShare, onPermissionChange: this.handleSharePermissionChange }))));
624
+ return (h(Host, { key: '90a91249e483f27f52c6677483793a00e78e7488' }, h("div", { key: 'be2392052be658194bc00c029abe883ce3fb4a79', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '3e0a4004dccbada37f1008c77ac143e453714db5', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'f6d11f6e0bc0a0be10bab2c5757fadd18d0a305c', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: 'a5720d2e7d7a2e257f17fd0e68a53d33b4bef711', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event) }), h("kritzel-controls", { key: '1324b903ea3cc8296467465a9524b812e65dd627', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '7b535fd7cd96bf64f64011b7cc30f8bd471b3bb6', class: "top-right-buttons" }, h("kritzel-settings", { key: '483995f3e3b81a381828d9dd0d2e25afb8a48966', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '8697a908a01a0cf6143b3822c232afd047e389a5', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: (event) => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '85a54896088999df529e70d524c775e92dcf5e6b', users: this.activeUsers }), h("kritzel-current-user", { key: 'cbcd428a95c2ab260f5fe175e75bbf9018de5c21', user: this.user, onItemSelect: event => this.handleCurrentUserItemSelect(event) }), h("kritzel-more-menu", { key: '972cc8721173cb2ed8ba448d9690e31e0a9321e1', onItemSelect: event => this.handleMoreMenuItemSelect(event) }), h("kritzel-share-dialog", { key: '3c5e325ca58af4f5c09e25bf8e059471f5e178d1', ref: el => (this.shareDialogRef = el), linkShare: this.currentLinkShare, workspaceId: this.activeWorkspace?.id, onToggleLinkShare: this.handleToggleLinkShare, onPermissionChange: this.handleSharePermissionChange }))));
626
625
  }
627
626
  static get is() { return "kritzel-editor"; }
628
627
  static get originalStyleUrls() {
@@ -36,7 +36,7 @@ export class KritzelEngine {
36
36
  return;
37
37
  }
38
38
  this.core.beforeWorkspaceChange();
39
- await this.core.initializeWorkspace(newWorkspace);
39
+ await this.initializeWorkspaceIfNeeded(newWorkspace);
40
40
  this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
41
41
  }
42
42
  /** Optional unique identifier for namespacing storage keys across multiple editor instances. */
@@ -1109,6 +1109,8 @@ export class KritzelEngine {
1109
1109
  _isYjsInitialized = false;
1110
1110
  _isResolvingActiveWorkspaceId = false;
1111
1111
  _stateChangeListenersRegistered = false;
1112
+ _workspaceInitializationPromise = null;
1113
+ _workspaceInitializationTargetKey = null;
1112
1114
  get isSelecting() {
1113
1115
  return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.state.isSelecting;
1114
1116
  }
@@ -1156,7 +1158,6 @@ export class KritzelEngine {
1156
1158
  this.core.store.state.isReady = true;
1157
1159
  this.isEngineReady.emit(this.core.store.state);
1158
1160
  }
1159
- console.log('loaded engine');
1160
1161
  }
1161
1162
  async initializeSyncAndWorkspace() {
1162
1163
  // Set sync configuration if provided
@@ -1171,17 +1172,17 @@ export class KritzelEngine {
1171
1172
  if (this.activeWorkspaceId) {
1172
1173
  const startupWorkspace = this.core.getWorkspaces().find(ws => ws.id === this.activeWorkspaceId);
1173
1174
  if (startupWorkspace) {
1174
- await this.core.initializeWorkspace(startupWorkspace);
1175
+ await this.initializeWorkspaceIfNeeded(startupWorkspace);
1175
1176
  }
1176
1177
  else {
1177
1178
  // When a specific workspace ID is requested, do not create a fallback workspace.
1178
- await this.core.initializeWorkspace(undefined, { skipFallbackCreation: true });
1179
+ await this.initializeWorkspaceIfNeeded(undefined, { skipFallbackCreation: true });
1179
1180
  }
1180
1181
  }
1181
1182
  else {
1182
1183
  // Resolve startup workspace, preferring explicit workspace object when provided.
1183
1184
  const startupWorkspace = this.resolveStartupWorkspace();
1184
- await this.core.initializeWorkspace(startupWorkspace);
1185
+ await this.initializeWorkspaceIfNeeded(startupWorkspace);
1185
1186
  }
1186
1187
  // Emit initial active workspace once startup initialization has completed
1187
1188
  const initialActiveWorkspace = this.core.store.state.activeWorkspace;
@@ -1233,9 +1234,32 @@ export class KritzelEngine {
1233
1234
  return;
1234
1235
  }
1235
1236
  this.core.beforeWorkspaceChange();
1236
- await this.core.initializeWorkspace(workspace);
1237
+ await this.initializeWorkspaceIfNeeded(workspace);
1237
1238
  this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
1238
1239
  }
1240
+ async initializeWorkspaceIfNeeded(workspace, options) {
1241
+ const targetWorkspaceId = workspace?.id ?? null;
1242
+ const targetKey = targetWorkspaceId ?? (options?.skipFallbackCreation ? '__NO_FALLBACK__' : '__AUTO__');
1243
+ if (targetWorkspaceId && this.core.store.state.activeWorkspace?.id === targetWorkspaceId) {
1244
+ return;
1245
+ }
1246
+ if (this._workspaceInitializationPromise && this._workspaceInitializationTargetKey === targetKey) {
1247
+ await this._workspaceInitializationPromise;
1248
+ return;
1249
+ }
1250
+ const initializationPromise = this.core.initializeWorkspace(workspace, options);
1251
+ this._workspaceInitializationPromise = initializationPromise;
1252
+ this._workspaceInitializationTargetKey = targetKey;
1253
+ try {
1254
+ await initializationPromise;
1255
+ }
1256
+ finally {
1257
+ if (this._workspaceInitializationPromise === initializationPromise) {
1258
+ this._workspaceInitializationPromise = null;
1259
+ this._workspaceInitializationTargetKey = null;
1260
+ }
1261
+ }
1262
+ }
1239
1263
  emitObjectsChange() {
1240
1264
  const objects = this.core.store.allObjects;
1241
1265
  const undoState = this.core.store.state.objects.undoState;
@@ -33,7 +33,8 @@ export const DEFAULT_ENGINE_CONFIG = {
33
33
  skipContextMenu: false,
34
34
  debugInfo: {
35
35
  showObjectInfo: false,
36
- showViewportInfo: false
36
+ showViewportInfo: false,
37
+ showSyncProviderInfo: false
37
38
  },
38
39
  host: null,
39
40
  pointerX: 0,
@@ -3,4 +3,4 @@
3
3
  * This file is auto-generated by the version bump scripts.
4
4
  * Do not modify manually.
5
5
  */
6
- export const KRITZEL_VERSION = '0.1.46';
6
+ export const KRITZEL_VERSION = '0.1.47';