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/cjs/index.cjs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var workspace_migrations = require('./workspace.migrations-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/components/index.js
CHANGED
|
@@ -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}
|