opfs-worker 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +62 -439
  2. package/dist/BaseOPFS-BPw9AIQ-.cjs +4 -0
  3. package/dist/BaseOPFS-BPw9AIQ-.cjs.map +1 -0
  4. package/dist/BaseOPFS-Cylz6ijk.js +2036 -0
  5. package/dist/BaseOPFS-Cylz6ijk.js.map +1 -0
  6. package/dist/OPFSAsync-BKSAJJeh.js +124 -0
  7. package/dist/OPFSAsync-BKSAJJeh.js.map +1 -0
  8. package/dist/OPFSAsync-s2P7y3sw.cjs +2 -0
  9. package/dist/OPFSAsync-s2P7y3sw.cjs.map +1 -0
  10. package/dist/OPFSFacade-DePnNRgt.cjs +2 -0
  11. package/dist/OPFSFacade-DePnNRgt.cjs.map +1 -0
  12. package/dist/OPFSFacade-XohWlHuu.js +281 -0
  13. package/dist/OPFSFacade-XohWlHuu.js.map +1 -0
  14. package/dist/OPFSSync-C7KBepe_.cjs +2 -0
  15. package/dist/OPFSSync-C7KBepe_.cjs.map +1 -0
  16. package/dist/OPFSSync-CsSQkpk5.js +208 -0
  17. package/dist/OPFSSync-CsSQkpk5.js.map +1 -0
  18. package/dist/assets/dedicated.worker-nY3tK4zi.js.map +1 -0
  19. package/dist/{OPFSWorker.d.ts → core/BaseOPFS.d.ts} +34 -304
  20. package/dist/core/BaseOPFS.d.ts.map +1 -0
  21. package/dist/core/OPFSAsync.d.ts +55 -0
  22. package/dist/core/OPFSAsync.d.ts.map +1 -0
  23. package/dist/core/OPFSSync.d.ts +54 -0
  24. package/dist/core/OPFSSync.d.ts.map +1 -0
  25. package/dist/createOPFSAsync-BwKDmHsy.cjs +2 -0
  26. package/dist/createOPFSAsync-BwKDmHsy.cjs.map +1 -0
  27. package/dist/createOPFSAsync-Y4Mg6qte.js +10 -0
  28. package/dist/createOPFSAsync-Y4Mg6qte.js.map +1 -0
  29. package/dist/createOPFSDedicated-CsnV6MLP.js +2333 -0
  30. package/dist/createOPFSDedicated-CsnV6MLP.js.map +1 -0
  31. package/dist/createOPFSDedicated-pKTRWLdz.cjs +2283 -0
  32. package/dist/createOPFSDedicated-pKTRWLdz.cjs.map +1 -0
  33. package/dist/createOPFSShared-CGdd__PH.js +23 -0
  34. package/dist/createOPFSShared-CGdd__PH.js.map +1 -0
  35. package/dist/createOPFSShared-CskROt7U.cjs +2 -0
  36. package/dist/createOPFSShared-CskROt7U.cjs.map +1 -0
  37. package/dist/dedicated.worker.js +2281 -0
  38. package/dist/dedicated.worker.js.map +1 -0
  39. package/dist/{OPFSFacade.d.ts → facade/OPFSFacade.d.ts} +31 -23
  40. package/dist/facade/OPFSFacade.d.ts.map +1 -0
  41. package/dist/facade/createOPFSAsync.d.ts +16 -0
  42. package/dist/facade/createOPFSAsync.d.ts.map +1 -0
  43. package/dist/facade/createOPFSDedicated.d.ts +17 -0
  44. package/dist/facade/createOPFSDedicated.d.ts.map +1 -0
  45. package/dist/facade/createOPFSShared.d.ts +24 -0
  46. package/dist/facade/createOPFSShared.d.ts.map +1 -0
  47. package/dist/index.async.cjs +2 -0
  48. package/dist/index.async.cjs.map +1 -0
  49. package/dist/index.async.d.ts +10 -0
  50. package/dist/index.async.d.ts.map +1 -0
  51. package/dist/index.async.js +55 -0
  52. package/dist/index.async.js.map +1 -0
  53. package/dist/index.cjs +1 -2477
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.d.ts +17 -3
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +61 -2828
  58. package/dist/index.js.map +1 -1
  59. package/dist/index.pure.cjs +1 -1
  60. package/dist/index.pure.cjs.map +1 -1
  61. package/dist/index.pure.d.ts +3 -1
  62. package/dist/index.pure.d.ts.map +1 -1
  63. package/dist/index.pure.js +50 -1053
  64. package/dist/index.pure.js.map +1 -1
  65. package/dist/index.sharedworker.cjs +2 -0
  66. package/dist/index.sharedworker.cjs.map +1 -0
  67. package/dist/index.sharedworker.d.ts +11 -0
  68. package/dist/index.sharedworker.d.ts.map +1 -0
  69. package/dist/index.sharedworker.js +55 -0
  70. package/dist/index.sharedworker.js.map +1 -0
  71. package/dist/index.sync.cjs +2 -0
  72. package/dist/index.sync.cjs.map +1 -0
  73. package/dist/index.sync.d.ts +11 -0
  74. package/dist/index.sync.d.ts.map +1 -0
  75. package/dist/index.sync.js +55 -0
  76. package/dist/index.sync.js.map +1 -0
  77. package/dist/shared.worker.js +2166 -0
  78. package/dist/shared.worker.js.map +1 -0
  79. package/dist/types.d.ts +9 -4
  80. package/dist/types.d.ts.map +1 -1
  81. package/dist/worker/createDedicatedWorker.d.ts +30 -0
  82. package/dist/worker/createDedicatedWorker.d.ts.map +1 -0
  83. package/dist/worker/createSharedWorker.d.ts +37 -0
  84. package/dist/worker/createSharedWorker.d.ts.map +1 -0
  85. package/dist/worker/dedicated.worker.d.ts +2 -0
  86. package/dist/worker/dedicated.worker.d.ts.map +1 -0
  87. package/dist/worker/shared.worker.d.ts +2 -0
  88. package/dist/worker/shared.worker.d.ts.map +1 -0
  89. package/docs/README.md +30 -0
  90. package/docs/api/backend.md +36 -0
  91. package/docs/api/create.md +82 -0
  92. package/docs/api/facade.md +52 -0
  93. package/docs/choosing-a-mode.md +41 -0
  94. package/docs/file-descriptors.md +8 -9
  95. package/docs/guides/async.md +36 -0
  96. package/docs/guides/dedicated.md +76 -0
  97. package/docs/guides/hashing.md +34 -0
  98. package/docs/guides/pure.md +46 -0
  99. package/docs/guides/sharedworker.md +57 -0
  100. package/docs/guides/streaming.md +51 -0
  101. package/docs/guides/watching.md +35 -0
  102. package/docs/migration.md +41 -0
  103. package/docs/types.md +20 -6
  104. package/package.json +42 -3
  105. package/src/{OPFSWorker.ts → core/BaseOPFS.ts} +54 -647
  106. package/src/core/OPFSAsync.ts +248 -0
  107. package/src/core/OPFSSync.ts +460 -0
  108. package/src/{OPFSFacade.ts → facade/OPFSFacade.ts} +83 -54
  109. package/src/facade/createOPFSAsync.ts +22 -0
  110. package/src/facade/createOPFSDedicated.ts +23 -0
  111. package/src/facade/createOPFSShared.ts +30 -0
  112. package/src/index.async.ts +11 -0
  113. package/src/index.pure.ts +3 -2
  114. package/src/index.sharedworker.ts +12 -0
  115. package/src/index.sync.ts +12 -0
  116. package/src/index.ts +37 -8
  117. package/src/types.ts +8 -4
  118. package/src/worker/createDedicatedWorker.ts +74 -0
  119. package/src/worker/createSharedWorker.ts +67 -0
  120. package/src/worker/dedicated.worker.ts +13 -0
  121. package/src/worker/shared.worker.ts +17 -0
  122. package/dist/OPFSFacade.d.ts.map +0 -1
  123. package/dist/OPFSWorker.d.ts.map +0 -1
  124. package/dist/assets/worker.entry-DUlEoroc.js.map +0 -1
  125. package/dist/createOPFSWorker.d.ts +0 -17
  126. package/dist/createOPFSWorker.d.ts.map +0 -1
  127. package/dist/helpers-DNj8ZoMu.cjs +0 -4
  128. package/dist/helpers-DNj8ZoMu.cjs.map +0 -1
  129. package/dist/helpers-WY2jfbOT.js +0 -1427
  130. package/dist/helpers-WY2jfbOT.js.map +0 -1
  131. package/dist/worker.entry.d.ts +0 -2
  132. package/dist/worker.entry.d.ts.map +0 -1
  133. package/docs/api-reference.md +0 -815
  134. package/src/createOPFSWorker.ts +0 -57
  135. package/src/worker.entry.ts +0 -6
@@ -1,5 +1,6 @@
1
- import { createOPFSWorker } from './createOPFSWorker';
2
- import { decodeBuffer, encodeString, isBinaryFileExtension } from './utils/encoder';
1
+ import { proxy, transfer } from 'comlink';
2
+
3
+ import { decodeBuffer, encodeString, isBinaryFileExtension } from '../utils/encoder';
3
4
 
4
5
  import type {
5
6
  BinaryEncoding,
@@ -7,13 +8,13 @@ import type {
7
8
  Encoding,
8
9
  FileOpenOptions,
9
10
  FileStat,
11
+ OPFSApi,
10
12
  OPFSOptions,
11
13
  PathLike,
12
- RemoteOPFSWorker,
13
14
  RenameOptions,
14
15
  StringEncoding,
15
16
  WatchOptions
16
- } from './types';
17
+ } from '../types';
17
18
 
18
19
  /**
19
20
  * Utility function to convert a PathLike to a string path
@@ -27,22 +28,37 @@ function normalizePath(path: PathLike): string {
27
28
  return path;
28
29
  }
29
30
 
31
+ /** Backend the facade talks to: an fs implementation plus its cleanup. */
32
+ export interface OPFSBackend {
33
+ fs: OPFSApi;
34
+ /** Underlying Worker / SharedWorker when the backend lives off-thread */
35
+ worker?: Worker | SharedWorker;
36
+ dispose: () => void;
37
+ }
38
+
30
39
  /**
31
- * Mode 1: Node-like facade with encoding helpers and string/binary auto-detection,
32
- * built on top of the raw worker API from {@link createOPFSWorker}.
40
+ * Node-like facade with encoding helpers and string/binary auto-detection.
33
41
  *
34
- * Use {@link createOPFS} to create one.
42
+ * Transport-agnostic: works over any {@link OPFSBackend} a Comlink proxy to
43
+ * a worker (`createOPFSDedicated`) or an in-process instance (`createOPFSAsync`).
44
+ *
45
+ * Escape hatch: {@link backend} is the raw bytes API; {@link worker} is the
46
+ * browser Worker / SharedWorker when one was created (undefined for async).
35
47
  */
36
48
  export class OPFSFacade {
37
- #fs: RemoteOPFSWorker;
49
+ #fs: OPFSApi;
38
50
  #dispose: () => void;
51
+ /** Raw backend (`OPFSApi`) — bytes in / bytes out, no encoding helpers */
52
+ readonly backend: OPFSApi;
53
+ /** Dedicated Worker or SharedWorker, if this facade was created with one */
54
+ readonly worker: Worker | SharedWorker | undefined;
39
55
  promises: OPFSFacade = this;
40
56
 
41
- constructor(options?: OPFSOptions) {
42
- const raw = createOPFSWorker(options);
43
-
44
- this.#fs = raw.fs;
45
- this.#dispose = raw.dispose;
57
+ constructor(backend: OPFSBackend) {
58
+ this.#fs = backend.fs;
59
+ this.backend = backend.fs;
60
+ this.worker = backend.worker;
61
+ this.#dispose = backend.dispose;
46
62
  }
47
63
 
48
64
  /**
@@ -120,12 +136,40 @@ export class OPFSFacade {
120
136
  return (encoding === 'binary') ? buffer : decodeBuffer(buffer, encoding);
121
137
  }
122
138
 
139
+ /**
140
+ * Normalize writable data into a Uint8Array.
141
+ *
142
+ * Accepts strings (encoded via `encoding`, auto-detected from the file
143
+ * extension when omitted), raw binary (`Uint8Array` / `ArrayBuffer`), and
144
+ * `Blob`/`File` sources (read via `arrayBuffer()`).
145
+ */
146
+ async #toBuffer(
147
+ path: string,
148
+ data: string | Uint8Array | ArrayBuffer | Blob,
149
+ encoding?: Encoding
150
+ ): Promise<Uint8Array> {
151
+ if (data instanceof Blob) {
152
+ return new Uint8Array(await data.arrayBuffer());
153
+ }
154
+
155
+ // If no encoding specified, auto-detect based on file extension
156
+ if (!encoding) {
157
+ encoding = (typeof data !== 'string' || isBinaryFileExtension(path)) ? 'binary' : 'utf-8';
158
+ }
159
+
160
+ if (typeof data === 'string') {
161
+ return encodeString(data, encoding);
162
+ }
163
+
164
+ return data instanceof Uint8Array ? data : new Uint8Array(data);
165
+ }
166
+
123
167
  /**
124
168
  * Write data to a file
125
169
  */
126
170
  async writeFile(
127
171
  path: PathLike,
128
- data: string | Uint8Array | ArrayBuffer,
172
+ data: string | Uint8Array | ArrayBuffer | Blob,
129
173
  options?: { encoding?: Encoding } | Encoding
130
174
  ): Promise<void> {
131
175
  const normalizedPath = normalizePath(path);
@@ -139,15 +183,7 @@ export class OPFSFacade {
139
183
  encoding = options.encoding;
140
184
  }
141
185
 
142
- // If no encoding specified, auto-detect based on file extension
143
- if (!encoding) {
144
- encoding = (typeof data !== 'string' || isBinaryFileExtension(normalizedPath)) ? 'binary' : 'utf-8';
145
- }
146
-
147
- // Convert data to Uint8Array
148
- const buffer = typeof data === 'string'
149
- ? encodeString(data, encoding)
150
- : (data instanceof Uint8Array ? data : new Uint8Array(data));
186
+ const buffer = await this.#toBuffer(normalizedPath, data, encoding);
151
187
 
152
188
  return this.#fs.writeFile(normalizedPath, buffer);
153
189
  }
@@ -157,24 +193,37 @@ export class OPFSFacade {
157
193
  */
158
194
  async appendFile(
159
195
  path: PathLike,
160
- data: string | Uint8Array | ArrayBuffer,
196
+ data: string | Uint8Array | ArrayBuffer | Blob,
161
197
  encoding?: Encoding
162
198
  ): Promise<void> {
163
199
  const normalizedPath = normalizePath(path);
164
200
 
165
- // If no encoding specified, auto-detect based on file extension
166
- if (!encoding) {
167
- encoding = (typeof data !== 'string' || isBinaryFileExtension(normalizedPath)) ? 'binary' : 'utf-8';
168
- }
169
-
170
- // Convert data to Uint8Array
171
- const buffer = typeof data === 'string'
172
- ? encodeString(data, encoding)
173
- : (data instanceof Uint8Array ? data : new Uint8Array(data));
201
+ const buffer = await this.#toBuffer(normalizedPath, data, encoding);
174
202
 
175
203
  return this.#fs.appendFile(normalizedPath, buffer);
176
204
  }
177
205
 
206
+ /**
207
+ * Create or overwrite a file from a byte stream without buffering the
208
+ * complete source in memory.
209
+ *
210
+ * Returns the total number of bytes written.
211
+ */
212
+ async importStream(
213
+ path: PathLike,
214
+ source: ReadableStream<Uint8Array> | Blob,
215
+ options?: { onProgress?: (bytesWritten: number) => void }
216
+ ): Promise<number> {
217
+ const normalizedPath = normalizePath(path);
218
+ const stream = source instanceof Blob ? source.stream() : source;
219
+ const transferredStream = transfer(stream, [stream]) as unknown as ReadableStream<Uint8Array>;
220
+ const onProgress = options?.onProgress
221
+ ? proxy((bytesWritten: number) => options.onProgress!(bytesWritten))
222
+ : undefined;
223
+
224
+ return this.#fs.writeStream(normalizedPath, transferredStream, onProgress);
225
+ }
226
+
178
227
  /**
179
228
  * Create a directory
180
229
  */
@@ -432,29 +481,9 @@ export class OPFSFacade {
432
481
  }
433
482
 
434
483
  /**
435
- * Dispose of resources, detach the worker and clean up the file system instance
484
+ * Dispose of resources, detach the backend and clean up the file system instance
436
485
  */
437
486
  dispose() {
438
487
  this.#dispose();
439
488
  }
440
489
  }
441
-
442
- /**
443
- * Mode 1: start an inlined worker and get a Node-like `fs` API on top of it.
444
- *
445
- * For the raw worker API without the facade, use {@link createOPFSWorker}.
446
- * To use the worker class inside your own worker, see `opfs-worker/pure`.
447
- */
448
- export function createOPFS(options?: OPFSOptions): OPFSFacade {
449
- return new OPFSFacade(options);
450
- }
451
-
452
- /**
453
- * @deprecated Use {@link createOPFS}. Kept for 1.x compatibility — still returns the facade.
454
- */
455
- export const createWorker = createOPFS;
456
-
457
- /**
458
- * @deprecated Use {@link OPFSFacade}.
459
- */
460
- export { OPFSFacade as OPFSFileSystem };
@@ -0,0 +1,22 @@
1
+ import { OPFSFacade } from './OPFSFacade';
2
+ import { OPFSAsync } from '../core/OPFSAsync';
3
+
4
+ import type { OPFSOptions } from '../types';
5
+
6
+ /**
7
+ * Async mode: Node-like `fs` API over the promise-based File System API,
8
+ * without any worker.
9
+ *
10
+ * Prefer importing from `opfs-worker/async` when you care about bundle size
11
+ * (avoids the inlined dedicated worker). Importing from `opfs-worker` works too.
12
+ *
13
+ * Writing requires `FileSystemFileHandle.createWritable()` — Chrome, Firefox,
14
+ * Safari 26+. File descriptors (`open`/`read`/`write`/...) are not supported
15
+ * and throw `OperationNotSupportedError` — use `createOPFSDedicated` from `opfs-worker`
16
+ * or `opfs-worker/sync` for positional I/O.
17
+ */
18
+ export function createOPFSAsync(options?: OPFSOptions): OPFSFacade {
19
+ const fs = new OPFSAsync(options);
20
+
21
+ return new OPFSFacade({ fs, dispose: () => fs.dispose() });
22
+ }
@@ -0,0 +1,23 @@
1
+ import { OPFSFacade } from './OPFSFacade';
2
+ import { createDedicatedWorker } from '../worker/createDedicatedWorker';
3
+
4
+ import type { DedicatedWorkerOptions } from '../worker/createDedicatedWorker';
5
+
6
+ /**
7
+ * Dedicated mode: start a dedicated worker and get a Node-like `fs` API
8
+ * backed by `OPFSSync`.
9
+ *
10
+ * Prefer importing from `opfs-worker/sync` when you only need the worker backend
11
+ * (avoids pulling `OPFSAsync` into the graph). Importing from `opfs-worker` works too.
12
+ *
13
+ * By default uses an inlined worker. Pass `url` / `worker` to load
14
+ * `opfs-worker/dedicated.worker.js` instead (see {@link DedicatedWorkerOptions}).
15
+ *
16
+ * Need the raw bytes API or the Worker instance? Use `fs.backend` / `fs.worker`.
17
+ * For the workerless async backend, use {@link createOPFSAsync}.
18
+ */
19
+ export function createOPFSDedicated(options?: DedicatedWorkerOptions): OPFSFacade {
20
+ const { fs, worker, dispose } = createDedicatedWorker(options);
21
+
22
+ return new OPFSFacade({ fs, worker, dispose });
23
+ }
@@ -0,0 +1,30 @@
1
+ import { OPFSFacade } from './OPFSFacade';
2
+ import { createSharedWorker } from '../worker/createSharedWorker';
3
+
4
+ import type { SharedWorkerOptions } from '../worker/createSharedWorker';
5
+
6
+ /**
7
+ * Shared mode: Node-like `fs` API over a SharedWorker running one `OPFSAsync`
8
+ * instance for every tab — writes are serialized across tabs by per-path locks,
9
+ * watch events reach all tabs via `BroadcastChannel`.
10
+ *
11
+ * Uses the async backend (sync access handles are unavailable in SharedWorker):
12
+ * writing requires `createWritable()` (Chrome, Firefox, Safari 26+), and file
13
+ * descriptors throw `OperationNotSupportedError`.
14
+ *
15
+ * Need the raw bytes API or the SharedWorker? Use `fs.backend` / `fs.worker`.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Vite: pass the worker url explicitly
20
+ * import workerUrl from 'opfs-worker/shared.worker.js?url';
21
+ * import { createOPFSShared } from 'opfs-worker/sharedworker';
22
+ *
23
+ * const fs = createOPFSShared({ root: '/my-app', url: workerUrl });
24
+ * ```
25
+ */
26
+ export function createOPFSShared(options?: SharedWorkerOptions): OPFSFacade {
27
+ const { fs, worker, dispose } = createSharedWorker(options);
28
+
29
+ return new OPFSFacade({ fs, worker, dispose });
30
+ }
@@ -0,0 +1,11 @@
1
+ export * from './types';
2
+ export * from './utils/errors';
3
+ export * from './utils/helpers';
4
+ export * from './utils/encoder';
5
+
6
+ export { BaseOPFS } from './core/BaseOPFS';
7
+ export { OPFSAsync } from './core/OPFSAsync';
8
+ export { OPFSFacade } from './facade/OPFSFacade';
9
+ export type { OPFSBackend } from './facade/OPFSFacade';
10
+
11
+ export { createOPFSAsync } from './facade/createOPFSAsync';
package/src/index.pure.ts CHANGED
@@ -3,5 +3,6 @@ export * from './utils/errors';
3
3
  export * from './utils/helpers';
4
4
  export * from './utils/encoder';
5
5
 
6
- // Explicit re-export shadows the type-only `OPFSWorker` coming from './types'
7
- export { OPFSWorker } from './OPFSWorker';
6
+ export { BaseOPFS } from './core/BaseOPFS';
7
+ export { OPFSSync } from './core/OPFSSync';
8
+ export { OPFSAsync } from './core/OPFSAsync';
@@ -0,0 +1,12 @@
1
+ export * from './types';
2
+ export * from './utils/errors';
3
+ export * from './utils/helpers';
4
+ export * from './utils/encoder';
5
+
6
+ export { BaseOPFS } from './core/BaseOPFS';
7
+ export { OPFSAsync } from './core/OPFSAsync';
8
+ export { OPFSFacade } from './facade/OPFSFacade';
9
+ export type { OPFSBackend } from './facade/OPFSFacade';
10
+
11
+ export { createOPFSShared } from './facade/createOPFSShared';
12
+ export type { SharedWorkerOptions } from './worker/createSharedWorker';
@@ -0,0 +1,12 @@
1
+ export * from './types';
2
+ export * from './utils/errors';
3
+ export * from './utils/helpers';
4
+ export * from './utils/encoder';
5
+
6
+ export { BaseOPFS } from './core/BaseOPFS';
7
+ export { OPFSSync } from './core/OPFSSync';
8
+ export { OPFSFacade } from './facade/OPFSFacade';
9
+ export type { OPFSBackend } from './facade/OPFSFacade';
10
+
11
+ export { createOPFSDedicated } from './facade/createOPFSDedicated';
12
+ export type { DedicatedWorkerOptions } from './worker/createDedicatedWorker';
package/src/index.ts CHANGED
@@ -4,12 +4,41 @@ export * from './utils/helpers';
4
4
  export * from './utils/encoder';
5
5
 
6
6
  export {
7
+ BaseOPFS,
7
8
  OPFSFacade,
8
- OPFSFileSystem,
9
- createOPFS,
10
- // 1.x aliases
11
- createWorker,
12
- } from './OPFSFacade';
13
-
14
- export { createOPFSWorker } from './createOPFSWorker';
15
- export type { RawWorker } from './createOPFSWorker';
9
+ OPFSSync,
10
+ createOPFSDedicated,
11
+ } from './index.sync';
12
+
13
+ export type {
14
+ DedicatedWorkerOptions,
15
+ OPFSBackend,
16
+ } from './index.sync';
17
+
18
+ export {
19
+ OPFSAsync,
20
+ createOPFSAsync,
21
+ } from './index.async';
22
+
23
+ export {
24
+ createOPFSShared,
25
+ } from './index.sharedworker';
26
+
27
+ export type {
28
+ SharedWorkerOptions,
29
+ } from './index.sharedworker';
30
+
31
+ /**
32
+ * Kept as a short alias for a default Sync backend
33
+ */
34
+ export { createOPFSDedicated as createOPFS } from './index.sync';
35
+
36
+ /**
37
+ * @deprecated Use {@link createOPFSDedicated}. Kept for 1.x → 2.x migration.
38
+ */
39
+ export { createOPFSDedicated as createWorker } from './index.sync';
40
+
41
+ /**
42
+ * @deprecated Use {@link OPFSFacade}. Kept for 1.x → 2.x migration.
43
+ */
44
+ export { OPFSFacade as OPFSFileSystem } from './index.sync';
package/src/types.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type { OPFSWorker } from './OPFSWorker';
2
- import type { Remote } from 'comlink';
1
+ import type { OPFSSync } from './core/OPFSSync';
3
2
 
4
3
  /**
5
4
  * Type for paths that can be either a string or URI
@@ -56,8 +55,13 @@ export interface WatchEvent {
56
55
  hash?: string;
57
56
  }
58
57
 
59
- export type { OPFSWorker };
60
- export type RemoteOPFSWorker = Remote<OPFSWorker>;
58
+ export type { OPFSSync };
59
+
60
+ /**
61
+ * Promise-based fs API surface shared by all backends: a Comlink proxy to
62
+ * `OPFSSync` in a worker, or an in-process `OPFSAsync` instance.
63
+ */
64
+ export type OPFSApi = { [K in keyof OPFSSync]: OPFSSync[K] };
61
65
 
62
66
  export interface OPFSOptions {
63
67
  /** Root path for the file system (default: '/') */
@@ -0,0 +1,74 @@
1
+ import { wrap } from 'comlink';
2
+
3
+ import WorkerCtor from './dedicated.worker?worker&inline';
4
+
5
+ import type { OPFSOptions, OPFSSync } from '../types';
6
+ import type { Remote } from 'comlink';
7
+
8
+ const InlineWorker = WorkerCtor as new (options?: WorkerOptions) => Worker;
9
+
10
+ type RemoteOPFSSync = Remote<OPFSSync>;
11
+
12
+ export interface DedicatedWorkerOptions extends OPFSOptions {
13
+ /**
14
+ * URL of the worker script, e.g. `import url from 'opfs-worker/dedicated.worker.js?url'` (Vite).
15
+ *
16
+ * Defaults to the inlined worker (no URL needed). Pass an explicit url when you
17
+ * prefer the self-contained file (strict CSP without `blob:`, or DIY hosting).
18
+ */
19
+ url?: string | URL;
20
+ /** Bring your own Worker instance (overrides `url`) */
21
+ worker?: Worker;
22
+ }
23
+
24
+ export interface RawWorker {
25
+ /** Comlink proxy to `OPFSSync` (bytes in / bytes out) */
26
+ fs: RemoteOPFSSync;
27
+ /** Underlying browser Worker */
28
+ worker: Worker;
29
+ /** Calls worker `dispose()` then `terminate()` */
30
+ dispose: () => void;
31
+ }
32
+
33
+ /** A `BroadcastChannel` instance can't cross the wire — send its name instead. */
34
+ function applyWorkerOptions(fs: Pick<RemoteOPFSSync, 'setOptions'>, options?: OPFSOptions): void {
35
+ if (!options) {
36
+ return;
37
+ }
38
+
39
+ if (options.broadcastChannel instanceof BroadcastChannel) {
40
+ options.broadcastChannel = options.broadcastChannel.name;
41
+ }
42
+
43
+ void fs.setOptions(options);
44
+ }
45
+
46
+ /**
47
+ * Internal helper: spawn a dedicated worker and wrap `OPFSSync` with Comlink.
48
+ * Prefer {@link createOPFSDedicated}; access the proxy / Worker via
49
+ * `facade.backend` / `facade.worker`.
50
+ */
51
+ export function createDedicatedWorker(options: DedicatedWorkerOptions = {}): RawWorker {
52
+ const { url, worker: providedWorker, ...fsOptions } = options;
53
+
54
+ const worker = providedWorker
55
+ ?? (url ? new Worker(url, { type: 'module' }) : new InlineWorker());
56
+ const fs = wrap<RemoteOPFSSync>(worker);
57
+
58
+ applyWorkerOptions(fs, fsOptions);
59
+
60
+ return {
61
+ fs,
62
+ worker,
63
+ dispose() {
64
+ void (async() => {
65
+ try {
66
+ await fs.dispose();
67
+ }
68
+ finally {
69
+ worker.terminate();
70
+ }
71
+ })();
72
+ },
73
+ };
74
+ }
@@ -0,0 +1,67 @@
1
+ import { wrap } from 'comlink';
2
+
3
+ import type { OPFSAsync } from '../core/OPFSAsync';
4
+ import type { OPFSOptions } from '../types';
5
+ import type { Remote } from 'comlink';
6
+
7
+ type RemoteOPFSAsync = Remote<OPFSAsync>;
8
+
9
+ export interface SharedWorkerOptions extends OPFSOptions {
10
+ /**
11
+ * URL of the worker script, e.g. `import url from 'opfs-worker/shared.worker.js?url'` (Vite).
12
+ *
13
+ * Defaults to `new URL('./shared.worker.js', import.meta.url)`, which works when
14
+ * `opfs-worker` is served as-is (CDN, unbundled deps). When your bundler inlines
15
+ * the package into app chunks, pass the url explicitly.
16
+ */
17
+ url?: string | URL;
18
+ /** Bring your own SharedWorker instance (overrides `url`) */
19
+ worker?: SharedWorker;
20
+ /** Worker name — tabs with the same script URL + name share one instance (default: 'opfs-worker') */
21
+ name?: string;
22
+ }
23
+
24
+ export interface RawSharedWorker {
25
+ /** Comlink proxy to the `OPFSAsync` instance shared by all connected tabs */
26
+ fs: RemoteOPFSAsync;
27
+ /** Underlying browser SharedWorker */
28
+ worker: SharedWorker;
29
+ /** Closes this tab's port; the worker keeps running for other tabs */
30
+ dispose: () => void;
31
+ }
32
+
33
+ /**
34
+ * Internal helper: connect to the SharedWorker and wrap `OPFSAsync` with Comlink.
35
+ * Prefer {@link createOPFSShared}; access the proxy / SharedWorker via
36
+ * `facade.backend` / `facade.worker`.
37
+ *
38
+ * Note: `OPFSOptions` are applied via `setOptions()` on the shared instance, so
39
+ * they affect every connected tab — use the same options in all tabs.
40
+ */
41
+ export function createSharedWorker(options: SharedWorkerOptions = {}): RawSharedWorker {
42
+ const { url, worker: providedWorker, name = 'opfs-worker', ...fsOptions } = options;
43
+
44
+ const worker = providedWorker ?? new SharedWorker(
45
+ url ?? new URL('./shared.worker.js', import.meta.url),
46
+ { type: 'module', name }
47
+ );
48
+
49
+ const fs = wrap<RemoteOPFSAsync>(worker.port);
50
+
51
+ if (Object.keys(fsOptions).length > 0) {
52
+ // A BroadcastChannel instance can't cross the wire — send its name instead
53
+ if (fsOptions.broadcastChannel instanceof BroadcastChannel) {
54
+ fsOptions.broadcastChannel = fsOptions.broadcastChannel.name;
55
+ }
56
+
57
+ void fs.setOptions(fsOptions);
58
+ }
59
+
60
+ return {
61
+ fs,
62
+ worker,
63
+ dispose() {
64
+ worker.port.close();
65
+ },
66
+ };
67
+ }
@@ -0,0 +1,13 @@
1
+ import { expose } from 'comlink';
2
+
3
+ import { OPFSSync } from '../core/OPFSSync';
4
+
5
+ /**
6
+ * Dedicated worker entry.
7
+ *
8
+ * Built two ways:
9
+ * - Inlined into `createOPFSDedicated` via `?worker&inline` (default path)
10
+ * - Self-contained `dist/dedicated.worker.js` → `opfs-worker/dedicated.worker.js`
11
+ * for DIY `new Worker(url, { type: 'module' })` + Comlink wrap
12
+ */
13
+ expose(new OPFSSync());
@@ -0,0 +1,17 @@
1
+ import { expose } from 'comlink';
2
+
3
+ import { OPFSAsync } from '../core/OPFSAsync';
4
+
5
+ /**
6
+ * Shared worker entry — built self-contained (comlink bundled in) to
7
+ * `dist/shared.worker.js`, exposed as `opfs-worker/shared.worker.js`.
8
+ *
9
+ * One `OPFSAsync` instance serves every connected tab, so per-path locks
10
+ * naturally serialize writes across tabs. Sync access handles are not
11
+ * available in a SharedWorker, hence the async backend.
12
+ */
13
+ const fs = new OPFSAsync();
14
+
15
+ (globalThis as unknown as { onconnect: (event: MessageEvent) => void }).onconnect = (event: MessageEvent) => {
16
+ expose(fs, event.ports[0]);
17
+ };
@@ -1 +0,0 @@
1
- {"version":3,"file":"OPFSFacade.d.ts","sourceRoot":"","sources":["../src/OPFSFacade.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"OPFSWorker.d.ts","sourceRoot":"","sources":["../src/OPFSWorker.ts"],"names":[],"mappings":"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"}