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
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HocuspocusProvider, a as HocuspocusProviderWebsocket } from './workspace.migrations-CvfM8aov.js';
2
- export { B as APP_STATE_MIGRATIONS, C as CURRENT_APP_STATE_SCHEMA_VERSION, z as CURRENT_WORKSPACE_SCHEMA_VERSION, v as DEFAULT_ASSET_STORAGE_CONFIG, D as DEFAULT_BRUSH_CONFIG, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, p as IndexedDBAssetProvider, I as IndexedDBSyncProvider, y as KritzelAlignment, r as KritzelAnchorManager, o as KritzelAssetResolver, g as KritzelBrushTool, m as KritzelCursorHelper, i as KritzelEraserTool, e as KritzelGroup, c as KritzelImage, j as KritzelImageTool, d as KritzelLine, h as KritzelLineTool, b as KritzelPath, n as KritzelSelectionTool, f as KritzelShape, l as KritzelShapeTool, K as KritzelText, k as KritzelTextTool, s as KritzelThemeManager, q as KritzelWorkspace, S as ShapeType, W as WORKSPACE_EXPORT_VERSION, E as WORKSPACE_MIGRATIONS, x as darkTheme, w as lightTheme, A as runMigrations } from './workspace.migrations-CvfM8aov.js';
1
+ import { H as HocuspocusProvider, a as HocuspocusProviderWebsocket } from './workspace.migrations-QMw-15p0.js';
2
+ export { B as APP_STATE_MIGRATIONS, C as CURRENT_APP_STATE_SCHEMA_VERSION, z as CURRENT_WORKSPACE_SCHEMA_VERSION, v as DEFAULT_ASSET_STORAGE_CONFIG, D as DEFAULT_BRUSH_CONFIG, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, p as IndexedDBAssetProvider, I as IndexedDBSyncProvider, y as KritzelAlignment, r as KritzelAnchorManager, o as KritzelAssetResolver, g as KritzelBrushTool, m as KritzelCursorHelper, i as KritzelEraserTool, e as KritzelGroup, c as KritzelImage, j as KritzelImageTool, d as KritzelLine, h as KritzelLineTool, b as KritzelPath, n as KritzelSelectionTool, f as KritzelShape, l as KritzelShapeTool, K as KritzelText, k as KritzelTextTool, s as KritzelThemeManager, q as KritzelWorkspace, S as ShapeType, W as WORKSPACE_EXPORT_VERSION, E as WORKSPACE_MIGRATIONS, x as darkTheme, w as lightTheme, A as runMigrations } from './workspace.migrations-QMw-15p0.js';
3
3
  import * as Y from 'yjs';
4
4
  import { WebsocketProvider } from 'y-websocket';
5
5
  import 'y-indexeddb';
@@ -886,7 +886,9 @@ class HttpAssetProvider {
886
886
  return { create: () => new HttpAssetProvider(options) };
887
887
  }
888
888
  async init() {
889
- // No initialization needed for a stateless HTTP provider.
889
+ if (!this._options.quiet) {
890
+ console.info('HttpAssetProvider initialized');
891
+ }
890
892
  }
891
893
  destroy() {
892
894
  // No-op; no resources to release.
@@ -935,6 +937,9 @@ class HttpAssetProvider {
935
937
  if (!res.ok) {
936
938
  throw new Error(`[HttpAssetProvider] Failed to delete asset ${id}: ${res.status} ${res.statusText}`);
937
939
  }
940
+ if (!this._options.quiet) {
941
+ console.info(`HttpAssetProvider: deleted asset ${id}`);
942
+ }
938
943
  }
939
944
  defaultUpload = async (url, blob, metadata, headers) => {
940
945
  const form = new FormData();
@@ -989,7 +994,9 @@ class PresignedAssetProvider {
989
994
  return { create: () => new PresignedAssetProvider(options) };
990
995
  }
991
996
  async init() {
992
- // Stateless provider.
997
+ if (!this._options.quiet) {
998
+ console.info('PresignedAssetProvider initialized');
999
+ }
993
1000
  }
994
1001
  destroy() {
995
1002
  // No-op.
@@ -1050,6 +1057,9 @@ class PresignedAssetProvider {
1050
1057
  if (!this._options.deleteAsset)
1051
1058
  return;
1052
1059
  await this._options.deleteAsset(id);
1060
+ if (!this._options.quiet) {
1061
+ console.info(`PresignedAssetProvider: deleted asset ${id}`);
1062
+ }
1053
1063
  }
1054
1064
  }
1055
1065
 
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-D9HaikfQ.js';
2
- import { b as KritzelPath, d as KritzelLine, F as KritzelColorHelper, n as KritzelSelectionTool, g as KritzelBrushTool, h as KritzelLineTool, l as KritzelShapeTool, k as KritzelTextTool, G as KritzelDevicesHelper, J as KritzelMouseButton, L as DEFAULT_COLOR_PALETTE, S as ShapeType, I as IndexedDBSyncProvider, D as DEFAULT_BRUSH_CONFIG, i as KritzelEraserTool, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, j as KritzelImageTool, y as KritzelAlignment, v as DEFAULT_ASSET_STORAGE_CONFIG, M as KritzelSelectionGroup, N as KritzelSelectionBox, O as KritzelIconRegistry, P as KritzelKeyboardHelper, Q as KritzelBaseHandler, R as KritzelToolRegistry, T as KritzelBaseObject, q as KritzelWorkspace, e as KritzelGroup, c as KritzelImage, f as KritzelShape, K as KritzelText, A as runMigrations, z as CURRENT_WORKSPACE_SCHEMA_VERSION, E as WORKSPACE_MIGRATIONS, C as CURRENT_APP_STATE_SCHEMA_VERSION, B as APP_STATE_MIGRATIONS, U as ObjectHelper, m as KritzelCursorHelper, r as KritzelAnchorManager, s as KritzelThemeManager, o as KritzelAssetResolver, V as KritzelClassHelper, X as KritzelEventHelper, Y as KritzelBaseTool, W as WORKSPACE_EXPORT_VERSION } from './workspace.migrations-CvfM8aov.js';
2
+ import { b as KritzelPath, d as KritzelLine, F as KritzelColorHelper, n as KritzelSelectionTool, g as KritzelBrushTool, h as KritzelLineTool, l as KritzelShapeTool, k as KritzelTextTool, G as KritzelDevicesHelper, J as KritzelMouseButton, L as DEFAULT_COLOR_PALETTE, S as ShapeType, I as IndexedDBSyncProvider, D as DEFAULT_BRUSH_CONFIG, i as KritzelEraserTool, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, j as KritzelImageTool, y as KritzelAlignment, v as DEFAULT_ASSET_STORAGE_CONFIG, M as KritzelSelectionGroup, N as KritzelSelectionBox, O as KritzelIconRegistry, P as KritzelKeyboardHelper, Q as KritzelBaseHandler, R as KritzelToolRegistry, T as KritzelBaseObject, q as KritzelWorkspace, e as KritzelGroup, c as KritzelImage, f as KritzelShape, K as KritzelText, A as runMigrations, z as CURRENT_WORKSPACE_SCHEMA_VERSION, E as WORKSPACE_MIGRATIONS, C as CURRENT_APP_STATE_SCHEMA_VERSION, B as APP_STATE_MIGRATIONS, U as ObjectHelper, m as KritzelCursorHelper, r as KritzelAnchorManager, s as KritzelThemeManager, o as KritzelAssetResolver, V as KritzelClassHelper, X as KritzelEventHelper, Y as KritzelBaseTool, W as WORKSPACE_EXPORT_VERSION } from './workspace.migrations-QMw-15p0.js';
3
3
  import * as Y from 'yjs';
4
4
  import 'y-indexeddb';
5
5
  import 'y-websocket';
@@ -28807,7 +28807,7 @@ const KritzelPortal = class {
28807
28807
  * This file is auto-generated by the version bump scripts.
28808
28808
  * Do not modify manually.
28809
28809
  */
28810
- const KRITZEL_VERSION = '0.1.89';
28810
+ const KRITZEL_VERSION = '0.1.91';
28811
28811
 
28812
28812
  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)}`;
28813
28813
 
@@ -25526,6 +25526,7 @@ class IndexedDBAssetProvider {
25526
25526
  type = 'local';
25527
25527
  name = 'IndexedDBAssetProvider';
25528
25528
  _dbName;
25529
+ _quiet;
25529
25530
  _db = null;
25530
25531
  /** In-memory cache of id -> object URL to avoid re-creating blob URLs. */
25531
25532
  _urlCache = new Map();
@@ -25533,6 +25534,7 @@ class IndexedDBAssetProvider {
25533
25534
  _knownIds = new Set();
25534
25535
  constructor(options) {
25535
25536
  this._dbName = options?.dbName ?? DEFAULT_DB_NAME;
25537
+ this._quiet = options?.quiet ?? false;
25536
25538
  }
25537
25539
  /**
25538
25540
  * Factory helper enabling use as `IndexedDBAssetProvider.with({ dbName: '...' })`
@@ -25547,6 +25549,9 @@ class IndexedDBAssetProvider {
25547
25549
  this._db = await this.openDatabase();
25548
25550
  // Warm up the known-ids cache so canResolve can answer synchronously.
25549
25551
  await this.loadKnownIds();
25552
+ if (!this._quiet) {
25553
+ console.info(`IndexedDBAssetProvider initialized: ${this._dbName}`);
25554
+ }
25550
25555
  }
25551
25556
  destroy() {
25552
25557
  for (const url of this._urlCache.values()) {
@@ -25563,6 +25568,9 @@ class IndexedDBAssetProvider {
25563
25568
  this._db.close();
25564
25569
  this._db = null;
25565
25570
  }
25571
+ if (!this._quiet) {
25572
+ console.info(`IndexedDBAssetProvider destroyed: ${this._dbName}`);
25573
+ }
25566
25574
  }
25567
25575
  canResolve(id) {
25568
25576
  return this._knownIds.has(id);
@@ -25778,6 +25786,7 @@ class KritzelAssetResolver {
25778
25786
  _pending = new Map();
25779
25787
  _flushTimer = null;
25780
25788
  _destroyed = false;
25789
+ _quiet = false;
25781
25790
  /** Dedupes concurrent resolves of the same id. */
25782
25791
  _resolvePromises = new Map();
25783
25792
  /**
@@ -25802,6 +25811,7 @@ class KritzelAssetResolver {
25802
25811
  async init(config) {
25803
25812
  if (this._initialized)
25804
25813
  return;
25814
+ this._quiet = config?.quiet ?? false;
25805
25815
  const providers = this.instantiateProviders(config?.providers ?? []);
25806
25816
  // Ensure a local provider always exists so uploads can be optimistic
25807
25817
  // and remote misses can be cached for later offline access.
@@ -25809,19 +25819,47 @@ class KritzelAssetResolver {
25809
25819
  if (!hasLocal) {
25810
25820
  providers.unshift(new IndexedDBAssetProvider());
25811
25821
  }
25822
+ // Normalize order: local providers first so resolution always
25823
+ // hits the local cache before making network requests.
25824
+ providers.sort((a, b) => {
25825
+ if (a.type === 'local' && b.type !== 'local')
25826
+ return -1;
25827
+ if (a.type !== 'local' && b.type === 'local')
25828
+ return 1;
25829
+ return 0;
25830
+ });
25812
25831
  this._providers = providers;
25813
25832
  this._local = providers.find(p => p instanceof IndexedDBAssetProvider) ?? null;
25814
25833
  this._remoteProviders = providers.filter(p => p.type === 'remote');
25815
- await Promise.all(this._providers.map(p => p.init()));
25834
+ // Initialize the local provider first (must succeed), then remote
25835
+ // providers individually so a failing remote does not block init.
25836
+ if (this._local) {
25837
+ await this._local.init();
25838
+ }
25839
+ for (const provider of this._remoteProviders) {
25840
+ try {
25841
+ await provider.init();
25842
+ }
25843
+ catch (err) {
25844
+ console.warn(`[KritzelAssetResolver] Remote provider "${provider.name}" failed to initialize. ` +
25845
+ `Assets will be served from the local provider until the remote becomes available.`, err);
25846
+ }
25847
+ }
25816
25848
  // Re-enqueue any uploads that were interrupted before completing.
25817
25849
  await this.recoverPendingUploads();
25818
25850
  this._initialized = true;
25851
+ if (!this._quiet) {
25852
+ this.logProviderConfiguration();
25853
+ }
25819
25854
  if (this._pending.size > 0) {
25820
25855
  this.scheduleFlush(0);
25821
25856
  }
25822
25857
  }
25823
25858
  /** Tears down the resolver and all providers. */
25824
25859
  destroy() {
25860
+ if (!this._quiet) {
25861
+ console.info('Asset resolver destroyed');
25862
+ }
25825
25863
  this._destroyed = true;
25826
25864
  if (this._flushTimer) {
25827
25865
  clearTimeout(this._flushTimer);
@@ -25978,6 +26016,25 @@ class KritzelAssetResolver {
25978
26016
  // ------------------------------------------------------------------
25979
26017
  // Internals
25980
26018
  // ------------------------------------------------------------------
26019
+ logProviderConfiguration() {
26020
+ const lines = [
26021
+ `Asset resolver initialized with ${this._providers.length} provider(s):`,
26022
+ ];
26023
+ for (const provider of this._providers) {
26024
+ const role = provider === this._local ? 'local (primary write target)' : provider.type;
26025
+ lines.push(` - ${provider.name} [${role}]`);
26026
+ }
26027
+ if (this._local) {
26028
+ lines.push(`Write strategy: local-first (${this._local.name} → immediate, remote → background queue)`);
26029
+ }
26030
+ if (this._remoteProviders.length > 0) {
26031
+ lines.push(`Remote replication: ${this._remoteProviders.map(p => p.name).join(', ')}`);
26032
+ }
26033
+ if (this._pending.size > 0) {
26034
+ lines.push(`Pending uploads recovered: ${this._pending.size}`);
26035
+ }
26036
+ console.info(lines.join('\n'));
26037
+ }
25981
26038
  instantiateProviders(configs) {
25982
26039
  return configs.map(config => {
25983
26040
  // A class constructor is a function; anything else is a factory
@@ -26002,6 +26059,7 @@ class KritzelAssetResolver {
26002
26059
  const pending = await this._local.listAssetsWithPendingRemotes();
26003
26060
  const configured = new Set(this._remoteProviders.map(p => p.name));
26004
26061
  const now = Date.now();
26062
+ let recoveredCount = 0;
26005
26063
  for (const asset of pending) {
26006
26064
  const names = (asset.pendingRemotes ?? []).filter(n => configured.has(n));
26007
26065
  if (names.length === 0) {
@@ -26016,8 +26074,12 @@ class KritzelAssetResolver {
26016
26074
  attempts: 0,
26017
26075
  nextAttemptAt: now,
26018
26076
  });
26077
+ recoveredCount++;
26019
26078
  }
26020
26079
  }
26080
+ if (!this._quiet && recoveredCount > 0) {
26081
+ console.info(`Asset resolver: recovered ${recoveredCount} pending upload(s)`);
26082
+ }
26021
26083
  }
26022
26084
  scheduleFlush(delayMs) {
26023
26085
  if (this._destroyed)
@@ -26071,6 +26133,9 @@ class KritzelAssetResolver {
26071
26133
  });
26072
26134
  this._pending.delete(key);
26073
26135
  await this.clearPendingRemote(job.id, job.providerName);
26136
+ if (!this._quiet) {
26137
+ console.info(`Asset resolver: uploaded ${job.id} to ${provider.name}`);
26138
+ }
26074
26139
  }
26075
26140
  catch (err) {
26076
26141
  job.attempts += 1;
@@ -1 +1 @@
1
- import{H as a,a as T}from"./p-CvfM8aov.js";export{B as APP_STATE_MIGRATIONS,C as CURRENT_APP_STATE_SCHEMA_VERSION,z as CURRENT_WORKSPACE_SCHEMA_VERSION,v as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,u as DEFAULT_LINE_TOOL_CONFIG,t as DEFAULT_TEXT_CONFIG,p as IndexedDBAssetProvider,I as IndexedDBSyncProvider,y as KritzelAlignment,r as KritzelAnchorManager,o as KritzelAssetResolver,g as KritzelBrushTool,m as KritzelCursorHelper,i as KritzelEraserTool,e as KritzelGroup,c as KritzelImage,j as KritzelImageTool,d as KritzelLine,h as KritzelLineTool,b as KritzelPath,n as KritzelSelectionTool,f as KritzelShape,l as KritzelShapeTool,K as KritzelText,k as KritzelTextTool,s as KritzelThemeManager,q as KritzelWorkspace,S as ShapeType,W as WORKSPACE_EXPORT_VERSION,E as WORKSPACE_MIGRATIONS,x as darkTheme,w as lightTheme,A as runMigrations}from"./p-CvfM8aov.js";import*as P from"yjs";import{WebsocketProvider as $}from"y-websocket";import"y-indexeddb";const _=Math.floor,U=127,R=Number.MAX_SAFE_INTEGER;class O{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const H=()=>new O,F=t=>{const e=new Uint8Array((t=>{let e=t.cpos;for(let s=0;s<t.bufs.length;s++)e+=t.bufs[s].length;return e})(t));let s=0;for(let i=0;i<t.bufs.length;i++){const n=t.bufs[i];e.set(n,s),s+=n.length}return e.set(new Uint8Array(t.cbuf.buffer,0,t.cpos),s),e},M=(t,e)=>{const s=t.cbuf.length;t.cpos===s&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(2*s),t.cpos=0),t.cbuf[t.cpos++]=e},N=(t,e)=>{for(;e>U;)M(t,128|U&e),e=_(e/128);M(t,U&e)},L=(t,e)=>{N(t,e.byteLength),((t,e)=>{const s=t.cbuf.length,i=t.cpos,n=((t,e)=>t<e?t:e)(s-i,e.length),o=e.length-n;t.cbuf.set(e.subarray(0,n),i),t.cpos+=n,o>0&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(((t,e)=>t>e?t:e)(2*s,o)),t.cbuf.set(e.subarray(n)),t.cpos=o)})(t,e)},G=t=>new Error(t),V=G("Unexpected end of array"),X=G("Integer out of Range");class J{constructor(t){this.arr=t,this.pos=0}}const Q=t=>((t,e)=>{const s=new Uint8Array(t.arr.buffer,t.pos+t.arr.byteOffset,e);return t.pos+=e,s})(t,Y(t)),Y=t=>{let e=0,s=1;const i=t.arr.length;for(;t.pos<i;){const i=t.arr[t.pos++];if(e+=(i&U)*s,s*=128,i<128)return e;if(e>R)throw X}throw V};class Z{type="local";doc;channel;_synced=!1;constructor(t,e,s){this.doc=e,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(t,e)=>{if(e!==this){const e=H();N(e,0),L(e,t),this.channel.postMessage(F(e))}};handleMessage(t){const e=(s=new Uint8Array(t),new J(s));var s;switch(Y(e)){case 0:const t=Q(e);P.applyUpdate(this.doc,t,this);break;case 1:this.broadcastSync();break;case 2:const s=Q(e),i=P.encodeStateAsUpdate(this.doc,s);if(i.length>0){const t=H();N(t,0),L(t,i),this.channel.postMessage(F(t))}}}broadcastSync(){const t=H();N(t,2),L(t,P.encodeStateVector(this.doc)),this.channel.postMessage(F(t))}async connect(){if(!this._synced)return new Promise((t=>{const e=()=>{this._synced?t():setTimeout(e,50)};e()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class tt{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(t,e,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||t;this.provider=new $(i,n,e,{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: ${i}/${n}`)}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new tt(e,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,e)=>{const s=setTimeout((()=>{e(new Error("WebSocket connection timeout"))}),1e4),i=({status:e})=>{"connected"===e&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())}))}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 et{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(t,e,s){const i=s?.name||t,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||et.sharedWebSocketProvider,r={};void 0!==s?.delay&&(r.delay=s.delay),void 0!==s?.factor&&(r.factor=s.factor),void 0!==s?.maxAttempts&&(r.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(r.minDelay=s.minDelay),void 0!==s?.maxDelay&&(r.maxDelay=s.maxDelay);const c=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info(`Hocuspocus connected: ${i}`),s?.onConnect&&s.onConnect())},h=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info(`Hocuspocus disconnected: ${i}`),s?.onDisconnect&&s.onDisconnect())},d=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info(`Hocuspocus synced: ${i}`),s?.onSynced&&s.onSynced())},l=t=>{this.isDestroyed||("connecting"===t.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(t))};if(o){this.usesSharedSocket=!0;const t={websocketProvider:o,name:i,document:e,token:s?.token||null,onStatus:l,onConnect:c,onDisconnect:h,onSynced:d,...r};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new a(t),this.provider.attach(),s?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:n,name:i,document:e,token:s?.token||null,autoConnect:!1,onStatus:l,onConnect:c,onDisconnect:h,onSynced:d,...r};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(t.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new a(t),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(t){if(et.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),et.sharedWebSocketProvider;const e={url:t.url};return t.WebSocketPolyfill&&(e.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(e.onConnect=t.onConnect),t.onDisconnect&&(e.onDisconnect=t.onDisconnect),t.onStatus&&(e.onStatus=t.onStatus),et.sharedWebSocketProvider=new T(e),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),et.sharedWebSocketProvider}static destroySharedWebSocket(){et.sharedWebSocketProvider&&(et.sharedWebSocketProvider.destroy(),et.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return et.sharedWebSocketProvider}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new et(e,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((t,e)=>{this.pendingConnectReject=e,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,e(new 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||t()};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 t();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 st{type="remote";name="HttpAssetProvider";_options;constructor(t){this._options=t}static with(t){return{create:()=>new st(t)}}async init(){}destroy(){}canResolve(t){return!0}async put(t,e){const s=e.id??this.generateUuid(),i={...e,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,t,i,n)).id??s,kind:e.kind??"file",mimeType:e.mimeType,size:t.size,createdAt:Date.now(),width:e.width,height:e.height,durationMs:e.durationMs,originalFilename:e.originalFilename}}async resolve(t){return this._options.resolveUrl(t)}async fetch(t){const e=await this._options.resolveUrl(t),s=await(this._options.headers?.())??{},i=await fetch(e,{headers:s});if(!i.ok)throw new Error(`[HttpAssetProvider] Failed to fetch asset ${t}: ${i.status} ${i.statusText}`);return i.blob()}async delete(t){if(!this._options.deleteUrl)return;const e=await this._options.deleteUrl(t),s=await(this._options.headers?.())??{},i=await fetch(e,{method:"DELETE",headers:s});if(!i.ok)throw new Error(`[HttpAssetProvider] Failed to delete asset ${t}: ${i.status} ${i.statusText}`)}defaultUpload=async(t,e,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",e,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(t,{method:"POST",headers:i,body:n});if(!o.ok)throw new Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(t){const e=t.indexOf("/");return e>=0?t.slice(e+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const t=crypto.getRandomValues(new Uint8Array(16));t[6]=15&t[6]|64,t[8]=63&t[8]|128;const e=Array.from(t,(t=>t.toString(16).padStart(2,"0"))).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}}class it{type="remote";name="PresignedAssetProvider";_options;constructor(t){this._options=t}static with(t){return{create:()=>new it(t)}}async init(){}destroy(){}canResolve(t){return!0}async put(t,e){const s=await this._options.getUploadDescriptor(e),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=e.mimeType),"POST"===i&&s.fields){const e=new FormData;for(const[t,i]of Object.entries(s.fields))e.append(t,i);e.append("file",t),o=e,delete n["Content-Type"],delete n["content-type"]}else o=t;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw new Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:e.kind??"file",mimeType:e.mimeType,size:t.size,createdAt:Date.now(),width:e.width,height:e.height,durationMs:e.durationMs,originalFilename:e.originalFilename}}async resolve(t){return this._options.getDownloadUrl(t)}async fetch(t){const e=await this._options.getDownloadUrl(t),s=await fetch(e);if(!s.ok)throw new Error(`[PresignedAssetProvider] Failed to fetch asset ${t}: ${s.status} ${s.statusText}`);return s.blob()}async delete(t){this._options.deleteAsset&&await this._options.deleteAsset(t)}}export{Z as BroadcastSyncProvider,et as HocuspocusSyncProvider,st as HttpAssetProvider,it as PresignedAssetProvider,tt as WebSocketSyncProvider}
1
+ import{H as a,a as T}from"./p-QMw-15p0.js";export{B as APP_STATE_MIGRATIONS,C as CURRENT_APP_STATE_SCHEMA_VERSION,z as CURRENT_WORKSPACE_SCHEMA_VERSION,v as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,u as DEFAULT_LINE_TOOL_CONFIG,t as DEFAULT_TEXT_CONFIG,p as IndexedDBAssetProvider,I as IndexedDBSyncProvider,y as KritzelAlignment,r as KritzelAnchorManager,o as KritzelAssetResolver,g as KritzelBrushTool,m as KritzelCursorHelper,i as KritzelEraserTool,e as KritzelGroup,c as KritzelImage,j as KritzelImageTool,d as KritzelLine,h as KritzelLineTool,b as KritzelPath,n as KritzelSelectionTool,f as KritzelShape,l as KritzelShapeTool,K as KritzelText,k as KritzelTextTool,s as KritzelThemeManager,q as KritzelWorkspace,S as ShapeType,W as WORKSPACE_EXPORT_VERSION,E as WORKSPACE_MIGRATIONS,x as darkTheme,w as lightTheme,A as runMigrations}from"./p-QMw-15p0.js";import*as P from"yjs";import{WebsocketProvider as $}from"y-websocket";import"y-indexeddb";const _=Math.floor,U=127,H=Number.MAX_SAFE_INTEGER;class R{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const O=()=>new R,F=t=>{const e=new Uint8Array((t=>{let e=t.cpos;for(let s=0;s<t.bufs.length;s++)e+=t.bufs[s].length;return e})(t));let s=0;for(let i=0;i<t.bufs.length;i++){const n=t.bufs[i];e.set(n,s),s+=n.length}return e.set(new Uint8Array(t.cbuf.buffer,0,t.cpos),s),e},M=(t,e)=>{const s=t.cbuf.length;t.cpos===s&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(2*s),t.cpos=0),t.cbuf[t.cpos++]=e},N=(t,e)=>{for(;e>U;)M(t,128|U&e),e=_(e/128);M(t,U&e)},L=(t,e)=>{N(t,e.byteLength),((t,e)=>{const s=t.cbuf.length,i=t.cpos,n=((t,e)=>t<e?t:e)(s-i,e.length),o=e.length-n;t.cbuf.set(e.subarray(0,n),i),t.cpos+=n,o>0&&(t.bufs.push(t.cbuf),t.cbuf=new Uint8Array(((t,e)=>t>e?t:e)(2*s,o)),t.cbuf.set(e.subarray(n)),t.cpos=o)})(t,e)},G=t=>new Error(t),V=G("Unexpected end of array"),Q=G("Integer out of Range");class X{constructor(t){this.arr=t,this.pos=0}}const J=t=>((t,e)=>{const s=new Uint8Array(t.arr.buffer,t.pos+t.arr.byteOffset,e);return t.pos+=e,s})(t,Y(t)),Y=t=>{let e=0,s=1;const i=t.arr.length;for(;t.pos<i;){const i=t.arr[t.pos++];if(e+=(i&U)*s,s*=128,i<128)return e;if(e>H)throw Q}throw V};class Z{type="local";doc;channel;_synced=!1;constructor(t,e,s){this.doc=e,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(t,e)=>{if(e!==this){const e=O();N(e,0),L(e,t),this.channel.postMessage(F(e))}};handleMessage(t){const e=(s=new Uint8Array(t),new X(s));var s;switch(Y(e)){case 0:const t=J(e);P.applyUpdate(this.doc,t,this);break;case 1:this.broadcastSync();break;case 2:const s=J(e),i=P.encodeStateAsUpdate(this.doc,s);if(i.length>0){const t=O();N(t,0),L(t,i),this.channel.postMessage(F(t))}}}broadcastSync(){const t=O();N(t,2),L(t,P.encodeStateVector(this.doc)),this.channel.postMessage(F(t))}async connect(){if(!this._synced)return new Promise((t=>{const e=()=>{this._synced?t():setTimeout(e,50)};e()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}class tt{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(t,e,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||t;this.provider=new $(i,n,e,{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: ${i}/${n}`)}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new tt(e,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,e)=>{const s=setTimeout((()=>{e(new Error("WebSocket connection timeout"))}),1e4),i=({status:e})=>{"connected"===e&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,t())}))}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 et{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(t,e,s){const i=s?.name||t,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||et.sharedWebSocketProvider,r={};void 0!==s?.delay&&(r.delay=s.delay),void 0!==s?.factor&&(r.factor=s.factor),void 0!==s?.maxAttempts&&(r.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(r.minDelay=s.minDelay),void 0!==s?.maxDelay&&(r.maxDelay=s.maxDelay);const c=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info(`Hocuspocus connected: ${i}`),s?.onConnect&&s.onConnect())},h=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info(`Hocuspocus disconnected: ${i}`),s?.onDisconnect&&s.onDisconnect())},d=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info(`Hocuspocus synced: ${i}`),s?.onSynced&&s.onSynced())},l=t=>{this.isDestroyed||("connecting"===t.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(t))};if(o){this.usesSharedSocket=!0;const t={websocketProvider:o,name:i,document:e,token:s?.token||null,onStatus:l,onConnect:c,onDisconnect:h,onSynced:d,...r};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new a(t),this.provider.attach(),s?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:n,name:i,document:e,token:s?.token||null,autoConnect:!1,onStatus:l,onConnect:c,onDisconnect:h,onSynced:d,...r};void 0!==s?.forceSyncInterval&&(t.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(t.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(t.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new a(t),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(t){if(et.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),et.sharedWebSocketProvider;const e={url:t.url};return t.WebSocketPolyfill&&(e.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(e.onConnect=t.onConnect),t.onDisconnect&&(e.onDisconnect=t.onDisconnect),t.onStatus&&(e.onStatus=t.onStatus),et.sharedWebSocketProvider=new T(e),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),et.sharedWebSocketProvider}static destroySharedWebSocket(){et.sharedWebSocketProvider&&(et.sharedWebSocketProvider.destroy(),et.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return et.sharedWebSocketProvider}static with(t){return{create:(e,s,i)=>{const n=i?{...t,...i}:t;return new et(e,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((t,e)=>{this.pendingConnectReject=e,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,e(new 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||t()};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 t();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 st{type="remote";name="HttpAssetProvider";_options;constructor(t){this._options=t}static with(t){return{create:()=>new st(t)}}async init(){this._options.quiet||console.info("HttpAssetProvider initialized")}destroy(){}canResolve(t){return!0}async put(t,e){const s=e.id??this.generateUuid(),i={...e,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,t,i,n)).id??s,kind:e.kind??"file",mimeType:e.mimeType,size:t.size,createdAt:Date.now(),width:e.width,height:e.height,durationMs:e.durationMs,originalFilename:e.originalFilename}}async resolve(t){return this._options.resolveUrl(t)}async fetch(t){const e=await this._options.resolveUrl(t),s=await(this._options.headers?.())??{},i=await fetch(e,{headers:s});if(!i.ok)throw new Error(`[HttpAssetProvider] Failed to fetch asset ${t}: ${i.status} ${i.statusText}`);return i.blob()}async delete(t){if(!this._options.deleteUrl)return;const e=await this._options.deleteUrl(t),s=await(this._options.headers?.())??{},i=await fetch(e,{method:"DELETE",headers:s});if(!i.ok)throw new Error(`[HttpAssetProvider] Failed to delete asset ${t}: ${i.status} ${i.statusText}`);this._options.quiet||console.info(`HttpAssetProvider: deleted asset ${t}`)}defaultUpload=async(t,e,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",e,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(t,{method:"POST",headers:i,body:n});if(!o.ok)throw new Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(t){const e=t.indexOf("/");return e>=0?t.slice(e+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const t=crypto.getRandomValues(new Uint8Array(16));t[6]=15&t[6]|64,t[8]=63&t[8]|128;const e=Array.from(t,(t=>t.toString(16).padStart(2,"0"))).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}}class it{type="remote";name="PresignedAssetProvider";_options;constructor(t){this._options=t}static with(t){return{create:()=>new it(t)}}async init(){this._options.quiet||console.info("PresignedAssetProvider initialized")}destroy(){}canResolve(t){return!0}async put(t,e){const s=await this._options.getUploadDescriptor(e),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=e.mimeType),"POST"===i&&s.fields){const e=new FormData;for(const[t,i]of Object.entries(s.fields))e.append(t,i);e.append("file",t),o=e,delete n["Content-Type"],delete n["content-type"]}else o=t;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw new Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:e.kind??"file",mimeType:e.mimeType,size:t.size,createdAt:Date.now(),width:e.width,height:e.height,durationMs:e.durationMs,originalFilename:e.originalFilename}}async resolve(t){return this._options.getDownloadUrl(t)}async fetch(t){const e=await this._options.getDownloadUrl(t),s=await fetch(e);if(!s.ok)throw new Error(`[PresignedAssetProvider] Failed to fetch asset ${t}: ${s.status} ${s.statusText}`);return s.blob()}async delete(t){this._options.deleteAsset&&(await this._options.deleteAsset(t),this._options.quiet||console.info(`PresignedAssetProvider: deleted asset ${t}`))}}export{Z as BroadcastSyncProvider,et as HocuspocusSyncProvider,st as HttpAssetProvider,it as PresignedAssetProvider,tt as WebSocketSyncProvider}