kritzel-stencil 0.1.80 → 0.1.81

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 (45) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +30 -37
  3. package/dist/cjs/{workspace.migrations-DUXtSb7C.js → workspace.migrations-BVBITEM5.js} +9 -9
  4. package/dist/collection/classes/core/core.class.js +6 -6
  5. package/dist/collection/classes/core/store.class.js +0 -12
  6. package/dist/collection/classes/objects/base-object.class.js +1 -1
  7. package/dist/collection/classes/objects/custom-element.class.js +1 -1
  8. package/dist/collection/classes/objects/group.class.js +1 -1
  9. package/dist/collection/classes/objects/image.class.js +1 -1
  10. package/dist/collection/classes/objects/line.class.js +1 -1
  11. package/dist/collection/classes/objects/path.class.js +1 -1
  12. package/dist/collection/classes/objects/selection-box.class.js +1 -1
  13. package/dist/collection/classes/objects/selection-group.class.js +1 -1
  14. package/dist/collection/classes/objects/shape.class.js +1 -1
  15. package/dist/collection/classes/objects/text.class.js +1 -1
  16. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +21 -16
  17. package/dist/collection/constants/version.js +1 -1
  18. package/dist/components/index.js +1 -1
  19. package/dist/components/kritzel-awareness-cursors.js +1 -1
  20. package/dist/components/kritzel-controls.js +1 -1
  21. package/dist/components/kritzel-editor.js +1 -1
  22. package/dist/components/kritzel-engine.js +1 -1
  23. package/dist/components/kritzel-settings.js +1 -1
  24. package/dist/components/kritzel-tool-config.js +1 -1
  25. package/dist/components/{p-CvyE2Wg-.js → p--7j0gU6F.js} +1 -1
  26. package/dist/components/{p-xYCbKFih.js → p-B4h_tGG1.js} +1 -1
  27. package/dist/components/{p-BzQmBVwr.js → p-CwQOwQm0.js} +2 -2
  28. package/dist/components/{p-BcwZ36sO.js → p-D8jD4OI9.js} +1 -1
  29. package/dist/components/p-DQK_4lkI.js +1 -0
  30. package/dist/components/{p-B-Gej_Ak.js → p-DXhiNQyH.js} +1 -1
  31. package/dist/components/{p-C_fSm7T4.js → p-Dxr5oLKF.js} +1 -1
  32. package/dist/esm/index.js +1 -1
  33. package/dist/esm/kritzel-active-users_42.entry.js +30 -37
  34. package/dist/esm/{workspace.migrations-OzSSw5kt.js → workspace.migrations-BVtbsm5p.js} +9 -9
  35. package/dist/stencil/index.esm.js +1 -1
  36. package/dist/stencil/p-56122555.entry.js +9 -0
  37. package/dist/stencil/p-BVtbsm5p.js +1 -0
  38. package/dist/stencil/stencil.esm.js +1 -1
  39. package/dist/types/classes/core/store.class.d.ts +0 -8
  40. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +1 -0
  41. package/dist/types/constants/version.d.ts +1 -1
  42. package/package.json +1 -1
  43. package/dist/components/p-C8WnYSHi.js +0 -1
  44. package/dist/stencil/p-OzSSw5kt.js +0 -1
  45. package/dist/stencil/p-f7be06a8.entry.js +0 -9
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var workspace_migrations = require('./workspace.migrations-DUXtSb7C.js');
3
+ var workspace_migrations = require('./workspace.migrations-BVBITEM5.js');
4
4
  var Y = require('yjs');
5
5
  var yWebsocket = require('y-websocket');
6
6
  require('y-indexeddb');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-CFnj_FXt.js');
4
- var workspace_migrations = require('./workspace.migrations-DUXtSb7C.js');
4
+ var workspace_migrations = require('./workspace.migrations-BVBITEM5.js');
5
5
  var Y = require('yjs');
6
6
  require('y-websocket');
7
7
  require('y-indexeddb');
@@ -20759,7 +20759,7 @@ class KritzelCustomElement extends workspace_migrations.KritzelBaseObject {
20759
20759
  const object = new KritzelCustomElement(config);
20760
20760
  object._core = core;
20761
20761
  object.id = object.generateId();
20762
- object.workspaceId = core.store.activeWorkspace.id;
20762
+ object.workspaceId = core.store.state.activeWorkspace.id;
20763
20763
  object.userId = core.user?.id;
20764
20764
  return object;
20765
20765
  }
@@ -22287,18 +22287,6 @@ class KritzelStore {
22287
22287
  }
22288
22288
  return this._state.objects;
22289
22289
  }
22290
- /**
22291
- * Gets the currently active workspace.
22292
- * Throws an error if no active workspace is set, as it is required for workspace-bound operations.
22293
- * @returns The current active KritzelWorkspace
22294
- * @throws Error if no active workspace is set in the state
22295
- */
22296
- get activeWorkspace() {
22297
- if (!this._state.activeWorkspace) {
22298
- throw new Error('Active workspace is not set.');
22299
- }
22300
- return this._state.activeWorkspace;
22301
- }
22302
22290
  /**
22303
22291
  * Gets the host element for the Kritzel editor.
22304
22292
  * Throws an error if the host is not set, as it is required for many operations.
@@ -23481,7 +23469,7 @@ class KritzelCore {
23481
23469
  workspace.updatedAt = new Date();
23482
23470
  this.saveWorkspaceToAppState(workspace);
23483
23471
  // Keep metadata map in sync when the active workspace's name changes
23484
- if (this._store.activeWorkspace?.id === workspace.id) {
23472
+ if (this._store.state.activeWorkspace?.id === workspace.id) {
23485
23473
  this._store.objects?.setWorkspaceName(workspace.name);
23486
23474
  }
23487
23475
  const workspaces = this._store.state.workspaces;
@@ -23499,7 +23487,7 @@ class KritzelCore {
23499
23487
  */
23500
23488
  deleteWorkspace(workspace) {
23501
23489
  // If deleting the active workspace, need to handle ObjectMap cleanup
23502
- if (this._store.activeWorkspace?.id === workspace.id) {
23490
+ if (this._store.state.activeWorkspace?.id === workspace.id) {
23503
23491
  this.engine.viewport?.cancelPendingUpdates();
23504
23492
  this._store.objects?.destroy();
23505
23493
  }
@@ -23520,7 +23508,7 @@ class KritzelCore {
23520
23508
  * @param scale - The zoom scale of the viewport
23521
23509
  */
23522
23510
  updateWorkspaceViewport(translateX, translateY, scale) {
23523
- const activeWorkspace = this._store.activeWorkspace;
23511
+ const activeWorkspace = this._store.state.activeWorkspace;
23524
23512
  if (!activeWorkspace) {
23525
23513
  return;
23526
23514
  }
@@ -23543,7 +23531,7 @@ class KritzelCore {
23543
23531
  * @returns True if the workspace is public, false otherwise
23544
23532
  */
23545
23533
  getIsPublic() {
23546
- return this._store.activeWorkspace?.isPublic ?? false;
23534
+ return this._store.state.activeWorkspace?.isPublic ?? false;
23547
23535
  }
23548
23536
  // ═══════════════════════════════════════════════════════════════════════════
23549
23537
  // Object Management Methods
@@ -23735,7 +23723,7 @@ class KritzelCore {
23735
23723
  if (!copiedObjects || copiedObjects.length === 0) {
23736
23724
  return;
23737
23725
  }
23738
- const activeWorkspace = this._store.activeWorkspace;
23726
+ const activeWorkspace = this._store.state.activeWorkspace;
23739
23727
  const originalIdMapping = this._store.state.copiedObjectIdMapping;
23740
23728
  // Check if we're pasting from a different workspace
23741
23729
  const isDifferentWorkspace = copiedObjects.some(obj => obj.workspaceId !== activeWorkspace.id);
@@ -24251,7 +24239,7 @@ class KritzelCore {
24251
24239
  // saving the old workspace's viewport to the new workspace
24252
24240
  this._kritzelEngine.viewport?.cancelPendingUpdates();
24253
24241
  // Immediately save the current workspace's viewport before switching
24254
- const currentWorkspace = this._store.activeWorkspace;
24242
+ const currentWorkspace = this._store.state.activeWorkspace;
24255
24243
  if (currentWorkspace) {
24256
24244
  this.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
24257
24245
  }
@@ -25606,13 +25594,13 @@ const KritzelEngine = class {
25606
25594
  }
25607
25595
  // Let batched prop updates settle, then perform an idempotent re-check.
25608
25596
  await Promise.resolve();
25609
- const currentWorkspaceId = this.core.store.activeWorkspace?.id;
25597
+ const currentWorkspaceId = this.core.store.state.activeWorkspace?.id;
25610
25598
  if (currentWorkspaceId === newWorkspaceId) {
25611
25599
  return;
25612
25600
  }
25613
25601
  this.core.beforeWorkspaceChange();
25614
25602
  await this.initializeWorkspaceIfNeeded(newWorkspace);
25615
- this.activeWorkspaceChange.emit(this.core.store.activeWorkspace);
25603
+ this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
25616
25604
  }
25617
25605
  /** Optional unique identifier for namespacing storage keys across multiple editor instances. */
25618
25606
  editorId;
@@ -25630,8 +25618,11 @@ const KritzelEngine = class {
25630
25618
  this._syncConfigRevision++;
25631
25619
  // Keep core config in sync immediately so late prop updates are not lost.
25632
25620
  this.core.setSyncConfig(newValue);
25633
- // If syncConfig arrives after componentDidLoad, initialize Yjs now
25634
- if (newValue && !this._isYjsInitialized) {
25621
+ // If syncConfig arrives after componentDidLoad, initialize Yjs now.
25622
+ // Guard on _isViewportReady to avoid restoring viewport state before
25623
+ // viewportWidth/viewportHeight are set (they default to 0 until the
25624
+ // KritzelViewport constructor runs inside componentDidLoad's timeout).
25625
+ if (newValue && !this._isYjsInitialized && this._isViewportReady) {
25635
25626
  await this.initializeSyncAndWorkspace();
25636
25627
  }
25637
25628
  }
@@ -26064,7 +26055,7 @@ const KritzelEngine = class {
26064
26055
  object._core = this.core;
26065
26056
  object.scale = this.core.store.state.scale;
26066
26057
  object.zIndex = this.core.store.currentZIndex;
26067
- object.workspaceId = this.core.store.activeWorkspace.id;
26058
+ object.workspaceId = this.core.store.state.activeWorkspace.id;
26068
26059
  // Handle KritzelText: recreate the editor now that _core is available
26069
26060
  // The editor's dispatchTransaction callback needs _core for persisting changes
26070
26061
  if (workspace_migrations.KritzelClassHelper.isInstanceOf(object, 'KritzelText')) {
@@ -26085,7 +26076,7 @@ const KritzelEngine = class {
26085
26076
  child._core = this.core;
26086
26077
  child.scale = this.core.store.state.scale;
26087
26078
  child.zIndex = this.core.store.currentZIndex;
26088
- child.workspaceId = this.core.store.activeWorkspace.id;
26079
+ child.workspaceId = this.core.store.state.activeWorkspace.id;
26089
26080
  idRemapping.set(oldId, child.id);
26090
26081
  object.childIds.push(child.id);
26091
26082
  });
@@ -26286,7 +26277,7 @@ const KritzelEngine = class {
26286
26277
  // Save critical state before screenshot to restore after
26287
26278
  const savedState = {
26288
26279
  objects: this.core.store.objects,
26289
- activeWorkspace: this.core.store.activeWorkspace,
26280
+ activeWorkspace: this.core.store.state.activeWorkspace,
26290
26281
  workspaces: this.core.store.state.workspaces,
26291
26282
  activeTool: this.core.store.state.activeTool,
26292
26283
  isReady: this.core.store.state.isReady,
@@ -26484,7 +26475,7 @@ const KritzelEngine = class {
26484
26475
  * @returns A JSON string representing the complete workspace state.
26485
26476
  */
26486
26477
  async exportAsJson() {
26487
- const workspace = this.core.store.activeWorkspace;
26478
+ const workspace = this.core.store.state.activeWorkspace;
26488
26479
  if (!workspace) {
26489
26480
  throw new Error('Cannot export workspace: no active workspace is loaded');
26490
26481
  }
@@ -26560,7 +26551,7 @@ const KritzelEngine = class {
26560
26551
  if (data.version && data.version !== workspace_migrations.WORKSPACE_EXPORT_VERSION) {
26561
26552
  console.warn(`Workspace version mismatch: expected ${workspace_migrations.WORKSPACE_EXPORT_VERSION}, got ${data.version}`);
26562
26553
  }
26563
- const activeWorkspace = this.core.store.activeWorkspace;
26554
+ const activeWorkspace = this.core.store.state.activeWorkspace;
26564
26555
  if (!activeWorkspace) {
26565
26556
  throw new Error('Cannot load objects: no active workspace is loaded');
26566
26557
  }
@@ -26700,7 +26691,7 @@ const KritzelEngine = class {
26700
26691
  }
26701
26692
  /** Returns the currently active workspace. */
26702
26693
  async getActiveWorkspace() {
26703
- const activeWorkspace = this.core.store.activeWorkspace;
26694
+ const activeWorkspace = this.core.store.state.activeWorkspace;
26704
26695
  if (!activeWorkspace) {
26705
26696
  throw new Error('No active workspace is loaded');
26706
26697
  }
@@ -26733,7 +26724,7 @@ const KritzelEngine = class {
26733
26724
  this.workspacesChange.emit(this.core.store.state.workspaces);
26734
26725
  this.core.beforeWorkspaceChange();
26735
26726
  await this.initializeWorkspaceIfNeeded(workspace);
26736
- this.activeWorkspaceChange.emit(this.core.store.activeWorkspace);
26727
+ this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
26737
26728
  }
26738
26729
  /**
26739
26730
  * Reinitializes sync by performing a full teardown and re-initialization.
@@ -26755,6 +26746,7 @@ const KritzelEngine = class {
26755
26746
  keyHandler;
26756
26747
  contextMenuElement = null;
26757
26748
  _lastHadSelectionGroup = false;
26749
+ _isViewportReady = false;
26758
26750
  _isYjsInitialized = false;
26759
26751
  _isResolvingActiveWorkspaceId = false;
26760
26752
  _stateChangeListenersRegistered = false;
@@ -26828,6 +26820,7 @@ const KritzelEngine = class {
26828
26820
  this.contextMenuHandler = new KritzelContextMenuHandler(this.core, this.globalContextMenuItems, this.objectContextMenuItems);
26829
26821
  this.keyHandler = new KritzelKeyHandler(this.core);
26830
26822
  this.viewport = new KritzelViewport(this.core, this.host);
26823
+ this._isViewportReady = true;
26831
26824
  // Initialize cursor manager with target element and shadow root
26832
26825
  this.core.cursorManager.setTargetElement(this.cursorTarget || document.body);
26833
26826
  if (this.host.shadowRoot) {
@@ -26893,7 +26886,7 @@ const KritzelEngine = class {
26893
26886
  await this.initializeWorkspaceIfNeeded(startupWorkspace);
26894
26887
  }
26895
26888
  // Emit initial active workspace once startup initialization has completed
26896
- const initialActiveWorkspace = this.core.store.activeWorkspace;
26889
+ const initialActiveWorkspace = this.core.store.state.activeWorkspace;
26897
26890
  if (initialActiveWorkspace) {
26898
26891
  this.activeWorkspaceChange.emit(initialActiveWorkspace);
26899
26892
  }
@@ -26922,7 +26915,7 @@ const KritzelEngine = class {
26922
26915
  if (!this.activeWorkspaceId || this._isResolvingActiveWorkspaceId) {
26923
26916
  return;
26924
26917
  }
26925
- if (this.core.store.activeWorkspace?.id === this.activeWorkspaceId) {
26918
+ if (this.core.store.state.activeWorkspace?.id === this.activeWorkspaceId) {
26926
26919
  return;
26927
26920
  }
26928
26921
  this._isResolvingActiveWorkspaceId = true;
@@ -26938,17 +26931,17 @@ const KritzelEngine = class {
26938
26931
  }
26939
26932
  return;
26940
26933
  }
26941
- if (this.core.store.activeWorkspace?.id === workspace.id) {
26934
+ if (this.core.store.state.activeWorkspace?.id === workspace.id) {
26942
26935
  return;
26943
26936
  }
26944
26937
  this.core.beforeWorkspaceChange();
26945
26938
  await this.initializeWorkspaceIfNeeded(workspace);
26946
- this.activeWorkspaceChange.emit(this.core.store.activeWorkspace);
26939
+ this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
26947
26940
  }
26948
26941
  async initializeWorkspaceIfNeeded(workspace, options) {
26949
26942
  const targetWorkspaceId = workspace?.id ?? null;
26950
26943
  const targetKey = targetWorkspaceId ?? (options?.skipFallbackCreation ? '__NO_FALLBACK__' : '__AUTO__');
26951
- if (targetWorkspaceId && this.core.store.activeWorkspace?.id === targetWorkspaceId) {
26944
+ if (targetWorkspaceId && this.core.store.state.activeWorkspace?.id === targetWorkspaceId) {
26952
26945
  return;
26953
26946
  }
26954
26947
  if (this._workspaceInitializationPromise && this._workspaceInitializationTargetKey === targetKey) {
@@ -28715,7 +28708,7 @@ const KritzelPortal = class {
28715
28708
  * This file is auto-generated by the version bump scripts.
28716
28709
  * Do not modify manually.
28717
28710
  */
28718
- const KRITZEL_VERSION = '0.1.80';
28711
+ const KRITZEL_VERSION = '0.1.81';
28719
28712
 
28720
28713
  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)}`;
28721
28714
 
@@ -446,7 +446,7 @@ class KritzelBaseObject {
446
446
  const object = new KritzelBaseObject();
447
447
  object._core = core;
448
448
  object.zIndex = core.store.currentZIndex;
449
- object.workspaceId = core.store.activeWorkspace.id;
449
+ object.workspaceId = core.store.state.activeWorkspace.id;
450
450
  object.userId = core.user?.id;
451
451
  return object;
452
452
  }
@@ -15343,7 +15343,7 @@ class KritzelText extends KritzelBaseObject {
15343
15343
  const object = new KritzelText();
15344
15344
  object._core = core;
15345
15345
  object.id = object.generateId();
15346
- object.workspaceId = core.store.activeWorkspace.id;
15346
+ object.workspaceId = core.store.state.activeWorkspace.id;
15347
15347
  object.userId = core.user?.id;
15348
15348
  object.fontSize = fontSize || 8;
15349
15349
  object.fontFamily = fontFamily || 'Arial';
@@ -15735,7 +15735,7 @@ class KritzelPath extends KritzelBaseObject {
15735
15735
  const object = new KritzelPath();
15736
15736
  object._core = core;
15737
15737
  object.id = object.generateId();
15738
- object.workspaceId = core.store.activeWorkspace.id;
15738
+ object.workspaceId = core.store.state.activeWorkspace.id;
15739
15739
  object.userId = core.user?.id;
15740
15740
  object.options = options;
15741
15741
  object.points = options?.points ?? [];
@@ -16237,7 +16237,7 @@ class KritzelImage extends KritzelBaseObject {
16237
16237
  const object = new KritzelImage();
16238
16238
  object._core = core;
16239
16239
  object.id = object.generateId();
16240
- object.workspaceId = core.store.activeWorkspace.id;
16240
+ object.workspaceId = core.store.state.activeWorkspace.id;
16241
16241
  object.userId = core.user?.id;
16242
16242
  object.x = 0;
16243
16243
  object.y = 0;
@@ -16388,7 +16388,7 @@ class KritzelLine extends KritzelBaseObject {
16388
16388
  const object = new KritzelLine();
16389
16389
  object._core = core;
16390
16390
  object.id = object.generateId();
16391
- object.workspaceId = core.store.activeWorkspace.id;
16391
+ object.workspaceId = core.store.state.activeWorkspace.id;
16392
16392
  object.userId = core.user?.id;
16393
16393
  object.options = options;
16394
16394
  object.startX = options?.startX ?? 0;
@@ -17148,7 +17148,7 @@ class KritzelGroup extends KritzelBaseObject {
17148
17148
  const group = new KritzelGroup();
17149
17149
  group._core = core;
17150
17150
  group.id = group.generateId();
17151
- group.workspaceId = core.store.activeWorkspace.id;
17151
+ group.workspaceId = core.store.state.activeWorkspace.id;
17152
17152
  group.userId = core.user?.id;
17153
17153
  group.scale = core.store.state.scale;
17154
17154
  group.zIndex = core.store.currentZIndex;
@@ -17706,7 +17706,7 @@ class KritzelShape extends KritzelBaseObject {
17706
17706
  const object = new KritzelShape();
17707
17707
  object._core = core;
17708
17708
  object.id = object.generateId();
17709
- object.workspaceId = core.store.activeWorkspace.id;
17709
+ object.workspaceId = core.store.state.activeWorkspace.id;
17710
17710
  object.userId = core.user?.id;
17711
17711
  object.x = config?.x ?? 0;
17712
17712
  object.y = config?.y ?? 0;
@@ -18617,7 +18617,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18617
18617
  const object = new KritzelSelectionGroup();
18618
18618
  object._core = core;
18619
18619
  object.id = object.generateId();
18620
- object.workspaceId = core.store.activeWorkspace.id;
18620
+ object.workspaceId = core.store.state.activeWorkspace.id;
18621
18621
  object.userId = core.user?.id;
18622
18622
  object.clientId = core.store.objects?.localClientId ?? undefined;
18623
18623
  object.scale = core.store.state.scale;
@@ -20944,7 +20944,7 @@ class KritzelSelectionBox extends KritzelBaseObject {
20944
20944
  const object = new KritzelSelectionBox();
20945
20945
  object._core = core;
20946
20946
  object.id = object.generateId();
20947
- object.workspaceId = core.store.activeWorkspace.id;
20947
+ object.workspaceId = core.store.state.activeWorkspace.id;
20948
20948
  object.userId = core.user?.id;
20949
20949
  object.scale = core.store.state.scale;
20950
20950
  object.zIndex = 99999;
@@ -358,7 +358,7 @@ export class KritzelCore {
358
358
  workspace.updatedAt = new Date();
359
359
  this.saveWorkspaceToAppState(workspace);
360
360
  // Keep metadata map in sync when the active workspace's name changes
361
- if (this._store.activeWorkspace?.id === workspace.id) {
361
+ if (this._store.state.activeWorkspace?.id === workspace.id) {
362
362
  this._store.objects?.setWorkspaceName(workspace.name);
363
363
  }
364
364
  const workspaces = this._store.state.workspaces;
@@ -376,7 +376,7 @@ export class KritzelCore {
376
376
  */
377
377
  deleteWorkspace(workspace) {
378
378
  // If deleting the active workspace, need to handle ObjectMap cleanup
379
- if (this._store.activeWorkspace?.id === workspace.id) {
379
+ if (this._store.state.activeWorkspace?.id === workspace.id) {
380
380
  this.engine.viewport?.cancelPendingUpdates();
381
381
  this._store.objects?.destroy();
382
382
  }
@@ -397,7 +397,7 @@ export class KritzelCore {
397
397
  * @param scale - The zoom scale of the viewport
398
398
  */
399
399
  updateWorkspaceViewport(translateX, translateY, scale) {
400
- const activeWorkspace = this._store.activeWorkspace;
400
+ const activeWorkspace = this._store.state.activeWorkspace;
401
401
  if (!activeWorkspace) {
402
402
  return;
403
403
  }
@@ -420,7 +420,7 @@ export class KritzelCore {
420
420
  * @returns True if the workspace is public, false otherwise
421
421
  */
422
422
  getIsPublic() {
423
- return this._store.activeWorkspace?.isPublic ?? false;
423
+ return this._store.state.activeWorkspace?.isPublic ?? false;
424
424
  }
425
425
  // ═══════════════════════════════════════════════════════════════════════════
426
426
  // Object Management Methods
@@ -612,7 +612,7 @@ export class KritzelCore {
612
612
  if (!copiedObjects || copiedObjects.length === 0) {
613
613
  return;
614
614
  }
615
- const activeWorkspace = this._store.activeWorkspace;
615
+ const activeWorkspace = this._store.state.activeWorkspace;
616
616
  const originalIdMapping = this._store.state.copiedObjectIdMapping;
617
617
  // Check if we're pasting from a different workspace
618
618
  const isDifferentWorkspace = copiedObjects.some(obj => obj.workspaceId !== activeWorkspace.id);
@@ -1128,7 +1128,7 @@ export class KritzelCore {
1128
1128
  // saving the old workspace's viewport to the new workspace
1129
1129
  this._kritzelEngine.viewport?.cancelPendingUpdates();
1130
1130
  // Immediately save the current workspace's viewport before switching
1131
- const currentWorkspace = this._store.activeWorkspace;
1131
+ const currentWorkspace = this._store.state.activeWorkspace;
1132
1132
  if (currentWorkspace) {
1133
1133
  this.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
1134
1134
  }
@@ -40,18 +40,6 @@ export class KritzelStore {
40
40
  }
41
41
  return this._state.objects;
42
42
  }
43
- /**
44
- * Gets the currently active workspace.
45
- * Throws an error if no active workspace is set, as it is required for workspace-bound operations.
46
- * @returns The current active KritzelWorkspace
47
- * @throws Error if no active workspace is set in the state
48
- */
49
- get activeWorkspace() {
50
- if (!this._state.activeWorkspace) {
51
- throw new Error('Active workspace is not set.');
52
- }
53
- return this._state.activeWorkspace;
54
- }
55
43
  /**
56
44
  * Gets the host element for the Kritzel editor.
57
45
  * Throws an error if the host is not set, as it is required for many operations.
@@ -208,7 +208,7 @@ export class KritzelBaseObject {
208
208
  const object = new KritzelBaseObject();
209
209
  object._core = core;
210
210
  object.zIndex = core.store.currentZIndex;
211
- object.workspaceId = core.store.activeWorkspace.id;
211
+ object.workspaceId = core.store.state.activeWorkspace.id;
212
212
  object.userId = core.user?.id;
213
213
  return object;
214
214
  }
@@ -48,7 +48,7 @@ export class KritzelCustomElement extends KritzelBaseObject {
48
48
  const object = new KritzelCustomElement(config);
49
49
  object._core = core;
50
50
  object.id = object.generateId();
51
- object.workspaceId = core.store.activeWorkspace.id;
51
+ object.workspaceId = core.store.state.activeWorkspace.id;
52
52
  object.userId = core.user?.id;
53
53
  return object;
54
54
  }
@@ -69,7 +69,7 @@ export class KritzelGroup extends KritzelBaseObject {
69
69
  const group = new KritzelGroup();
70
70
  group._core = core;
71
71
  group.id = group.generateId();
72
- group.workspaceId = core.store.activeWorkspace.id;
72
+ group.workspaceId = core.store.state.activeWorkspace.id;
73
73
  group.userId = core.user?.id;
74
74
  group.scale = core.store.state.scale;
75
75
  group.zIndex = core.store.currentZIndex;
@@ -39,7 +39,7 @@ export class KritzelImage extends KritzelBaseObject {
39
39
  const object = new KritzelImage();
40
40
  object._core = core;
41
41
  object.id = object.generateId();
42
- object.workspaceId = core.store.activeWorkspace.id;
42
+ object.workspaceId = core.store.state.activeWorkspace.id;
43
43
  object.userId = core.user?.id;
44
44
  object.x = 0;
45
45
  object.y = 0;
@@ -79,7 +79,7 @@ export class KritzelLine extends KritzelBaseObject {
79
79
  const object = new KritzelLine();
80
80
  object._core = core;
81
81
  object.id = object.generateId();
82
- object.workspaceId = core.store.activeWorkspace.id;
82
+ object.workspaceId = core.store.state.activeWorkspace.id;
83
83
  object.userId = core.user?.id;
84
84
  object.options = options;
85
85
  object.startX = options?.startX ?? 0;
@@ -61,7 +61,7 @@ export class KritzelPath extends KritzelBaseObject {
61
61
  const object = new KritzelPath();
62
62
  object._core = core;
63
63
  object.id = object.generateId();
64
- object.workspaceId = core.store.activeWorkspace.id;
64
+ object.workspaceId = core.store.state.activeWorkspace.id;
65
65
  object.userId = core.user?.id;
66
66
  object.options = options;
67
67
  object.points = options?.points ?? [];
@@ -18,7 +18,7 @@ export class KritzelSelectionBox extends KritzelBaseObject {
18
18
  const object = new KritzelSelectionBox();
19
19
  object._core = core;
20
20
  object.id = object.generateId();
21
- object.workspaceId = core.store.activeWorkspace.id;
21
+ object.workspaceId = core.store.state.activeWorkspace.id;
22
22
  object.userId = core.user?.id;
23
23
  object.scale = core.store.state.scale;
24
24
  object.zIndex = 99999;
@@ -91,7 +91,7 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
91
91
  const object = new KritzelSelectionGroup();
92
92
  object._core = core;
93
93
  object.id = object.generateId();
94
- object.workspaceId = core.store.activeWorkspace.id;
94
+ object.workspaceId = core.store.state.activeWorkspace.id;
95
95
  object.userId = core.user?.id;
96
96
  object.clientId = core.store.objects?.localClientId ?? undefined;
97
97
  object.scale = core.store.state.scale;
@@ -105,7 +105,7 @@ export class KritzelShape extends KritzelBaseObject {
105
105
  const object = new KritzelShape();
106
106
  object._core = core;
107
107
  object.id = object.generateId();
108
- object.workspaceId = core.store.activeWorkspace.id;
108
+ object.workspaceId = core.store.state.activeWorkspace.id;
109
109
  object.userId = core.user?.id;
110
110
  object.x = config?.x ?? 0;
111
111
  object.y = config?.y ?? 0;
@@ -121,7 +121,7 @@ export class KritzelText extends KritzelBaseObject {
121
121
  const object = new KritzelText();
122
122
  object._core = core;
123
123
  object.id = object.generateId();
124
- object.workspaceId = core.store.activeWorkspace.id;
124
+ object.workspaceId = core.store.state.activeWorkspace.id;
125
125
  object.userId = core.user?.id;
126
126
  object.fontSize = fontSize || 8;
127
127
  object.fontFamily = fontFamily || 'Arial';
@@ -31,13 +31,13 @@ export class KritzelEngine {
31
31
  }
32
32
  // Let batched prop updates settle, then perform an idempotent re-check.
33
33
  await Promise.resolve();
34
- const currentWorkspaceId = this.core.store.activeWorkspace?.id;
34
+ const currentWorkspaceId = this.core.store.state.activeWorkspace?.id;
35
35
  if (currentWorkspaceId === newWorkspaceId) {
36
36
  return;
37
37
  }
38
38
  this.core.beforeWorkspaceChange();
39
39
  await this.initializeWorkspaceIfNeeded(newWorkspace);
40
- this.activeWorkspaceChange.emit(this.core.store.activeWorkspace);
40
+ this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
41
41
  }
42
42
  /** Optional unique identifier for namespacing storage keys across multiple editor instances. */
43
43
  editorId;
@@ -55,8 +55,11 @@ export class KritzelEngine {
55
55
  this._syncConfigRevision++;
56
56
  // Keep core config in sync immediately so late prop updates are not lost.
57
57
  this.core.setSyncConfig(newValue);
58
- // If syncConfig arrives after componentDidLoad, initialize Yjs now
59
- if (newValue && !this._isYjsInitialized) {
58
+ // If syncConfig arrives after componentDidLoad, initialize Yjs now.
59
+ // Guard on _isViewportReady to avoid restoring viewport state before
60
+ // viewportWidth/viewportHeight are set (they default to 0 until the
61
+ // KritzelViewport constructor runs inside componentDidLoad's timeout).
62
+ if (newValue && !this._isYjsInitialized && this._isViewportReady) {
60
63
  await this.initializeSyncAndWorkspace();
61
64
  }
62
65
  }
@@ -489,7 +492,7 @@ export class KritzelEngine {
489
492
  object._core = this.core;
490
493
  object.scale = this.core.store.state.scale;
491
494
  object.zIndex = this.core.store.currentZIndex;
492
- object.workspaceId = this.core.store.activeWorkspace.id;
495
+ object.workspaceId = this.core.store.state.activeWorkspace.id;
493
496
  // Handle KritzelText: recreate the editor now that _core is available
494
497
  // The editor's dispatchTransaction callback needs _core for persisting changes
495
498
  if (KritzelClassHelper.isInstanceOf(object, 'KritzelText')) {
@@ -510,7 +513,7 @@ export class KritzelEngine {
510
513
  child._core = this.core;
511
514
  child.scale = this.core.store.state.scale;
512
515
  child.zIndex = this.core.store.currentZIndex;
513
- child.workspaceId = this.core.store.activeWorkspace.id;
516
+ child.workspaceId = this.core.store.state.activeWorkspace.id;
514
517
  idRemapping.set(oldId, child.id);
515
518
  object.childIds.push(child.id);
516
519
  });
@@ -711,7 +714,7 @@ export class KritzelEngine {
711
714
  // Save critical state before screenshot to restore after
712
715
  const savedState = {
713
716
  objects: this.core.store.objects,
714
- activeWorkspace: this.core.store.activeWorkspace,
717
+ activeWorkspace: this.core.store.state.activeWorkspace,
715
718
  workspaces: this.core.store.state.workspaces,
716
719
  activeTool: this.core.store.state.activeTool,
717
720
  isReady: this.core.store.state.isReady,
@@ -909,7 +912,7 @@ export class KritzelEngine {
909
912
  * @returns A JSON string representing the complete workspace state.
910
913
  */
911
914
  async exportAsJson() {
912
- const workspace = this.core.store.activeWorkspace;
915
+ const workspace = this.core.store.state.activeWorkspace;
913
916
  if (!workspace) {
914
917
  throw new Error('Cannot export workspace: no active workspace is loaded');
915
918
  }
@@ -985,7 +988,7 @@ export class KritzelEngine {
985
988
  if (data.version && data.version !== WORKSPACE_EXPORT_VERSION) {
986
989
  console.warn(`Workspace version mismatch: expected ${WORKSPACE_EXPORT_VERSION}, got ${data.version}`);
987
990
  }
988
- const activeWorkspace = this.core.store.activeWorkspace;
991
+ const activeWorkspace = this.core.store.state.activeWorkspace;
989
992
  if (!activeWorkspace) {
990
993
  throw new Error('Cannot load objects: no active workspace is loaded');
991
994
  }
@@ -1125,7 +1128,7 @@ export class KritzelEngine {
1125
1128
  }
1126
1129
  /** Returns the currently active workspace. */
1127
1130
  async getActiveWorkspace() {
1128
- const activeWorkspace = this.core.store.activeWorkspace;
1131
+ const activeWorkspace = this.core.store.state.activeWorkspace;
1129
1132
  if (!activeWorkspace) {
1130
1133
  throw new Error('No active workspace is loaded');
1131
1134
  }
@@ -1158,7 +1161,7 @@ export class KritzelEngine {
1158
1161
  this.workspacesChange.emit(this.core.store.state.workspaces);
1159
1162
  this.core.beforeWorkspaceChange();
1160
1163
  await this.initializeWorkspaceIfNeeded(workspace);
1161
- this.activeWorkspaceChange.emit(this.core.store.activeWorkspace);
1164
+ this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
1162
1165
  }
1163
1166
  /**
1164
1167
  * Reinitializes sync by performing a full teardown and re-initialization.
@@ -1180,6 +1183,7 @@ export class KritzelEngine {
1180
1183
  keyHandler;
1181
1184
  contextMenuElement = null;
1182
1185
  _lastHadSelectionGroup = false;
1186
+ _isViewportReady = false;
1183
1187
  _isYjsInitialized = false;
1184
1188
  _isResolvingActiveWorkspaceId = false;
1185
1189
  _stateChangeListenersRegistered = false;
@@ -1238,6 +1242,7 @@ export class KritzelEngine {
1238
1242
  this.contextMenuHandler = new KritzelContextMenuHandler(this.core, this.globalContextMenuItems, this.objectContextMenuItems);
1239
1243
  this.keyHandler = new KritzelKeyHandler(this.core);
1240
1244
  this.viewport = new KritzelViewport(this.core, this.host);
1245
+ this._isViewportReady = true;
1241
1246
  // Initialize cursor manager with target element and shadow root
1242
1247
  this.core.cursorManager.setTargetElement(this.cursorTarget || document.body);
1243
1248
  if (this.host.shadowRoot) {
@@ -1303,7 +1308,7 @@ export class KritzelEngine {
1303
1308
  await this.initializeWorkspaceIfNeeded(startupWorkspace);
1304
1309
  }
1305
1310
  // Emit initial active workspace once startup initialization has completed
1306
- const initialActiveWorkspace = this.core.store.activeWorkspace;
1311
+ const initialActiveWorkspace = this.core.store.state.activeWorkspace;
1307
1312
  if (initialActiveWorkspace) {
1308
1313
  this.activeWorkspaceChange.emit(initialActiveWorkspace);
1309
1314
  }
@@ -1332,7 +1337,7 @@ export class KritzelEngine {
1332
1337
  if (!this.activeWorkspaceId || this._isResolvingActiveWorkspaceId) {
1333
1338
  return;
1334
1339
  }
1335
- if (this.core.store.activeWorkspace?.id === this.activeWorkspaceId) {
1340
+ if (this.core.store.state.activeWorkspace?.id === this.activeWorkspaceId) {
1336
1341
  return;
1337
1342
  }
1338
1343
  this._isResolvingActiveWorkspaceId = true;
@@ -1348,17 +1353,17 @@ export class KritzelEngine {
1348
1353
  }
1349
1354
  return;
1350
1355
  }
1351
- if (this.core.store.activeWorkspace?.id === workspace.id) {
1356
+ if (this.core.store.state.activeWorkspace?.id === workspace.id) {
1352
1357
  return;
1353
1358
  }
1354
1359
  this.core.beforeWorkspaceChange();
1355
1360
  await this.initializeWorkspaceIfNeeded(workspace);
1356
- this.activeWorkspaceChange.emit(this.core.store.activeWorkspace);
1361
+ this.activeWorkspaceChange.emit(this.core.store.state.activeWorkspace);
1357
1362
  }
1358
1363
  async initializeWorkspaceIfNeeded(workspace, options) {
1359
1364
  const targetWorkspaceId = workspace?.id ?? null;
1360
1365
  const targetKey = targetWorkspaceId ?? (options?.skipFallbackCreation ? '__NO_FALLBACK__' : '__AUTO__');
1361
- if (targetWorkspaceId && this.core.store.activeWorkspace?.id === targetWorkspaceId) {
1366
+ if (targetWorkspaceId && this.core.store.state.activeWorkspace?.id === targetWorkspaceId) {
1362
1367
  return;
1363
1368
  }
1364
1369
  if (this._workspaceInitializationPromise && this._workspaceInitializationTargetKey === targetKey) {