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