effect-start 0.17.2 → 0.19.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.
- package/dist/Development.d.ts +7 -2
- package/dist/Development.js +12 -6
- package/dist/PlatformRuntime.d.ts +4 -0
- package/dist/PlatformRuntime.js +9 -0
- package/dist/Route.d.ts +6 -2
- package/dist/Route.js +22 -0
- package/dist/RouteHttp.d.ts +1 -1
- package/dist/RouteHttp.js +12 -19
- package/dist/RouteMount.d.ts +2 -1
- package/dist/Start.d.ts +1 -5
- package/dist/Start.js +1 -8
- package/dist/Unique.d.ts +50 -0
- package/dist/Unique.js +187 -0
- package/dist/bun/BunHttpServer.js +5 -6
- package/dist/bun/BunRoute.d.ts +1 -1
- package/dist/bun/BunRoute.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/node/Effectify.d.ts +209 -0
- package/dist/node/Effectify.js +19 -0
- package/dist/node/FileSystem.d.ts +3 -5
- package/dist/node/FileSystem.js +42 -62
- package/dist/node/PlatformError.d.ts +46 -0
- package/dist/node/PlatformError.js +43 -0
- package/dist/testing/TestLogger.js +1 -1
- package/package.json +10 -5
- package/src/Development.ts +13 -18
- package/src/PlatformRuntime.ts +11 -0
- package/src/Route.ts +31 -2
- package/src/RouteHttp.ts +15 -31
- package/src/RouteMount.ts +1 -1
- package/src/Start.ts +1 -15
- package/src/Unique.ts +232 -0
- package/src/bun/BunHttpServer.ts +6 -9
- package/src/bun/BunRoute.ts +3 -3
- package/src/index.ts +1 -0
- package/src/node/Effectify.ts +262 -0
- package/src/node/FileSystem.ts +59 -97
- package/src/node/PlatformError.ts +102 -0
- package/src/testing/TestLogger.ts +1 -1
- package/dist/Random.d.ts +0 -5
- package/dist/Random.js +0 -49
- package/src/Commander.test.ts +0 -1639
- package/src/ContentNegotiation.test.ts +0 -603
- package/src/Development.test.ts +0 -119
- package/src/Entity.test.ts +0 -592
- package/src/FileRouterPattern.test.ts +0 -147
- package/src/FileRouter_files.test.ts +0 -64
- package/src/FileRouter_path.test.ts +0 -145
- package/src/FileRouter_tree.test.ts +0 -132
- package/src/Http.test.ts +0 -319
- package/src/HttpAppExtra.test.ts +0 -103
- package/src/HttpUtils.test.ts +0 -85
- package/src/PathPattern.test.ts +0 -648
- package/src/Random.ts +0 -59
- package/src/RouteBody.test.ts +0 -232
- package/src/RouteHook.test.ts +0 -40
- package/src/RouteHttp.test.ts +0 -2909
- package/src/RouteMount.test.ts +0 -481
- package/src/RouteSchema.test.ts +0 -427
- package/src/RouteSse.test.ts +0 -249
- package/src/RouteTree.test.ts +0 -494
- package/src/RouteTrie.test.ts +0 -322
- package/src/RouterPattern.test.ts +0 -676
- package/src/Values.test.ts +0 -263
- package/src/bun/BunBundle.test.ts +0 -268
- package/src/bun/BunBundle_imports.test.ts +0 -48
- package/src/bun/BunHttpServer.test.ts +0 -251
- package/src/bun/BunImportTrackerPlugin.test.ts +0 -77
- package/src/bun/BunRoute.test.ts +0 -162
- package/src/bundler/BundleHttp.test.ts +0 -132
- package/src/effect/HttpRouter.test.ts +0 -548
- package/src/experimental/EncryptedCookies.test.ts +0 -488
- package/src/hyper/HyperHtml.test.ts +0 -209
- package/src/hyper/HyperRoute.test.tsx +0 -197
- package/src/middlewares/BasicAuthMiddleware.test.ts +0 -84
- package/src/testing/TestHttpClient.test.ts +0 -83
- package/src/testing/TestLogger.test.ts +0 -51
- package/src/x/datastar/Datastar.test.ts +0 -266
- package/src/x/tailwind/TailwindPlugin.test.ts +0 -333
package/src/node/FileSystem.ts
CHANGED
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Adapted from @effect/platform
|
|
3
3
|
*/
|
|
4
|
-
import { effectify } from "@effect/platform/Effectify"
|
|
5
|
-
import * as Error from "@effect/platform/Error"
|
|
6
|
-
import type {
|
|
7
|
-
PlatformError,
|
|
8
|
-
SystemErrorReason,
|
|
9
|
-
} from "@effect/platform/Error"
|
|
10
|
-
import { SystemError } from "@effect/platform/Error"
|
|
11
4
|
import * as FileSystem from "@effect/platform/FileSystem"
|
|
12
5
|
import type * as Context from "effect/Context"
|
|
13
6
|
import * as Effect from "effect/Effect"
|
|
14
|
-
import
|
|
7
|
+
import * as Function from "effect/Function"
|
|
15
8
|
import * as Layer from "effect/Layer"
|
|
16
9
|
import * as Option from "effect/Option"
|
|
17
10
|
import * as Stream from "effect/Stream"
|
|
18
|
-
import * as
|
|
11
|
+
import * as NCrypto from "node:crypto"
|
|
19
12
|
import * as NFS from "node:fs"
|
|
20
13
|
import * as NOS from "node:os"
|
|
21
14
|
import * as NPath from "node:path"
|
|
15
|
+
import * as Effectify from "./Effectify.ts"
|
|
16
|
+
import * as PlatformError from "./PlatformError.ts"
|
|
22
17
|
|
|
23
18
|
const handleBadArgument = (method: string) => (cause: unknown) =>
|
|
24
|
-
new
|
|
19
|
+
new PlatformError.BadArgument({
|
|
25
20
|
module: "FileSystem",
|
|
26
21
|
method,
|
|
27
22
|
cause,
|
|
28
23
|
})
|
|
29
24
|
|
|
30
|
-
// == access
|
|
31
|
-
|
|
32
25
|
const access = (() => {
|
|
33
|
-
const nodeAccess = effectify(
|
|
26
|
+
const nodeAccess = Effectify.effectify(
|
|
34
27
|
NFS.access,
|
|
35
28
|
handleErrnoException("FileSystem", "access"),
|
|
36
29
|
handleBadArgument("access"),
|
|
@@ -47,10 +40,8 @@ const access = (() => {
|
|
|
47
40
|
}
|
|
48
41
|
})()
|
|
49
42
|
|
|
50
|
-
// == copy
|
|
51
|
-
|
|
52
43
|
const copy = (() => {
|
|
53
|
-
const nodeCp = effectify(
|
|
44
|
+
const nodeCp = Effectify.effectify(
|
|
54
45
|
NFS.cp,
|
|
55
46
|
handleErrnoException("FileSystem", "copy"),
|
|
56
47
|
handleBadArgument("copy"),
|
|
@@ -63,10 +54,8 @@ const copy = (() => {
|
|
|
63
54
|
})
|
|
64
55
|
})()
|
|
65
56
|
|
|
66
|
-
// == copyFile
|
|
67
|
-
|
|
68
57
|
const copyFile = (() => {
|
|
69
|
-
const nodeCopyFile = effectify(
|
|
58
|
+
const nodeCopyFile = Effectify.effectify(
|
|
70
59
|
NFS.copyFile,
|
|
71
60
|
handleErrnoException("FileSystem", "copyFile"),
|
|
72
61
|
handleBadArgument("copyFile"),
|
|
@@ -74,10 +63,8 @@ const copyFile = (() => {
|
|
|
74
63
|
return (fromPath: string, toPath: string) => nodeCopyFile(fromPath, toPath)
|
|
75
64
|
})()
|
|
76
65
|
|
|
77
|
-
// == chmod
|
|
78
|
-
|
|
79
66
|
const chmod = (() => {
|
|
80
|
-
const nodeChmod = effectify(
|
|
67
|
+
const nodeChmod = Effectify.effectify(
|
|
81
68
|
NFS.chmod,
|
|
82
69
|
handleErrnoException("FileSystem", "chmod"),
|
|
83
70
|
handleBadArgument("chmod"),
|
|
@@ -85,10 +72,8 @@ const chmod = (() => {
|
|
|
85
72
|
return (path: string, mode: number) => nodeChmod(path, mode)
|
|
86
73
|
})()
|
|
87
74
|
|
|
88
|
-
// == chown
|
|
89
|
-
|
|
90
75
|
const chown = (() => {
|
|
91
|
-
const nodeChown = effectify(
|
|
76
|
+
const nodeChown = Effectify.effectify(
|
|
92
77
|
NFS.chown,
|
|
93
78
|
handleErrnoException("FileSystem", "chown"),
|
|
94
79
|
handleBadArgument("chown"),
|
|
@@ -96,10 +81,8 @@ const chown = (() => {
|
|
|
96
81
|
return (path: string, uid: number, gid: number) => nodeChown(path, uid, gid)
|
|
97
82
|
})()
|
|
98
83
|
|
|
99
|
-
// == link
|
|
100
|
-
|
|
101
84
|
const link = (() => {
|
|
102
|
-
const nodeLink = effectify(
|
|
85
|
+
const nodeLink = Effectify.effectify(
|
|
103
86
|
NFS.link,
|
|
104
87
|
handleErrnoException("FileSystem", "link"),
|
|
105
88
|
handleBadArgument("link"),
|
|
@@ -108,10 +91,8 @@ const link = (() => {
|
|
|
108
91
|
nodeLink(existingPath, newPath)
|
|
109
92
|
})()
|
|
110
93
|
|
|
111
|
-
// == makeDirectory
|
|
112
|
-
|
|
113
94
|
const makeDirectory = (() => {
|
|
114
|
-
const nodeMkdir = effectify(
|
|
95
|
+
const nodeMkdir = Effectify.effectify(
|
|
115
96
|
NFS.mkdir,
|
|
116
97
|
handleErrnoException("FileSystem", "makeDirectory"),
|
|
117
98
|
handleBadArgument("makeDirectory"),
|
|
@@ -123,10 +104,8 @@ const makeDirectory = (() => {
|
|
|
123
104
|
})
|
|
124
105
|
})()
|
|
125
106
|
|
|
126
|
-
// == makeTempDirectory
|
|
127
|
-
|
|
128
107
|
const makeTempDirectoryFactory = (method: string) => {
|
|
129
|
-
const nodeMkdtemp = effectify(
|
|
108
|
+
const nodeMkdtemp = Effectify.effectify(
|
|
130
109
|
NFS.mkdtemp,
|
|
131
110
|
handleErrnoException("FileSystem", method),
|
|
132
111
|
handleBadArgument(method),
|
|
@@ -145,10 +124,8 @@ const makeTempDirectoryFactory = (method: string) => {
|
|
|
145
124
|
}
|
|
146
125
|
const makeTempDirectory = makeTempDirectoryFactory("makeTempDirectory")
|
|
147
126
|
|
|
148
|
-
// == remove
|
|
149
|
-
|
|
150
127
|
const removeFactory = (method: string) => {
|
|
151
|
-
const nodeRm = effectify(
|
|
128
|
+
const nodeRm = Effectify.effectify(
|
|
152
129
|
NFS.rm,
|
|
153
130
|
handleErrnoException("FileSystem", method),
|
|
154
131
|
handleBadArgument(method),
|
|
@@ -164,8 +141,6 @@ const removeFactory = (method: string) => {
|
|
|
164
141
|
}
|
|
165
142
|
const remove = removeFactory("remove")
|
|
166
143
|
|
|
167
|
-
// == makeTempDirectoryScoped
|
|
168
|
-
|
|
169
144
|
const makeTempDirectoryScoped = (() => {
|
|
170
145
|
const makeDirectory = makeTempDirectoryFactory("makeTempDirectoryScoped")
|
|
171
146
|
const removeDirectory = removeFactory("makeTempDirectoryScoped")
|
|
@@ -179,22 +154,20 @@ const makeTempDirectoryScoped = (() => {
|
|
|
179
154
|
)
|
|
180
155
|
})()
|
|
181
156
|
|
|
182
|
-
// == open
|
|
183
|
-
|
|
184
157
|
const openFactory = (method: string) => {
|
|
185
|
-
const nodeOpen = effectify(
|
|
158
|
+
const nodeOpen = Effectify.effectify(
|
|
186
159
|
NFS.open,
|
|
187
160
|
handleErrnoException("FileSystem", method),
|
|
188
161
|
handleBadArgument(method),
|
|
189
162
|
)
|
|
190
|
-
const nodeClose = effectify(
|
|
163
|
+
const nodeClose = Effectify.effectify(
|
|
191
164
|
NFS.close,
|
|
192
165
|
handleErrnoException("FileSystem", method),
|
|
193
166
|
handleBadArgument(method),
|
|
194
167
|
)
|
|
195
168
|
|
|
196
169
|
return (path: string, options?: FileSystem.OpenFileOptions) =>
|
|
197
|
-
pipe(
|
|
170
|
+
Function.pipe(
|
|
198
171
|
Effect.acquireRelease(
|
|
199
172
|
nodeOpen(path, options?.flag ?? "r", options?.mode),
|
|
200
173
|
(fd) => Effect.orDie(nodeClose(fd)),
|
|
@@ -211,32 +184,32 @@ const open = openFactory("open")
|
|
|
211
184
|
|
|
212
185
|
const makeFile = (() => {
|
|
213
186
|
const nodeReadFactory = (method: string) =>
|
|
214
|
-
effectify(
|
|
187
|
+
Effectify.effectify(
|
|
215
188
|
NFS.read,
|
|
216
189
|
handleErrnoException("FileSystem", method),
|
|
217
190
|
handleBadArgument(method),
|
|
218
191
|
)
|
|
219
192
|
const nodeRead = nodeReadFactory("read")
|
|
220
193
|
const nodeReadAlloc = nodeReadFactory("readAlloc")
|
|
221
|
-
const nodeStat = effectify(
|
|
194
|
+
const nodeStat = Effectify.effectify(
|
|
222
195
|
NFS.fstat,
|
|
223
196
|
handleErrnoException("FileSystem", "stat"),
|
|
224
197
|
handleBadArgument("stat"),
|
|
225
198
|
)
|
|
226
|
-
const nodeTruncate = effectify(
|
|
199
|
+
const nodeTruncate = Effectify.effectify(
|
|
227
200
|
NFS.ftruncate,
|
|
228
201
|
handleErrnoException("FileSystem", "truncate"),
|
|
229
202
|
handleBadArgument("truncate"),
|
|
230
203
|
)
|
|
231
204
|
|
|
232
|
-
const nodeSync = effectify(
|
|
205
|
+
const nodeSync = Effectify.effectify(
|
|
233
206
|
NFS.fsync,
|
|
234
207
|
handleErrnoException("FileSystem", "sync"),
|
|
235
208
|
handleBadArgument("sync"),
|
|
236
209
|
)
|
|
237
210
|
|
|
238
211
|
const nodeWriteFactory = (method: string) =>
|
|
239
|
-
effectify(
|
|
212
|
+
Effectify.effectify(
|
|
240
213
|
NFS.write,
|
|
241
214
|
handleErrnoException("FileSystem", method),
|
|
242
215
|
handleBadArgument(method),
|
|
@@ -372,7 +345,7 @@ const makeFile = (() => {
|
|
|
372
345
|
|
|
373
346
|
private writeAllChunk(
|
|
374
347
|
buffer: Uint8Array,
|
|
375
|
-
): Effect.Effect<void,
|
|
348
|
+
): Effect.Effect<void, PlatformError.PlatformError> {
|
|
376
349
|
return Effect.flatMap(
|
|
377
350
|
Effect.suspend(() =>
|
|
378
351
|
nodeWriteAll(
|
|
@@ -386,7 +359,7 @@ const makeFile = (() => {
|
|
|
386
359
|
(bytesWritten) => {
|
|
387
360
|
if (bytesWritten === 0) {
|
|
388
361
|
return Effect.fail(
|
|
389
|
-
new
|
|
362
|
+
new PlatformError.SystemError({
|
|
390
363
|
module: "FileSystem",
|
|
391
364
|
method: "writeAll",
|
|
392
365
|
reason: "WriteZero",
|
|
@@ -416,15 +389,13 @@ const makeFile = (() => {
|
|
|
416
389
|
new FileImpl(fd, append)
|
|
417
390
|
})()
|
|
418
391
|
|
|
419
|
-
// == makeTempFile
|
|
420
|
-
|
|
421
392
|
const makeTempFileFactory = (method: string) => {
|
|
422
393
|
const makeDirectory = makeTempDirectoryFactory(method)
|
|
423
394
|
const open = openFactory(method)
|
|
424
395
|
const randomHexString = (bytes: number) =>
|
|
425
|
-
Effect.sync(() =>
|
|
396
|
+
Effect.sync(() => NCrypto.randomBytes(bytes).toString("hex"))
|
|
426
397
|
return (options?: FileSystem.MakeTempFileOptions) =>
|
|
427
|
-
pipe(
|
|
398
|
+
Function.pipe(
|
|
428
399
|
Effect.zip(makeDirectory(options), randomHexString(6)),
|
|
429
400
|
Effect.map(([directory, random]) =>
|
|
430
401
|
NPath.join(directory, random + (options?.suffix ?? ""))
|
|
@@ -434,8 +405,6 @@ const makeTempFileFactory = (method: string) => {
|
|
|
434
405
|
}
|
|
435
406
|
const makeTempFile = makeTempFileFactory("makeTempFile")
|
|
436
407
|
|
|
437
|
-
// == makeTempFileScoped
|
|
438
|
-
|
|
439
408
|
const makeTempFileScoped = (() => {
|
|
440
409
|
const makeFile = makeTempFileFactory("makeTempFileScoped")
|
|
441
410
|
const removeDirectory = removeFactory("makeTempFileScoped")
|
|
@@ -447,8 +416,6 @@ const makeTempFileScoped = (() => {
|
|
|
447
416
|
)
|
|
448
417
|
})()
|
|
449
418
|
|
|
450
|
-
// == readDirectory
|
|
451
|
-
|
|
452
419
|
const readDirectory = (
|
|
453
420
|
path: string,
|
|
454
421
|
options?: FileSystem.ReadDirectoryOptions,
|
|
@@ -459,10 +426,8 @@ const readDirectory = (
|
|
|
459
426
|
handleErrnoException("FileSystem", "readDirectory")(err as any, [path]),
|
|
460
427
|
})
|
|
461
428
|
|
|
462
|
-
// == readFile
|
|
463
|
-
|
|
464
429
|
const readFile = (path: string) =>
|
|
465
|
-
Effect.async<Uint8Array,
|
|
430
|
+
Effect.async<Uint8Array, PlatformError.PlatformError>((resume, signal) => {
|
|
466
431
|
try {
|
|
467
432
|
NFS.readFile(path, { signal }, (err, data) => {
|
|
468
433
|
if (err) {
|
|
@@ -480,10 +445,8 @@ const readFile = (path: string) =>
|
|
|
480
445
|
}
|
|
481
446
|
})
|
|
482
447
|
|
|
483
|
-
// == readLink
|
|
484
|
-
|
|
485
448
|
const readLink = (() => {
|
|
486
|
-
const nodeReadLink = effectify(
|
|
449
|
+
const nodeReadLink = Effectify.effectify(
|
|
487
450
|
NFS.readlink,
|
|
488
451
|
handleErrnoException("FileSystem", "readLink"),
|
|
489
452
|
handleBadArgument("readLink"),
|
|
@@ -491,10 +454,8 @@ const readLink = (() => {
|
|
|
491
454
|
return (path: string) => nodeReadLink(path)
|
|
492
455
|
})()
|
|
493
456
|
|
|
494
|
-
// == realPath
|
|
495
|
-
|
|
496
457
|
const realPath = (() => {
|
|
497
|
-
const nodeRealPath = effectify(
|
|
458
|
+
const nodeRealPath = Effectify.effectify(
|
|
498
459
|
NFS.realpath,
|
|
499
460
|
handleErrnoException("FileSystem", "realPath"),
|
|
500
461
|
handleBadArgument("realPath"),
|
|
@@ -502,10 +463,8 @@ const realPath = (() => {
|
|
|
502
463
|
return (path: string) => nodeRealPath(path)
|
|
503
464
|
})()
|
|
504
465
|
|
|
505
|
-
// == rename
|
|
506
|
-
|
|
507
466
|
const rename = (() => {
|
|
508
|
-
const nodeRename = effectify(
|
|
467
|
+
const nodeRename = Effectify.effectify(
|
|
509
468
|
NFS.rename,
|
|
510
469
|
handleErrnoException("FileSystem", "rename"),
|
|
511
470
|
handleBadArgument("rename"),
|
|
@@ -513,8 +472,6 @@ const rename = (() => {
|
|
|
513
472
|
return (oldPath: string, newPath: string) => nodeRename(oldPath, newPath)
|
|
514
473
|
})()
|
|
515
474
|
|
|
516
|
-
// == stat
|
|
517
|
-
|
|
518
475
|
const makeFileInfo = (stat: NFS.Stats): FileSystem.File.Info => ({
|
|
519
476
|
type: stat.isFile()
|
|
520
477
|
? "File"
|
|
@@ -546,7 +503,7 @@ const makeFileInfo = (stat: NFS.Stats): FileSystem.File.Info => ({
|
|
|
546
503
|
blocks: Option.fromNullable(stat.blocks),
|
|
547
504
|
})
|
|
548
505
|
const stat = (() => {
|
|
549
|
-
const nodeStat = effectify(
|
|
506
|
+
const nodeStat = Effectify.effectify(
|
|
550
507
|
NFS.stat,
|
|
551
508
|
handleErrnoException("FileSystem", "stat"),
|
|
552
509
|
handleBadArgument("stat"),
|
|
@@ -554,10 +511,8 @@ const stat = (() => {
|
|
|
554
511
|
return (path: string) => Effect.map(nodeStat(path), makeFileInfo)
|
|
555
512
|
})()
|
|
556
513
|
|
|
557
|
-
// == symlink
|
|
558
|
-
|
|
559
514
|
const symlink = (() => {
|
|
560
|
-
const nodeSymlink = effectify(
|
|
515
|
+
const nodeSymlink = Effectify.effectify(
|
|
561
516
|
NFS.symlink,
|
|
562
517
|
handleErrnoException("FileSystem", "symlink"),
|
|
563
518
|
handleBadArgument("symlink"),
|
|
@@ -565,10 +520,8 @@ const symlink = (() => {
|
|
|
565
520
|
return (target: string, path: string) => nodeSymlink(target, path)
|
|
566
521
|
})()
|
|
567
522
|
|
|
568
|
-
// == truncate
|
|
569
|
-
|
|
570
523
|
const truncate = (() => {
|
|
571
|
-
const nodeTruncate = effectify(
|
|
524
|
+
const nodeTruncate = Effectify.effectify(
|
|
572
525
|
NFS.truncate,
|
|
573
526
|
handleErrnoException("FileSystem", "truncate"),
|
|
574
527
|
handleBadArgument("truncate"),
|
|
@@ -577,10 +530,8 @@ const truncate = (() => {
|
|
|
577
530
|
nodeTruncate(path, length !== undefined ? Number(length) : undefined)
|
|
578
531
|
})()
|
|
579
532
|
|
|
580
|
-
// == utimes
|
|
581
|
-
|
|
582
533
|
const utimes = (() => {
|
|
583
|
-
const nodeUtimes = effectify(
|
|
534
|
+
const nodeUtimes = Effectify.effectify(
|
|
584
535
|
NFS.utimes,
|
|
585
536
|
handleErrnoException("FileSystem", "utime"),
|
|
586
537
|
handleBadArgument("utime"),
|
|
@@ -589,10 +540,10 @@ const utimes = (() => {
|
|
|
589
540
|
nodeUtimes(path, atime, mtime)
|
|
590
541
|
})()
|
|
591
542
|
|
|
592
|
-
// == watch
|
|
593
|
-
|
|
594
543
|
const watchNode = (path: string, options?: FileSystem.WatchOptions) =>
|
|
595
|
-
Stream.asyncScoped<FileSystem.WatchEvent,
|
|
544
|
+
Stream.asyncScoped<FileSystem.WatchEvent, PlatformError.PlatformError>((
|
|
545
|
+
emit,
|
|
546
|
+
) =>
|
|
596
547
|
Effect.acquireRelease(
|
|
597
548
|
Effect.sync(() => {
|
|
598
549
|
const watcher = NFS.watch(
|
|
@@ -621,7 +572,7 @@ const watchNode = (path: string, options?: FileSystem.WatchOptions) =>
|
|
|
621
572
|
)
|
|
622
573
|
watcher.on("error", (error) => {
|
|
623
574
|
emit.fail(
|
|
624
|
-
new
|
|
575
|
+
new PlatformError.SystemError({
|
|
625
576
|
module: "FileSystem",
|
|
626
577
|
reason: "Unknown",
|
|
627
578
|
method: "watch",
|
|
@@ -654,14 +605,12 @@ const watch = (
|
|
|
654
605
|
Stream.unwrap,
|
|
655
606
|
)
|
|
656
607
|
|
|
657
|
-
// == writeFile
|
|
658
|
-
|
|
659
608
|
const writeFile = (
|
|
660
609
|
path: string,
|
|
661
610
|
data: Uint8Array,
|
|
662
611
|
options?: FileSystem.WriteFileOptions,
|
|
663
612
|
) =>
|
|
664
|
-
Effect.async<void,
|
|
613
|
+
Effect.async<void, PlatformError.PlatformError>((resume, signal) => {
|
|
665
614
|
try {
|
|
666
615
|
NFS.writeFile(path, data, {
|
|
667
616
|
signal,
|
|
@@ -683,7 +632,7 @@ const writeFile = (
|
|
|
683
632
|
}
|
|
684
633
|
})
|
|
685
634
|
|
|
686
|
-
const
|
|
635
|
+
const make = Effect.map(
|
|
687
636
|
Effect.serviceOption(FileSystem.WatchBackend),
|
|
688
637
|
(backend) =>
|
|
689
638
|
FileSystem.make({
|
|
@@ -716,22 +665,35 @@ const makeFileSystem = Effect.map(
|
|
|
716
665
|
}),
|
|
717
666
|
)
|
|
718
667
|
|
|
719
|
-
export const layer = Layer.
|
|
668
|
+
export const layer = Layer.unwrapEffect(
|
|
669
|
+
Effect
|
|
670
|
+
.gen(function*() {
|
|
671
|
+
const mod = yield* Effect.tryPromise(() =>
|
|
672
|
+
import("@effect/platform/FileSystem")
|
|
673
|
+
)
|
|
674
|
+
return Layer.effect(mod.FileSystem, make)
|
|
675
|
+
})
|
|
676
|
+
.pipe(
|
|
677
|
+
Effect.catchAll(() =>
|
|
678
|
+
Effect.die(new globalThis.Error("@effect/platform is not installed"))
|
|
679
|
+
),
|
|
680
|
+
),
|
|
681
|
+
)
|
|
720
682
|
|
|
721
683
|
export {
|
|
722
|
-
Error,
|
|
723
684
|
FileSystem,
|
|
685
|
+
PlatformError as Error,
|
|
724
686
|
}
|
|
725
687
|
|
|
726
688
|
export function handleErrnoException(
|
|
727
|
-
module: SystemError["module"],
|
|
689
|
+
module: PlatformError.SystemError["module"],
|
|
728
690
|
method: string,
|
|
729
691
|
) {
|
|
730
692
|
return function(
|
|
731
693
|
err: NodeJS.ErrnoException,
|
|
732
694
|
[path]: [path: NFS.PathLike | number, ...args: Array<any>],
|
|
733
|
-
): PlatformError {
|
|
734
|
-
let reason: SystemErrorReason = "Unknown"
|
|
695
|
+
): PlatformError.PlatformError {
|
|
696
|
+
let reason: PlatformError.SystemErrorReason = "Unknown"
|
|
735
697
|
|
|
736
698
|
switch (err.code) {
|
|
737
699
|
case "ENOENT":
|
|
@@ -763,7 +725,7 @@ export function handleErrnoException(
|
|
|
763
725
|
break
|
|
764
726
|
}
|
|
765
727
|
|
|
766
|
-
return new SystemError({
|
|
728
|
+
return new PlatformError.SystemError({
|
|
767
729
|
reason,
|
|
768
730
|
module,
|
|
769
731
|
method,
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Adapted from @effect/platform
|
|
3
|
+
*/
|
|
4
|
+
import type * as Cause from "effect/Cause"
|
|
5
|
+
import * as Data from "effect/Data"
|
|
6
|
+
import * as Predicate from "effect/Predicate"
|
|
7
|
+
import * as Schema from "effect/Schema"
|
|
8
|
+
import type * as Types from "effect/Types"
|
|
9
|
+
|
|
10
|
+
import { TypeId as TypeId_ } from "@effect/platform/Error"
|
|
11
|
+
|
|
12
|
+
export const TypeId: typeof TypeId_ = TypeId_
|
|
13
|
+
|
|
14
|
+
export type TypeId = typeof TypeId
|
|
15
|
+
|
|
16
|
+
export const isPlatformError = (u: unknown): u is PlatformError => Predicate.hasProperty(u, TypeId)
|
|
17
|
+
|
|
18
|
+
export const TypeIdError = <const TypeId extends symbol, const Tag extends string>(
|
|
19
|
+
typeId: TypeId,
|
|
20
|
+
tag: Tag,
|
|
21
|
+
): new<A extends Record<string, any>>(
|
|
22
|
+
args: Types.Simplify<A>,
|
|
23
|
+
) =>
|
|
24
|
+
& Cause.YieldableError
|
|
25
|
+
& Record<TypeId, TypeId>
|
|
26
|
+
& { readonly _tag: Tag }
|
|
27
|
+
& Readonly<A> => {
|
|
28
|
+
class Base extends Data.Error<{}> {
|
|
29
|
+
readonly _tag = tag
|
|
30
|
+
}
|
|
31
|
+
;(Base.prototype as any)[typeId] = typeId
|
|
32
|
+
;(Base.prototype as any).name = tag
|
|
33
|
+
return Base as any
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const Module = Schema.Literal(
|
|
37
|
+
"Clipboard",
|
|
38
|
+
"Command",
|
|
39
|
+
"FileSystem",
|
|
40
|
+
"KeyValueStore",
|
|
41
|
+
"Path",
|
|
42
|
+
"Stream",
|
|
43
|
+
"Terminal",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export class BadArgument
|
|
47
|
+
extends Schema.TaggedError<BadArgument>("@effect/platform/Error/BadArgument")("BadArgument", {
|
|
48
|
+
module: Module,
|
|
49
|
+
method: Schema.String,
|
|
50
|
+
description: Schema.optional(Schema.String),
|
|
51
|
+
cause: Schema.optional(Schema.Defect),
|
|
52
|
+
})
|
|
53
|
+
{
|
|
54
|
+
readonly [TypeId]: typeof TypeId = TypeId
|
|
55
|
+
|
|
56
|
+
get message(): string {
|
|
57
|
+
return `${this.module}.${this.method}${this.description ? `: ${this.description}` : ""}`
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const SystemErrorReason = Schema.Literal(
|
|
62
|
+
"AlreadyExists",
|
|
63
|
+
"BadResource",
|
|
64
|
+
"Busy",
|
|
65
|
+
"InvalidData",
|
|
66
|
+
"NotFound",
|
|
67
|
+
"PermissionDenied",
|
|
68
|
+
"TimedOut",
|
|
69
|
+
"UnexpectedEof",
|
|
70
|
+
"Unknown",
|
|
71
|
+
"WouldBlock",
|
|
72
|
+
"WriteZero",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
export type SystemErrorReason = typeof SystemErrorReason.Type
|
|
76
|
+
|
|
77
|
+
export class SystemError
|
|
78
|
+
extends Schema.TaggedError<SystemError>("@effect/platform/Error/SystemError")("SystemError", {
|
|
79
|
+
reason: SystemErrorReason,
|
|
80
|
+
module: Module,
|
|
81
|
+
method: Schema.String,
|
|
82
|
+
description: Schema.optional(Schema.String),
|
|
83
|
+
syscall: Schema.optional(Schema.String),
|
|
84
|
+
pathOrDescriptor: Schema.optional(Schema.Union(Schema.String, Schema.Number)),
|
|
85
|
+
cause: Schema.optional(Schema.Defect),
|
|
86
|
+
})
|
|
87
|
+
{
|
|
88
|
+
readonly [TypeId]: typeof TypeId = TypeId
|
|
89
|
+
|
|
90
|
+
get message(): string {
|
|
91
|
+
return `${this.reason}: ${this.module}.${this.method}${
|
|
92
|
+
this.pathOrDescriptor !== undefined ? ` (${this.pathOrDescriptor})` : ""
|
|
93
|
+
}${this.description ? `: ${this.description}` : ""}`
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type PlatformError = BadArgument | SystemError
|
|
98
|
+
|
|
99
|
+
export const PlatformError: Schema.Union<[
|
|
100
|
+
typeof BadArgument,
|
|
101
|
+
typeof SystemError,
|
|
102
|
+
]> = Schema.Union(BadArgument, SystemError)
|
|
@@ -28,7 +28,7 @@ export function layer(): Layer.Layer<TestLogger> {
|
|
|
28
28
|
|
|
29
29
|
const customLogger = Logger.make(({ message, logLevel, cause }) => {
|
|
30
30
|
const causeStr = !Cause.isEmpty(cause)
|
|
31
|
-
? ` ${Cause.pretty(cause)}`
|
|
31
|
+
? ` ${Cause.pretty(cause, { renderErrorCause: true })}`
|
|
32
32
|
: ""
|
|
33
33
|
MutableRef.update(
|
|
34
34
|
mutableRef,
|
package/dist/Random.d.ts
DELETED
package/dist/Random.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
export function uuid() {
|
|
2
|
-
return base36(uuid4bytes());
|
|
3
|
-
}
|
|
4
|
-
export function uuidSorted() {
|
|
5
|
-
return base36(uuid7bytes());
|
|
6
|
-
}
|
|
7
|
-
export function token(length) {
|
|
8
|
-
return base36(bytes(length));
|
|
9
|
-
}
|
|
10
|
-
function base36(bytes) {
|
|
11
|
-
if (bytes.length === 0)
|
|
12
|
-
return "";
|
|
13
|
-
let zeros = 0;
|
|
14
|
-
while (zeros < bytes.length && bytes[zeros] === 0)
|
|
15
|
-
zeros++;
|
|
16
|
-
let n = 0n;
|
|
17
|
-
for (let i = zeros; i < bytes.length; i++)
|
|
18
|
-
n = (n << 8n) + BigInt(bytes[i]);
|
|
19
|
-
return "0".repeat(zeros) + (n === 0n ? "" : n.toString(36));
|
|
20
|
-
}
|
|
21
|
-
export function bytes(length) {
|
|
22
|
-
const buf = new Uint8Array(length);
|
|
23
|
-
crypto.getRandomValues(buf);
|
|
24
|
-
return buf;
|
|
25
|
-
}
|
|
26
|
-
export function uuid4bytes() {
|
|
27
|
-
const buf = bytes(16);
|
|
28
|
-
buf[6] = (buf[6] & 0x0f) | 0x40; // version 4
|
|
29
|
-
buf[8] = (buf[8] & 0x3f) | 0x80; // variant
|
|
30
|
-
return buf;
|
|
31
|
-
}
|
|
32
|
-
function uuid7bytes() {
|
|
33
|
-
const buf = new Uint8Array(16);
|
|
34
|
-
const timestamp = BigInt(Date.now());
|
|
35
|
-
// 48-bit timestamp (6 bytes)
|
|
36
|
-
buf[0] = Number((timestamp >> 40n) & 0xffn);
|
|
37
|
-
buf[1] = Number((timestamp >> 32n) & 0xffn);
|
|
38
|
-
buf[2] = Number((timestamp >> 24n) & 0xffn);
|
|
39
|
-
buf[3] = Number((timestamp >> 16n) & 0xffn);
|
|
40
|
-
buf[4] = Number((timestamp >> 8n) & 0xffn);
|
|
41
|
-
buf[5] = Number(timestamp & 0xffn);
|
|
42
|
-
// 12-bit random A (1.5 bytes)
|
|
43
|
-
crypto.getRandomValues(buf.subarray(6, 8));
|
|
44
|
-
buf[6] = (buf[6] & 0x0f) | 0x70; // version 7
|
|
45
|
-
// 2-bit variant + 62-bit random B (8 bytes)
|
|
46
|
-
crypto.getRandomValues(buf.subarray(8, 16));
|
|
47
|
-
buf[8] = (buf[8] & 0x3f) | 0x80; // variant
|
|
48
|
-
return buf;
|
|
49
|
-
}
|