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.
- package/dist/cjs/index.cjs.js +13 -3
- package/dist/cjs/kritzel-active-users_42.cjs.entry.js +2 -2
- package/dist/cjs/{workspace.migrations-B_dbGmyV.js → workspace.migrations-CxultIEq.js} +66 -1
- package/dist/collection/classes/providers/assets/asset-resolver.class.js +58 -1
- package/dist/collection/classes/providers/assets/http-asset-provider.class.js +6 -1
- package/dist/collection/classes/providers/assets/indexeddb-asset-provider.class.js +8 -0
- package/dist/collection/classes/providers/assets/presigned-asset-provider.class.js +6 -1
- package/dist/collection/constants/version.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/kritzel-editor.js +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-settings.js +1 -1
- package/dist/components/{p-CaRobExg.js → p-cxYQlXqh.js} +1 -1
- package/dist/components/{p-CYnEIdQL.js → p-lDidcKSG.js} +2 -2
- package/dist/esm/index.js +14 -4
- package/dist/esm/kritzel-active-users_42.entry.js +2 -2
- package/dist/esm/{workspace.migrations-CvfM8aov.js → workspace.migrations-QMw-15p0.js} +66 -1
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/{p-7fc12473.entry.js → p-07b533ac.entry.js} +2 -2
- package/dist/stencil/{p-CvfM8aov.js → p-QMw-15p0.js} +1 -1
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/providers/assets/asset-resolver.class.d.ts +2 -0
- package/dist/types/classes/providers/assets/http-asset-provider.class.d.ts +4 -0
- package/dist/types/classes/providers/assets/indexeddb-asset-provider.class.d.ts +5 -0
- package/dist/types/classes/providers/assets/presigned-asset-provider.class.d.ts +4 -0
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/interfaces/asset-storage-config.interface.d.ts +4 -0
- 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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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.
|
|
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
|
-
|
|
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}
|