@effect/platform-node-shared 0.57.1 → 4.0.0-beta.1

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 (218) hide show
  1. package/README.md +3 -3
  2. package/dist/NodeChildProcessSpawner.d.ts +37 -0
  3. package/dist/NodeChildProcessSpawner.d.ts.map +1 -0
  4. package/dist/NodeChildProcessSpawner.js +567 -0
  5. package/dist/NodeChildProcessSpawner.js.map +1 -0
  6. package/dist/{dts/NodeClusterSocket.d.ts → NodeClusterSocket.d.ts} +4 -7
  7. package/dist/NodeClusterSocket.d.ts.map +1 -0
  8. package/dist/{esm/NodeClusterSocket.js → NodeClusterSocket.js} +9 -10
  9. package/dist/NodeClusterSocket.js.map +1 -0
  10. package/dist/NodeFileSystem.d.ts +8 -0
  11. package/dist/NodeFileSystem.d.ts.map +1 -0
  12. package/dist/{esm/internal/fileSystem.js → NodeFileSystem.js} +125 -96
  13. package/dist/NodeFileSystem.js.map +1 -0
  14. package/dist/NodePath.d.ts +18 -0
  15. package/dist/NodePath.d.ts.map +1 -0
  16. package/dist/NodePath.js +56 -0
  17. package/dist/NodePath.js.map +1 -0
  18. package/dist/NodeRuntime.d.ts +28 -0
  19. package/dist/NodeRuntime.d.ts.map +1 -0
  20. package/dist/{esm/internal/runtime.js → NodeRuntime.js} +8 -8
  21. package/dist/NodeRuntime.js.map +1 -0
  22. package/dist/NodeSink.d.ts +40 -0
  23. package/dist/NodeSink.d.ts.map +1 -0
  24. package/dist/NodeSink.js +50 -0
  25. package/dist/NodeSink.js.map +1 -0
  26. package/dist/{dts/NodeSocket.d.ts → NodeSocket.d.ts} +10 -10
  27. package/dist/NodeSocket.d.ts.map +1 -0
  28. package/dist/{esm/NodeSocket.js → NodeSocket.js} +51 -39
  29. package/dist/NodeSocket.js.map +1 -0
  30. package/dist/{dts/NodeSocketServer.d.ts → NodeSocketServer.d.ts} +8 -10
  31. package/dist/NodeSocketServer.d.ts.map +1 -0
  32. package/dist/NodeSocketServer.js +192 -0
  33. package/dist/NodeSocketServer.js.map +1 -0
  34. package/dist/NodeStdio.d.ts +11 -0
  35. package/dist/NodeStdio.d.ts.map +1 -0
  36. package/dist/NodeStdio.js +43 -0
  37. package/dist/NodeStdio.js.map +1 -0
  38. package/dist/NodeStream.d.ts +127 -0
  39. package/dist/NodeStream.d.ts.map +1 -0
  40. package/dist/NodeStream.js +249 -0
  41. package/dist/NodeStream.js.map +1 -0
  42. package/dist/NodeTerminal.d.ts +15 -0
  43. package/dist/NodeTerminal.d.ts.map +1 -0
  44. package/dist/{esm/internal/terminal.js → NodeTerminal.js} +28 -25
  45. package/dist/NodeTerminal.js.map +1 -0
  46. package/dist/internal/utils.d.ts +2 -0
  47. package/dist/internal/utils.d.ts.map +1 -0
  48. package/dist/{esm/internal/error.js → internal/utils.js} +4 -5
  49. package/dist/internal/utils.js.map +1 -0
  50. package/package.json +53 -124
  51. package/src/NodeChildProcessSpawner.ts +713 -0
  52. package/src/NodeClusterSocket.ts +12 -13
  53. package/src/NodeFileSystem.ts +632 -5
  54. package/src/NodePath.ts +48 -9
  55. package/src/NodeRuntime.ts +53 -4
  56. package/src/NodeSink.ts +65 -62
  57. package/src/NodeSocket.ts +65 -49
  58. package/src/NodeSocketServer.ts +108 -88
  59. package/src/NodeStdio.ts +49 -0
  60. package/src/NodeStream.ts +324 -83
  61. package/src/NodeTerminal.ts +100 -9
  62. package/src/internal/{error.ts → utils.ts} +6 -7
  63. package/NodeClusterSocket/package.json +0 -6
  64. package/NodeCommandExecutor/package.json +0 -6
  65. package/NodeFileSystem/ParcelWatcher/package.json +0 -6
  66. package/NodeFileSystem/package.json +0 -6
  67. package/NodeKeyValueStore/package.json +0 -6
  68. package/NodeMultipart/package.json +0 -6
  69. package/NodePath/package.json +0 -6
  70. package/NodeRuntime/package.json +0 -6
  71. package/NodeSink/package.json +0 -6
  72. package/NodeSocket/package.json +0 -6
  73. package/NodeSocketServer/package.json +0 -6
  74. package/NodeStream/package.json +0 -6
  75. package/NodeTerminal/package.json +0 -6
  76. package/dist/cjs/NodeClusterSocket.js +0 -50
  77. package/dist/cjs/NodeClusterSocket.js.map +0 -1
  78. package/dist/cjs/NodeCommandExecutor.js +0 -14
  79. package/dist/cjs/NodeCommandExecutor.js.map +0 -1
  80. package/dist/cjs/NodeFileSystem/ParcelWatcher.js +0 -20
  81. package/dist/cjs/NodeFileSystem/ParcelWatcher.js.map +0 -1
  82. package/dist/cjs/NodeFileSystem.js +0 -18
  83. package/dist/cjs/NodeFileSystem.js.map +0 -1
  84. package/dist/cjs/NodeKeyValueStore.js +0 -18
  85. package/dist/cjs/NodeKeyValueStore.js.map +0 -1
  86. package/dist/cjs/NodeMultipart.js +0 -24
  87. package/dist/cjs/NodeMultipart.js.map +0 -1
  88. package/dist/cjs/NodePath.js +0 -28
  89. package/dist/cjs/NodePath.js.map +0 -1
  90. package/dist/cjs/NodeRuntime.js +0 -14
  91. package/dist/cjs/NodeRuntime.js.map +0 -1
  92. package/dist/cjs/NodeSink.js +0 -50
  93. package/dist/cjs/NodeSink.js.map +0 -1
  94. package/dist/cjs/NodeSocket.js +0 -153
  95. package/dist/cjs/NodeSocket.js.map +0 -1
  96. package/dist/cjs/NodeSocketServer.js +0 -178
  97. package/dist/cjs/NodeSocketServer.js.map +0 -1
  98. package/dist/cjs/NodeStream.js +0 -76
  99. package/dist/cjs/NodeStream.js.map +0 -1
  100. package/dist/cjs/NodeTerminal.js +0 -19
  101. package/dist/cjs/NodeTerminal.js.map +0 -1
  102. package/dist/cjs/internal/commandExecutor.js +0 -153
  103. package/dist/cjs/internal/commandExecutor.js.map +0 -1
  104. package/dist/cjs/internal/error.js +0 -45
  105. package/dist/cjs/internal/error.js.map +0 -1
  106. package/dist/cjs/internal/fileSystem/parcelWatcher.js +0 -68
  107. package/dist/cjs/internal/fileSystem/parcelWatcher.js.map +0 -1
  108. package/dist/cjs/internal/fileSystem.js +0 -400
  109. package/dist/cjs/internal/fileSystem.js.map +0 -1
  110. package/dist/cjs/internal/multipart.js +0 -147
  111. package/dist/cjs/internal/multipart.js.map +0 -1
  112. package/dist/cjs/internal/path.js +0 -53
  113. package/dist/cjs/internal/path.js.map +0 -1
  114. package/dist/cjs/internal/runtime.js +0 -37
  115. package/dist/cjs/internal/runtime.js.map +0 -1
  116. package/dist/cjs/internal/sink.js +0 -28
  117. package/dist/cjs/internal/sink.js.map +0 -1
  118. package/dist/cjs/internal/stream.js +0 -233
  119. package/dist/cjs/internal/stream.js.map +0 -1
  120. package/dist/cjs/internal/terminal.js +0 -90
  121. package/dist/cjs/internal/terminal.js.map +0 -1
  122. package/dist/dts/NodeClusterSocket.d.ts.map +0 -1
  123. package/dist/dts/NodeCommandExecutor.d.ts +0 -12
  124. package/dist/dts/NodeCommandExecutor.d.ts.map +0 -1
  125. package/dist/dts/NodeFileSystem/ParcelWatcher.d.ts +0 -13
  126. package/dist/dts/NodeFileSystem/ParcelWatcher.d.ts.map +0 -1
  127. package/dist/dts/NodeFileSystem.d.ts +0 -11
  128. package/dist/dts/NodeFileSystem.d.ts.map +0 -1
  129. package/dist/dts/NodeKeyValueStore.d.ts +0 -12
  130. package/dist/dts/NodeKeyValueStore.d.ts.map +0 -1
  131. package/dist/dts/NodeMultipart.d.ts +0 -27
  132. package/dist/dts/NodeMultipart.d.ts.map +0 -1
  133. package/dist/dts/NodePath.d.ts +0 -21
  134. package/dist/dts/NodePath.d.ts.map +0 -1
  135. package/dist/dts/NodeRuntime.d.ts +0 -10
  136. package/dist/dts/NodeRuntime.d.ts.map +0 -1
  137. package/dist/dts/NodeSink.d.ts +0 -36
  138. package/dist/dts/NodeSink.d.ts.map +0 -1
  139. package/dist/dts/NodeSocket.d.ts.map +0 -1
  140. package/dist/dts/NodeSocketServer.d.ts.map +0 -1
  141. package/dist/dts/NodeStream.d.ts +0 -119
  142. package/dist/dts/NodeStream.d.ts.map +0 -1
  143. package/dist/dts/NodeTerminal.d.ts +0 -18
  144. package/dist/dts/NodeTerminal.d.ts.map +0 -1
  145. package/dist/dts/internal/commandExecutor.d.ts +0 -2
  146. package/dist/dts/internal/commandExecutor.d.ts.map +0 -1
  147. package/dist/dts/internal/error.d.ts +0 -2
  148. package/dist/dts/internal/error.d.ts.map +0 -1
  149. package/dist/dts/internal/fileSystem/parcelWatcher.d.ts +0 -4
  150. package/dist/dts/internal/fileSystem/parcelWatcher.d.ts.map +0 -1
  151. package/dist/dts/internal/fileSystem.d.ts +0 -2
  152. package/dist/dts/internal/fileSystem.d.ts.map +0 -1
  153. package/dist/dts/internal/multipart.d.ts +0 -2
  154. package/dist/dts/internal/multipart.d.ts.map +0 -1
  155. package/dist/dts/internal/path.d.ts +0 -2
  156. package/dist/dts/internal/path.d.ts.map +0 -1
  157. package/dist/dts/internal/runtime.d.ts +0 -2
  158. package/dist/dts/internal/runtime.d.ts.map +0 -1
  159. package/dist/dts/internal/sink.d.ts +0 -2
  160. package/dist/dts/internal/sink.d.ts.map +0 -1
  161. package/dist/dts/internal/stream.d.ts +0 -2
  162. package/dist/dts/internal/stream.d.ts.map +0 -1
  163. package/dist/dts/internal/terminal.d.ts +0 -2
  164. package/dist/dts/internal/terminal.d.ts.map +0 -1
  165. package/dist/esm/NodeClusterSocket.js.map +0 -1
  166. package/dist/esm/NodeCommandExecutor.js +0 -7
  167. package/dist/esm/NodeCommandExecutor.js.map +0 -1
  168. package/dist/esm/NodeFileSystem/ParcelWatcher.js +0 -12
  169. package/dist/esm/NodeFileSystem/ParcelWatcher.js.map +0 -1
  170. package/dist/esm/NodeFileSystem.js +0 -10
  171. package/dist/esm/NodeFileSystem.js.map +0 -1
  172. package/dist/esm/NodeKeyValueStore.js +0 -10
  173. package/dist/esm/NodeKeyValueStore.js.map +0 -1
  174. package/dist/esm/NodeMultipart.js +0 -17
  175. package/dist/esm/NodeMultipart.js.map +0 -1
  176. package/dist/esm/NodePath.js +0 -20
  177. package/dist/esm/NodePath.js.map +0 -1
  178. package/dist/esm/NodeRuntime.js +0 -7
  179. package/dist/esm/NodeRuntime.js.map +0 -1
  180. package/dist/esm/NodeSink.js +0 -43
  181. package/dist/esm/NodeSink.js.map +0 -1
  182. package/dist/esm/NodeSocket.js.map +0 -1
  183. package/dist/esm/NodeSocketServer.js +0 -167
  184. package/dist/esm/NodeSocketServer.js.map +0 -1
  185. package/dist/esm/NodeStream.js +0 -69
  186. package/dist/esm/NodeStream.js.map +0 -1
  187. package/dist/esm/NodeTerminal.js +0 -12
  188. package/dist/esm/NodeTerminal.js.map +0 -1
  189. package/dist/esm/internal/commandExecutor.js +0 -146
  190. package/dist/esm/internal/commandExecutor.js.map +0 -1
  191. package/dist/esm/internal/error.js.map +0 -1
  192. package/dist/esm/internal/fileSystem/parcelWatcher.js +0 -61
  193. package/dist/esm/internal/fileSystem/parcelWatcher.js.map +0 -1
  194. package/dist/esm/internal/fileSystem.js.map +0 -1
  195. package/dist/esm/internal/multipart.js +0 -137
  196. package/dist/esm/internal/multipart.js.map +0 -1
  197. package/dist/esm/internal/path.js +0 -46
  198. package/dist/esm/internal/path.js.map +0 -1
  199. package/dist/esm/internal/runtime.js.map +0 -1
  200. package/dist/esm/internal/sink.js +0 -19
  201. package/dist/esm/internal/sink.js.map +0 -1
  202. package/dist/esm/internal/stream.js +0 -217
  203. package/dist/esm/internal/stream.js.map +0 -1
  204. package/dist/esm/internal/terminal.js.map +0 -1
  205. package/dist/esm/package.json +0 -4
  206. package/src/NodeCommandExecutor.ts +0 -13
  207. package/src/NodeFileSystem/ParcelWatcher.ts +0 -15
  208. package/src/NodeKeyValueStore.ts +0 -20
  209. package/src/NodeMultipart.ts +0 -40
  210. package/src/internal/commandExecutor.ts +0 -251
  211. package/src/internal/fileSystem/parcelWatcher.ts +0 -64
  212. package/src/internal/fileSystem.ts +0 -648
  213. package/src/internal/multipart.ts +0 -141
  214. package/src/internal/path.ts +0 -63
  215. package/src/internal/runtime.ts +0 -34
  216. package/src/internal/sink.ts +0 -57
  217. package/src/internal/stream.ts +0 -375
  218. package/src/internal/terminal.ts +0 -104
@@ -1,648 +0,0 @@
1
- import { effectify } from "@effect/platform/Effectify"
2
- import * as Error from "@effect/platform/Error"
3
- import * as FileSystem from "@effect/platform/FileSystem"
4
- import type * as Context from "effect/Context"
5
- import * as Effect from "effect/Effect"
6
- import { pipe } from "effect/Function"
7
- import * as Layer from "effect/Layer"
8
- import * as Option from "effect/Option"
9
- import * as Stream from "effect/Stream"
10
- import * as Crypto from "node:crypto"
11
- import * as NFS from "node:fs"
12
- import * as OS from "node:os"
13
- import * as Path from "node:path"
14
- import { handleErrnoException } from "./error.js"
15
-
16
- const handleBadArgument = (method: string) => (cause: unknown) =>
17
- new Error.BadArgument({
18
- module: "FileSystem",
19
- method,
20
- cause
21
- })
22
-
23
- // == access
24
-
25
- const access = (() => {
26
- const nodeAccess = effectify(
27
- NFS.access,
28
- handleErrnoException("FileSystem", "access"),
29
- handleBadArgument("access")
30
- )
31
- return (path: string, options?: FileSystem.AccessFileOptions) => {
32
- let mode = NFS.constants.F_OK
33
- if (options?.readable) {
34
- mode |= NFS.constants.R_OK
35
- }
36
- if (options?.writable) {
37
- mode |= NFS.constants.W_OK
38
- }
39
- return nodeAccess(path, mode)
40
- }
41
- })()
42
-
43
- // == copy
44
-
45
- const copy = (() => {
46
- const nodeCp = effectify(
47
- NFS.cp,
48
- handleErrnoException("FileSystem", "copy"),
49
- handleBadArgument("copy")
50
- )
51
- return (fromPath: string, toPath: string, options?: FileSystem.CopyOptions) =>
52
- nodeCp(fromPath, toPath, {
53
- force: options?.overwrite ?? false,
54
- preserveTimestamps: options?.preserveTimestamps ?? false,
55
- recursive: true
56
- })
57
- })()
58
-
59
- // == copyFile
60
-
61
- const copyFile = (() => {
62
- const nodeCopyFile = effectify(
63
- NFS.copyFile,
64
- handleErrnoException("FileSystem", "copyFile"),
65
- handleBadArgument("copyFile")
66
- )
67
- return (fromPath: string, toPath: string) => nodeCopyFile(fromPath, toPath)
68
- })()
69
-
70
- // == chmod
71
-
72
- const chmod = (() => {
73
- const nodeChmod = effectify(
74
- NFS.chmod,
75
- handleErrnoException("FileSystem", "chmod"),
76
- handleBadArgument("chmod")
77
- )
78
- return (path: string, mode: number) => nodeChmod(path, mode)
79
- })()
80
-
81
- // == chown
82
-
83
- const chown = (() => {
84
- const nodeChown = effectify(
85
- NFS.chown,
86
- handleErrnoException("FileSystem", "chown"),
87
- handleBadArgument("chown")
88
- )
89
- return (path: string, uid: number, gid: number) => nodeChown(path, uid, gid)
90
- })()
91
-
92
- // == link
93
-
94
- const link = (() => {
95
- const nodeLink = effectify(
96
- NFS.link,
97
- handleErrnoException("FileSystem", "link"),
98
- handleBadArgument("link")
99
- )
100
- return (existingPath: string, newPath: string) => nodeLink(existingPath, newPath)
101
- })()
102
-
103
- // == makeDirectory
104
-
105
- const makeDirectory = (() => {
106
- const nodeMkdir = effectify(
107
- NFS.mkdir,
108
- handleErrnoException("FileSystem", "makeDirectory"),
109
- handleBadArgument("makeDirectory")
110
- )
111
- return (path: string, options?: FileSystem.MakeDirectoryOptions) =>
112
- nodeMkdir(path, {
113
- recursive: options?.recursive ?? false,
114
- mode: options?.mode
115
- })
116
- })()
117
-
118
- // == makeTempDirectory
119
-
120
- const makeTempDirectoryFactory = (method: string) => {
121
- const nodeMkdtemp = effectify(
122
- NFS.mkdtemp,
123
- handleErrnoException("FileSystem", method),
124
- handleBadArgument(method)
125
- )
126
- return (options?: FileSystem.MakeTempDirectoryOptions) =>
127
- Effect.suspend(() => {
128
- const prefix = options?.prefix ?? ""
129
- const directory = typeof options?.directory === "string"
130
- ? Path.join(options.directory, ".")
131
- : OS.tmpdir()
132
-
133
- return nodeMkdtemp(prefix ? Path.join(directory, prefix) : directory + "/")
134
- })
135
- }
136
- const makeTempDirectory = makeTempDirectoryFactory("makeTempDirectory")
137
-
138
- // == remove
139
-
140
- const removeFactory = (method: string) => {
141
- const nodeRm = effectify(
142
- NFS.rm,
143
- handleErrnoException("FileSystem", method),
144
- handleBadArgument(method)
145
- )
146
- return (path: string, options?: FileSystem.RemoveOptions) =>
147
- nodeRm(
148
- path,
149
- { recursive: options?.recursive ?? false, force: options?.force ?? false }
150
- )
151
- }
152
- const remove = removeFactory("remove")
153
-
154
- // == makeTempDirectoryScoped
155
-
156
- const makeTempDirectoryScoped = (() => {
157
- const makeDirectory = makeTempDirectoryFactory("makeTempDirectoryScoped")
158
- const removeDirectory = removeFactory("makeTempDirectoryScoped")
159
- return (
160
- options?: FileSystem.MakeTempDirectoryOptions
161
- ) =>
162
- Effect.acquireRelease(
163
- makeDirectory(options),
164
- (directory) => Effect.orDie(removeDirectory(directory, { recursive: true }))
165
- )
166
- })()
167
-
168
- // == open
169
-
170
- const openFactory = (method: string) => {
171
- const nodeOpen = effectify(
172
- NFS.open,
173
- handleErrnoException("FileSystem", method),
174
- handleBadArgument(method)
175
- )
176
- const nodeClose = effectify(
177
- NFS.close,
178
- handleErrnoException("FileSystem", method),
179
- handleBadArgument(method)
180
- )
181
-
182
- return (path: string, options?: FileSystem.OpenFileOptions) =>
183
- pipe(
184
- Effect.acquireRelease(
185
- nodeOpen(path, options?.flag ?? "r", options?.mode),
186
- (fd) => Effect.orDie(nodeClose(fd))
187
- ),
188
- Effect.map((fd) => makeFile(FileSystem.FileDescriptor(fd), options?.flag?.startsWith("a") ?? false))
189
- )
190
- }
191
- const open = openFactory("open")
192
-
193
- const makeFile = (() => {
194
- const nodeReadFactory = (method: string) =>
195
- effectify(
196
- NFS.read,
197
- handleErrnoException("FileSystem", method),
198
- handleBadArgument(method)
199
- )
200
- const nodeRead = nodeReadFactory("read")
201
- const nodeReadAlloc = nodeReadFactory("readAlloc")
202
- const nodeStat = effectify(
203
- NFS.fstat,
204
- handleErrnoException("FileSystem", "stat"),
205
- handleBadArgument("stat")
206
- )
207
- const nodeTruncate = effectify(
208
- NFS.ftruncate,
209
- handleErrnoException("FileSystem", "truncate"),
210
- handleBadArgument("truncate")
211
- )
212
-
213
- const nodeSync = effectify(
214
- NFS.fsync,
215
- handleErrnoException("FileSystem", "sync"),
216
- handleBadArgument("sync")
217
- )
218
-
219
- const nodeWriteFactory = (method: string) =>
220
- effectify(
221
- NFS.write,
222
- handleErrnoException("FileSystem", method),
223
- handleBadArgument(method)
224
- )
225
- const nodeWrite = nodeWriteFactory("write")
226
- const nodeWriteAll = nodeWriteFactory("writeAll")
227
-
228
- class FileImpl implements FileSystem.File {
229
- readonly [FileSystem.FileTypeId]: FileSystem.FileTypeId
230
-
231
- private readonly semaphore = Effect.unsafeMakeSemaphore(1)
232
- private position: bigint = 0n
233
-
234
- constructor(
235
- readonly fd: FileSystem.File.Descriptor,
236
- private readonly append: boolean
237
- ) {
238
- this[FileSystem.FileTypeId] = FileSystem.FileTypeId
239
- }
240
-
241
- get stat() {
242
- return Effect.map(nodeStat(this.fd), makeFileInfo)
243
- }
244
-
245
- get sync() {
246
- return nodeSync(this.fd)
247
- }
248
-
249
- seek(offset: FileSystem.SizeInput, from: FileSystem.SeekMode) {
250
- const offsetSize = FileSystem.Size(offset)
251
- return this.semaphore.withPermits(1)(
252
- Effect.sync(() => {
253
- if (from === "start") {
254
- this.position = offsetSize
255
- } else if (from === "current") {
256
- this.position = this.position + offsetSize
257
- }
258
-
259
- return this.position
260
- })
261
- )
262
- }
263
-
264
- read(buffer: Uint8Array) {
265
- return this.semaphore.withPermits(1)(
266
- Effect.map(
267
- Effect.suspend(() =>
268
- nodeRead(this.fd, {
269
- buffer,
270
- position: this.position
271
- })
272
- ),
273
- (bytesRead) => {
274
- const sizeRead = FileSystem.Size(bytesRead)
275
- this.position = this.position + sizeRead
276
- return sizeRead
277
- }
278
- )
279
- )
280
- }
281
-
282
- readAlloc(size: FileSystem.SizeInput) {
283
- const sizeNumber = Number(size)
284
- return this.semaphore.withPermits(1)(Effect.flatMap(
285
- Effect.sync(() => Buffer.allocUnsafeSlow(sizeNumber)),
286
- (buffer) =>
287
- Effect.map(
288
- nodeReadAlloc(this.fd, {
289
- buffer,
290
- position: this.position
291
- }),
292
- (bytesRead): Option.Option<Buffer> => {
293
- if (bytesRead === 0) {
294
- return Option.none()
295
- }
296
-
297
- this.position = this.position + BigInt(bytesRead)
298
- if (bytesRead === sizeNumber) {
299
- return Option.some(buffer)
300
- }
301
-
302
- const dst = Buffer.allocUnsafeSlow(bytesRead)
303
- buffer.copy(dst, 0, 0, bytesRead)
304
- return Option.some(dst)
305
- }
306
- )
307
- ))
308
- }
309
-
310
- truncate(length?: FileSystem.SizeInput) {
311
- return this.semaphore.withPermits(1)(
312
- Effect.map(nodeTruncate(this.fd, length ? Number(length) : undefined), () => {
313
- if (!this.append) {
314
- const len = BigInt(length ?? 0)
315
- if (this.position > len) {
316
- this.position = len
317
- }
318
- }
319
- })
320
- )
321
- }
322
-
323
- write(buffer: Uint8Array) {
324
- return this.semaphore.withPermits(1)(
325
- Effect.map(
326
- Effect.suspend(() =>
327
- nodeWrite(this.fd, buffer, undefined, undefined, this.append ? undefined : Number(this.position))
328
- ),
329
- (bytesWritten) => {
330
- const sizeWritten = FileSystem.Size(bytesWritten)
331
- if (!this.append) {
332
- this.position = this.position + sizeWritten
333
- }
334
-
335
- return sizeWritten
336
- }
337
- )
338
- )
339
- }
340
-
341
- private writeAllChunk(buffer: Uint8Array): Effect.Effect<void, Error.PlatformError> {
342
- return Effect.flatMap(
343
- Effect.suspend(() =>
344
- nodeWriteAll(this.fd, buffer, undefined, undefined, this.append ? undefined : Number(this.position))
345
- ),
346
- (bytesWritten) => {
347
- if (bytesWritten === 0) {
348
- return Effect.fail(
349
- new Error.SystemError({
350
- module: "FileSystem",
351
- method: "writeAll",
352
- reason: "WriteZero",
353
- pathOrDescriptor: this.fd,
354
- description: "write returned 0 bytes written"
355
- })
356
- )
357
- }
358
-
359
- if (!this.append) {
360
- this.position = this.position + BigInt(bytesWritten)
361
- }
362
-
363
- return bytesWritten < buffer.length ? this.writeAllChunk(buffer.subarray(bytesWritten)) : Effect.void
364
- }
365
- )
366
- }
367
-
368
- writeAll(buffer: Uint8Array) {
369
- return this.semaphore.withPermits(1)(this.writeAllChunk(buffer))
370
- }
371
- }
372
-
373
- return (fd: FileSystem.File.Descriptor, append: boolean): FileSystem.File => new FileImpl(fd, append)
374
- })()
375
-
376
- // == makeTempFile
377
-
378
- const makeTempFileFactory = (method: string) => {
379
- const makeDirectory = makeTempDirectoryFactory(method)
380
- const open = openFactory(method)
381
- const randomHexString = (bytes: number) => Effect.sync(() => Crypto.randomBytes(bytes).toString("hex"))
382
- return (options?: FileSystem.MakeTempFileOptions) =>
383
- pipe(
384
- Effect.zip(makeDirectory(options), randomHexString(6)),
385
- Effect.map(([directory, random]) => Path.join(directory, random + (options?.suffix ?? ""))),
386
- Effect.tap((path) => Effect.scoped(open(path, { flag: "w+" })))
387
- )
388
- }
389
- const makeTempFile = makeTempFileFactory("makeTempFile")
390
-
391
- // == makeTempFileScoped
392
-
393
- const makeTempFileScoped = (() => {
394
- const makeFile = makeTempFileFactory("makeTempFileScoped")
395
- const removeDirectory = removeFactory("makeTempFileScoped")
396
- return (options?: FileSystem.MakeTempFileOptions) =>
397
- Effect.acquireRelease(
398
- makeFile(options),
399
- (file) => Effect.orDie(removeDirectory(Path.dirname(file), { recursive: true }))
400
- )
401
- })()
402
-
403
- // == readDirectory
404
-
405
- const readDirectory = (path: string, options?: FileSystem.ReadDirectoryOptions) =>
406
- Effect.tryPromise({
407
- try: () => NFS.promises.readdir(path, options),
408
- catch: (err) => handleErrnoException("FileSystem", "readDirectory")(err as any, [path])
409
- })
410
-
411
- // == readFile
412
-
413
- const readFile = (path: string) =>
414
- Effect.async<Uint8Array, Error.PlatformError>((resume, signal) => {
415
- try {
416
- NFS.readFile(path, { signal }, (err, data) => {
417
- if (err) {
418
- resume(Effect.fail(handleErrnoException("FileSystem", "readFile")(err, [path])))
419
- } else {
420
- resume(Effect.succeed(data))
421
- }
422
- })
423
- } catch (err) {
424
- resume(Effect.fail(handleBadArgument("readFile")(err)))
425
- }
426
- })
427
-
428
- // == readLink
429
-
430
- const readLink = (() => {
431
- const nodeReadLink = effectify(
432
- NFS.readlink,
433
- handleErrnoException("FileSystem", "readLink"),
434
- handleBadArgument("readLink")
435
- )
436
- return (path: string) => nodeReadLink(path)
437
- })()
438
-
439
- // == realPath
440
-
441
- const realPath = (() => {
442
- const nodeRealPath = effectify(
443
- NFS.realpath,
444
- handleErrnoException("FileSystem", "realPath"),
445
- handleBadArgument("realPath")
446
- )
447
- return (path: string) => nodeRealPath(path)
448
- })()
449
-
450
- // == rename
451
-
452
- const rename = (() => {
453
- const nodeRename = effectify(
454
- NFS.rename,
455
- handleErrnoException("FileSystem", "rename"),
456
- handleBadArgument("rename")
457
- )
458
- return (oldPath: string, newPath: string) => nodeRename(oldPath, newPath)
459
- })()
460
-
461
- // == stat
462
-
463
- const makeFileInfo = (stat: NFS.Stats): FileSystem.File.Info => ({
464
- type: stat.isFile() ?
465
- "File" :
466
- stat.isDirectory() ?
467
- "Directory" :
468
- stat.isSymbolicLink() ?
469
- "SymbolicLink" :
470
- stat.isBlockDevice() ?
471
- "BlockDevice" :
472
- stat.isCharacterDevice() ?
473
- "CharacterDevice" :
474
- stat.isFIFO() ?
475
- "FIFO" :
476
- stat.isSocket() ?
477
- "Socket" :
478
- "Unknown",
479
- mtime: Option.fromNullable(stat.mtime),
480
- atime: Option.fromNullable(stat.atime),
481
- birthtime: Option.fromNullable(stat.birthtime),
482
- dev: stat.dev,
483
- rdev: Option.fromNullable(stat.rdev),
484
- ino: Option.fromNullable(stat.ino),
485
- mode: stat.mode,
486
- nlink: Option.fromNullable(stat.nlink),
487
- uid: Option.fromNullable(stat.uid),
488
- gid: Option.fromNullable(stat.gid),
489
- size: FileSystem.Size(stat.size),
490
- blksize: Option.map(Option.fromNullable(stat.blksize), FileSystem.Size),
491
- blocks: Option.fromNullable(stat.blocks)
492
- })
493
- const stat = (() => {
494
- const nodeStat = effectify(
495
- NFS.stat,
496
- handleErrnoException("FileSystem", "stat"),
497
- handleBadArgument("stat")
498
- )
499
- return (path: string) => Effect.map(nodeStat(path), makeFileInfo)
500
- })()
501
-
502
- // == symlink
503
-
504
- const symlink = (() => {
505
- const nodeSymlink = effectify(
506
- NFS.symlink,
507
- handleErrnoException("FileSystem", "symlink"),
508
- handleBadArgument("symlink")
509
- )
510
- return (target: string, path: string) => nodeSymlink(target, path)
511
- })()
512
-
513
- // == truncate
514
-
515
- const truncate = (() => {
516
- const nodeTruncate = effectify(
517
- NFS.truncate,
518
- handleErrnoException("FileSystem", "truncate"),
519
- handleBadArgument("truncate")
520
- )
521
- return (path: string, length?: FileSystem.SizeInput) =>
522
- nodeTruncate(path, length !== undefined ? Number(length) : undefined)
523
- })()
524
-
525
- // == utimes
526
-
527
- const utimes = (() => {
528
- const nodeUtimes = effectify(
529
- NFS.utimes,
530
- handleErrnoException("FileSystem", "utime"),
531
- handleBadArgument("utime")
532
- )
533
- return (path: string, atime: number | Date, mtime: number | Date) => nodeUtimes(path, atime, mtime)
534
- })()
535
-
536
- // == watch
537
-
538
- const watchNode = (path: string, options?: FileSystem.WatchOptions) =>
539
- Stream.asyncScoped<FileSystem.WatchEvent, Error.PlatformError>((emit) =>
540
- Effect.acquireRelease(
541
- Effect.sync(() => {
542
- const watcher = NFS.watch(path, { recursive: options?.recursive }, (event, path) => {
543
- if (!path) return
544
- switch (event) {
545
- case "rename": {
546
- emit.fromEffect(Effect.matchEffect(stat(path), {
547
- onSuccess: (_) => Effect.succeed(FileSystem.WatchEventCreate({ path })),
548
- onFailure: (err) =>
549
- err._tag === "SystemError" && err.reason === "NotFound"
550
- ? Effect.succeed(FileSystem.WatchEventRemove({ path }))
551
- : Effect.fail(err)
552
- }))
553
- return
554
- }
555
- case "change": {
556
- emit.single(FileSystem.WatchEventUpdate({ path }))
557
- return
558
- }
559
- }
560
- })
561
- watcher.on("error", (error) => {
562
- emit.fail(
563
- new Error.SystemError({
564
- module: "FileSystem",
565
- reason: "Unknown",
566
- method: "watch",
567
- pathOrDescriptor: path,
568
- cause: error
569
- })
570
- )
571
- })
572
- watcher.on("close", () => {
573
- emit.end()
574
- })
575
- return watcher
576
- }),
577
- (watcher) => Effect.sync(() => watcher.close())
578
- )
579
- )
580
-
581
- const watch = (
582
- backend: Option.Option<Context.Tag.Service<FileSystem.WatchBackend>>,
583
- path: string,
584
- options?: FileSystem.WatchOptions
585
- ) =>
586
- stat(path).pipe(
587
- Effect.map((stat) =>
588
- backend.pipe(
589
- Option.flatMap((_) => _.register(path, stat, options)),
590
- Option.getOrElse(() => watchNode(path, options))
591
- )
592
- ),
593
- Stream.unwrap
594
- )
595
-
596
- // == writeFile
597
-
598
- const writeFile = (path: string, data: Uint8Array, options?: FileSystem.WriteFileOptions) =>
599
- Effect.async<void, Error.PlatformError>((resume, signal) => {
600
- try {
601
- NFS.writeFile(path, data, {
602
- signal,
603
- flag: options?.flag,
604
- mode: options?.mode
605
- }, (err) => {
606
- if (err) {
607
- resume(Effect.fail(handleErrnoException("FileSystem", "writeFile")(err, [path])))
608
- } else {
609
- resume(Effect.void)
610
- }
611
- })
612
- } catch (err) {
613
- resume(Effect.fail(handleBadArgument("writeFile")(err)))
614
- }
615
- })
616
-
617
- const makeFileSystem = Effect.map(Effect.serviceOption(FileSystem.WatchBackend), (backend) =>
618
- FileSystem.make({
619
- access,
620
- chmod,
621
- chown,
622
- copy,
623
- copyFile,
624
- link,
625
- makeDirectory,
626
- makeTempDirectory,
627
- makeTempDirectoryScoped,
628
- makeTempFile,
629
- makeTempFileScoped,
630
- open,
631
- readDirectory,
632
- readFile,
633
- readLink,
634
- realPath,
635
- remove,
636
- rename,
637
- stat,
638
- symlink,
639
- truncate,
640
- utimes,
641
- watch(path, options) {
642
- return watch(backend, path, options)
643
- },
644
- writeFile
645
- }))
646
-
647
- /** @internal */
648
- export const layer = Layer.effect(FileSystem.FileSystem, makeFileSystem)