@livestore/utils 0.4.0 → 0.5.0-dev.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 (247) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/NoopTracer.d.ts +7 -8
  3. package/dist/NoopTracer.d.ts.map +1 -1
  4. package/dist/NoopTracer.js +3 -18
  5. package/dist/NoopTracer.js.map +1 -1
  6. package/dist/NoopTracer.test.d.ts +2 -0
  7. package/dist/NoopTracer.test.d.ts.map +1 -0
  8. package/dist/NoopTracer.test.js +17 -0
  9. package/dist/NoopTracer.test.js.map +1 -0
  10. package/dist/browser/Opfs/Opfs.d.ts +179 -29
  11. package/dist/browser/Opfs/Opfs.d.ts.map +1 -1
  12. package/dist/browser/Opfs/Opfs.js +132 -307
  13. package/dist/browser/Opfs/Opfs.js.map +1 -1
  14. package/dist/browser/Opfs/debug-utils.d.ts.map +1 -1
  15. package/dist/browser/Opfs/debug-utils.js +5 -4
  16. package/dist/browser/Opfs/debug-utils.js.map +1 -1
  17. package/dist/browser/Opfs/utils.d.ts +8 -8
  18. package/dist/browser/Opfs/utils.d.ts.map +1 -1
  19. package/dist/browser/Opfs/utils.js +35 -26
  20. package/dist/browser/Opfs/utils.js.map +1 -1
  21. package/dist/browser/QuotaExceededError.d.ts +10 -9
  22. package/dist/browser/QuotaExceededError.d.ts.map +1 -1
  23. package/dist/browser/WebChannelBrowser.d.ts.map +1 -1
  24. package/dist/browser/WebChannelBrowser.js +21 -10
  25. package/dist/browser/WebChannelBrowser.js.map +1 -1
  26. package/dist/browser/WebError.d.ts +54 -86
  27. package/dist/browser/WebError.d.ts.map +1 -1
  28. package/dist/browser/WebError.js +91 -84
  29. package/dist/browser/WebError.js.map +1 -1
  30. package/dist/browser/WebError.test.js +6 -6
  31. package/dist/browser/WebError.test.js.map +1 -1
  32. package/dist/browser/WebLock.d.ts.map +1 -1
  33. package/dist/browser/WebLock.js +13 -13
  34. package/dist/browser/WebLock.js.map +1 -1
  35. package/dist/effect/Debug.d.ts +4 -7
  36. package/dist/effect/Debug.d.ts.map +1 -1
  37. package/dist/effect/Debug.js +32 -36
  38. package/dist/effect/Debug.js.map +1 -1
  39. package/dist/effect/Effect.d.ts +31 -22
  40. package/dist/effect/Effect.d.ts.map +1 -1
  41. package/dist/effect/Effect.js +51 -47
  42. package/dist/effect/Effect.js.map +1 -1
  43. package/dist/effect/Effect.test.d.ts +2 -0
  44. package/dist/effect/Effect.test.d.ts.map +1 -0
  45. package/dist/effect/Effect.test.js +72 -0
  46. package/dist/effect/Effect.test.js.map +1 -0
  47. package/dist/effect/Error.d.ts +4 -6
  48. package/dist/effect/Error.d.ts.map +1 -1
  49. package/dist/effect/Logger.d.ts +0 -6
  50. package/dist/effect/Logger.d.ts.map +1 -1
  51. package/dist/effect/Logger.js +0 -32
  52. package/dist/effect/Logger.js.map +1 -1
  53. package/dist/effect/OtelTracer.d.ts +1 -1
  54. package/dist/effect/OtelTracer.d.ts.map +1 -1
  55. package/dist/effect/OtelTracer.js +2 -3
  56. package/dist/effect/OtelTracer.js.map +1 -1
  57. package/dist/effect/RpcClient.d.ts +7 -7
  58. package/dist/effect/RpcClient.d.ts.map +1 -1
  59. package/dist/effect/RpcClient.js +72 -52
  60. package/dist/effect/RpcClient.js.map +1 -1
  61. package/dist/effect/Schedule.d.ts +1 -1
  62. package/dist/effect/Schedule.d.ts.map +1 -1
  63. package/dist/effect/Schedule.js +2 -2
  64. package/dist/effect/Schedule.js.map +1 -1
  65. package/dist/effect/Schema/debug-diff.d.ts +1 -1
  66. package/dist/effect/Schema/debug-diff.d.ts.map +1 -1
  67. package/dist/effect/Schema/debug-diff.js +5 -7
  68. package/dist/effect/Schema/debug-diff.js.map +1 -1
  69. package/dist/effect/Schema/debug-diff.test.js +7 -4
  70. package/dist/effect/Schema/debug-diff.test.js.map +1 -1
  71. package/dist/effect/Schema/index.d.ts +28 -20
  72. package/dist/effect/Schema/index.d.ts.map +1 -1
  73. package/dist/effect/Schema/index.js +55 -28
  74. package/dist/effect/Schema/index.js.map +1 -1
  75. package/dist/effect/Stream.d.ts +13 -5
  76. package/dist/effect/Stream.d.ts.map +1 -1
  77. package/dist/effect/Stream.js +19 -12
  78. package/dist/effect/Stream.js.map +1 -1
  79. package/dist/effect/Stream.test.js +9 -9
  80. package/dist/effect/Stream.test.js.map +1 -1
  81. package/dist/effect/Subscribable.d.ts +9 -3
  82. package/dist/effect/Subscribable.d.ts.map +1 -1
  83. package/dist/effect/Subscribable.js +20 -35
  84. package/dist/effect/Subscribable.js.map +1 -1
  85. package/dist/effect/SubscriptionRef.d.ts +5 -6
  86. package/dist/effect/SubscriptionRef.d.ts.map +1 -1
  87. package/dist/effect/SubscriptionRef.js +2 -3
  88. package/dist/effect/SubscriptionRef.js.map +1 -1
  89. package/dist/effect/TaskTracing.d.ts +1 -1
  90. package/dist/effect/TaskTracing.d.ts.map +1 -1
  91. package/dist/effect/TaskTracing.js +12 -16
  92. package/dist/effect/TaskTracing.js.map +1 -1
  93. package/dist/effect/WebChannel/WebChannel.d.ts +7 -7
  94. package/dist/effect/WebChannel/WebChannel.d.ts.map +1 -1
  95. package/dist/effect/WebChannel/WebChannel.js +64 -43
  96. package/dist/effect/WebChannel/WebChannel.js.map +1 -1
  97. package/dist/effect/WebChannel/WebChannel.test.js +15 -15
  98. package/dist/effect/WebChannel/WebChannel.test.js.map +1 -1
  99. package/dist/effect/WebChannel/broadcastChannelWithAck.d.ts.map +1 -1
  100. package/dist/effect/WebChannel/broadcastChannelWithAck.js +16 -9
  101. package/dist/effect/WebChannel/broadcastChannelWithAck.js.map +1 -1
  102. package/dist/effect/WebChannel/common.d.ts +16 -17
  103. package/dist/effect/WebChannel/common.d.ts.map +1 -1
  104. package/dist/effect/WebChannel/common.js +6 -6
  105. package/dist/effect/WebChannel/common.js.map +1 -1
  106. package/dist/effect/WebSocket.d.ts +4 -6
  107. package/dist/effect/WebSocket.d.ts.map +1 -1
  108. package/dist/effect/WebSocket.js +4 -4
  109. package/dist/effect/WebSocket.js.map +1 -1
  110. package/dist/effect/WebSocket.test.js +2 -2
  111. package/dist/effect/WebSocket.test.js.map +1 -1
  112. package/dist/effect/mod.browser-build.test.d.ts +2 -0
  113. package/dist/effect/mod.browser-build.test.d.ts.map +1 -0
  114. package/dist/effect/mod.browser-build.test.js +18 -0
  115. package/dist/effect/mod.browser-build.test.js.map +1 -0
  116. package/dist/effect/mod.d.ts +13 -15
  117. package/dist/effect/mod.d.ts.map +1 -1
  118. package/dist/effect/mod.js +13 -18
  119. package/dist/effect/mod.js.map +1 -1
  120. package/dist/effect/spanEvent.d.ts.map +1 -1
  121. package/dist/effect/spanEvent.js +2 -2
  122. package/dist/effect/spanEvent.js.map +1 -1
  123. package/dist/effect/spanEvent.test.js +10 -13
  124. package/dist/effect/spanEvent.test.js.map +1 -1
  125. package/dist/fast-deep-equal.d.ts.map +1 -1
  126. package/dist/fast-deep-equal.js +1 -2
  127. package/dist/fast-deep-equal.js.map +1 -1
  128. package/dist/misc.js +2 -2
  129. package/dist/misc.js.map +1 -1
  130. package/dist/mod.d.ts +0 -35
  131. package/dist/mod.d.ts.map +1 -1
  132. package/dist/mod.js +0 -8
  133. package/dist/mod.js.map +1 -1
  134. package/dist/node/mod.d.ts +17 -11
  135. package/dist/node/mod.d.ts.map +1 -1
  136. package/dist/node/mod.js +23 -16
  137. package/dist/node/mod.js.map +1 -1
  138. package/dist/object/index.d.ts +0 -9
  139. package/dist/object/index.d.ts.map +1 -1
  140. package/dist/object/index.js +0 -9
  141. package/dist/object/index.js.map +1 -1
  142. package/dist/string.d.ts +0 -2
  143. package/dist/string.d.ts.map +1 -1
  144. package/dist/string.js +0 -2
  145. package/dist/string.js.map +1 -1
  146. package/package.json +18 -36
  147. package/src/NoopTracer.test.ts +20 -0
  148. package/src/NoopTracer.ts +18 -41
  149. package/src/browser/Opfs/Opfs.ts +304 -277
  150. package/src/browser/Opfs/debug-utils.ts +7 -6
  151. package/src/browser/Opfs/utils.ts +36 -26
  152. package/src/browser/QuotaExceededError.ts +13 -10
  153. package/src/browser/WebChannelBrowser.ts +25 -11
  154. package/src/browser/WebError.test.ts +6 -6
  155. package/src/browser/WebError.ts +107 -133
  156. package/src/browser/WebLock.ts +13 -14
  157. package/src/effect/Debug.ts +66 -59
  158. package/src/effect/Effect.test.ts +117 -0
  159. package/src/effect/Effect.ts +84 -71
  160. package/src/effect/Logger.ts +0 -48
  161. package/src/effect/OtelTracer.ts +2 -3
  162. package/src/effect/RpcClient.ts +80 -61
  163. package/src/effect/Schedule.ts +4 -5
  164. package/src/effect/Schema/debug-diff.test.ts +6 -6
  165. package/src/effect/Schema/debug-diff.ts +6 -8
  166. package/src/effect/Schema/index.ts +122 -61
  167. package/src/effect/Stream.test.ts +9 -9
  168. package/src/effect/Stream.ts +23 -16
  169. package/src/effect/Subscribable.ts +31 -42
  170. package/src/effect/SubscriptionRef.ts +8 -12
  171. package/src/effect/TaskTracing.ts +13 -16
  172. package/src/effect/WebChannel/WebChannel.test.ts +23 -23
  173. package/src/effect/WebChannel/WebChannel.ts +87 -55
  174. package/src/effect/WebChannel/broadcastChannelWithAck.ts +21 -11
  175. package/src/effect/WebChannel/common.ts +14 -15
  176. package/src/effect/WebSocket.test.ts +2 -2
  177. package/src/effect/WebSocket.ts +9 -6
  178. package/src/effect/mod.browser-build.test.ts +19 -0
  179. package/src/effect/mod.ts +35 -69
  180. package/src/effect/spanEvent.test.ts +10 -13
  181. package/src/effect/spanEvent.ts +5 -3
  182. package/src/fast-deep-equal.ts +1 -2
  183. package/src/misc.ts +2 -2
  184. package/src/mod.ts +0 -36
  185. package/src/node/mod.ts +26 -20
  186. package/src/object/index.ts +0 -24
  187. package/src/string.ts +0 -3
  188. package/dist/effect/BucketQueue.d.ts +0 -20
  189. package/dist/effect/BucketQueue.d.ts.map +0 -1
  190. package/dist/effect/BucketQueue.js +0 -34
  191. package/dist/effect/BucketQueue.js.map +0 -1
  192. package/dist/effect/Scheduler.d.ts +0 -4
  193. package/dist/effect/Scheduler.d.ts.map +0 -1
  194. package/dist/effect/Scheduler.js +0 -9
  195. package/dist/effect/Scheduler.js.map +0 -1
  196. package/dist/effect/ServiceContext.d.ts +0 -37
  197. package/dist/effect/ServiceContext.d.ts.map +0 -1
  198. package/dist/effect/ServiceContext.js +0 -55
  199. package/dist/effect/ServiceContext.js.map +0 -1
  200. package/dist/guards.d.ts +0 -20
  201. package/dist/guards.d.ts.map +0 -1
  202. package/dist/guards.js +0 -20
  203. package/dist/guards.js.map +0 -1
  204. package/dist/node/ChildProcessRunner/ChildProcessRunner.d.ts +0 -4
  205. package/dist/node/ChildProcessRunner/ChildProcessRunner.d.ts.map +0 -1
  206. package/dist/node/ChildProcessRunner/ChildProcessRunner.js +0 -128
  207. package/dist/node/ChildProcessRunner/ChildProcessRunner.js.map +0 -1
  208. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.d.ts +0 -10
  209. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.d.ts.map +0 -1
  210. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js +0 -217
  211. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js.map +0 -1
  212. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts +0 -84
  213. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts.map +0 -1
  214. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.js +0 -68
  215. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.js.map +0 -1
  216. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.d.ts +0 -2
  217. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.d.ts.map +0 -1
  218. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js +0 -52
  219. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js.map +0 -1
  220. package/dist/node/ChildProcessRunner/ChildProcessWorker.d.ts +0 -23
  221. package/dist/node/ChildProcessRunner/ChildProcessWorker.d.ts.map +0 -1
  222. package/dist/node/ChildProcessRunner/ChildProcessWorker.js +0 -138
  223. package/dist/node/ChildProcessRunner/ChildProcessWorker.js.map +0 -1
  224. package/dist/object/omit.d.ts +0 -3
  225. package/dist/object/omit.d.ts.map +0 -1
  226. package/dist/object/omit.js +0 -14
  227. package/dist/object/omit.js.map +0 -1
  228. package/dist/object/pick.d.ts +0 -14
  229. package/dist/object/pick.d.ts.map +0 -1
  230. package/dist/object/pick.js +0 -17
  231. package/dist/object/pick.js.map +0 -1
  232. package/dist/time.d.ts +0 -12
  233. package/dist/time.d.ts.map +0 -1
  234. package/dist/time.js +0 -22
  235. package/dist/time.js.map +0 -1
  236. package/src/effect/BucketQueue.ts +0 -49
  237. package/src/effect/Scheduler.ts +0 -13
  238. package/src/effect/ServiceContext.ts +0 -108
  239. package/src/guards.ts +0 -23
  240. package/src/node/ChildProcessRunner/ChildProcessRunner.ts +0 -148
  241. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.ts +0 -311
  242. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/schema.ts +0 -78
  243. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.ts +0 -65
  244. package/src/node/ChildProcessRunner/ChildProcessWorker.ts +0 -169
  245. package/src/object/omit.ts +0 -17
  246. package/src/object/pick.ts +0 -27
  247. package/src/time.ts +0 -25
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="webworker" />
2
2
 
3
- import { Effect, Option, Schema, Stream } from 'effect'
3
+ import { Context, Effect, Layer, Option, Schema, type Scope, Stream } from 'effect'
4
4
 
5
5
  import * as WebError from '../WebError.ts'
6
6
 
@@ -13,146 +13,276 @@ import * as WebError from '../WebError.ts'
13
13
  *
14
14
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Origin_private_file_system | MDN Reference}
15
15
  */
16
- export class Opfs extends Effect.Service<Opfs>()('@livestore/utils/Opfs', {
17
- sync: () => {
18
- /**
19
- * Acquire the OPFS root directory handle.
20
- *
21
- * @returns Root directory handle for the current origin.
22
- *
23
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/StorageManager/getDirectory | MDN Reference}
24
- */
25
- const getRootDirectoryHandle = Effect.tryPromise({
26
- try: () => navigator.storage.getDirectory(),
27
- catch: (u) => WebError.parseWebError(u, [WebError.SecurityError]),
28
- })
16
+ export interface Service {
17
+ /**
18
+ * Acquire the OPFS root directory handle.
19
+ *
20
+ * @returns Root directory handle for the current origin.
21
+ *
22
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/StorageManager/getDirectory | MDN Reference}
23
+ */
24
+ readonly getRootDirectoryHandle: Effect.Effect<FileSystemDirectoryHandle, WebError.WebError>
25
+ /**
26
+ * Resolve (and optionally create) a file handle relative to a directory.
27
+ *
28
+ * @param parent - Directory to search.
29
+ * @param name - Target file name.
30
+ * @param options - Forwarded `getFileHandle` options such as `{ create: true }`.
31
+ *
32
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getFileHandle | MDN Reference}
33
+ */
34
+ readonly getFileHandle: (
35
+ parent: FileSystemDirectoryHandle,
36
+ name: string,
37
+ options?: FileSystemGetFileOptions,
38
+ ) => Effect.Effect<FileSystemFileHandle, WebError.WebError>
39
+ /**
40
+ * Resolve (and optionally create) a directory handle relative to another directory.
41
+ *
42
+ * @param parent - Directory to search.
43
+ * @param name - Target directory name.
44
+ * @param options - Forwarded `getDirectoryHandle` options such as `{ create: true }`.
45
+ *
46
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getDirectoryHandle | MDN Reference}
47
+ */
48
+ readonly getDirectoryHandle: (
49
+ parent: FileSystemDirectoryHandle,
50
+ name: string,
51
+ options?: FileSystemGetDirectoryOptions,
52
+ ) => Effect.Effect<FileSystemDirectoryHandle, WebError.WebError>
53
+ /**
54
+ * Remove a file-system entry (file or directory) from its parent directory.
55
+ *
56
+ * @param parent - Directory containing the entry.
57
+ * @param name - Entry name.
58
+ * @param options - Removal behavior (for example `{ recursive: true }`).
59
+ *
60
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/removeEntry | MDN Reference}
61
+ */
62
+ readonly removeEntry: (
63
+ parent: FileSystemDirectoryHandle,
64
+ name: string,
65
+ options?: FileSystemRemoveOptions,
66
+ ) => Effect.Effect<void, WebError.WebError>
67
+ /**
68
+ * Return a stream of child file-system handles for a directory.
69
+ *
70
+ * @param directory - Directory whose children are to be streamed
71
+ * @returns `Stream` of `FileSystemHandle`
72
+ *
73
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/values | MDN Reference}
74
+ */
75
+ readonly values: (
76
+ directory: FileSystemDirectoryHandle,
77
+ ) => Stream.Stream<FileSystemHandle, WebError.NotAllowedError | WebError.NotFoundError | WebError.UnknownError>
78
+ /**
79
+ * Resolve the relative path from a parent directory to a descendant handle.
80
+ *
81
+ * @param parent - Reference directory.
82
+ * @param child - File or directory handle within the parent hierarchy.
83
+ * @returns `Option.some(pathSegments)` when reachable, otherwise `Option.none()`.
84
+ *
85
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/resolve | MDN Reference}
86
+ */
87
+ readonly resolve: (
88
+ parent: FileSystemDirectoryHandle,
89
+ child: FileSystemHandle,
90
+ ) => Effect.Effect<Option.Option<ReadonlyArray<string>>, WebError.WebError>
91
+ /**
92
+ * Read the underlying `File` for a file handle.
93
+ *
94
+ * @param handle - Handle referencing the target file.
95
+ *
96
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/getFile | MDN Reference}
97
+ */
98
+ readonly getFile: (handle: FileSystemFileHandle) => Effect.Effect<File, WebError.WebError>
99
+ /**
100
+ * Overwrite the contents of a file with the provided data.
101
+ *
102
+ * @param handle - File to write to.
103
+ * @param data - Chunk(s) accepted by `FileSystemWritableFileStream.write`.
104
+ * @param options - Stream creation options (for example, `{ keepExistingData: false }`).
105
+ *
106
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createWritable | MDN Reference}
107
+ */
108
+ readonly writeFile: (
109
+ handle: FileSystemFileHandle,
110
+ data: FileSystemWriteChunkType,
111
+ options?: FileSystemCreateWritableOptions,
112
+ ) => Effect.Effect<void, WebError.WebError>
113
+ /**
114
+ * Append data to the end of an existing file.
115
+ *
116
+ * @param handle - File to extend.
117
+ * @param data - Data to append.
118
+ *
119
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/write | MDN Reference}
120
+ */
121
+ readonly appendToFile: (
122
+ handle: FileSystemFileHandle,
123
+ data: FileSystemWriteChunkType,
124
+ ) => Effect.Effect<void, WebError.WebError>
125
+ /**
126
+ * Truncate a file to the specified size in bytes.
127
+ *
128
+ * @param handle - File to shrink or pad.
129
+ * @param size - Target byte length.
130
+ *
131
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/truncate | MDN Reference}
132
+ */
133
+ readonly truncateFile: (handle: FileSystemFileHandle, size: number) => Effect.Effect<void, WebError.WebError>
134
+ /**
135
+ * Create a synchronous access handle for a file.
136
+ *
137
+ * @param handle - File handle to open.
138
+ * @returns A managed handle that is automatically closed when released.
139
+ *
140
+ * @remarks
141
+ * - Only available in Dedicated Web Workers.
142
+ * - This method is asynchronous even though the `FileSystemSyncAccessHandle` APIs are synchronous.
143
+ *
144
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle | MDN Reference}
145
+ */
146
+ readonly createSyncAccessHandle: (
147
+ handle: FileSystemFileHandle,
148
+ ) => Effect.Effect<FileSystemSyncAccessHandle, WebError.WebError, Scope.Scope>
149
+ /**
150
+ * Perform a synchronous read into the provided buffer from a sync access handle.
151
+ *
152
+ * @param handle - Sync access handle to read from.
153
+ * @param buffer - Destination buffer (can be a specific view like Uint8Array).
154
+ * @param options - Read position options.
155
+ * @returns Number of bytes read.
156
+ *
157
+ * @remarks
158
+ * Only available in Dedicated Web Workers.
159
+ *
160
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/read | MDN Reference}
161
+ */
162
+ readonly syncRead: (
163
+ handle: FileSystemSyncAccessHandle,
164
+ buffer: ArrayBuffer | ArrayBufferView,
165
+ options?: FileSystemReadWriteOptions,
166
+ ) => Effect.Effect<number, WebError.WebError>
167
+ /**
168
+ * Perform a synchronous write from the provided buffer into the file.
169
+ *
170
+ * @param handle - Sync access handle to write to.
171
+ * @param buffer - Source data.
172
+ * @param options - Write position options.
173
+ * @returns Number of bytes written.
174
+ *
175
+ * @remarks
176
+ * Only available in Dedicated Web Workers.
177
+ *
178
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/write | MDN Reference}
179
+ */
180
+ readonly syncWrite: (
181
+ handle: FileSystemSyncAccessHandle,
182
+ buffer: AllowSharedBufferSource,
183
+ options?: FileSystemReadWriteOptions,
184
+ ) => Effect.Effect<number, WebError.WebError>
185
+ /**
186
+ * Truncate the file associated with a sync access handle to the specified size.
187
+ *
188
+ * @param handle - Sync access handle to mutate.
189
+ * @param size - Desired byte length.
190
+ *
191
+ * @remarks
192
+ * Only available in Dedicated Web Workers.
193
+ *
194
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/truncate | MDN Reference}
195
+ */
196
+ readonly syncTruncate: (handle: FileSystemSyncAccessHandle, size: number) => Effect.Effect<void, WebError.WebError>
197
+ /**
198
+ * Retrieve the current size of a file via its sync access handle.
199
+ *
200
+ * @param handle - Sync access handle.
201
+ * @returns File size in bytes.
202
+ *
203
+ * @remarks
204
+ * Only available in Dedicated Web Workers.
205
+ *
206
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/getSize | MDN Reference}
207
+ */
208
+ readonly syncGetSize: (handle: FileSystemSyncAccessHandle) => Effect.Effect<number, WebError.WebError>
209
+ /**
210
+ * Flush pending synchronous writes to durable storage.
211
+ *
212
+ * @param handle - Sync access handle to flush.
213
+ *
214
+ * @remarks
215
+ * Only available in Dedicated Web Workers.
216
+ *
217
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/flush | MDN Reference}
218
+ */
219
+ readonly syncFlush: (handle: FileSystemSyncAccessHandle) => Effect.Effect<void, WebError.WebError>
220
+ }
221
+
222
+ export class Opfs extends Context.Service<Opfs, Service>()('@livestore/utils/Opfs') {}
29
223
 
30
- /**
31
- * Resolve (and optionally create) a file handle relative to a directory.
32
- *
33
- * @param parent - Directory to search.
34
- * @param name - Target file name.
35
- * @param options - Forwarded `getFileHandle` options such as `{ create: true }`.
36
- *
37
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getFileHandle | MDN Reference}
38
- */
39
- const getFileHandle = (parent: FileSystemDirectoryHandle, name: string, options?: FileSystemGetFileOptions) =>
224
+ export const layer = Layer.succeed(
225
+ Opfs,
226
+ Opfs.of({
227
+ getRootDirectoryHandle: Effect.tryPromise({
228
+ try: () => navigator.storage.getDirectory(),
229
+ catch: (u) => WebError.classifyWebError(u, [WebError.SecurityError]),
230
+ }),
231
+ getFileHandle: (parent: FileSystemDirectoryHandle, name: string, options?: FileSystemGetFileOptions) =>
40
232
  Effect.tryPromise({
41
233
  try: () => parent.getFileHandle(name, options),
42
234
  catch: (u) =>
43
- WebError.parseWebError(u, [
235
+ WebError.classifyWebError(u, [
44
236
  WebError.NotAllowedError,
45
237
  WebError.TypeError,
46
238
  WebError.TypeMismatchError,
47
239
  WebError.NotFoundError,
48
240
  ]),
49
- })
50
-
51
- /**
52
- * Resolve (and optionally create) a directory handle relative to another directory.
53
- *
54
- * @param parent - Directory to search.
55
- * @param name - Target directory name.
56
- * @param options - Forwarded `getDirectoryHandle` options such as `{ create: true }`.
57
- *
58
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getDirectoryHandle | MDN Reference}
59
- */
60
- const getDirectoryHandle = (
61
- parent: FileSystemDirectoryHandle,
62
- name: string,
63
- options?: FileSystemGetDirectoryOptions,
64
- ) =>
241
+ }),
242
+ getDirectoryHandle: (parent: FileSystemDirectoryHandle, name: string, options?: FileSystemGetDirectoryOptions) =>
65
243
  Effect.tryPromise({
66
244
  try: () => parent.getDirectoryHandle(name, options),
67
245
  catch: (u) =>
68
- WebError.parseWebError(u, [
246
+ WebError.classifyWebError(u, [
69
247
  WebError.NotAllowedError,
70
248
  WebError.TypeError,
71
249
  WebError.TypeMismatchError,
72
250
  WebError.NotFoundError,
73
251
  ]),
74
- })
75
-
76
- /**
77
- * Remove a file-system entry (file or directory) from its parent directory.
78
- *
79
- * @param parent - Directory containing the entry.
80
- * @param name - Entry name.
81
- * @param options - Removal behavior (for example `{ recursive: true }`).
82
- *
83
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/removeEntry | MDN Reference}
84
- */
85
- const removeEntry = (parent: FileSystemDirectoryHandle, name: string, options?: FileSystemRemoveOptions) =>
252
+ }),
253
+ removeEntry: (parent: FileSystemDirectoryHandle, name: string, options?: FileSystemRemoveOptions) =>
86
254
  Effect.tryPromise({
87
255
  try: () => parent.removeEntry(name, options),
88
256
  catch: (u) =>
89
- WebError.parseWebError(u, [
257
+ WebError.classifyWebError(u, [
90
258
  WebError.TypeError,
91
259
  WebError.NotAllowedError,
92
260
  WebError.InvalidModificationError,
93
261
  WebError.NotFoundError,
94
262
  WebError.NoModificationAllowedError,
95
263
  ]),
96
- })
97
-
98
- /**
99
- * Return a stream of child file-system handles for a directory.
100
- *
101
- * @param directory - Directory whose children are to be streamed
102
- * @returns `Stream` of `FileSystemHandle`
103
- *
104
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/values | MDN Reference}
105
- */
106
- const values = (
264
+ }),
265
+ values: (
107
266
  directory: FileSystemDirectoryHandle,
108
267
  ): Stream.Stream<
109
268
  FileSystemHandle,
110
269
  WebError.NotAllowedError | WebError.NotFoundError | WebError.UnknownError,
111
270
  never
112
271
  > =>
113
- Stream.fromAsyncIterable(
114
- (directory as unknown as { values(): AsyncIterable<FileSystemHandle> }).values(),
115
- (u) => WebError.parseWebError(u, [WebError.NotAllowedError, WebError.NotFoundError]),
116
- )
117
-
118
- /**
119
- * Resolve the relative path from a parent directory to a descendant handle.
120
- *
121
- * @param parent - Reference directory.
122
- * @param child - File or directory handle within the parent hierarchy.
123
- * @returns `Option.some(pathSegments)` when reachable, otherwise `Option.none()`.
124
- *
125
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/resolve | MDN Reference}
126
- */
127
- const resolve = (parent: FileSystemDirectoryHandle, child: FileSystemHandle) =>
272
+ Stream.fromAsyncIterable(directory.values(), (u) =>
273
+ WebError.classifyWebError(u, [WebError.NotAllowedError, WebError.NotFoundError]),
274
+ ),
275
+ resolve: (parent: FileSystemDirectoryHandle, child: FileSystemHandle) =>
128
276
  Effect.tryPromise({
129
277
  try: () => parent.resolve(child),
130
- catch: (u) => WebError.parseWebError(u),
131
- }).pipe(Effect.map((path) => (path === null ? Option.none() : Option.some(path))))
132
-
133
- /**
134
- * Read the underlying `File` for a file handle.
135
- *
136
- * @param handle - Handle referencing the target file.
137
- *
138
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/getFile | MDN Reference}
139
- */
140
- const getFile = (handle: FileSystemFileHandle) =>
278
+ catch: (u) => WebError.classifyWebError(u),
279
+ }).pipe(Effect.map((path) => (path === null ? Option.none() : Option.some(path)))),
280
+ getFile: (handle: FileSystemFileHandle) =>
141
281
  Effect.tryPromise({
142
282
  try: () => handle.getFile(),
143
- catch: (u) => WebError.parseWebError(u, [WebError.NotAllowedError, WebError.NotFoundError]),
144
- })
145
-
146
- /**
147
- * Overwrite the contents of a file with the provided data.
148
- *
149
- * @param handle - File to write to.
150
- * @param data - Chunk(s) accepted by `FileSystemWritableFileStream.write`.
151
- * @param options - Stream creation options (for example `{ keepExistingData: false }`).
152
- *
153
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createWritable | MDN Reference}
154
- */
155
- const writeFile = (
283
+ catch: (u) => WebError.classifyWebError(u, [WebError.NotAllowedError, WebError.NotFoundError]),
284
+ }),
285
+ writeFile: (
156
286
  handle: FileSystemFileHandle,
157
287
  data: FileSystemWriteChunkType,
158
288
  options?: FileSystemCreateWritableOptions,
@@ -161,7 +291,7 @@ export class Opfs extends Effect.Service<Opfs>()('@livestore/utils/Opfs', {
161
291
  Effect.tryPromise({
162
292
  try: () => handle.createWritable(options),
163
293
  catch: (u) =>
164
- WebError.parseWebError(u, [
294
+ WebError.classifyWebError(u, [
165
295
  WebError.NotAllowedError,
166
296
  WebError.NotFoundError,
167
297
  WebError.NoModificationAllowedError,
@@ -172,29 +302,20 @@ export class Opfs extends Effect.Service<Opfs>()('@livestore/utils/Opfs', {
172
302
  Effect.tryPromise({
173
303
  try: () => stream.write(data),
174
304
  catch: (u) =>
175
- WebError.parseWebError(u, [WebError.NotAllowedError, WebError.QuotaExceededError, WebError.TypeError]),
305
+ WebError.classifyWebError(u, [WebError.NotAllowedError, WebError.QuotaExceededError, WebError.TypeError]),
176
306
  }),
177
307
  (stream) =>
178
308
  Effect.tryPromise({
179
309
  try: () => stream.close(),
180
- catch: (u) => WebError.parseWebError(u, [WebError.TypeError]),
181
- }).pipe(Effect.orElse(() => Effect.void)),
182
- )
183
-
184
- /**
185
- * Append data to the end of an existing file.
186
- *
187
- * @param handle - File to extend.
188
- * @param data - Data to append.
189
- *
190
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/write | MDN Reference}
191
- */
192
- const appendToFile = (handle: FileSystemFileHandle, data: FileSystemWriteChunkType) =>
310
+ catch: (u) => WebError.classifyWebError(u, [WebError.TypeError]),
311
+ }).pipe(Effect.catchCause(() => Effect.void)),
312
+ ),
313
+ appendToFile: (handle: FileSystemFileHandle, data: FileSystemWriteChunkType) =>
193
314
  Effect.acquireUseRelease(
194
315
  Effect.tryPromise({
195
316
  try: () => handle.createWritable({ keepExistingData: true }),
196
317
  catch: (u) =>
197
- WebError.parseWebError(u, [
318
+ WebError.classifyWebError(u, [
198
319
  WebError.NotAllowedError,
199
320
  WebError.NotFoundError,
200
321
  WebError.NoModificationAllowedError,
@@ -203,38 +324,36 @@ export class Opfs extends Effect.Service<Opfs>()('@livestore/utils/Opfs', {
203
324
  }),
204
325
  (stream) =>
205
326
  Effect.gen(function* () {
206
- const file = yield* getFile(handle)
327
+ const file = yield* Effect.tryPromise({
328
+ try: () => handle.getFile(),
329
+ catch: (u) => WebError.classifyWebError(u, [WebError.NotAllowedError, WebError.NotFoundError]),
330
+ })
207
331
  yield* Effect.tryPromise({
208
332
  try: () => stream.seek(file.size),
209
- catch: (u) => WebError.parseWebError(u, [WebError.NotAllowedError, WebError.TypeError]),
333
+ catch: (u) => WebError.classifyWebError(u, [WebError.NotAllowedError, WebError.TypeError]),
210
334
  })
211
335
  yield* Effect.tryPromise({
212
336
  try: () => stream.write(data),
213
337
  catch: (u) =>
214
- WebError.parseWebError(u, [WebError.NotAllowedError, WebError.QuotaExceededError, WebError.TypeError]),
338
+ WebError.classifyWebError(u, [
339
+ WebError.NotAllowedError,
340
+ WebError.QuotaExceededError,
341
+ WebError.TypeError,
342
+ ]),
215
343
  })
216
344
  }),
217
345
  (stream) =>
218
346
  Effect.tryPromise({
219
347
  try: () => stream.close(),
220
- catch: (u) => WebError.parseWebError(u, [WebError.TypeError]),
221
- }).pipe(Effect.orElse(() => Effect.void)),
222
- )
223
-
224
- /**
225
- * Truncate a file to the specified size in bytes.
226
- *
227
- * @param handle - File to shrink or pad.
228
- * @param size - Target byte length.
229
- *
230
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/truncate | MDN Reference}
231
- */
232
- const truncateFile = (handle: FileSystemFileHandle, size: number) =>
348
+ catch: (u) => WebError.classifyWebError(u, [WebError.TypeError]),
349
+ }).pipe(Effect.catchCause(() => Effect.void)),
350
+ ),
351
+ truncateFile: (handle: FileSystemFileHandle, size: number) =>
233
352
  Effect.acquireUseRelease(
234
353
  Effect.tryPromise({
235
354
  try: () => handle.createWritable({ keepExistingData: true }),
236
355
  catch: (u) =>
237
- WebError.parseWebError(u, [
356
+ WebError.classifyWebError(u, [
238
357
  WebError.NotAllowedError,
239
358
  WebError.NotFoundError,
240
359
  WebError.NoModificationAllowedError,
@@ -245,33 +364,20 @@ export class Opfs extends Effect.Service<Opfs>()('@livestore/utils/Opfs', {
245
364
  Effect.tryPromise({
246
365
  try: () => stream.truncate(size),
247
366
  catch: (u) =>
248
- WebError.parseWebError(u, [WebError.NotAllowedError, WebError.TypeError, WebError.QuotaExceededError]),
367
+ WebError.classifyWebError(u, [WebError.NotAllowedError, WebError.TypeError, WebError.QuotaExceededError]),
249
368
  }),
250
369
  (stream) =>
251
370
  Effect.tryPromise({
252
371
  try: () => stream.close(),
253
- catch: (u) => WebError.parseWebError(u, [WebError.TypeError]),
254
- }).pipe(Effect.orElse(() => Effect.void)),
255
- )
256
-
257
- /**
258
- * Create a synchronous access handle for a file.
259
- *
260
- * @param handle - File handle to open.
261
- * @returns A managed handle that is automatically closed when released.
262
- *
263
- * @remarks
264
- * - Only available in Dedicated Web Workers.
265
- * - This method is asynchronous even though the `FileSystemSyncAccessHandle` APIs are synchronous.
266
- *
267
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle | MDN Reference}
268
- */
269
- const createSyncAccessHandle = (handle: FileSystemFileHandle) =>
372
+ catch: (u) => WebError.classifyWebError(u, [WebError.TypeError]),
373
+ }).pipe(Effect.catchCause(() => Effect.void)),
374
+ ),
375
+ createSyncAccessHandle: (handle: FileSystemFileHandle) =>
270
376
  Effect.acquireRelease(
271
377
  Effect.tryPromise({
272
378
  try: () => handle.createSyncAccessHandle(),
273
379
  catch: (u) =>
274
- WebError.parseWebError(u, [
380
+ WebError.classifyWebError(u, [
275
381
  WebError.NotAllowedError,
276
382
  WebError.InvalidStateError,
277
383
  WebError.NotFoundError,
@@ -279,125 +385,43 @@ export class Opfs extends Effect.Service<Opfs>()('@livestore/utils/Opfs', {
279
385
  ]),
280
386
  }),
281
387
  (syncHandle) => Effect.sync(() => syncHandle.close()),
282
- )
283
-
284
- /**
285
- * Perform a synchronous read into the provided buffer from a sync access handle.
286
- *
287
- * @param handle - Sync access handle to read from.
288
- * @param buffer - Destination buffer (can be a specific view like Uint8Array).
289
- * @param options - Read position options.
290
- * @returns Number of bytes read.
291
- *
292
- * @remarks
293
- * Only available in Dedicated Web Workers.
294
- *
295
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/read | MDN Reference}
296
- */
297
- const syncRead = (
388
+ ),
389
+ syncRead: (
298
390
  handle: FileSystemSyncAccessHandle,
299
391
  buffer: ArrayBuffer | ArrayBufferView,
300
392
  options?: FileSystemReadWriteOptions,
301
393
  ) =>
302
394
  Effect.try({
303
395
  try: () => handle.read(buffer, options),
304
- catch: (u) => WebError.parseWebError(u, [WebError.RangeError, WebError.InvalidStateError, WebError.TypeError]),
305
- })
306
-
307
- /**
308
- * Perform a synchronous write from the provided buffer into the file.
309
- *
310
- * @param handle - Sync access handle to write to.
311
- * @param buffer - Source data.
312
- * @param options - Write position options.
313
- * @returns Number of bytes written.
314
- *
315
- * @remarks
316
- * Only available in Dedicated Web Workers.
317
- *
318
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/write | MDN Reference}
319
- */
320
- const syncWrite = (
396
+ catch: (u) =>
397
+ WebError.classifyWebError(u, [WebError.RangeError, WebError.InvalidStateError, WebError.TypeError]),
398
+ }),
399
+ syncWrite: (
321
400
  handle: FileSystemSyncAccessHandle,
322
401
  buffer: AllowSharedBufferSource,
323
402
  options?: FileSystemReadWriteOptions,
324
403
  ) =>
325
404
  Effect.try({
326
405
  try: () => handle.write(buffer, options),
327
- catch: (u) => WebError.parseWebError(u),
328
- })
329
-
330
- /**
331
- * Truncate the file associated with a sync access handle to the specified size.
332
- *
333
- * @param handle - Sync access handle to mutate.
334
- * @param size - Desired byte length.
335
- *
336
- * @remarks
337
- * Only available in Dedicated Web Workers.
338
- *
339
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/truncate | MDN Reference}
340
- */
341
- const syncTruncate = (handle: FileSystemSyncAccessHandle, size: number) =>
406
+ catch: (u) => WebError.classifyWebError(u),
407
+ }),
408
+ syncTruncate: (handle: FileSystemSyncAccessHandle, size: number) =>
342
409
  Effect.try({
343
410
  try: () => handle.truncate(size),
344
- catch: (u) => WebError.parseWebError(u),
345
- })
346
-
347
- /**
348
- * Retrieve the current size of a file via its sync access handle.
349
- *
350
- * @param handle - Sync access handle.
351
- * @returns File size in bytes.
352
- *
353
- * @remarks
354
- * Only available in Dedicated Web Workers.
355
- *
356
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/getSize | MDN Reference}
357
- */
358
- const syncGetSize = (handle: FileSystemSyncAccessHandle) =>
411
+ catch: (u) => WebError.classifyWebError(u),
412
+ }),
413
+ syncGetSize: (handle: FileSystemSyncAccessHandle) =>
359
414
  Effect.try({
360
415
  try: () => handle.getSize(),
361
- catch: (u) => WebError.parseWebError(u),
362
- })
363
-
364
- /**
365
- * Flush pending synchronous writes to durable storage.
366
- *
367
- * @param handle - Sync access handle to flush.
368
- *
369
- * @remarks
370
- * Only available in Dedicated Web Workers.
371
- *
372
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/flush | MDN Reference}
373
- */
374
- const syncFlush = (handle: FileSystemSyncAccessHandle) =>
416
+ catch: (u) => WebError.classifyWebError(u),
417
+ }),
418
+ syncFlush: (handle: FileSystemSyncAccessHandle) =>
375
419
  Effect.try({
376
420
  try: () => handle.flush(),
377
- catch: (u) => WebError.parseWebError(u),
378
- })
379
-
380
- return {
381
- getRootDirectoryHandle,
382
- getFileHandle,
383
- getDirectoryHandle,
384
- removeEntry,
385
- values,
386
- resolve,
387
- getFile,
388
- writeFile,
389
- appendToFile,
390
- truncateFile,
391
- createSyncAccessHandle,
392
- syncRead,
393
- syncWrite,
394
- syncTruncate,
395
- syncGetSize,
396
- syncFlush,
397
- } as const
398
- },
399
- accessors: true,
400
- }) {}
421
+ catch: (u) => WebError.classifyWebError(u),
422
+ }),
423
+ }),
424
+ )
401
425
 
402
426
  const notFoundError = new WebError.NotFoundError({
403
427
  cause: new DOMException('The object can not be found here.', 'NotFoundError'),
@@ -408,29 +432,32 @@ const unknownError = (message: string) => new WebError.UnknownError({ descriptio
408
432
  /**
409
433
  * A no-op Opfs service that can be used for testing.
410
434
  */
411
- export const noopOpfs = new Opfs({
412
- getRootDirectoryHandle: Effect.fail(unknownError('OPFS is not supported in this environment')),
413
- getFileHandle: () => Effect.fail(notFoundError),
414
- getDirectoryHandle: () => Effect.fail(notFoundError),
415
- removeEntry: () => Effect.fail(notFoundError),
416
- values: () => Effect.fail(notFoundError),
417
- resolve: () => Effect.succeed(Option.none()),
418
- getFile: () => Effect.fail(notFoundError),
419
- writeFile: () => Effect.fail(notFoundError),
420
- appendToFile: () => Effect.fail(notFoundError),
421
- truncateFile: () => Effect.fail(notFoundError),
422
- createSyncAccessHandle: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
423
- syncRead: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
424
- syncWrite: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
425
- syncTruncate: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
426
- syncGetSize: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
427
- syncFlush: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
428
- })
435
+ export const layerNoop = Layer.succeed(
436
+ Opfs,
437
+ Opfs.of({
438
+ getRootDirectoryHandle: Effect.fail(unknownError('OPFS is not supported in this environment')),
439
+ getFileHandle: () => Effect.fail(notFoundError),
440
+ getDirectoryHandle: () => Effect.fail(notFoundError),
441
+ removeEntry: () => Effect.fail(notFoundError),
442
+ values: () => Stream.fail(notFoundError),
443
+ resolve: () => Effect.succeed(Option.none()),
444
+ getFile: () => Effect.fail(notFoundError),
445
+ writeFile: () => Effect.fail(notFoundError),
446
+ appendToFile: () => Effect.fail(notFoundError),
447
+ truncateFile: () => Effect.fail(notFoundError),
448
+ createSyncAccessHandle: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
449
+ syncRead: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
450
+ syncWrite: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
451
+ syncTruncate: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
452
+ syncGetSize: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
453
+ syncFlush: () => Effect.fail(unknownError('OPFS is not supported in this environment')),
454
+ }),
455
+ )
429
456
 
430
457
  /**
431
458
  * Error raised when OPFS operations fail.
432
459
  */
433
460
  export class OpfsError extends Schema.TaggedError<OpfsError>('~@livestore/utils/OpfsError')('OpfsError', {
434
461
  message: Schema.String,
435
- cause: Schema.optional(Schema.Defect),
462
+ cause: Schema.optional(Schema.Defect()),
436
463
  }) {}