opfs-worker 2.1.1 → 2.1.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.
Files changed (100) hide show
  1. package/README.md +21 -20
  2. package/dist/BaseOPFS-Bu7FZtCb.cjs +2 -0
  3. package/dist/BaseOPFS-Bu7FZtCb.cjs.map +1 -0
  4. package/dist/{BaseOPFS-BusBkyJX.js → BaseOPFS-C3NE4BKr.js} +790 -548
  5. package/dist/BaseOPFS-C3NE4BKr.js.map +1 -0
  6. package/dist/OPFSAsync-C0RsxCX5.cjs +2 -0
  7. package/dist/OPFSAsync-C0RsxCX5.cjs.map +1 -0
  8. package/dist/{OPFSAsync-CO44W23e.js → OPFSAsync-aeLUdIqd.js} +19 -19
  9. package/dist/OPFSAsync-aeLUdIqd.js.map +1 -0
  10. package/dist/{OPFSFacade-hrNXCn6w.cjs → OPFSFacade-BJv2yuWU.cjs} +2 -2
  11. package/dist/{OPFSFacade-hrNXCn6w.cjs.map → OPFSFacade-BJv2yuWU.cjs.map} +1 -1
  12. package/dist/{OPFSFacade-CEaSqTut.js → OPFSFacade-DiogtQoq.js} +2 -2
  13. package/dist/{OPFSFacade-CEaSqTut.js.map → OPFSFacade-DiogtQoq.js.map} +1 -1
  14. package/dist/OPFSSync-3qlSBYmz.cjs +2 -0
  15. package/dist/OPFSSync-3qlSBYmz.cjs.map +1 -0
  16. package/dist/{OPFSSync-D7obTsl3.js → OPFSSync-CvSOswhW.js} +57 -57
  17. package/dist/OPFSSync-CvSOswhW.js.map +1 -0
  18. package/dist/assets/dedicated.worker-Bqqr9UBA.js.map +1 -0
  19. package/dist/core/BaseOPFS.d.ts +23 -3
  20. package/dist/core/BaseOPFS.d.ts.map +1 -1
  21. package/dist/core/OPFSAsync.d.ts.map +1 -1
  22. package/dist/core/OPFSSync.d.ts.map +1 -1
  23. package/dist/createOPFSAsync-B611B63X.js +10 -0
  24. package/dist/{createOPFSAsync-DdhJYoC0.js.map → createOPFSAsync-B611B63X.js.map} +1 -1
  25. package/dist/createOPFSAsync-BATjJg8k.cjs +2 -0
  26. package/dist/{createOPFSAsync-DyWpvmL-.cjs.map → createOPFSAsync-BATjJg8k.cjs.map} +1 -1
  27. package/dist/{createOPFSDedicated-BwTc0NV5.js → createOPFSDedicated-DgudPTB8.js} +1086 -817
  28. package/dist/createOPFSDedicated-DgudPTB8.js.map +1 -0
  29. package/dist/{createOPFSDedicated-CEeRexom.cjs → createOPFSDedicated-EmIwluQo.cjs} +1037 -797
  30. package/dist/createOPFSDedicated-EmIwluQo.cjs.map +1 -0
  31. package/dist/{createOPFSShared-BSFWsoLe.js → createOPFSShared-BWYln8jJ.js} +2 -2
  32. package/dist/{createOPFSShared-BSFWsoLe.js.map → createOPFSShared-BWYln8jJ.js.map} +1 -1
  33. package/dist/{createOPFSShared-BoCft_BS.cjs → createOPFSShared-DPJpCd7z.cjs} +2 -2
  34. package/dist/{createOPFSShared-BoCft_BS.cjs.map → createOPFSShared-DPJpCd7z.cjs.map} +1 -1
  35. package/dist/dedicated.worker.js +1034 -794
  36. package/dist/dedicated.worker.js.map +1 -1
  37. package/dist/facade/createOPFSDedicated.d.ts +4 -2
  38. package/dist/facade/createOPFSDedicated.d.ts.map +1 -1
  39. package/dist/index.async.cjs +1 -1
  40. package/dist/index.async.js +33 -32
  41. package/dist/index.cjs +1 -1
  42. package/dist/index.d.ts +1 -5
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +44 -43
  45. package/dist/index.pure.cjs +1 -1
  46. package/dist/index.pure.js +38 -37
  47. package/dist/index.sharedworker.cjs +1 -1
  48. package/dist/index.sharedworker.js +34 -33
  49. package/dist/index.sync.cjs +1 -1
  50. package/dist/index.sync.d.ts +2 -0
  51. package/dist/index.sync.d.ts.map +1 -1
  52. package/dist/index.sync.js +34 -32
  53. package/dist/shared.worker.js +1056 -820
  54. package/dist/shared.worker.js.map +1 -1
  55. package/dist/types.d.ts +5 -5
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/utils/helpers.d.ts +13 -3
  58. package/dist/utils/helpers.d.ts.map +1 -1
  59. package/dist/worker/createDedicatedWorker.d.ts +8 -3
  60. package/dist/worker/createDedicatedWorker.d.ts.map +1 -1
  61. package/docs/README.md +18 -0
  62. package/docs/api/README.md +221 -0
  63. package/docs/{file-descriptors.md → api/file-descriptors.md} +13 -13
  64. package/docs/guides/async.md +2 -2
  65. package/docs/guides/dedicated.md +6 -4
  66. package/docs/guides/hashing.md +1 -1
  67. package/docs/guides/pure.md +1 -1
  68. package/docs/guides/sharedworker.md +1 -1
  69. package/docs/guides/streaming.md +2 -2
  70. package/docs/migration.md +8 -9
  71. package/docs/types.md +4 -4
  72. package/package.json +10 -9
  73. package/src/core/BaseOPFS.ts +46 -4
  74. package/src/core/OPFSAsync.ts +4 -5
  75. package/src/core/OPFSSync.ts +6 -7
  76. package/src/facade/createOPFSDedicated.ts +4 -2
  77. package/src/index.sync.ts +2 -0
  78. package/src/index.ts +1 -5
  79. package/src/types.ts +5 -3
  80. package/src/utils/helpers.ts +32 -6
  81. package/src/worker/createDedicatedWorker.ts +85 -7
  82. package/src/worker/dedicated.worker.ts +12 -1
  83. package/dist/BaseOPFS-BusBkyJX.js.map +0 -1
  84. package/dist/BaseOPFS-CYwrD7-q.cjs +0 -4
  85. package/dist/BaseOPFS-CYwrD7-q.cjs.map +0 -1
  86. package/dist/OPFSAsync-B2dR-2VR.cjs +0 -2
  87. package/dist/OPFSAsync-B2dR-2VR.cjs.map +0 -1
  88. package/dist/OPFSAsync-CO44W23e.js.map +0 -1
  89. package/dist/OPFSSync-BPrNtvFS.cjs +0 -2
  90. package/dist/OPFSSync-BPrNtvFS.cjs.map +0 -1
  91. package/dist/OPFSSync-D7obTsl3.js.map +0 -1
  92. package/dist/assets/dedicated.worker-DW6UqFo0.js.map +0 -1
  93. package/dist/createOPFSAsync-DdhJYoC0.js +0 -10
  94. package/dist/createOPFSAsync-DyWpvmL-.cjs +0 -2
  95. package/dist/createOPFSDedicated-BwTc0NV5.js.map +0 -1
  96. package/dist/createOPFSDedicated-CEeRexom.cjs.map +0 -1
  97. package/docs/api/backend.md +0 -36
  98. package/docs/api/create.md +0 -82
  99. package/docs/api/facade.md +0 -53
  100. package/docs/choosing-a-mode.md +0 -41
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { BaseOPFS } from './core/BaseOPFS';
1
2
  import type { OPFSSync } from './core/OPFSSync';
2
3
  /**
3
4
  * Type for paths that can be either a string or URI
@@ -38,12 +39,11 @@ export interface WatchEvent {
38
39
  }
39
40
  export type { OPFSSync };
40
41
  /**
41
- * Promise-based fs API surface shared by all backends: a Comlink proxy to
42
- * `OPFSSync` in a worker, or an in-process `OPFSAsync` instance.
42
+ * Public bytes API shared by all backends (`OPFSSync`, `OPFSAsync`, or a
43
+ * Comlink proxy to one of them). Declared on {@link BaseOPFS}; subclasses
44
+ * implement the abstract I/O and FD methods.
43
45
  */
44
- export type OPFSApi = {
45
- [K in keyof OPFSSync]: OPFSSync[K];
46
- };
46
+ export type OPFSApi = Pick<BaseOPFS, keyof BaseOPFS>;
47
47
  export interface OPFSOptions {
48
48
  /** Root path for the file system (default: '/') */
49
49
  root?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,CAAC;AAEpC,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,WAAW,CAAC;AAExC,MAAM,MAAM,cAAc,GAAG,OAAO,GAChC,MAAM,GACN,OAAO,GACP,SAAS,GACT,UAAU,GACV,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,KAAK,CAAC;AAEV,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC;AAEvD,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACxB;AAED,oBAAY,cAAc;IACtB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,OAAO,YAAY;CACtB;AAED,MAAM,WAAW,UAAU;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG;KAAG,CAAC,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;CAAE,CAAC;AAE7D,MAAM,WAAW,WAAW;IACxB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,aAAa,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACpF,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;CACvD;AAED,kEAAkE;AAClE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;AAExD;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAElG,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAChC,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAC9B,qCAAqC;IACrC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC1B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IACzB,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -5,17 +5,26 @@ import type { Encoding } from '../types';
5
5
  * @throws {OPFSNotSupportedError} If the browser does not support the OPFS API
6
6
  */
7
7
  export declare function checkOPFSSupport(): void;
8
+ /**
9
+ * Join a mount `root` with an API path into an absolute OPFS path.
10
+ *
11
+ * Lock keys and cross-instance coordination use this so `/x.txt` under
12
+ * `root: '/app'` and `/app/x.txt` under `root: '/'` resolve to the same file.
13
+ */
14
+ export declare function absoluteOpfsPath(root: string, path: string): string;
8
15
  /**
9
16
  * Run a callback while holding an exclusive lock on a path
10
17
  *
11
18
  * Locks are always exclusive: OPFS permits a single sync access handle per file,
12
- * so readers can't share access either.
19
+ * so readers can't share access either. The lock key is the absolute OPFS path
20
+ * (`root` + API `path`) so different mounts of the same file serialize correctly.
13
21
  *
14
- * @param path - The path to lock
22
+ * @param path - The API path to lock (relative to `root`)
15
23
  * @param fn - The callback to run while holding the lock
24
+ * @param root - Mount root (default: `/`)
16
25
  * @returns The value returned by the callback
17
26
  */
18
- export declare function withLock<T>(path: string, fn: () => Promise<T>): Promise<T>;
27
+ export declare function withLock<T>(path: string, fn: () => Promise<T>, root?: string): Promise<T>;
19
28
  /**
20
29
  * Split a path into an array of segments
21
30
  *
@@ -174,6 +183,7 @@ export declare function removeEntry(parentHandle: FileSystemDirectoryHandle, pat
174
183
  recursive?: boolean;
175
184
  force?: boolean;
176
185
  useTrash?: boolean;
186
+ root?: string;
177
187
  }): Promise<void>;
178
188
  /**
179
189
  * Validate read/write arguments for file descriptor operations
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ export interface DedicatedWorkerOptions extends OPFSOptions {
9
9
  * prefer the self-contained file (strict CSP without `blob:`, or DIY hosting).
10
10
  */
11
11
  url?: string | URL;
12
- /** Bring your own Worker instance (overrides `url`) */
12
+ /** Bring your own Worker instance (overrides `url`) — not pooled */
13
13
  worker?: Worker;
14
14
  }
15
15
  export interface RawWorker {
@@ -17,13 +17,18 @@ export interface RawWorker {
17
17
  fs: RemoteOPFSSync;
18
18
  /** Underlying browser Worker */
19
19
  worker: Worker;
20
- /** Calls worker `dispose()` then `terminate()` */
20
+ /** Drops this facade's port; terminates the Worker when the last user of this pool entry disposes */
21
21
  dispose: () => void;
22
22
  }
23
23
  /**
24
- * Internal helper: spawn a dedicated worker and wrap `OPFSSync` with Comlink.
24
+ * Internal helper: spawn (or reuse) a dedicated worker and wrap `OPFSSync` with Comlink.
25
25
  * Prefer {@link createOPFSDedicated}; access the proxy / Worker via
26
26
  * `facade.backend` / `facade.worker`.
27
+ *
28
+ * Calls with the same `root` (and same `url`, if any) share one Worker on this page.
29
+ * Different roots get different Workers. Passing `worker` bypasses the pool.
30
+ *
31
+ * `setOptions` hits the shared instance — keep options consistent for the same root.
27
32
  */
28
33
  export declare function createDedicatedWorker(options?: DedicatedWorkerOptions): RawWorker;
29
34
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"createDedicatedWorker.d.ts","sourceRoot":"","sources":["../../src/worker/createDedicatedWorker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAItC,KAAK,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEvC,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACvD;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACtB,yDAAyD;IACzD,EAAE,EAAE,cAAc,CAAC;IACnB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAeD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,SAAS,CAuBrF"}
1
+ {"version":3,"file":"createDedicatedWorker.d.ts","sourceRoot":"","sources":["../../src/worker/createDedicatedWorker.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAItC,KAAK,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEvC,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACvD;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACtB,yDAAyD;IACzD,EAAE,EAAE,cAAc,CAAC;IACnB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,qGAAqG;IACrG,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAmCD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,SAAS,CA2ErF"}
package/docs/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # Docs
2
+
3
+ - [API overview](./api/README.md) — entries, facade methods, options, trade-offs
4
+ - [File descriptors](./api/file-descriptors.md) — positional `open` / `read` / `write`
5
+ - [Types](./types.md)
6
+ - [Migration from 1.x](./migration.md)
7
+
8
+ ## Guides
9
+
10
+ | Guide | About |
11
+ | ----------------------------------------- | --------------------------------------------------------- |
12
+ | [Dedicated worker](./guides/dedicated.md) | How to use OPFS via a dedicated worker (the default path) |
13
+ | [Async](./guides/async.md) | How to use OPFS on the main thread, without a worker |
14
+ | [SharedWorker](./guides/sharedworker.md) | How to share one filesystem across all tabs |
15
+ | [Pure classes](./guides/pure.md) | How to drop OPFS into a worker you already run |
16
+ | [Streaming](./guides/streaming.md) | How to handle large files and bulk uploads |
17
+ | [Watching](./guides/watching.md) | How to listen for file changes across tabs |
18
+ | [Hashing](./guides/hashing.md) | How file hashes / etags work on `stat` and watch events |
@@ -0,0 +1,221 @@
1
+ # API
2
+
3
+ The sync backend works in every browser that has OPFS, but the browser only allows it inside a dedicated worker — `createOPFS()` / `createOPFSDedicated()` set that up for you. The async backend can run on the main thread or in a SharedWorker, but needs a modern browser — writes will not work in Safari before 26.
4
+
5
+ ## Package entries
6
+
7
+ | Import from | Worker | Use it when |
8
+ | -------------------------- | ------------------------------------------ | --------------------------------------------------------------------- |
9
+ | `opfs-worker` | Starts a dedicated worker | Default; fine if bundle size doesn’t matter or tree-shaking is set up |
10
+ | `opfs-worker/sync` | Starts a dedicated worker | Same as the default, without async / shared code in the bundle |
11
+ | `opfs-worker/async` | Runs directly in the current thread | Main thread or your own worker; Safari prior to 26 can’t write |
12
+ | `opfs-worker/sharedworker` | Starts one SharedWorker shared by all tabs | One shared fs process for every tab; Safari prior to 26 can’t write |
13
+ | `opfs-worker/pure` | None | Low-level classes to build your own custom worker |
14
+
15
+ ## Facade
16
+
17
+ Every helper returns an `OPFSFacade` — the same Node-like API in all modes. The facade hides the actual work: depending on which helper you call, it either creates a dedicated worker and talks to it, works with OPFS directly in the current thread, or connects to a SharedWorker.
18
+
19
+ Each takes optional `[options](#options)`.
20
+
21
+ | Function | From | Under the hood |
22
+ | ------------------ | ------------------------------------------- | ------------------------------------------------ |
23
+ | `createOPFS` | `opfs-worker` or `opfs-worker/sync` | Dedicated worker + `OPFSSync` |
24
+ | `createOPFSAsync` | `opfs-worker` or `opfs-worker/async` | OPFS directly, `OPFSAsync` in the current thread |
25
+ | `createOPFSShared` | `opfs-worker` or `opfs-worker/sharedworker` | SharedWorker + `OPFSAsync` |
26
+
27
+ ```typescript
28
+ import { createOPFS, createOPFSAsync, createOPFSShared } from 'opfs-worker';
29
+
30
+ const fs = createOPFS(); // or createOPFSAsync(), createOPFSShared({ url: '...' })
31
+ ```
32
+
33
+ ### File I/O
34
+
35
+ Paths are `string | URL` everywhere below.
36
+
37
+ | Method | Parameters | Returns |
38
+ | -------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------- | --------------- |
39
+ | `readFile` | `path`, optional `encoding` or `{ encoding }` | `Promise<string | Uint8Array>` — auto by extension if omitted (`.txt`→ string,`.bin` → bytes) |
40
+ | `writeFile` | `path`, `data` (`string | Uint8Array | ArrayBuffer | Blob`), optional encoding | `Promise<void>` |
41
+ | `appendFile` | `path`, `data` (`string | Uint8Array | ArrayBuffer | Blob`), optional encoding | `Promise<void>` |
42
+ | `readText` | `path`, `encoding?` (default `'utf-8'`) | `Promise<string>` |
43
+ | `writeText` | `path`, `text`, `encoding?` (default `'utf-8'`) | `Promise<void>` |
44
+ | `appendText` | `path`, `text`, `encoding?` (default `'utf-8'`) | `Promise<void>` |
45
+ | `readBlob` | `path` | `Promise<Blob>` — disk-backed, not copied into memory. See [streaming](../guides/streaming.md) |
46
+ | `importStream` | `path`, `ReadableStream | Blob | File`, optional `{ onProgress }` | `Promise<number>` — bytes written. See [streaming](../guides/streaming.md) |
47
+ | `importFiles` | `[path, data][]` / `Map` / iterable, optional `{ onProgress }` | `Promise<ImportFilesResult>` — paths, count, bytes. See [streaming](../guides/streaming.md) |
48
+
49
+ For Node compatibility, `fs.promises` is the same instance (`fs.promises === fs`).
50
+
51
+ ### Directories & metadata
52
+
53
+ | Method | Parameters | Returns |
54
+ | ---------- | -------------------------------------------------------------------- | ------------------------------------------------------------------- |
55
+ | `mkdir` | `path`, optional `{ recursive }` (numeric mode accepted and ignored) | `Promise<void>` |
56
+ | `readDir` | `path` | `Promise<DirentData[]>` |
57
+ | `stat` | `path` | `Promise<FileStat>` |
58
+ | `exists` | `path` | `Promise<boolean>` |
59
+ | `realpath` | `path` | `Promise<string>` |
60
+ | `remove` | `path`, optional `{ recursive, force }` | `Promise<void>` |
61
+ | `rename` | `oldPath`, `newPath`, optional `{ overwrite }` | `Promise<void>` |
62
+ | `copy` | `source`, `destination`, optional `{ recursive, overwrite }` | `Promise<void>` |
63
+ | `clear` | `path?` (default `/`) | `Promise<void>` — empties the directory, keeps the directory itself |
64
+ | `index` | — | `Promise<Map<string, FileStat>>` |
65
+
66
+ ### Watch & lifecycle
67
+
68
+ | Method | Parameters | Returns |
69
+ | ------------ | --------------------------------------------------------------------- | ------------------------------------------------ |
70
+ | `watch` | `path`, optional `{ recursive, include, exclude }` | `() => void` unsubscribe |
71
+ | `unwatch` | `path` | `void` |
72
+ | `setOptions` | `options` — see [Options](#options) / [hashing](../guides/hashing.md) | `Promise<void>` |
73
+ | `dispose` | — | `void` — tears down watches, backend, and worker |
74
+
75
+ ### File descriptors
76
+
77
+ Dedicated / `OPFSSync` only — async throws `ENOTSUP`. Details: [file descriptors](./file-descriptors.md).
78
+
79
+ | Method | Parameters | Returns |
80
+ | ----------- | -------------------------------------------------- | ------------------------------------------- |
81
+ | `open` | `path`, optional `{ create, exclusive, truncate }` | `Promise<number>` — file descriptor |
82
+ | `read` | `fd`, `buffer`, `offset`, `length`, `position?` | `Promise<{ bytesRead, buffer }>` |
83
+ | `write` | `fd`, `buffer`, `offset?`, `length?`, `position?` | `Promise<number>` — bytes written |
84
+ | `close` | `fd` | `Promise<void>` |
85
+ | `fstat` | `fd` | `Promise<FileStat>` |
86
+ | `ftruncate` | `fd`, `size?` (default `0`) | `Promise<void>` |
87
+ | `fsync` | `fd` | `Promise<void>` — best-effort flush in OPFS |
88
+
89
+ ### Node aliases
90
+
91
+ | Alias | Parameters | Returns |
92
+ | --------- | --------------------------------------- | ----------------------------------------------- |
93
+ | `unlink` | `path` | same as `remove(path)` |
94
+ | `rm` | `path`, optional `{ recursive, force }` | same as `remove` |
95
+ | `rmdir` | `path` | same as `remove(path)` |
96
+ | `readdir` | `path` | same as `readDir` |
97
+ | `lstat` | `path` | same as `stat` |
98
+ | `chmod` | `path`, `mode` | `Promise<void>` — no-op (no Unix modes in OPFS) |
99
+
100
+ ### Backend access
101
+
102
+ `fs.backend` is the raw bytes API the facade wraps — a Comlink proxy to the worker for dedicated / SharedWorker, or the in-process `OPFSAsync` instance for async. Same methods as the facade, but without encoding helpers (you pass / get `Uint8Array`).
103
+
104
+ | Field | Type | Notes |
105
+ | ------------ | -------------------------------- | -------------------- | ---------- | ---------------------------------------------------- |
106
+ | `fs.backend` | `[OPFSApi](../types.md#opfsapi)` | bytes in / bytes out |
107
+ | `fs.worker` | `Worker | SharedWorker | undefined` | set when a worker was created; `undefined` for async |
108
+
109
+ ## Options
110
+
111
+ Passed to any `createOPFS*` (and to `setOptions()` later).
112
+
113
+ | Option | Default | What it does |
114
+ | ------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
115
+ | `root` | `'/'` | Scope all paths under this OPFS subdirectory |
116
+ | `namespace` | `'opfs-worker:${root}'` | Stamp on every [watch](../guides/watching.md) event |
117
+ | `hashAlgorithm` | `'etag'` | File hash on `stat` / `index` / watch — `'etag'`, `'SHA-*'`, or `null`/`false` to disable. See [hashing](../guides/hashing.md) |
118
+ | `maxFileSize` | `50MB` | Skip SHA- hashing above this size (`etag` ignores it) |
119
+ | `broadcastChannel` | `'opfs-worker'` | Channel name, a `BroadcastChannel` instance, or `null` to disable |
120
+
121
+ ```typescript
122
+ const fs = createOPFS({
123
+ root: '/my-app',
124
+ hashAlgorithm: 'SHA-256',
125
+ maxFileSize: 10 * 1024 * 1024,
126
+ });
127
+ ```
128
+
129
+ ### Dedicated worker only
130
+
131
+ | Option | Type | Default | What it does |
132
+ | -------- | -------- | ------- | ------------------------------------------- | ---------------------------------------------------------------------------------- |
133
+ | `url` | `string | URL` | inlined worker | Script URL for `opfs-worker/dedicated.worker.js` (or your own) instead of the blob |
134
+ | `worker` | `Worker` | — | Pass an existing `Worker` (overrides `url`) |
135
+
136
+ Leave these unset unless you need them — the default inlined worker is enough.
137
+
138
+ ```typescript
139
+ const fs = createOPFS({ root: '/my-app' });
140
+
141
+ // Escape hatches only:
142
+ // createOPFS({ root: '/my-app', url: workerUrl }) // CSP without blob:
143
+ // createOPFS({ root: '/my-app', worker: existingWorker }) // bring your own Worker
144
+ ```
145
+
146
+ ### SharedWorker only
147
+
148
+ | Option | Type | Default | What it does |
149
+ | -------- | -------------- | --------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
150
+ | `url` | `string | URL` | next to the package | Script URL for `opfs-worker/shared.worker.js` — with Vite: `import url from '…/shared.worker.js?url'` |
151
+ | `worker` | `SharedWorker` | — | Pass an existing `SharedWorker` (overrides `url`) |
152
+ | `name` | `string` | `'opfs-worker'` | Tabs with the same script URL + name share one instance |
153
+
154
+ ```typescript
155
+ import workerUrl from 'opfs-worker/shared.worker.js?url'; // Vite
156
+ import { createOPFSShared } from 'opfs-worker/sharedworker';
157
+
158
+ const fs = createOPFSShared({
159
+ root: '/my-app',
160
+ url: workerUrl,
161
+ name: 'opfs-worker',
162
+ });
163
+ ```
164
+
165
+ ## Ready-made worker files
166
+
167
+ These files already contain a backend (`OPFSSync` or `OPFSAsync`) wrapped in Comlink expose.
168
+
169
+ | Export | Inside | Start with |
170
+ | --------------------------------- | --------------------- | -------------------------------------------------------- |
171
+ | `opfs-worker/dedicated.worker.js` | Comlink + `OPFSSync` | `new Worker(url, { type: 'module' })` or `{ url }` |
172
+ | `opfs-worker/shared.worker.js` | Comlink + `OPFSAsync` | `new SharedWorker(url, { type: 'module' })` or `{ url }` |
173
+
174
+ ### Use the facade with a worker URL
175
+
176
+ This is required for SharedWorker. For dedicated workers, use it only when the default inlined worker is blocked by CSP or you want to host the script yourself.
177
+
178
+ ```typescript
179
+ import workerUrl from 'opfs-worker/dedicated.worker.js?url';
180
+
181
+ const fs = createOPFS({ root: '/my-app', url: workerUrl });
182
+ ```
183
+
184
+ You can also create the `Worker` yourself and pass it to the facade. The facade still handles Comlink, options, encoding helpers, buffer transfers, and cleanup.
185
+
186
+ ```typescript
187
+ const worker = new Worker(workerUrl, { type: 'module' });
188
+ const fs = createOPFS({ root: '/my-app', worker });
189
+ ```
190
+
191
+ ### Use the worker without the facade
192
+
193
+ Wrap it with Comlink and configure the backend manually. This exposes the bytes API directly: no encoding helpers, automatic FD buffer transfers, or automatic worker termination.
194
+
195
+ ```typescript
196
+ import { wrap } from 'comlink';
197
+ import type { OPFSApi } from 'opfs-worker';
198
+ import workerUrl from 'opfs-worker/dedicated.worker.js?url';
199
+
200
+ const worker = new Worker(workerUrl, { type: 'module' });
201
+ const backend = wrap<OPFSApi>(worker);
202
+
203
+ await backend.setOptions({ root: '/my-app' });
204
+ await backend.writeFile('/hello.txt', new TextEncoder().encode('hello'));
205
+
206
+ await backend.dispose();
207
+ worker.terminate();
208
+ ```
209
+
210
+ Guides: [Dedicated worker](../guides/dedicated.md), [SharedWorker](../guides/sharedworker.md).
211
+
212
+ ## Trade-offs
213
+
214
+ | | Dedicated (`OPFSSync`) | Async (`OPFSAsync`) |
215
+ | ----------------------------------- | ------------------------------------------------ | ---------------------------- |
216
+ | File descriptors | yes | throw `ENOTSUP` |
217
+ | Browser support | every browser that has OPFS | Safari before 26 can’t write |
218
+ | SharedWorker | no | yes |
219
+ | One instance for all tabs | no | yes, with `createOPFSShared` |
220
+ | Bundle | ~80 KB inlined worker, or ready-made worker file | small via `/async` |
221
+ | Works under strict CSP (no `blob:`) | pass a worker `url` instead of the inlined blob | n/a |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Positional I/O on the **dedicated / sync** backend (`createOPFSDedicated` / `createOPFS`, or `OPFSSync` from `/pure`). Async and SharedWorker throw `ENOTSUP`.
4
4
 
5
- If you call FD `read`/`write` on **`fs.backend`** from the main thread, transfer buffers with Comlink. The [facade](./api/facade.md) does that for you.
5
+ If you call FD `read`/`write` on **`fs.backend`** from the main thread, transfer buffers with Comlink. The [facade](./README.md#facade) does that for you.
6
6
 
7
7
  ```typescript
8
8
  import { transfer } from 'comlink';
@@ -17,11 +17,11 @@ const fd = await fs.open('/data/unique.txt', { create: true, exclusive: true });
17
17
  const fd = await fs.open('/data/log.txt', { create: true, truncate: true });
18
18
  ```
19
19
 
20
- | Option | Default | |
21
- | ------ | ------- | --- |
22
- | `create` | `false` | Create the file if missing |
20
+ | Option | Default | |
21
+ | ----------- | ------- | ---------------------------------------------- |
22
+ | `create` | `false` | Create the file if missing |
23
23
  | `exclusive` | `false` | With `create`, fail if the file already exists |
24
- | `truncate` | `false` | Truncate to zero length |
24
+ | `truncate` | `false` | Truncate to zero length |
25
25
 
26
26
  Throws `AlreadyExistsError` (`exclusive`), `FileTypeError` (path is a directory), or `FileSystemOperationError`.
27
27
 
@@ -127,11 +127,11 @@ try {
127
127
 
128
128
  ## Errors
129
129
 
130
- | Error | When |
131
- | ----- | ---- |
132
- | `AlreadyExistsError` | `exclusive: true` and file exists |
133
- | `ExistenceError` | Missing path |
134
- | `FileTypeError` | File vs directory mismatch |
135
- | `ValidationError` | Bad offset / length / args |
136
- | `FileSystemOperationError` / `IOError` | Underlying FS / I/O failure |
137
- | `PermissionError` | Access denied |
130
+ | Error | When |
131
+ | -------------------------------------- | --------------------------------- |
132
+ | `AlreadyExistsError` | `exclusive: true` and file exists |
133
+ | `ExistenceError` | Missing path |
134
+ | `FileTypeError` | File vs directory mismatch |
135
+ | `ValidationError` | Bad offset / length / args |
136
+ | `FileSystemOperationError` / `IOError` | Underlying FS / I/O failure |
137
+ | `PermissionError` | Access denied |
@@ -1,6 +1,6 @@
1
- # Async (no worker)
1
+ # Async
2
2
 
3
- `OPFSAsync` on the current thread `getFile()` / `createWritable()`, no Comlink, no worker in the bundle.
3
+ `OPFSAsync` on the **current** thread (main or a worker you already run). Does not create a worker. Uses `getFile()` / `createWritable()`, no Comlink.
4
4
 
5
5
  Same limits apply as SharedWorker (it’s the same backend).
6
6
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  The default path: `OPFSSync` inside a dedicated Web Worker. You get file descriptors and the fastest write path the browser allows for OPFS.
4
4
 
5
- See also [Choosing a mode](../choosing-a-mode.md).
5
+ See also [API](../api/README.md).
6
6
 
7
7
  ## Facade
8
8
 
@@ -16,7 +16,7 @@ await fs.writeFile('/config.json', JSON.stringify({ theme: 'dark' }));
16
16
  const config = await fs.readFile('/config.json'); // string — auto-detected
17
17
  ```
18
18
 
19
- `createOPFS` is the same thing with a shorter name.
19
+ `createOPFS` is the same thing with a shorter name (also from `opfs-worker/sync`).
20
20
 
21
21
  The worker is inlined by default, so you don’t need a special bundler worker setup.
22
22
 
@@ -70,7 +70,9 @@ const fs = new OPFSFacade({
70
70
 
71
71
  ## Notes
72
72
 
73
- - Each call gets its own worker. Tabs don’t share state use [SharedWorker](./sharedworker.md) for that.
73
+ - Same `root` (and same `url`) on one page reuses one Worker; different roots get different Workers. `dispose()` drops your port and terminates the Worker only when the last facade for that pool entry is gone.
74
+ - Tabs don’t share a dedicated Worker — use [SharedWorker](./sharedworker.md) for that.
74
75
  - Sync access handles only work in a dedicated worker.
76
+ - `setOptions` hits the shared instance for a pooled root — keep options consistent.
75
77
 
76
- Also: [file descriptors](../file-descriptors.md), [streaming](./streaming.md), [create helpers](../api/create.md).
78
+ Also: [file descriptors](../api/file-descriptors.md), [streaming](./streaming.md), [API](../api/README.md).
@@ -31,4 +31,4 @@ const fs = createOPFS({
31
31
  });
32
32
  ```
33
33
 
34
- Full options table: [`create` helpers](../api/create.md#options).
34
+ Full options table: [API → Options](../api/README.md#options).
@@ -43,4 +43,4 @@ onconnect = (e) => {
43
43
 
44
44
  Or use the [SharedWorker guide](./sharedworker.md).
45
45
 
46
- Also: [backend API](../api/backend.md), [dedicated](./dedicated.md), [async](./async.md).
46
+ Also: [dedicated](./dedicated.md), [async](./async.md), [API](../api/README.md).
@@ -54,4 +54,4 @@ fs.dispose(); // closes this tab’s port only
54
54
  - `setOptions` hits the shared instance, so keep options consistent across tabs.
55
55
  - Same script URL + `name` (default `'opfs-worker'`) → same instance.
56
56
 
57
- Also: [async](./async.md), [watching](./watching.md), [create helpers](../api/create.md).
57
+ Also: [async](./async.md), [watching](./watching.md), [API](../api/README.md).
@@ -140,7 +140,7 @@ dropZone.addEventListener('drop', async (e) => {
140
140
  });
141
141
  ```
142
142
 
143
- The [demo](https://kachurun.github.io/opfs-worker/) implements exactly this flow — see `demo/FileBrowser.tsx`.
143
+ The [demo](https://kachurun.github.io/opfs-worker/) implements exactly this flow — see `demo/components/FileBrowser/`.
144
144
 
145
145
  ## `writeStream` (raw)
146
146
 
@@ -182,4 +182,4 @@ When the file system runs in a worker, the `Blob` crosses the boundary by refere
182
182
 
183
183
  Dedicated path chunks through FDs; async path uses `createWritable()` (Safari 26+ for writes).
184
184
 
185
- Also: [facade](../api/facade.md), [backend](../api/backend.md).
185
+ Also: [facade](../api/README.md#facade).
package/docs/migration.md CHANGED
@@ -2,14 +2,13 @@
2
2
 
3
3
  ## Renames
4
4
 
5
- | Was | Now |
6
- | ------------------------ | ------------------------------------------------------------------------------------ |
7
- | `createWorker` | `createOPFSDedicated` (`createOPFS` alias; deprecated `createWorker` still exported) |
8
- | `OPFSFileSystem` | `OPFSFacade` (deprecated alias kept) |
9
- | `OPFSWorker` | `OPFSSync` |
10
- | `opfs-worker/raw` | `opfs-worker/pure` |
11
- | `opfs-worker/raw?worker` | `createOPFSDedicated()` + `fs.backend` / `fs.worker`, or `dedicated.worker.js` |
12
- | `fs.sync(entries)` | `fs.importFiles(entries)` (`createIndex` alias kept, deprecated) |
5
+ | Was | Now |
6
+ | ------------------------- | ---------------------------------------------------- |
7
+ | `createWorker` | `createOPFS` (deprecated alias kept) |
8
+ | `OPFSFileSystem` | `OPFSFacade` (deprecated alias kept) |
9
+ | `OPFSWorker` | `OPFSSync` |
10
+ | `opfs-worker/raw` | `opfs-worker/pure` |
11
+ | `fs.createIndex(entries)` | `fs.importFiles(entries)` (`createIndex` alias kept) |
13
12
 
14
13
  ```diff
15
14
  - import { createWorker, OPFSFileSystem } from 'opfs-worker';
@@ -38,4 +37,4 @@
38
37
  - Multiple FDs on one path share one sync handle, each with its own cursor
39
38
  - Dedicated `dispose()` terminates the browser `Worker`
40
39
 
41
- Full entry map: [Choosing a mode](./choosing-a-mode.md).
40
+ Full entry map: [API](./api/README.md).
package/docs/types.md CHANGED
@@ -69,10 +69,10 @@ Entries accept `Iterable<[path, string | Uint8Array | Blob]>` or `Map<string,
69
69
 
70
70
  ## `OPFSApi`
71
71
 
72
- Promise-based surface shared by all backends — a Comlink proxy to `OPFSSync`, or an in-process `OPFSAsync`. What `OPFSFacade` talks to (see `OPFSBackend` in [Create helpers](./api/create.md)).
72
+ Public bytes API shared by all backends — the public methods of `BaseOPFS` (subclasses `OPFSSync` / `OPFSAsync`, or a Comlink proxy). What `OPFSFacade` talks to via `fs.backend`.
73
73
 
74
74
  ```typescript
75
- type OPFSApi = { [K in keyof OPFSSync]: OPFSSync[K] };
75
+ type OPFSApi = Pick<BaseOPFS, keyof BaseOPFS>;
76
76
  ```
77
77
 
78
78
  ## `PathLike`
@@ -93,8 +93,6 @@ interface FileOpenOptions {
93
93
 
94
94
  ## `OPFSOptions`
95
95
 
96
- Table: [Create helpers → Options](./api/create.md#options).
97
-
98
96
  ```typescript
99
97
  interface OPFSOptions {
100
98
  /** Root path (default: '/') */
@@ -110,6 +108,8 @@ interface OPFSOptions {
110
108
  }
111
109
  ```
112
110
 
111
+ Defaults and behavior: [API → Options](./api/README.md#options).
112
+
113
113
  ## `WatchEventType`
114
114
 
115
115
  ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opfs-worker",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "A robust TypeScript library for working with Origin Private File System (OPFS) through Web Workers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -89,6 +89,7 @@
89
89
  "homepage": "https://github.com/kachurun/opfs-worker#readme",
90
90
  "devDependencies": {
91
91
  "@changesets/cli": "^2.29.5",
92
+ "@codemirror/commands": "6.10.4",
92
93
  "@codemirror/lang-cpp": "6.0.3",
93
94
  "@codemirror/lang-css": "6.3.1",
94
95
  "@codemirror/lang-go": "6.0.1",
@@ -103,28 +104,29 @@
103
104
  "@codemirror/lang-sql": "6.10.0",
104
105
  "@codemirror/lang-xml": "6.1.0",
105
106
  "@codemirror/lang-yaml": "6.1.3",
107
+ "@codemirror/language": "6.12.4",
106
108
  "@codemirror/legacy-modes": "6.5.3",
109
+ "@codemirror/state": "6.7.1",
107
110
  "@codemirror/theme-one-dark": "6.1.3",
111
+ "@codemirror/view": "6.43.6",
108
112
  "@flexbe/eslint-config": "^1.0.11",
109
113
  "@tailwindcss/vite": "4.3.3",
110
114
  "@types/minimatch": "^6.0.0",
111
115
  "@types/node": "^24.2.0",
112
- "@types/react": "^19.1.9",
113
- "@types/react-dom": "^19.1.7",
114
116
  "@typescript-eslint/eslint-plugin": "^8.39.0",
115
117
  "@typescript-eslint/parser": "^8.39.0",
116
- "@uiw/react-codemirror": "4.25.11",
117
118
  "@vitest/coverage-v8": "^3.2.4",
118
119
  "daisyui": "5.7.4",
119
120
  "eslint": "^9.32.0",
121
+ "fflate": "0.8.3",
120
122
  "happy-dom": "^18.0.1",
121
- "lucide-react": "1.26.0",
122
- "react": "^19.1.1",
123
- "react-dom": "^19.1.1",
124
- "react-icons": "5.7.0",
123
+ "lucide-solid": "1.27.0",
124
+ "solid-icons": "1.2.0",
125
+ "solid-js": "1.9.14",
125
126
  "tailwindcss": "4.3.3",
126
127
  "typescript": "^5.9.2",
127
128
  "vite": "^7.0.6",
129
+ "vite-plugin-solid": "2.11.13",
128
130
  "vitest": "^3.2.4"
129
131
  },
130
132
  "engines": {
@@ -136,7 +138,6 @@
136
138
  "packageManager": "bun@1.2.19",
137
139
  "dependencies": {
138
140
  "comlink": "^4.4.2",
139
- "fflate": "0.8.3",
140
141
  "minimatch": "^10.0.3"
141
142
  },
142
143
  "publishConfig": {