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.
- package/dist/cjs/index.cjs.js +39 -9
- package/dist/cjs/kritzel-active-users_38.cjs.entry.js +40 -14
- package/dist/collection/classes/providers/broadcast-sync-provider.class.js +3 -1
- package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js +21 -2
- package/dist/collection/classes/providers/websocket-sync-provider.class.js +15 -6
- package/dist/collection/classes/structures/app-state-map.structure.js +3 -2
- package/dist/collection/classes/structures/object-map.structure.js +3 -2
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +1 -2
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +30 -6
- package/dist/collection/configs/default-engine-config.js +2 -1
- package/dist/collection/constants/version.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/kritzel-editor.js +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-settings.js +1 -1
- package/dist/components/{p-Dn3QBIRf.js → p-DbRfuRFb.js} +2 -2
- package/dist/components/{p-B6QKNHJJ.js → p-Twjj9gUr.js} +1 -1
- package/dist/esm/index.js +39 -9
- package/dist/esm/kritzel-active-users_38.entry.js +40 -14
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-fd4ec8dc.entry.js +9 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/providers/broadcast-sync-provider.class.d.ts +3 -1
- package/dist/types/classes/providers/websocket-sync-provider.class.d.ts +5 -0
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +3 -0
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/interfaces/debug-info.interface.d.ts +1 -0
- package/dist/types/interfaces/sync-provider.interface.d.ts +3 -1
- package/package.json +1 -1
- package/dist/stencil/p-676eac95.entry.js +0 -9
package/dist/cjs/index.cjs.js
CHANGED
|
@@ -378,7 +378,9 @@ class BroadcastSyncProvider {
|
|
|
378
378
|
setTimeout(() => {
|
|
379
379
|
this._synced = true;
|
|
380
380
|
}, 100);
|
|
381
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
490
|
+
if (!this._quiet) {
|
|
491
|
+
console.info('WebSocket connected');
|
|
492
|
+
}
|
|
484
493
|
}
|
|
485
494
|
else if (status === 'disconnected') {
|
|
486
495
|
this.isConnected = false;
|
|
487
|
-
|
|
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
|
-
|
|
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: '
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
42
|
+
if (!this._quiet) {
|
|
43
|
+
console.info('WebSocket connected');
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
46
|
else if (status === 'disconnected') {
|
|
40
47
|
this.isConnected = false;
|
|
41
|
-
|
|
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: '
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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;
|