kritzel-stencil 0.1.89 → 0.1.91

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 (28) hide show
  1. package/dist/cjs/index.cjs.js +13 -3
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +2 -2
  3. package/dist/cjs/{workspace.migrations-B_dbGmyV.js → workspace.migrations-CxultIEq.js} +66 -1
  4. package/dist/collection/classes/providers/assets/asset-resolver.class.js +58 -1
  5. package/dist/collection/classes/providers/assets/http-asset-provider.class.js +6 -1
  6. package/dist/collection/classes/providers/assets/indexeddb-asset-provider.class.js +8 -0
  7. package/dist/collection/classes/providers/assets/presigned-asset-provider.class.js +6 -1
  8. package/dist/collection/constants/version.js +1 -1
  9. package/dist/components/index.js +1 -1
  10. package/dist/components/kritzel-editor.js +1 -1
  11. package/dist/components/kritzel-engine.js +1 -1
  12. package/dist/components/kritzel-settings.js +1 -1
  13. package/dist/components/{p-CaRobExg.js → p-cxYQlXqh.js} +1 -1
  14. package/dist/components/{p-CYnEIdQL.js → p-lDidcKSG.js} +2 -2
  15. package/dist/esm/index.js +14 -4
  16. package/dist/esm/kritzel-active-users_42.entry.js +2 -2
  17. package/dist/esm/{workspace.migrations-CvfM8aov.js → workspace.migrations-QMw-15p0.js} +66 -1
  18. package/dist/stencil/index.esm.js +1 -1
  19. package/dist/stencil/{p-7fc12473.entry.js → p-07b533ac.entry.js} +2 -2
  20. package/dist/stencil/{p-CvfM8aov.js → p-QMw-15p0.js} +1 -1
  21. package/dist/stencil/stencil.esm.js +1 -1
  22. package/dist/types/classes/providers/assets/asset-resolver.class.d.ts +2 -0
  23. package/dist/types/classes/providers/assets/http-asset-provider.class.d.ts +4 -0
  24. package/dist/types/classes/providers/assets/indexeddb-asset-provider.class.d.ts +5 -0
  25. package/dist/types/classes/providers/assets/presigned-asset-provider.class.d.ts +4 -0
  26. package/dist/types/constants/version.d.ts +1 -1
  27. package/dist/types/interfaces/asset-storage-config.interface.d.ts +4 -0
  28. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var workspace_migrations = require('./workspace.migrations-B_dbGmyV.js');
3
+ var workspace_migrations = require('./workspace.migrations-CxultIEq.js');
4
4
  var Y = require('yjs');
5
5
  var yWebsocket = require('y-websocket');
6
6
  require('y-indexeddb');
@@ -907,7 +907,9 @@ class HttpAssetProvider {
907
907
  return { create: () => new HttpAssetProvider(options) };
908
908
  }
909
909
  async init() {
910
- // No initialization needed for a stateless HTTP provider.
910
+ if (!this._options.quiet) {
911
+ console.info('HttpAssetProvider initialized');
912
+ }
911
913
  }
912
914
  destroy() {
913
915
  // No-op; no resources to release.
@@ -956,6 +958,9 @@ class HttpAssetProvider {
956
958
  if (!res.ok) {
957
959
  throw new Error(`[HttpAssetProvider] Failed to delete asset ${id}: ${res.status} ${res.statusText}`);
958
960
  }
961
+ if (!this._options.quiet) {
962
+ console.info(`HttpAssetProvider: deleted asset ${id}`);
963
+ }
959
964
  }
960
965
  defaultUpload = async (url, blob, metadata, headers) => {
961
966
  const form = new FormData();
@@ -1010,7 +1015,9 @@ class PresignedAssetProvider {
1010
1015
  return { create: () => new PresignedAssetProvider(options) };
1011
1016
  }
1012
1017
  async init() {
1013
- // Stateless provider.
1018
+ if (!this._options.quiet) {
1019
+ console.info('PresignedAssetProvider initialized');
1020
+ }
1014
1021
  }
1015
1022
  destroy() {
1016
1023
  // No-op.
@@ -1071,6 +1078,9 @@ class PresignedAssetProvider {
1071
1078
  if (!this._options.deleteAsset)
1072
1079
  return;
1073
1080
  await this._options.deleteAsset(id);
1081
+ if (!this._options.quiet) {
1082
+ console.info(`PresignedAssetProvider: deleted asset ${id}`);
1083
+ }
1074
1084
  }
1075
1085
  }
1076
1086
 
@@ -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-B_dbGmyV.js');
4
+ var workspace_migrations = require('./workspace.migrations-CxultIEq.js');
5
5
  var Y = require('yjs');
6
6
  require('y-indexeddb');
7
7
  require('y-websocket');
@@ -28829,7 +28829,7 @@ const KritzelPortal = class {
28829
28829
  * This file is auto-generated by the version bump scripts.
28830
28830
  * Do not modify manually.
28831
28831
  */
28832
- const KRITZEL_VERSION = '0.1.89';
28832
+ const KRITZEL_VERSION = '0.1.91';
28833
28833
 
28834
28834
  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)}`;
28835
28835
 
@@ -25548,6 +25548,7 @@ class IndexedDBAssetProvider {
25548
25548
  type = 'local';
25549
25549
  name = 'IndexedDBAssetProvider';
25550
25550
  _dbName;
25551
+ _quiet;
25551
25552
  _db = null;
25552
25553
  /** In-memory cache of id -> object URL to avoid re-creating blob URLs. */
25553
25554
  _urlCache = new Map();
@@ -25555,6 +25556,7 @@ class IndexedDBAssetProvider {
25555
25556
  _knownIds = new Set();
25556
25557
  constructor(options) {
25557
25558
  this._dbName = options?.dbName ?? DEFAULT_DB_NAME;
25559
+ this._quiet = options?.quiet ?? false;
25558
25560
  }
25559
25561
  /**
25560
25562
  * Factory helper enabling use as `IndexedDBAssetProvider.with({ dbName: '...' })`
@@ -25569,6 +25571,9 @@ class IndexedDBAssetProvider {
25569
25571
  this._db = await this.openDatabase();
25570
25572
  // Warm up the known-ids cache so canResolve can answer synchronously.
25571
25573
  await this.loadKnownIds();
25574
+ if (!this._quiet) {
25575
+ console.info(`IndexedDBAssetProvider initialized: ${this._dbName}`);
25576
+ }
25572
25577
  }
25573
25578
  destroy() {
25574
25579
  for (const url of this._urlCache.values()) {
@@ -25585,6 +25590,9 @@ class IndexedDBAssetProvider {
25585
25590
  this._db.close();
25586
25591
  this._db = null;
25587
25592
  }
25593
+ if (!this._quiet) {
25594
+ console.info(`IndexedDBAssetProvider destroyed: ${this._dbName}`);
25595
+ }
25588
25596
  }
25589
25597
  canResolve(id) {
25590
25598
  return this._knownIds.has(id);
@@ -25800,6 +25808,7 @@ class KritzelAssetResolver {
25800
25808
  _pending = new Map();
25801
25809
  _flushTimer = null;
25802
25810
  _destroyed = false;
25811
+ _quiet = false;
25803
25812
  /** Dedupes concurrent resolves of the same id. */
25804
25813
  _resolvePromises = new Map();
25805
25814
  /**
@@ -25824,6 +25833,7 @@ class KritzelAssetResolver {
25824
25833
  async init(config) {
25825
25834
  if (this._initialized)
25826
25835
  return;
25836
+ this._quiet = config?.quiet ?? false;
25827
25837
  const providers = this.instantiateProviders(config?.providers ?? []);
25828
25838
  // Ensure a local provider always exists so uploads can be optimistic
25829
25839
  // and remote misses can be cached for later offline access.
@@ -25831,19 +25841,47 @@ class KritzelAssetResolver {
25831
25841
  if (!hasLocal) {
25832
25842
  providers.unshift(new IndexedDBAssetProvider());
25833
25843
  }
25844
+ // Normalize order: local providers first so resolution always
25845
+ // hits the local cache before making network requests.
25846
+ providers.sort((a, b) => {
25847
+ if (a.type === 'local' && b.type !== 'local')
25848
+ return -1;
25849
+ if (a.type !== 'local' && b.type === 'local')
25850
+ return 1;
25851
+ return 0;
25852
+ });
25834
25853
  this._providers = providers;
25835
25854
  this._local = providers.find(p => p instanceof IndexedDBAssetProvider) ?? null;
25836
25855
  this._remoteProviders = providers.filter(p => p.type === 'remote');
25837
- await Promise.all(this._providers.map(p => p.init()));
25856
+ // Initialize the local provider first (must succeed), then remote
25857
+ // providers individually so a failing remote does not block init.
25858
+ if (this._local) {
25859
+ await this._local.init();
25860
+ }
25861
+ for (const provider of this._remoteProviders) {
25862
+ try {
25863
+ await provider.init();
25864
+ }
25865
+ catch (err) {
25866
+ console.warn(`[KritzelAssetResolver] Remote provider "${provider.name}" failed to initialize. ` +
25867
+ `Assets will be served from the local provider until the remote becomes available.`, err);
25868
+ }
25869
+ }
25838
25870
  // Re-enqueue any uploads that were interrupted before completing.
25839
25871
  await this.recoverPendingUploads();
25840
25872
  this._initialized = true;
25873
+ if (!this._quiet) {
25874
+ this.logProviderConfiguration();
25875
+ }
25841
25876
  if (this._pending.size > 0) {
25842
25877
  this.scheduleFlush(0);
25843
25878
  }
25844
25879
  }
25845
25880
  /** Tears down the resolver and all providers. */
25846
25881
  destroy() {
25882
+ if (!this._quiet) {
25883
+ console.info('Asset resolver destroyed');
25884
+ }
25847
25885
  this._destroyed = true;
25848
25886
  if (this._flushTimer) {
25849
25887
  clearTimeout(this._flushTimer);
@@ -26000,6 +26038,25 @@ class KritzelAssetResolver {
26000
26038
  // ------------------------------------------------------------------
26001
26039
  // Internals
26002
26040
  // ------------------------------------------------------------------
26041
+ logProviderConfiguration() {
26042
+ const lines = [
26043
+ `Asset resolver initialized with ${this._providers.length} provider(s):`,
26044
+ ];
26045
+ for (const provider of this._providers) {
26046
+ const role = provider === this._local ? 'local (primary write target)' : provider.type;
26047
+ lines.push(` - ${provider.name} [${role}]`);
26048
+ }
26049
+ if (this._local) {
26050
+ lines.push(`Write strategy: local-first (${this._local.name} → immediate, remote → background queue)`);
26051
+ }
26052
+ if (this._remoteProviders.length > 0) {
26053
+ lines.push(`Remote replication: ${this._remoteProviders.map(p => p.name).join(', ')}`);
26054
+ }
26055
+ if (this._pending.size > 0) {
26056
+ lines.push(`Pending uploads recovered: ${this._pending.size}`);
26057
+ }
26058
+ console.info(lines.join('\n'));
26059
+ }
26003
26060
  instantiateProviders(configs) {
26004
26061
  return configs.map(config => {
26005
26062
  // A class constructor is a function; anything else is a factory
@@ -26024,6 +26081,7 @@ class KritzelAssetResolver {
26024
26081
  const pending = await this._local.listAssetsWithPendingRemotes();
26025
26082
  const configured = new Set(this._remoteProviders.map(p => p.name));
26026
26083
  const now = Date.now();
26084
+ let recoveredCount = 0;
26027
26085
  for (const asset of pending) {
26028
26086
  const names = (asset.pendingRemotes ?? []).filter(n => configured.has(n));
26029
26087
  if (names.length === 0) {
@@ -26038,8 +26096,12 @@ class KritzelAssetResolver {
26038
26096
  attempts: 0,
26039
26097
  nextAttemptAt: now,
26040
26098
  });
26099
+ recoveredCount++;
26041
26100
  }
26042
26101
  }
26102
+ if (!this._quiet && recoveredCount > 0) {
26103
+ console.info(`Asset resolver: recovered ${recoveredCount} pending upload(s)`);
26104
+ }
26043
26105
  }
26044
26106
  scheduleFlush(delayMs) {
26045
26107
  if (this._destroyed)
@@ -26093,6 +26155,9 @@ class KritzelAssetResolver {
26093
26155
  });
26094
26156
  this._pending.delete(key);
26095
26157
  await this.clearPendingRemote(job.id, job.providerName);
26158
+ if (!this._quiet) {
26159
+ console.info(`Asset resolver: uploaded ${job.id} to ${provider.name}`);
26160
+ }
26096
26161
  }
26097
26162
  catch (err) {
26098
26163
  job.attempts += 1;
@@ -31,6 +31,7 @@ export class KritzelAssetResolver {
31
31
  _pending = new Map();
32
32
  _flushTimer = null;
33
33
  _destroyed = false;
34
+ _quiet = false;
34
35
  /** Dedupes concurrent resolves of the same id. */
35
36
  _resolvePromises = new Map();
36
37
  /**
@@ -55,6 +56,7 @@ export class KritzelAssetResolver {
55
56
  async init(config) {
56
57
  if (this._initialized)
57
58
  return;
59
+ this._quiet = config?.quiet ?? false;
58
60
  const providers = this.instantiateProviders(config?.providers ?? []);
59
61
  // Ensure a local provider always exists so uploads can be optimistic
60
62
  // and remote misses can be cached for later offline access.
@@ -62,19 +64,47 @@ export class KritzelAssetResolver {
62
64
  if (!hasLocal) {
63
65
  providers.unshift(new IndexedDBAssetProvider());
64
66
  }
67
+ // Normalize order: local providers first so resolution always
68
+ // hits the local cache before making network requests.
69
+ providers.sort((a, b) => {
70
+ if (a.type === 'local' && b.type !== 'local')
71
+ return -1;
72
+ if (a.type !== 'local' && b.type === 'local')
73
+ return 1;
74
+ return 0;
75
+ });
65
76
  this._providers = providers;
66
77
  this._local = providers.find(p => p instanceof IndexedDBAssetProvider) ?? null;
67
78
  this._remoteProviders = providers.filter(p => p.type === 'remote');
68
- await Promise.all(this._providers.map(p => p.init()));
79
+ // Initialize the local provider first (must succeed), then remote
80
+ // providers individually so a failing remote does not block init.
81
+ if (this._local) {
82
+ await this._local.init();
83
+ }
84
+ for (const provider of this._remoteProviders) {
85
+ try {
86
+ await provider.init();
87
+ }
88
+ catch (err) {
89
+ console.warn(`[KritzelAssetResolver] Remote provider "${provider.name}" failed to initialize. ` +
90
+ `Assets will be served from the local provider until the remote becomes available.`, err);
91
+ }
92
+ }
69
93
  // Re-enqueue any uploads that were interrupted before completing.
70
94
  await this.recoverPendingUploads();
71
95
  this._initialized = true;
96
+ if (!this._quiet) {
97
+ this.logProviderConfiguration();
98
+ }
72
99
  if (this._pending.size > 0) {
73
100
  this.scheduleFlush(0);
74
101
  }
75
102
  }
76
103
  /** Tears down the resolver and all providers. */
77
104
  destroy() {
105
+ if (!this._quiet) {
106
+ console.info('Asset resolver destroyed');
107
+ }
78
108
  this._destroyed = true;
79
109
  if (this._flushTimer) {
80
110
  clearTimeout(this._flushTimer);
@@ -231,6 +261,25 @@ export class KritzelAssetResolver {
231
261
  // ------------------------------------------------------------------
232
262
  // Internals
233
263
  // ------------------------------------------------------------------
264
+ logProviderConfiguration() {
265
+ const lines = [
266
+ `Asset resolver initialized with ${this._providers.length} provider(s):`,
267
+ ];
268
+ for (const provider of this._providers) {
269
+ const role = provider === this._local ? 'local (primary write target)' : provider.type;
270
+ lines.push(` - ${provider.name} [${role}]`);
271
+ }
272
+ if (this._local) {
273
+ lines.push(`Write strategy: local-first (${this._local.name} → immediate, remote → background queue)`);
274
+ }
275
+ if (this._remoteProviders.length > 0) {
276
+ lines.push(`Remote replication: ${this._remoteProviders.map(p => p.name).join(', ')}`);
277
+ }
278
+ if (this._pending.size > 0) {
279
+ lines.push(`Pending uploads recovered: ${this._pending.size}`);
280
+ }
281
+ console.info(lines.join('\n'));
282
+ }
234
283
  instantiateProviders(configs) {
235
284
  return configs.map(config => {
236
285
  // A class constructor is a function; anything else is a factory
@@ -255,6 +304,7 @@ export class KritzelAssetResolver {
255
304
  const pending = await this._local.listAssetsWithPendingRemotes();
256
305
  const configured = new Set(this._remoteProviders.map(p => p.name));
257
306
  const now = Date.now();
307
+ let recoveredCount = 0;
258
308
  for (const asset of pending) {
259
309
  const names = (asset.pendingRemotes ?? []).filter(n => configured.has(n));
260
310
  if (names.length === 0) {
@@ -269,8 +319,12 @@ export class KritzelAssetResolver {
269
319
  attempts: 0,
270
320
  nextAttemptAt: now,
271
321
  });
322
+ recoveredCount++;
272
323
  }
273
324
  }
325
+ if (!this._quiet && recoveredCount > 0) {
326
+ console.info(`Asset resolver: recovered ${recoveredCount} pending upload(s)`);
327
+ }
274
328
  }
275
329
  scheduleFlush(delayMs) {
276
330
  if (this._destroyed)
@@ -324,6 +378,9 @@ export class KritzelAssetResolver {
324
378
  });
325
379
  this._pending.delete(key);
326
380
  await this.clearPendingRemote(job.id, job.providerName);
381
+ if (!this._quiet) {
382
+ console.info(`Asset resolver: uploaded ${job.id} to ${provider.name}`);
383
+ }
327
384
  }
328
385
  catch (err) {
329
386
  job.attempts += 1;
@@ -20,7 +20,9 @@ export class HttpAssetProvider {
20
20
  return { create: () => new HttpAssetProvider(options) };
21
21
  }
22
22
  async init() {
23
- // No initialization needed for a stateless HTTP provider.
23
+ if (!this._options.quiet) {
24
+ console.info('HttpAssetProvider initialized');
25
+ }
24
26
  }
25
27
  destroy() {
26
28
  // No-op; no resources to release.
@@ -69,6 +71,9 @@ export class HttpAssetProvider {
69
71
  if (!res.ok) {
70
72
  throw new Error(`[HttpAssetProvider] Failed to delete asset ${id}: ${res.status} ${res.statusText}`);
71
73
  }
74
+ if (!this._options.quiet) {
75
+ console.info(`HttpAssetProvider: deleted asset ${id}`);
76
+ }
72
77
  }
73
78
  defaultUpload = async (url, blob, metadata, headers) => {
74
79
  const form = new FormData();
@@ -20,6 +20,7 @@ export class IndexedDBAssetProvider {
20
20
  type = 'local';
21
21
  name = 'IndexedDBAssetProvider';
22
22
  _dbName;
23
+ _quiet;
23
24
  _db = null;
24
25
  /** In-memory cache of id -> object URL to avoid re-creating blob URLs. */
25
26
  _urlCache = new Map();
@@ -27,6 +28,7 @@ export class IndexedDBAssetProvider {
27
28
  _knownIds = new Set();
28
29
  constructor(options) {
29
30
  this._dbName = options?.dbName ?? DEFAULT_DB_NAME;
31
+ this._quiet = options?.quiet ?? false;
30
32
  }
31
33
  /**
32
34
  * Factory helper enabling use as `IndexedDBAssetProvider.with({ dbName: '...' })`
@@ -41,6 +43,9 @@ export class IndexedDBAssetProvider {
41
43
  this._db = await this.openDatabase();
42
44
  // Warm up the known-ids cache so canResolve can answer synchronously.
43
45
  await this.loadKnownIds();
46
+ if (!this._quiet) {
47
+ console.info(`IndexedDBAssetProvider initialized: ${this._dbName}`);
48
+ }
44
49
  }
45
50
  destroy() {
46
51
  for (const url of this._urlCache.values()) {
@@ -57,6 +62,9 @@ export class IndexedDBAssetProvider {
57
62
  this._db.close();
58
63
  this._db = null;
59
64
  }
65
+ if (!this._quiet) {
66
+ console.info(`IndexedDBAssetProvider destroyed: ${this._dbName}`);
67
+ }
60
68
  }
61
69
  canResolve(id) {
62
70
  return this._knownIds.has(id);
@@ -16,7 +16,9 @@ export class PresignedAssetProvider {
16
16
  return { create: () => new PresignedAssetProvider(options) };
17
17
  }
18
18
  async init() {
19
- // Stateless provider.
19
+ if (!this._options.quiet) {
20
+ console.info('PresignedAssetProvider initialized');
21
+ }
20
22
  }
21
23
  destroy() {
22
24
  // No-op.
@@ -77,5 +79,8 @@ export class PresignedAssetProvider {
77
79
  if (!this._options.deleteAsset)
78
80
  return;
79
81
  await this._options.deleteAsset(id);
82
+ if (!this._options.quiet) {
83
+ console.info(`PresignedAssetProvider: deleted asset ${id}`);
84
+ }
80
85
  }
81
86
  }
@@ -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.89';
6
+ export const KRITZEL_VERSION = '0.1.91';
@@ -1 +1 @@
1
- export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-BWj1eE2b.js";export{d as KritzelBrushTool,b as KritzelGroup,a as KritzelImage,e as KritzelLineTool,h as KritzelSelectionTool,c as KritzelShape,g as KritzelShapeTool,K as KritzelText,f as KritzelTextTool,S as ShapeType}from"./p-TIoiUjzO.js";export{a as KritzelLine,K as KritzelPath}from"./p-DQK_4lkI.js";export{A as APP_STATE_MIGRATIONS,d as IndexedDBAssetProvider,I as IndexedDBSyncProvider,f as KritzelAlignment,e as KritzelAnchorManager,c as KritzelAssetResolver,b as KritzelCursorHelper,K as KritzelEraserTool,a as KritzelImageTool,W as WORKSPACE_MIGRATIONS,r as runMigrations}from"./p-CYnEIdQL.js";import*as t from"yjs";import{WebsocketProvider as i}from"y-websocket";import{H as n,a as o}from"./kritzel-editor.js";export{d as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,c as DEFAULT_LINE_TOOL_CONFIG,b as DEFAULT_TEXT_CONFIG,KritzelEditor,defineCustomElement as defineCustomElementKritzelEditor}from"./kritzel-editor.js";export{K as KritzelWorkspace,W as WORKSPACE_EXPORT_VERSION}from"./p-DhMlShij.js";export{K as KritzelThemeManager,d as darkTheme,l as lightTheme}from"./p-CjazGGq3.js";export{C as CURRENT_APP_STATE_SCHEMA_VERSION,a as CURRENT_WORKSPACE_SCHEMA_VERSION}from"./p-CW-VyJgK.js";export{KritzelActiveUsers,defineCustomElement as defineCustomElementKritzelActiveUsers}from"./kritzel-active-users.js";export{KritzelAvatar,defineCustomElement as defineCustomElementKritzelAvatar}from"./kritzel-avatar.js";export{KritzelAwarenessCursors,defineCustomElement as defineCustomElementKritzelAwarenessCursors}from"./kritzel-awareness-cursors.js";export{KritzelBackToContent,defineCustomElement as defineCustomElementKritzelBackToContent}from"./kritzel-back-to-content.js";export{KritzelBrushStyle,defineCustomElement as defineCustomElementKritzelBrushStyle}from"./kritzel-brush-style.js";export{KritzelButton,defineCustomElement as defineCustomElementKritzelButton}from"./kritzel-button.js";export{KritzelColor,defineCustomElement as defineCustomElementKritzelColor}from"./kritzel-color.js";export{KritzelColorPalette,defineCustomElement as defineCustomElementKritzelColorPalette}from"./kritzel-color-palette.js";export{KritzelContextMenu,defineCustomElement as defineCustomElementKritzelContextMenu}from"./kritzel-context-menu.js";export{KritzelControls,defineCustomElement as defineCustomElementKritzelControls}from"./kritzel-controls.js";export{KritzelCurrentUser,defineCustomElement as defineCustomElementKritzelCurrentUser}from"./kritzel-current-user.js";export{KritzelCurrentUserDialog,defineCustomElement as defineCustomElementKritzelCurrentUserDialog}from"./kritzel-current-user-dialog.js";export{KritzelCursorTrail,defineCustomElement as defineCustomElementKritzelCursorTrail}from"./kritzel-cursor-trail.js";export{KritzelDialog,defineCustomElement as defineCustomElementKritzelDialog}from"./kritzel-dialog.js";export{KritzelDropdown,defineCustomElement as defineCustomElementKritzelDropdown}from"./kritzel-dropdown.js";export{KritzelEngine,defineCustomElement as defineCustomElementKritzelEngine}from"./kritzel-engine.js";export{KritzelExport,defineCustomElement as defineCustomElementKritzelExport}from"./kritzel-export.js";export{KritzelFont,defineCustomElement as defineCustomElementKritzelFont}from"./kritzel-font.js";export{KritzelFontFamily,defineCustomElement as defineCustomElementKritzelFontFamily}from"./kritzel-font-family.js";export{KritzelFontSize,defineCustomElement as defineCustomElementKritzelFontSize}from"./kritzel-font-size.js";export{KritzelIcon,defineCustomElement as defineCustomElementKritzelIcon}from"./kritzel-icon.js";export{KritzelInput,defineCustomElement as defineCustomElementKritzelInput}from"./kritzel-input.js";export{KritzelLineEndings,defineCustomElement as defineCustomElementKritzelLineEndings}from"./kritzel-line-endings.js";export{KritzelLoginDialog,defineCustomElement as defineCustomElementKritzelLoginDialog}from"./kritzel-login-dialog.js";export{KritzelMasterDetail,defineCustomElement as defineCustomElementKritzelMasterDetail}from"./kritzel-master-detail.js";export{KritzelMenu,defineCustomElement as defineCustomElementKritzelMenu}from"./kritzel-menu.js";export{KritzelMenuItem,defineCustomElement as defineCustomElementKritzelMenuItem}from"./kritzel-menu-item.js";export{KritzelMoreMenu,defineCustomElement as defineCustomElementKritzelMoreMenu}from"./kritzel-more-menu.js";export{KritzelNumericInput,defineCustomElement as defineCustomElementKritzelNumericInput}from"./kritzel-numeric-input.js";export{KritzelOpacitySlider,defineCustomElement as defineCustomElementKritzelOpacitySlider}from"./kritzel-opacity-slider.js";export{KritzelPillTabs,defineCustomElement as defineCustomElementKritzelPillTabs}from"./kritzel-pill-tabs.js";export{KritzelPortal,defineCustomElement as defineCustomElementKritzelPortal}from"./kritzel-portal.js";export{KritzelSettings,defineCustomElement as defineCustomElementKritzelSettings}from"./kritzel-settings.js";export{KritzelShapeFill,defineCustomElement as defineCustomElementKritzelShapeFill}from"./kritzel-shape-fill.js";export{KritzelShareDialog,defineCustomElement as defineCustomElementKritzelShareDialog}from"./kritzel-share-dialog.js";export{KritzelSlideToggle,defineCustomElement as defineCustomElementKritzelSlideToggle}from"./kritzel-slide-toggle.js";export{KritzelSplitButton,defineCustomElement as defineCustomElementKritzelSplitButton}from"./kritzel-split-button.js";export{KritzelStrokeSize,defineCustomElement as defineCustomElementKritzelStrokeSize}from"./kritzel-stroke-size.js";export{KritzelToolConfig,defineCustomElement as defineCustomElementKritzelToolConfig}from"./kritzel-tool-config.js";export{KritzelTooltip,defineCustomElement as defineCustomElementKritzelTooltip}from"./kritzel-tooltip.js";export{KritzelUtilityPanel,defineCustomElement as defineCustomElementKritzelUtilityPanel}from"./kritzel-utility-panel.js";export{KritzelWorkspaceManager,defineCustomElement as defineCustomElementKritzelWorkspaceManager}from"./kritzel-workspace-manager.js";const m=Math.floor,u=127,z=Number.MAX_SAFE_INTEGER;class p{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const E=()=>new p,y=e=>{const t=new Uint8Array((e=>{let t=e.cpos;for(let s=0;s<e.bufs.length;s++)t+=e.bufs[s].length;return t})(e));let s=0;for(let i=0;i<e.bufs.length;i++){const n=e.bufs[i];t.set(n,s),s+=n.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),s),t},k=(e,t)=>{const s=e.cbuf.length;e.cpos===s&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(2*s),e.cpos=0),e.cbuf[e.cpos++]=t},w=(e,t)=>{for(;t>u;)k(e,128|u&t),t=m(t/128);k(e,u&t)},x=(e,t)=>{w(e,t.byteLength),((e,t)=>{const s=e.cbuf.length,i=e.cpos,n=((e,t)=>e<t?e:t)(s-i,t.length),o=t.length-n;e.cbuf.set(t.subarray(0,n),i),e.cpos+=n,o>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(((e,t)=>e>t?e:t)(2*s,o)),e.cbuf.set(t.subarray(n)),e.cpos=o)})(e,t)},T=e=>Error(e),j=T("Unexpected end of array"),P=T("Integer out of Range");class v{constructor(e){this.arr=e,this.pos=0}}const U=e=>((e,t)=>{const s=new Uint8Array(e.arr.buffer,e.pos+e.arr.byteOffset,t);return e.pos+=t,s})(e,M(e)),M=e=>{let t=0,s=1;const i=e.arr.length;for(;e.pos<i;){const i=e.arr[e.pos++];if(t+=(i&u)*s,s*=128,i<128)return t;if(t>z)throw P}throw j};class _{type="local";doc;channel;_synced=!1;constructor(e,t,s){this.doc=t,this.channel=new BroadcastChannel(e),this.channel.onmessage=e=>{this.handleMessage(e.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info("BroadcastChannel Provider initialized: "+e)}handleDocUpdate=(e,t)=>{if(t!==this){const t=E();w(t,0),x(t,e),this.channel.postMessage(y(t))}};handleMessage(e){const s=(e=>new v(e))(new Uint8Array(e));switch(M(s)){case 0:const e=U(s);t.applyUpdate(this.doc,e,this);break;case 1:this.broadcastSync();break;case 2:const i=U(s),n=t.encodeStateAsUpdate(this.doc,i);if(n.length>0){const e=E();w(e,0),x(e,n),this.channel.postMessage(y(e))}}}broadcastSync(){const e=E();w(e,2),x(e,t.encodeStateVector(this.doc)),this.channel.postMessage(y(e))}async connect(){if(!this._synced)return new Promise((e=>{const t=()=>{this._synced?e():setTimeout(t,50)};t()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class F{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(e,t,s){const n=s?.url||"ws://localhost:1234",o=s?.roomName||e;this.provider=new i(n,o,t,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${n}/${o}`)}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new F(t,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:e})=>{"connected"===e?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===e&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(e=>{e&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((e,t)=>{const s=setTimeout((()=>{t(Error("WebSocket connection timeout"))}),1e4),i=({status:t})=>{"connected"===t&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class O{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(e,t,s){const i=s?.name||e,o=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const r=s?.websocketProvider||O.sharedWebSocketProvider,l={};void 0!==s?.delay&&(l.delay=s.delay),void 0!==s?.factor&&(l.factor=s.factor),void 0!==s?.maxAttempts&&(l.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(l.minDelay=s.minDelay),void 0!==s?.maxDelay&&(l.maxDelay=s.maxDelay);const a=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info("Hocuspocus connected: "+i),s?.onConnect&&s.onConnect())},c=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info("Hocuspocus disconnected: "+i),s?.onDisconnect&&s.onDisconnect())},m=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info("Hocuspocus synced: "+i),s?.onSynced&&s.onSynced())},d=e=>{this.isDestroyed||("connecting"===e.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(e))};if(r){this.usesSharedSocket=!0;const e={websocketProvider:r,name:i,document:t,token:s?.token||null,onStatus:d,onConnect:a,onDisconnect:c,onSynced:m,...l};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new n(e),this.provider.attach(),s?.quiet||console.info("Hocuspocus Provider initialized (multiplexed): "+i)}else{this.usesSharedSocket=!1;const e={url:o,name:i,document:t,token:s?.token||null,autoConnect:!1,onStatus:d,onConnect:a,onDisconnect:c,onSynced:m,...l};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(e.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new n(e),s?.quiet||console.info(`Hocuspocus Provider initialized: ${o}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(e){if(O.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),O.sharedWebSocketProvider;const t={url:e.url};return e.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),e.onConnect&&(t.onConnect=e.onConnect),e.onDisconnect&&(t.onDisconnect=e.onDisconnect),e.onStatus&&(t.onStatus=e.onStatus),O.sharedWebSocketProvider=new o(t),console.info("Shared Hocuspocus WebSocket created: "+e.url),O.sharedWebSocketProvider}static destroySharedWebSocket(){O.sharedWebSocketProvider&&(O.sharedWebSocketProvider.destroy(),O.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return O.sharedWebSocketProvider}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new O(t,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((e,t)=>{this.pendingConnectReject=t,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,t(Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||e()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void e();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}class ${type="remote";name="HttpAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new $(e)}}async init(){}destroy(){}canResolve(e){return!0}async put(e,t){const s=t.id??this.generateUuid(),i={...t,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,e,i,n)).id??s,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.resolveUrl(e)}async fetch(e){const t=await this._options.resolveUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to fetch asset ${e}: ${i.status} ${i.statusText}`);return i.blob()}async delete(e){if(!this._options.deleteUrl)return;const t=await this._options.deleteUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{method:"DELETE",headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to delete asset ${e}: ${i.status} ${i.statusText}`)}defaultUpload=async(e,t,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",t,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(e,{method:"POST",headers:i,body:n});if(!o.ok)throw Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(e){const t=e.indexOf("/");return t>=0?e.slice(t+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const e=crypto.getRandomValues(new Uint8Array(16));e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,(e=>e.toString(16).padStart(2,"0"))).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}}class R{type="remote";name="PresignedAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new R(e)}}async init(){}destroy(){}canResolve(e){return!0}async put(e,t){const s=await this._options.getUploadDescriptor(t),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=t.mimeType),"POST"===i&&s.fields){const t=new FormData;for(const[e,i]of Object.entries(s.fields))t.append(e,i);t.append("file",e),o=t,delete n["Content-Type"],delete n["content-type"]}else o=e;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.getDownloadUrl(e)}async fetch(e){const t=await this._options.getDownloadUrl(e),s=await fetch(t);if(!s.ok)throw Error(`[PresignedAssetProvider] Failed to fetch asset ${e}: ${s.status} ${s.statusText}`);return s.blob()}async delete(e){this._options.deleteAsset&&await this._options.deleteAsset(e)}}export{_ as BroadcastSyncProvider,O as HocuspocusSyncProvider,$ as HttpAssetProvider,R as PresignedAssetProvider,F as WebSocketSyncProvider}
1
+ export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-BWj1eE2b.js";export{d as KritzelBrushTool,b as KritzelGroup,a as KritzelImage,e as KritzelLineTool,h as KritzelSelectionTool,c as KritzelShape,g as KritzelShapeTool,K as KritzelText,f as KritzelTextTool,S as ShapeType}from"./p-TIoiUjzO.js";export{a as KritzelLine,K as KritzelPath}from"./p-DQK_4lkI.js";export{A as APP_STATE_MIGRATIONS,d as IndexedDBAssetProvider,I as IndexedDBSyncProvider,f as KritzelAlignment,e as KritzelAnchorManager,c as KritzelAssetResolver,b as KritzelCursorHelper,K as KritzelEraserTool,a as KritzelImageTool,W as WORKSPACE_MIGRATIONS,r as runMigrations}from"./p-lDidcKSG.js";import*as t from"yjs";import{WebsocketProvider as i}from"y-websocket";import{H as o,a as n}from"./kritzel-editor.js";export{d as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,c as DEFAULT_LINE_TOOL_CONFIG,b as DEFAULT_TEXT_CONFIG,KritzelEditor,defineCustomElement as defineCustomElementKritzelEditor}from"./kritzel-editor.js";export{K as KritzelWorkspace,W as WORKSPACE_EXPORT_VERSION}from"./p-DhMlShij.js";export{K as KritzelThemeManager,d as darkTheme,l as lightTheme}from"./p-CjazGGq3.js";export{C as CURRENT_APP_STATE_SCHEMA_VERSION,a as CURRENT_WORKSPACE_SCHEMA_VERSION}from"./p-CW-VyJgK.js";export{KritzelActiveUsers,defineCustomElement as defineCustomElementKritzelActiveUsers}from"./kritzel-active-users.js";export{KritzelAvatar,defineCustomElement as defineCustomElementKritzelAvatar}from"./kritzel-avatar.js";export{KritzelAwarenessCursors,defineCustomElement as defineCustomElementKritzelAwarenessCursors}from"./kritzel-awareness-cursors.js";export{KritzelBackToContent,defineCustomElement as defineCustomElementKritzelBackToContent}from"./kritzel-back-to-content.js";export{KritzelBrushStyle,defineCustomElement as defineCustomElementKritzelBrushStyle}from"./kritzel-brush-style.js";export{KritzelButton,defineCustomElement as defineCustomElementKritzelButton}from"./kritzel-button.js";export{KritzelColor,defineCustomElement as defineCustomElementKritzelColor}from"./kritzel-color.js";export{KritzelColorPalette,defineCustomElement as defineCustomElementKritzelColorPalette}from"./kritzel-color-palette.js";export{KritzelContextMenu,defineCustomElement as defineCustomElementKritzelContextMenu}from"./kritzel-context-menu.js";export{KritzelControls,defineCustomElement as defineCustomElementKritzelControls}from"./kritzel-controls.js";export{KritzelCurrentUser,defineCustomElement as defineCustomElementKritzelCurrentUser}from"./kritzel-current-user.js";export{KritzelCurrentUserDialog,defineCustomElement as defineCustomElementKritzelCurrentUserDialog}from"./kritzel-current-user-dialog.js";export{KritzelCursorTrail,defineCustomElement as defineCustomElementKritzelCursorTrail}from"./kritzel-cursor-trail.js";export{KritzelDialog,defineCustomElement as defineCustomElementKritzelDialog}from"./kritzel-dialog.js";export{KritzelDropdown,defineCustomElement as defineCustomElementKritzelDropdown}from"./kritzel-dropdown.js";export{KritzelEngine,defineCustomElement as defineCustomElementKritzelEngine}from"./kritzel-engine.js";export{KritzelExport,defineCustomElement as defineCustomElementKritzelExport}from"./kritzel-export.js";export{KritzelFont,defineCustomElement as defineCustomElementKritzelFont}from"./kritzel-font.js";export{KritzelFontFamily,defineCustomElement as defineCustomElementKritzelFontFamily}from"./kritzel-font-family.js";export{KritzelFontSize,defineCustomElement as defineCustomElementKritzelFontSize}from"./kritzel-font-size.js";export{KritzelIcon,defineCustomElement as defineCustomElementKritzelIcon}from"./kritzel-icon.js";export{KritzelInput,defineCustomElement as defineCustomElementKritzelInput}from"./kritzel-input.js";export{KritzelLineEndings,defineCustomElement as defineCustomElementKritzelLineEndings}from"./kritzel-line-endings.js";export{KritzelLoginDialog,defineCustomElement as defineCustomElementKritzelLoginDialog}from"./kritzel-login-dialog.js";export{KritzelMasterDetail,defineCustomElement as defineCustomElementKritzelMasterDetail}from"./kritzel-master-detail.js";export{KritzelMenu,defineCustomElement as defineCustomElementKritzelMenu}from"./kritzel-menu.js";export{KritzelMenuItem,defineCustomElement as defineCustomElementKritzelMenuItem}from"./kritzel-menu-item.js";export{KritzelMoreMenu,defineCustomElement as defineCustomElementKritzelMoreMenu}from"./kritzel-more-menu.js";export{KritzelNumericInput,defineCustomElement as defineCustomElementKritzelNumericInput}from"./kritzel-numeric-input.js";export{KritzelOpacitySlider,defineCustomElement as defineCustomElementKritzelOpacitySlider}from"./kritzel-opacity-slider.js";export{KritzelPillTabs,defineCustomElement as defineCustomElementKritzelPillTabs}from"./kritzel-pill-tabs.js";export{KritzelPortal,defineCustomElement as defineCustomElementKritzelPortal}from"./kritzel-portal.js";export{KritzelSettings,defineCustomElement as defineCustomElementKritzelSettings}from"./kritzel-settings.js";export{KritzelShapeFill,defineCustomElement as defineCustomElementKritzelShapeFill}from"./kritzel-shape-fill.js";export{KritzelShareDialog,defineCustomElement as defineCustomElementKritzelShareDialog}from"./kritzel-share-dialog.js";export{KritzelSlideToggle,defineCustomElement as defineCustomElementKritzelSlideToggle}from"./kritzel-slide-toggle.js";export{KritzelSplitButton,defineCustomElement as defineCustomElementKritzelSplitButton}from"./kritzel-split-button.js";export{KritzelStrokeSize,defineCustomElement as defineCustomElementKritzelStrokeSize}from"./kritzel-stroke-size.js";export{KritzelToolConfig,defineCustomElement as defineCustomElementKritzelToolConfig}from"./kritzel-tool-config.js";export{KritzelTooltip,defineCustomElement as defineCustomElementKritzelTooltip}from"./kritzel-tooltip.js";export{KritzelUtilityPanel,defineCustomElement as defineCustomElementKritzelUtilityPanel}from"./kritzel-utility-panel.js";export{KritzelWorkspaceManager,defineCustomElement as defineCustomElementKritzelWorkspaceManager}from"./kritzel-workspace-manager.js";const m=Math.floor,u=127,z=Number.MAX_SAFE_INTEGER;class p{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const E=()=>new p,y=e=>{const t=new Uint8Array((e=>{let t=e.cpos;for(let s=0;s<e.bufs.length;s++)t+=e.bufs[s].length;return t})(e));let s=0;for(let i=0;i<e.bufs.length;i++){const o=e.bufs[i];t.set(o,s),s+=o.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),s),t},k=(e,t)=>{const s=e.cbuf.length;e.cpos===s&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(2*s),e.cpos=0),e.cbuf[e.cpos++]=t},w=(e,t)=>{for(;t>u;)k(e,128|u&t),t=m(t/128);k(e,u&t)},x=(e,t)=>{w(e,t.byteLength),((e,t)=>{const s=e.cbuf.length,i=e.cpos,o=((e,t)=>e<t?e:t)(s-i,t.length),n=t.length-o;e.cbuf.set(t.subarray(0,o),i),e.cpos+=o,n>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(((e,t)=>e>t?e:t)(2*s,n)),e.cbuf.set(t.subarray(o)),e.cpos=n)})(e,t)},T=e=>Error(e),j=T("Unexpected end of array"),P=T("Integer out of Range");class v{constructor(e){this.arr=e,this.pos=0}}const U=e=>((e,t)=>{const s=new Uint8Array(e.arr.buffer,e.pos+e.arr.byteOffset,t);return e.pos+=t,s})(e,M(e)),M=e=>{let t=0,s=1;const i=e.arr.length;for(;e.pos<i;){const i=e.arr[e.pos++];if(t+=(i&u)*s,s*=128,i<128)return t;if(t>z)throw P}throw j};class _{type="local";doc;channel;_synced=!1;constructor(e,t,s){this.doc=t,this.channel=new BroadcastChannel(e),this.channel.onmessage=e=>{this.handleMessage(e.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info("BroadcastChannel Provider initialized: "+e)}handleDocUpdate=(e,t)=>{if(t!==this){const t=E();w(t,0),x(t,e),this.channel.postMessage(y(t))}};handleMessage(e){const s=(e=>new v(e))(new Uint8Array(e));switch(M(s)){case 0:const e=U(s);t.applyUpdate(this.doc,e,this);break;case 1:this.broadcastSync();break;case 2:const i=U(s),o=t.encodeStateAsUpdate(this.doc,i);if(o.length>0){const e=E();w(e,0),x(e,o),this.channel.postMessage(y(e))}}}broadcastSync(){const e=E();w(e,2),x(e,t.encodeStateVector(this.doc)),this.channel.postMessage(y(e))}async connect(){if(!this._synced)return new Promise((e=>{const t=()=>{this._synced?e():setTimeout(t,50)};t()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class F{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(e,t,s){const o=s?.url||"ws://localhost:1234",n=s?.roomName||e;this.provider=new i(o,n,t,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${o}/${n}`)}static with(e){return{create:(t,s,i)=>{const o=i?{...e,...i}:e;return new F(t,s,o)}}}setupEventListeners(){this.provider.on("status",(({status:e})=>{"connected"===e?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===e&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(e=>{e&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((e,t)=>{const s=setTimeout((()=>{t(Error("WebSocket connection timeout"))}),1e4),i=({status:t})=>{"connected"===t&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class O{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(e,t,s){const i=s?.name||e,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const r=s?.websocketProvider||O.sharedWebSocketProvider,l={};void 0!==s?.delay&&(l.delay=s.delay),void 0!==s?.factor&&(l.factor=s.factor),void 0!==s?.maxAttempts&&(l.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(l.minDelay=s.minDelay),void 0!==s?.maxDelay&&(l.maxDelay=s.maxDelay);const a=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info("Hocuspocus connected: "+i),s?.onConnect&&s.onConnect())},c=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info("Hocuspocus disconnected: "+i),s?.onDisconnect&&s.onDisconnect())},m=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info("Hocuspocus synced: "+i),s?.onSynced&&s.onSynced())},d=e=>{this.isDestroyed||("connecting"===e.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(e))};if(r){this.usesSharedSocket=!0;const e={websocketProvider:r,name:i,document:t,token:s?.token||null,onStatus:d,onConnect:a,onDisconnect:c,onSynced:m,...l};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new o(e),this.provider.attach(),s?.quiet||console.info("Hocuspocus Provider initialized (multiplexed): "+i)}else{this.usesSharedSocket=!1;const e={url:n,name:i,document:t,token:s?.token||null,autoConnect:!1,onStatus:d,onConnect:a,onDisconnect:c,onSynced:m,...l};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(e.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new o(e),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(e){if(O.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),O.sharedWebSocketProvider;const t={url:e.url};return e.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),e.onConnect&&(t.onConnect=e.onConnect),e.onDisconnect&&(t.onDisconnect=e.onDisconnect),e.onStatus&&(t.onStatus=e.onStatus),O.sharedWebSocketProvider=new n(t),console.info("Shared Hocuspocus WebSocket created: "+e.url),O.sharedWebSocketProvider}static destroySharedWebSocket(){O.sharedWebSocketProvider&&(O.sharedWebSocketProvider.destroy(),O.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return O.sharedWebSocketProvider}static with(e){return{create:(t,s,i)=>{const o=i?{...e,...i}:e;return new O(t,s,o)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((e,t)=>{this.pendingConnectReject=t,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,t(Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||e()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void e();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}class ${type="remote";name="HttpAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new $(e)}}async init(){this._options.quiet||console.info("HttpAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=t.id??this.generateUuid(),i={...t,id:s},o=await(this._options.headers?.())??{},n=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(n,e,i,o)).id??s,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.resolveUrl(e)}async fetch(e){const t=await this._options.resolveUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to fetch asset ${e}: ${i.status} ${i.statusText}`);return i.blob()}async delete(e){if(!this._options.deleteUrl)return;const t=await this._options.deleteUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{method:"DELETE",headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to delete asset ${e}: ${i.status} ${i.statusText}`);this._options.quiet||console.info("HttpAssetProvider: deleted asset "+e)}defaultUpload=async(e,t,s,i)=>{const o=new FormData;o.append("metadata",JSON.stringify(s)),o.append("file",t,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const n=await fetch(e,{method:"POST",headers:i,body:o});if(!n.ok)throw Error(`[HttpAssetProvider] Upload failed: ${n.status} ${n.statusText}`);return(n.headers.get("content-type")||"").includes("application/json")?await n.json():{}};extensionFromMime(e){const t=e.indexOf("/");return t>=0?e.slice(t+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const e=crypto.getRandomValues(new Uint8Array(16));e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,(e=>e.toString(16).padStart(2,"0"))).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}}class H{type="remote";name="PresignedAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new H(e)}}async init(){this._options.quiet||console.info("PresignedAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=await this._options.getUploadDescriptor(t),i=s.method??"PUT",o={...s.headers??{}};let n;if(o["Content-Type"]||o["content-type"]||(o["Content-Type"]=t.mimeType),"POST"===i&&s.fields){const t=new FormData;for(const[e,i]of Object.entries(s.fields))t.append(e,i);t.append("file",e),n=t,delete o["Content-Type"],delete o["content-type"]}else n=e;const r=await fetch(s.url,{method:i,headers:o,body:n});if(!r.ok)throw Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.getDownloadUrl(e)}async fetch(e){const t=await this._options.getDownloadUrl(e),s=await fetch(t);if(!s.ok)throw Error(`[PresignedAssetProvider] Failed to fetch asset ${e}: ${s.status} ${s.statusText}`);return s.blob()}async delete(e){this._options.deleteAsset&&(await this._options.deleteAsset(e),this._options.quiet||console.info("PresignedAssetProvider: deleted asset "+e))}}export{_ as BroadcastSyncProvider,O as HocuspocusSyncProvider,$ as HttpAssetProvider,H as PresignedAssetProvider,F as WebSocketSyncProvider}