@lvce-editor/cache-worker 0.0.2

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/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Cache Worker
2
+
3
+ Browser storage APIs for LVCE workers. `@lvce-editor/cache-worker` provides Cache Storage, IndexedDB, and Origin Private File System (OPFS) operations through a worker RPC command map.
4
+
5
+ ## Commands
6
+
7
+ | Command | Arguments | Result |
8
+ | ------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
9
+ | `Cache.getCacheStorageItem` | `(request, cacheName = 'lvce-cache')` | Structured-cloneable `{ body: ArrayBuffer, headers: [string, string][], status, statusText }` or `null` when missing |
10
+ | `Cache.setCacheStorageItem` | `(request, value, cacheName = 'lvce-cache')` | `undefined`; stores a body accepted by the browser `Response` constructor |
11
+ | `Cache.removeCacheStorageItem` | `(request, cacheName = 'lvce-cache')` | `boolean` indicating whether an item was removed |
12
+ | `IndexedDb.addIndexedDbFileHandle` | `(key, handle, databaseName = 'lvce-cache-worker')` | `undefined` after the write transaction commits |
13
+ | `IndexedDb.getIndexedDbFileHandle` | `(key, databaseName = 'lvce-cache-worker')` | Stored handle or `null` when missing through worker RPC |
14
+ | `IndexedDb.removeIndexedDbFileHandle` | `(key, databaseName = 'lvce-cache-worker')` | `undefined` after the delete transaction commits; deleting a missing key is a no-op |
15
+ | `Opfs.readFile` | `(name)` | UTF-8 text; rejects when the file does not exist |
16
+ | `Opfs.writeFile` | `(name, content)` | `undefined` after the writable is closed |
17
+ | `Opfs.removeFile` | `(name)` | `undefined`; rejects when the file does not exist |
18
+
19
+ Missing browser APIs reject with an error that names the unavailable capability. Browser storage quota, security, invalid key, structured-clone, and transaction errors are propagated to the caller. File handles must be structured-cloneable by the browser and writable in the current origin. OPFS filenames are single path components; directory traversal is not supported.
20
+
21
+ Resolve the worker entry URL with `getCacheWorkerUrl` and connect it using `@lvce-editor/rpc`'s `ModuleWorkerRpcParent`:
22
+
23
+ ```js
24
+ import { ModuleWorkerRpcParent } from '@lvce-editor/rpc'
25
+ import { getCacheWorkerUrl } from '@lvce-editor/cache-worker'
26
+
27
+ const rpc = await ModuleWorkerRpcParent.create({
28
+ commandMap: {},
29
+ url: getCacheWorkerUrl().href,
30
+ })
31
+ ```
32
+
33
+ The worker registers the commands in `src/parts/CommandMap/CommandMap.js`. `Response` values are converted to structured-cloneable data before crossing RPC; callers can create a new `Response` from the returned body and metadata.
34
+
35
+ ## Development
36
+
37
+ This repository uses npm workspaces and a root `package-lock.json`.
38
+
39
+ The cross-browser suite checks Cache Storage and OPFS through worker RPC in Chromium and Firefox. IndexedDB file-handle restoration is covered in Firefox; Chromium checks general structured-clone persistence.
40
+
41
+ ```sh
42
+ npm ci
43
+ npm test
44
+ npm run build
45
+ npm run e2e
46
+ ```
47
+
48
+ The browser suite runs against Chromium and Firefox. Install both with `npx playwright install --with-deps chromium firefox`.
@@ -0,0 +1,809 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // node_modules/@lvce-editor/ipc/dist/index.js
8
+ var isMessagePort = (value) => {
9
+ return value && value instanceof MessagePort;
10
+ };
11
+ var isMessagePortMain = (value) => {
12
+ return value && value.constructor && value.constructor.name === "MessagePortMain";
13
+ };
14
+ var isOffscreenCanvas = (value) => {
15
+ return typeof OffscreenCanvas !== "undefined" && value instanceof OffscreenCanvas;
16
+ };
17
+ var isInstanceOf = (value, constructorName) => {
18
+ return value?.constructor?.name === constructorName;
19
+ };
20
+ var isSocket = (value) => {
21
+ return isInstanceOf(value, "Socket");
22
+ };
23
+ var transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
24
+ var isTransferrable = (value) => {
25
+ for (const fn of transferrables) {
26
+ if (fn(value)) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ };
32
+ var walkValue = (value, transferrables2, isTransferrable2) => {
33
+ if (!value) {
34
+ return;
35
+ }
36
+ if (isTransferrable2(value)) {
37
+ transferrables2.push(value);
38
+ return;
39
+ }
40
+ if (Array.isArray(value)) {
41
+ for (const item of value) {
42
+ walkValue(item, transferrables2, isTransferrable2);
43
+ }
44
+ return;
45
+ }
46
+ if (typeof value === "object") {
47
+ for (const property of Object.values(value)) {
48
+ walkValue(property, transferrables2, isTransferrable2);
49
+ }
50
+ }
51
+ };
52
+ var getTransferrables = (value) => {
53
+ const transferrables2 = [];
54
+ walkValue(value, transferrables2, isTransferrable);
55
+ return transferrables2;
56
+ };
57
+ var attachEvents = (that) => {
58
+ const handleMessage2 = (...args) => {
59
+ const data = that.getData(...args);
60
+ that.dispatchEvent(new MessageEvent("message", {
61
+ data
62
+ }));
63
+ };
64
+ that.onMessage(handleMessage2);
65
+ const handleClose = (event) => {
66
+ that.dispatchEvent(new Event("close"));
67
+ };
68
+ that.onClose(handleClose);
69
+ };
70
+ var Ipc = class extends EventTarget {
71
+ constructor(rawIpc) {
72
+ super();
73
+ this._rawIpc = rawIpc;
74
+ attachEvents(this);
75
+ }
76
+ };
77
+ var readyMessage = "ready";
78
+ var getData$2 = (event) => {
79
+ return event.data;
80
+ };
81
+ var listen$7 = () => {
82
+ if (typeof WorkerGlobalScope === "undefined") {
83
+ throw new TypeError("module is not in web worker scope");
84
+ }
85
+ return globalThis;
86
+ };
87
+ var signal$8 = (global) => {
88
+ global.postMessage(readyMessage);
89
+ };
90
+ var IpcChildWithModuleWorker = class extends Ipc {
91
+ getData(event) {
92
+ return getData$2(event);
93
+ }
94
+ send(message) {
95
+ this._rawIpc.postMessage(message);
96
+ }
97
+ sendAndTransfer(message) {
98
+ const transfer = getTransferrables(message);
99
+ this._rawIpc.postMessage(message, transfer);
100
+ }
101
+ dispose() {
102
+ }
103
+ onClose(callback) {
104
+ }
105
+ onMessage(callback) {
106
+ this._rawIpc.addEventListener("message", callback);
107
+ }
108
+ };
109
+ var wrap$f = (global) => {
110
+ return new IpcChildWithModuleWorker(global);
111
+ };
112
+ var IpcChildWithModuleWorker$1 = {
113
+ __proto__: null,
114
+ listen: listen$7,
115
+ signal: signal$8,
116
+ wrap: wrap$f
117
+ };
118
+
119
+ // node_modules/@lvce-editor/command/dist/index.js
120
+ var CommandNotFoundError = class extends Error {
121
+ constructor(command) {
122
+ super(`Command not found ${command}`);
123
+ this.name = "CommandNotFoundError";
124
+ }
125
+ };
126
+ var commands = /* @__PURE__ */ Object.create(null);
127
+ var register = (commandMap2) => {
128
+ Object.assign(commands, commandMap2);
129
+ };
130
+ var getCommand = (key) => {
131
+ return commands[key];
132
+ };
133
+ var execute = (command, ...args) => {
134
+ const fn = getCommand(command);
135
+ if (!fn) {
136
+ throw new CommandNotFoundError(command);
137
+ }
138
+ return fn(...args);
139
+ };
140
+
141
+ // node_modules/@lvce-editor/json-rpc/dist/index.js
142
+ var Two = "2.0";
143
+ var callbacks = /* @__PURE__ */ Object.create(null);
144
+ var get = (id2) => {
145
+ return callbacks[id2];
146
+ };
147
+ var remove = (id2) => {
148
+ delete callbacks[id2];
149
+ };
150
+ var JsonRpcError = class extends Error {
151
+ constructor(message) {
152
+ super(message);
153
+ this.name = "JsonRpcError";
154
+ }
155
+ };
156
+ var NewLine = "\n";
157
+ var DomException = "DOMException";
158
+ var ReferenceError$1 = "ReferenceError";
159
+ var SyntaxError$1 = "SyntaxError";
160
+ var TypeError$1 = "TypeError";
161
+ var getErrorConstructor = (message, type) => {
162
+ if (type) {
163
+ switch (type) {
164
+ case DomException:
165
+ return DOMException;
166
+ case ReferenceError$1:
167
+ return ReferenceError;
168
+ case SyntaxError$1:
169
+ return SyntaxError;
170
+ case TypeError$1:
171
+ return TypeError;
172
+ default:
173
+ return Error;
174
+ }
175
+ }
176
+ if (message.startsWith("TypeError: ")) {
177
+ return TypeError;
178
+ }
179
+ if (message.startsWith("SyntaxError: ")) {
180
+ return SyntaxError;
181
+ }
182
+ if (message.startsWith("ReferenceError: ")) {
183
+ return ReferenceError;
184
+ }
185
+ return Error;
186
+ };
187
+ var constructError = (message, type, name) => {
188
+ const ErrorConstructor = getErrorConstructor(message, type);
189
+ if (ErrorConstructor === DOMException && name) {
190
+ return new ErrorConstructor(message, name);
191
+ }
192
+ if (ErrorConstructor === Error) {
193
+ const error = new Error(message);
194
+ if (name && name !== "VError") {
195
+ Object.defineProperty(error, "name", {
196
+ configurable: true,
197
+ value: name
198
+ });
199
+ }
200
+ return error;
201
+ }
202
+ return new ErrorConstructor(message);
203
+ };
204
+ var joinLines = (lines) => {
205
+ return lines.join(NewLine);
206
+ };
207
+ var splitLines = (lines) => {
208
+ return lines.split(NewLine);
209
+ };
210
+ var getCurrentStack = () => {
211
+ const stackLinesToSkip = 3;
212
+ const currentStack = joinLines(splitLines(new Error().stack || "").slice(stackLinesToSkip));
213
+ return currentStack;
214
+ };
215
+ var getNewLineIndex = (string2, startIndex) => {
216
+ {
217
+ return string2.indexOf(NewLine);
218
+ }
219
+ };
220
+ var getParentStack = (error) => {
221
+ let parentStack = error.stack || error.data || error.message || "";
222
+ if (parentStack.startsWith(" at")) {
223
+ parentStack = error.message + NewLine + parentStack;
224
+ }
225
+ return parentStack;
226
+ };
227
+ var MethodNotFound = -32601;
228
+ var Custom = -32001;
229
+ var setStack = (error, stack) => {
230
+ const descriptor = Object.getOwnPropertyDescriptor(error, "stack");
231
+ if (descriptor) {
232
+ if (!descriptor.configurable && !descriptor.writable) {
233
+ return;
234
+ }
235
+ if (!descriptor.configurable && descriptor.writable) {
236
+ error.stack = stack;
237
+ return;
238
+ }
239
+ }
240
+ Object.defineProperty(error, "stack", {
241
+ configurable: true,
242
+ value: stack,
243
+ writable: true
244
+ });
245
+ };
246
+ var restoreExistingError = (error, currentStack) => {
247
+ if (typeof error.stack === "string") {
248
+ setStack(error, `${error.stack}${NewLine}${currentStack}`);
249
+ }
250
+ return error;
251
+ };
252
+ var restoreMethodNotFoundError = (error, currentStack) => {
253
+ const restoredError = new JsonRpcError(error.message);
254
+ Object.assign(restoredError, {
255
+ code: error.code
256
+ });
257
+ const parentStack = getParentStack(error);
258
+ setStack(restoredError, `${parentStack}${NewLine}${currentStack}`);
259
+ return restoredError;
260
+ };
261
+ var restoreStackFromData = (restoredError, error, currentStack) => {
262
+ if (error.data.stack && error.data.type && error.message) {
263
+ setStack(restoredError, `${error.data.type}: ${error.message}${NewLine}${error.data.stack}${NewLine}${currentStack}`);
264
+ return;
265
+ }
266
+ if (error.data.stack) {
267
+ setStack(restoredError, error.data.stack);
268
+ }
269
+ };
270
+ var applyDataProperties = (restoredError, error) => {
271
+ restoreStackFromData(restoredError, error, getCurrentStack());
272
+ if (error.data.codeFrame) {
273
+ restoredError.codeFrame = error.data.codeFrame;
274
+ }
275
+ if (typeof error.data.code === "string" || typeof error.data.code === "number") {
276
+ Object.defineProperty(restoredError, "code", {
277
+ configurable: true,
278
+ value: error.data.code,
279
+ writable: true
280
+ });
281
+ }
282
+ if (error.data.type) {
283
+ restoredError.name = error.data.type;
284
+ }
285
+ };
286
+ var applyDirectProperties = (restoredError, error) => {
287
+ if (error.stack) {
288
+ const lowerStack = restoredError.stack || "";
289
+ const indexNewLine = getNewLineIndex(lowerStack);
290
+ const parentStack = getParentStack(error);
291
+ setStack(restoredError, `${parentStack}${lowerStack.slice(indexNewLine)}`);
292
+ }
293
+ if (error.codeFrame) {
294
+ restoredError.codeFrame = error.codeFrame;
295
+ }
296
+ };
297
+ var restoreMessageError = (error, _currentStack) => {
298
+ const restoredError = constructError(error.message, error.type || error.data?.type, error.name);
299
+ if (typeof error.code === "string" || typeof error.code === "number") {
300
+ Object.defineProperty(restoredError, "code", {
301
+ configurable: true,
302
+ value: error.code,
303
+ writable: true
304
+ });
305
+ }
306
+ if (error.data) {
307
+ applyDataProperties(restoredError, error);
308
+ } else {
309
+ applyDirectProperties(restoredError, error);
310
+ }
311
+ return restoredError;
312
+ };
313
+ var getFallbackMessage = (error) => {
314
+ if (error && typeof error.message === "string" && error.message) {
315
+ return error.message;
316
+ }
317
+ if (error && error.data) {
318
+ return getFallbackMessage(error.data);
319
+ }
320
+ const stringified = String(error);
321
+ if (stringified !== "[object Object]") {
322
+ return stringified;
323
+ }
324
+ try {
325
+ return JSON.stringify(error);
326
+ } catch {
327
+ return stringified;
328
+ }
329
+ };
330
+ var restoreJsonRpcError = (error) => {
331
+ const currentStack = getCurrentStack();
332
+ if (error && error instanceof Error) {
333
+ return restoreExistingError(error, currentStack);
334
+ }
335
+ if (error && error.code && error.code === MethodNotFound) {
336
+ return restoreMethodNotFoundError(error, currentStack);
337
+ }
338
+ if (error && error.error) {
339
+ return restoreJsonRpcError(error.error);
340
+ }
341
+ if (error && error.message) {
342
+ return restoreMessageError(error);
343
+ }
344
+ return new Error(`JsonRpc Error: ${getFallbackMessage(error)}`);
345
+ };
346
+ var unwrapJsonRpcResult = (responseMessage) => {
347
+ if ("error" in responseMessage) {
348
+ const restoredError = restoreJsonRpcError(responseMessage.error);
349
+ throw restoredError;
350
+ }
351
+ if ("result" in responseMessage) {
352
+ return responseMessage.result;
353
+ }
354
+ throw new JsonRpcError("unexpected response message");
355
+ };
356
+ var warn = (...args) => {
357
+ console.warn(...args);
358
+ };
359
+ var resolve = (id2, response) => {
360
+ const fn = get(id2);
361
+ if (!fn) {
362
+ console.log(response);
363
+ warn(`callback ${id2} may already be disposed`);
364
+ return;
365
+ }
366
+ fn(response);
367
+ remove(id2);
368
+ };
369
+ var E_COMMAND_NOT_FOUND = "E_COMMAND_NOT_FOUND";
370
+ var getErrorType = (prettyError) => {
371
+ if (prettyError && prettyError.type) {
372
+ return prettyError.type;
373
+ }
374
+ if (prettyError && prettyError.constructor && prettyError.constructor.name) {
375
+ return prettyError.constructor.name;
376
+ }
377
+ return void 0;
378
+ };
379
+ var isAlreadyStack = (line) => {
380
+ return line.trim().startsWith("at ");
381
+ };
382
+ var getStack = (prettyError) => {
383
+ const stackString = prettyError.stack || "";
384
+ const newLineIndex = stackString.indexOf("\n");
385
+ if (newLineIndex !== -1 && !isAlreadyStack(stackString.slice(0, newLineIndex))) {
386
+ return stackString.slice(newLineIndex + 1);
387
+ }
388
+ return stackString;
389
+ };
390
+ var getErrorProperty = (error, prettyError) => {
391
+ if (error && error.code === E_COMMAND_NOT_FOUND) {
392
+ return {
393
+ code: MethodNotFound,
394
+ data: error.stack,
395
+ message: error.message
396
+ };
397
+ }
398
+ return {
399
+ code: Custom,
400
+ data: {
401
+ code: prettyError.code ?? error?.code,
402
+ codeFrame: prettyError.codeFrame,
403
+ name: prettyError.name ?? error?.name,
404
+ stack: getStack(prettyError),
405
+ type: getErrorType(prettyError)
406
+ },
407
+ message: prettyError.message
408
+ };
409
+ };
410
+ var create$1 = (id2, error) => {
411
+ return {
412
+ error,
413
+ id: id2,
414
+ jsonrpc: Two
415
+ };
416
+ };
417
+ var getErrorResponse = (id2, error, preparePrettyError2, logError2) => {
418
+ const prettyError = preparePrettyError2(error);
419
+ logError2(error, prettyError);
420
+ const errorProperty = getErrorProperty(error, prettyError);
421
+ return create$1(id2, errorProperty);
422
+ };
423
+ var create = (message, result) => {
424
+ return {
425
+ id: message.id,
426
+ jsonrpc: Two,
427
+ result: result ?? null
428
+ };
429
+ };
430
+ var getSuccessResponse = (message, result) => {
431
+ const resultProperty = result ?? null;
432
+ return create(message, resultProperty);
433
+ };
434
+ var getErrorResponseSimple = (id2, error) => {
435
+ return {
436
+ error: {
437
+ code: Custom,
438
+ data: error instanceof Error ? {
439
+ ...error,
440
+ code: "code" in error ? error.code : void 0,
441
+ stack: error.stack,
442
+ type: error.name
443
+ } : error,
444
+ // @ts-ignore
445
+ message: error.message
446
+ },
447
+ id: id2,
448
+ jsonrpc: Two
449
+ };
450
+ };
451
+ var getResponse = async (message, ipc, execute2, preparePrettyError2, logError2, requiresSocket2) => {
452
+ try {
453
+ const result = requiresSocket2(message.method) ? await execute2(message.method, ipc, ...message.params) : await execute2(message.method, ...message.params);
454
+ return getSuccessResponse(message, result);
455
+ } catch (error) {
456
+ if (ipc.canUseSimpleErrorResponse) {
457
+ return getErrorResponseSimple(message.id, error);
458
+ }
459
+ return getErrorResponse(message.id, error, preparePrettyError2, logError2);
460
+ }
461
+ };
462
+ var defaultPreparePrettyError = (error) => {
463
+ return error;
464
+ };
465
+ var defaultLogError = () => {
466
+ };
467
+ var defaultRequiresSocket = () => {
468
+ return false;
469
+ };
470
+ var defaultResolve = resolve;
471
+ var normalizeParams = (args) => {
472
+ if (args.length === 1) {
473
+ const options = args[0];
474
+ return {
475
+ execute: options.execute,
476
+ ipc: options.ipc,
477
+ logError: options.logError || defaultLogError,
478
+ message: options.message,
479
+ preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
480
+ requiresSocket: options.requiresSocket || defaultRequiresSocket,
481
+ resolve: options.resolve || defaultResolve
482
+ };
483
+ }
484
+ return {
485
+ execute: args[2],
486
+ ipc: args[0],
487
+ logError: args[5],
488
+ message: args[1],
489
+ preparePrettyError: args[4],
490
+ requiresSocket: args[6],
491
+ resolve: args[3]
492
+ };
493
+ };
494
+ var handleJsonRpcMessage = async (...args) => {
495
+ const options = normalizeParams(args);
496
+ const {
497
+ execute: execute2,
498
+ ipc,
499
+ logError: logError2,
500
+ message,
501
+ preparePrettyError: preparePrettyError2,
502
+ requiresSocket: requiresSocket2,
503
+ resolve: resolve2
504
+ } = options;
505
+ if ("id" in message) {
506
+ if ("method" in message) {
507
+ const response = await getResponse(message, ipc, execute2, preparePrettyError2, logError2, requiresSocket2);
508
+ try {
509
+ ipc.send(response);
510
+ } catch (error) {
511
+ const errorResponse = getErrorResponse(message.id, error, preparePrettyError2, logError2);
512
+ ipc.send(errorResponse);
513
+ }
514
+ return;
515
+ }
516
+ resolve2(message.id, message);
517
+ return;
518
+ }
519
+ if ("method" in message) {
520
+ await getResponse(message, ipc, execute2, preparePrettyError2, logError2, requiresSocket2);
521
+ return;
522
+ }
523
+ throw new JsonRpcError("unexpected message");
524
+ };
525
+
526
+ // node_modules/@lvce-editor/rpc/dist/parts/JsonRpcVersion/JsonRpcVersion.js
527
+ var Two2 = "2.0";
528
+
529
+ // node_modules/@lvce-editor/rpc/dist/parts/JsonRpcEvent/JsonRpcEvent.js
530
+ var create2 = (method, params) => {
531
+ return {
532
+ jsonrpc: Two2,
533
+ method,
534
+ params
535
+ };
536
+ };
537
+
538
+ // node_modules/@lvce-editor/rpc/dist/parts/JsonRpcRequest/JsonRpcRequest.js
539
+ var create3 = (id2, method, params) => {
540
+ const message = {
541
+ id: id2,
542
+ jsonrpc: Two2,
543
+ method,
544
+ params
545
+ };
546
+ return message;
547
+ };
548
+
549
+ // node_modules/@lvce-editor/rpc/dist/parts/Id/Id.js
550
+ var id = 0;
551
+ var create4 = () => {
552
+ return ++id;
553
+ };
554
+
555
+ // node_modules/@lvce-editor/rpc/dist/parts/RegisterPromise/RegisterPromise.js
556
+ var registerPromise = (map) => {
557
+ const id2 = create4();
558
+ const { promise, resolve: resolve2 } = Promise.withResolvers();
559
+ map[id2] = resolve2;
560
+ return { id: id2, promise };
561
+ };
562
+
563
+ // node_modules/@lvce-editor/rpc/dist/parts/CreateRpc/CreateRpc.js
564
+ var invokeHelper = async (callbacks2, ipc, method, params, useSendAndTransfer) => {
565
+ const { id: id2, promise } = registerPromise(callbacks2);
566
+ const message = create3(id2, method, params);
567
+ if (useSendAndTransfer && ipc.sendAndTransfer) {
568
+ ipc.sendAndTransfer(message);
569
+ } else {
570
+ ipc.send(message);
571
+ }
572
+ const responseMessage = await promise;
573
+ return unwrapJsonRpcResult(responseMessage);
574
+ };
575
+ var createRpc = (ipc) => {
576
+ const callbacks2 = /* @__PURE__ */ Object.create(null);
577
+ ipc._resolve = (id2, response) => {
578
+ const fn = callbacks2[id2];
579
+ if (!fn) {
580
+ console.warn(`callback ${id2} may already be disposed`);
581
+ return;
582
+ }
583
+ fn(response);
584
+ delete callbacks2[id2];
585
+ };
586
+ const rpc = {
587
+ async dispose() {
588
+ await ipc?.dispose();
589
+ },
590
+ invoke(method, ...params) {
591
+ return invokeHelper(callbacks2, ipc, method, params, false);
592
+ },
593
+ invokeAndTransfer(method, ...params) {
594
+ return invokeHelper(callbacks2, ipc, method, params, true);
595
+ },
596
+ // @ts-ignore
597
+ ipc,
598
+ /**
599
+ * @deprecated
600
+ */
601
+ send(method, ...params) {
602
+ const message = create2(method, params);
603
+ ipc.send(message);
604
+ }
605
+ };
606
+ return rpc;
607
+ };
608
+
609
+ // node_modules/@lvce-editor/rpc/dist/parts/HandleMessage/HandleMessage.js
610
+ var requiresSocket = () => {
611
+ return false;
612
+ };
613
+ var preparePrettyError = (error) => {
614
+ return error;
615
+ };
616
+ var logError = () => {
617
+ };
618
+ var handleMessage = (event) => {
619
+ if (event.data === "ready") {
620
+ return Promise.resolve();
621
+ }
622
+ const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
623
+ const actualExecute = event?.target?.execute || execute;
624
+ return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
625
+ };
626
+
627
+ // node_modules/@lvce-editor/rpc/dist/parts/HandleIpc/HandleIpc.js
628
+ var handleIpc = (ipc) => {
629
+ if ("addEventListener" in ipc) {
630
+ ipc.addEventListener("message", handleMessage);
631
+ } else if ("on" in ipc) {
632
+ ipc.on("message", handleMessage);
633
+ }
634
+ };
635
+
636
+ // node_modules/@lvce-editor/rpc/dist/parts/IpcChildNode/IpcChildNode.js
637
+ var listen = async (module, options) => {
638
+ const rawIpc = await module.listen(options);
639
+ if (module.signal) {
640
+ module.signal(rawIpc);
641
+ }
642
+ const ipc = module.wrap(rawIpc);
643
+ return ipc;
644
+ };
645
+
646
+ // node_modules/@lvce-editor/rpc/dist/parts/WebWorkerRpcClient2/WebWorkerRpcClient2.js
647
+ var WebWorkerRpcClient2_exports = {};
648
+ __export(WebWorkerRpcClient2_exports, {
649
+ create: () => create5
650
+ });
651
+ var create5 = async ({ commandMap: commandMap2 }) => {
652
+ register(commandMap2);
653
+ const ipc = await listen(IpcChildWithModuleWorker$1);
654
+ handleIpc(ipc);
655
+ const rpc = createRpc(ipc);
656
+ return rpc;
657
+ };
658
+
659
+ // packages/cache-worker/src/parts/Cache/Cache.js
660
+ var getCacheStorage = () => {
661
+ if (typeof caches === "undefined") {
662
+ throw new Error("Cache Storage is not available in this context");
663
+ }
664
+ return caches;
665
+ };
666
+ var getCacheStorageItem = async (request, cacheName = "lvce-cache") => {
667
+ const cache = await getCacheStorage().open(cacheName);
668
+ const response = await cache.match(request);
669
+ if (!response) {
670
+ return null;
671
+ }
672
+ return {
673
+ body: await response.arrayBuffer(),
674
+ headers: [...response.headers.entries()],
675
+ status: response.status,
676
+ statusText: response.statusText
677
+ };
678
+ };
679
+ var setCacheStorageItem = async (request, value, cacheName = "lvce-cache") => {
680
+ const cache = await getCacheStorage().open(cacheName);
681
+ const response = new Response(value);
682
+ await cache.put(request, response);
683
+ };
684
+ var removeCacheStorageItem = async (request, cacheName = "lvce-cache") => {
685
+ const cache = await getCacheStorage().open(cacheName);
686
+ return cache.delete(request);
687
+ };
688
+
689
+ // packages/cache-worker/src/parts/IndexedDb/IndexedDb.js
690
+ var requestResult = (request) => new Promise((resolve2, reject) => {
691
+ request.onsuccess = () => resolve2(request.result);
692
+ request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
693
+ });
694
+ var transactionDone = (transaction) => new Promise((resolve2, reject) => {
695
+ transaction.oncomplete = () => resolve2();
696
+ transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
697
+ transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed"));
698
+ });
699
+ var openDatabase = (name) => {
700
+ if (typeof indexedDB === "undefined") {
701
+ throw new Error("IndexedDB is not available in this context");
702
+ }
703
+ return new Promise((resolve2, reject) => {
704
+ const request = indexedDB.open(name, 1);
705
+ request.onupgradeneeded = () => {
706
+ if (!request.result.objectStoreNames.contains("file-handles")) {
707
+ request.result.createObjectStore("file-handles");
708
+ }
709
+ };
710
+ request.onsuccess = () => {
711
+ request.result.onversionchange = () => request.result.close();
712
+ resolve2(request.result);
713
+ };
714
+ request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB database"));
715
+ request.onblocked = () => reject(new Error(`Opening IndexedDB database "${name}" was blocked`));
716
+ });
717
+ };
718
+ var addIndexedDbFileHandle = async (key, handle, databaseName = "lvce-cache-worker") => {
719
+ const database = await openDatabase(databaseName);
720
+ const transaction = database.transaction("file-handles", "readwrite");
721
+ const done = transactionDone(transaction);
722
+ const request = transaction.objectStore("file-handles").put(handle, key);
723
+ try {
724
+ await Promise.all([requestResult(request), done]);
725
+ } finally {
726
+ database.close();
727
+ }
728
+ };
729
+ var getIndexedDbFileHandle = async (key, databaseName = "lvce-cache-worker") => {
730
+ const database = await openDatabase(databaseName);
731
+ const transaction = database.transaction("file-handles", "readonly");
732
+ const done = transactionDone(transaction);
733
+ try {
734
+ const value = await requestResult(transaction.objectStore("file-handles").get(key));
735
+ await done;
736
+ return value;
737
+ } finally {
738
+ database.close();
739
+ }
740
+ };
741
+ var removeIndexedDbFileHandle = async (key, databaseName = "lvce-cache-worker") => {
742
+ const database = await openDatabase(databaseName);
743
+ const transaction = database.transaction("file-handles", "readwrite");
744
+ const done = transactionDone(transaction);
745
+ const request = transaction.objectStore("file-handles").delete(key);
746
+ try {
747
+ await Promise.all([requestResult(request), done]);
748
+ } finally {
749
+ database.close();
750
+ }
751
+ };
752
+
753
+ // packages/cache-worker/src/parts/Opfs/Opfs.js
754
+ var getRoot = async () => {
755
+ if (typeof navigator === "undefined" || typeof navigator.storage?.getDirectory !== "function") {
756
+ throw new Error("Origin Private File System is not available in this context");
757
+ }
758
+ return navigator.storage.getDirectory();
759
+ };
760
+ var validateName = (name) => {
761
+ if (typeof name !== "string" || name.length === 0 || name === "." || name === ".." || /[/\\]/.test(name)) {
762
+ throw new TypeError("OPFS filename must be a non-empty single path component");
763
+ }
764
+ };
765
+ var readFile = async (name) => {
766
+ validateName(name);
767
+ const root = await getRoot();
768
+ const handle = await root.getFileHandle(name);
769
+ return (await handle.getFile()).text();
770
+ };
771
+ var writeFile = async (name, content) => {
772
+ validateName(name);
773
+ const root = await getRoot();
774
+ const handle = await root.getFileHandle(name, { create: true });
775
+ const writable = await handle.createWritable();
776
+ try {
777
+ await writable.write(content);
778
+ } catch (error) {
779
+ await writable.abort();
780
+ throw error;
781
+ }
782
+ await writable.close();
783
+ };
784
+ var removeFile = async (name) => {
785
+ validateName(name);
786
+ const root = await getRoot();
787
+ await root.removeEntry(name);
788
+ };
789
+
790
+ // packages/cache-worker/src/parts/CommandMap/CommandMap.js
791
+ var commandMap = {
792
+ "Cache.getCacheStorageItem": getCacheStorageItem,
793
+ "Cache.setCacheStorageItem": setCacheStorageItem,
794
+ "Cache.removeCacheStorageItem": removeCacheStorageItem,
795
+ "IndexedDb.addIndexedDbFileHandle": addIndexedDbFileHandle,
796
+ "IndexedDb.getIndexedDbFileHandle": getIndexedDbFileHandle,
797
+ "IndexedDb.removeIndexedDbFileHandle": removeIndexedDbFileHandle,
798
+ "Opfs.readFile": readFile,
799
+ "Opfs.writeFile": writeFile,
800
+ "Opfs.removeFile": removeFile
801
+ };
802
+
803
+ // packages/cache-worker/src/parts/Listen/Listen.js
804
+ var listen2 = async () => {
805
+ await WebWorkerRpcClient2_exports.create({ commandMap });
806
+ };
807
+
808
+ // packages/cache-worker/src/cacheWorkerMain.js
809
+ await listen2();
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export const getCacheWorkerUrl = () => new URL('./cacheWorkerMain.js', import.meta.url)
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@lvce-editor/cache-worker",
3
+ "version": "0.0.2",
4
+ "description": "Worker APIs for Cache Storage, IndexedDB, and OPFS",
5
+ "license": "MIT",
6
+ "author": "Lvce Editor",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/lvce-editor/cache-worker.git"
10
+ },
11
+ "type": "module",
12
+ "main": "index.js",
13
+ "exports": {
14
+ ".": "./index.js",
15
+ "./cacheWorkerMain.js": "./cacheWorkerMain.js"
16
+ }
17
+ }