effect-start 0.23.0 → 0.25.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/ChildProcess.js +32 -20
- package/dist/Commander.js +377 -293
- package/dist/ContentNegotiation.js +424 -318
- package/dist/Cookies.js +340 -271
- package/dist/Development.js +85 -49
- package/dist/Effectify.js +22 -14
- package/dist/Entity.js +260 -195
- package/dist/Fetch.js +192 -0
- package/dist/FilePathPattern.js +88 -77
- package/dist/FileRouter.js +192 -136
- package/dist/FileRouterCodegen.js +262 -191
- package/dist/FileSystem.js +126 -64
- package/dist/Http.js +96 -77
- package/dist/PathPattern.js +311 -273
- package/dist/PlatformError.js +36 -21
- package/dist/PlatformRuntime.js +65 -40
- package/dist/Route.js +122 -79
- package/dist/RouteBody.js +83 -58
- package/dist/RouteError.js +46 -25
- package/dist/RouteHook.js +58 -34
- package/dist/RouteHttp.js +346 -237
- package/dist/RouteHttpTracer.js +86 -58
- package/dist/RouteMount.js +81 -58
- package/dist/RouteSchema.js +253 -170
- package/dist/RouteSse.js +87 -72
- package/dist/RouteTree.js +99 -73
- package/dist/RouteTrie.js +160 -133
- package/dist/SchemaExtra.js +87 -62
- package/dist/Socket.js +32 -21
- package/dist/SqlIntrospect.js +317 -268
- package/dist/Start.js +55 -25
- package/dist/StartApp.js +3 -21
- package/dist/StreamExtra.js +109 -74
- package/dist/System.js +37 -21
- package/dist/TuplePathPattern.js +64 -58
- package/dist/Unique.js +159 -120
- package/dist/Values.js +48 -32
- package/dist/bun/BunBundle.js +158 -109
- package/dist/bun/BunChildProcessSpawner.js +121 -82
- package/dist/bun/BunImportTrackerPlugin.js +85 -63
- package/dist/bun/BunRoute.js +135 -99
- package/dist/bun/BunRuntime.js +39 -29
- package/dist/bun/BunServer.js +268 -140
- package/dist/bun/BunVirtualFilesPlugin.js +47 -33
- package/dist/bun/_BunEnhancedResolve.js +107 -82
- package/dist/bun/index.js +5 -5
- package/dist/bundler/Bundle.js +82 -38
- package/dist/bundler/BundleFiles.js +140 -82
- package/dist/bundler/BundleRoute.js +49 -38
- package/dist/client/Overlay.js +29 -28
- package/dist/client/ScrollState.js +94 -82
- package/dist/client/index.js +79 -61
- package/dist/console/Console.js +40 -24
- package/dist/console/ConsoleErrors.js +189 -178
- package/dist/console/ConsoleLogger.js +52 -43
- package/dist/console/ConsoleMetrics.js +69 -58
- package/dist/console/ConsoleProcess.js +57 -47
- package/dist/console/ConsoleStore.js +56 -45
- package/dist/console/ConsoleTracer.js +101 -88
- package/dist/console/Simulation.js +714 -563
- package/dist/console/index.js +3 -3
- package/dist/console/routes/tree.js +29 -28
- package/dist/datastar/actions/fetch.js +514 -381
- package/dist/datastar/actions/peek.js +12 -12
- package/dist/datastar/actions/setAll.js +18 -11
- package/dist/datastar/actions/toggleAll.js +18 -11
- package/dist/datastar/attributes/attr.js +48 -47
- package/dist/datastar/attributes/bind.js +186 -167
- package/dist/datastar/attributes/class.js +51 -44
- package/dist/datastar/attributes/computed.js +23 -24
- package/dist/datastar/attributes/effect.js +9 -8
- package/dist/datastar/attributes/indicator.js +32 -29
- package/dist/datastar/attributes/init.js +26 -25
- package/dist/datastar/attributes/jsonSignals.js +32 -29
- package/dist/datastar/attributes/on.js +76 -73
- package/dist/datastar/attributes/onIntersect.js +51 -51
- package/dist/datastar/attributes/onInterval.js +30 -29
- package/dist/datastar/attributes/onSignalPatch.js +49 -40
- package/dist/datastar/attributes/ref.js +10 -9
- package/dist/datastar/attributes/show.js +31 -30
- package/dist/datastar/attributes/signals.js +17 -16
- package/dist/datastar/attributes/style.js +56 -49
- package/dist/datastar/attributes/text.js +28 -25
- package/dist/datastar/engine.js +1079 -933
- package/dist/datastar/index.js +25 -24
- package/dist/datastar/utils.js +203 -155
- package/dist/datastar/watchers/patchElements.js +459 -372
- package/dist/datastar/watchers/patchSignals.js +13 -13
- package/dist/experimental/EncryptedCookies.js +305 -189
- package/dist/experimental/index.js +1 -1
- package/dist/hyper/Hyper.js +22 -17
- package/dist/hyper/HyperHtml.js +138 -123
- package/dist/hyper/HyperNode.js +11 -9
- package/dist/hyper/HyperRoute.js +41 -28
- package/dist/hyper/html.js +27 -27
- package/dist/hyper/index.js +5 -5
- package/dist/hyper/jsx-runtime.js +11 -5
- package/dist/index.js +8 -8
- package/dist/node/NodeFileSystem.js +606 -341
- package/dist/node/NodeUtils.js +21 -18
- package/dist/sql/Sql.js +8 -0
- package/dist/sql/bun/index.js +134 -67
- package/dist/sql/index.js +1 -0
- package/dist/sql/libsql/index.js +156 -0
- package/dist/sql/mssql/docker.js +103 -60
- package/dist/sql/mssql/index.js +182 -101
- package/dist/testing/TestLogger.js +39 -29
- package/dist/testing/index.js +2 -2
- package/dist/testing/utils.js +45 -23
- package/dist/x/cloudflare/CloudflareTunnel.js +61 -28
- package/dist/x/cloudflare/index.js +1 -1
- package/dist/x/tailscale/TailscaleTunnel.js +86 -60
- package/dist/x/tailscale/index.js +1 -1
- package/dist/x/tailwind/TailwindPlugin.js +280 -205
- package/dist/x/tailwind/compile.js +185 -129
- package/dist/x/tailwind/plugin.js +13 -11
- package/package.json +1 -1
- package/src/Development.ts +3 -1
- package/src/Entity.ts +17 -0
- package/src/Fetch.ts +271 -0
- package/src/SqlIntrospect.ts +64 -70
- package/src/Start.ts +24 -22
- package/src/StartApp.ts +11 -0
- package/src/bun/BunServer.ts +89 -16
- package/src/hyper/HyperHtml.ts +0 -1
- package/src/sql/bun/index.ts +1 -1
- package/src/sql/index.ts +1 -0
- package/src/sql/libsql/index.ts +173 -0
- package/src/sql/libsql/libsql.d.ts +39 -0
- package/src/sql/mssql/index.ts +1 -1
- package/src/x/tailscale/TailscaleTunnel.ts +7 -5
- package/dist/BlobStore.d.ts +0 -80
- package/dist/BlobStore.js +0 -19
- package/dist/ChildProcess.d.ts +0 -60
- package/dist/Commander.d.ts +0 -100
- package/dist/ContentNegotiation.d.ts +0 -12
- package/dist/Cookies.d.ts +0 -47
- package/dist/Development.d.ts +0 -39
- package/dist/Effectify.d.ts +0 -209
- package/dist/Entity.d.ts +0 -47
- package/dist/FilePathPattern.d.ts +0 -29
- package/dist/FileRouter.d.ts +0 -56
- package/dist/FileRouterCodegen.d.ts +0 -18
- package/dist/FileRouterPattern.d.ts +0 -9
- package/dist/FileRouterPattern.js +0 -35
- package/dist/FileSystem.d.ts +0 -158
- package/dist/Http.d.ts +0 -37
- package/dist/HttpAppExtra.d.ts +0 -7
- package/dist/HttpAppExtra.js +0 -320
- package/dist/HttpUtils.d.ts +0 -3
- package/dist/HttpUtils.js +0 -11
- package/dist/PathPattern.d.ts +0 -134
- package/dist/PlatformError.d.ts +0 -38
- package/dist/PlatformRuntime.d.ts +0 -27
- package/dist/Route.d.ts +0 -97
- package/dist/RouteBody.d.ts +0 -47
- package/dist/RouteError.d.ts +0 -98
- package/dist/RouteHook.d.ts +0 -12
- package/dist/RouteHttp.d.ts +0 -21
- package/dist/RouteHttpTracer.d.ts +0 -10
- package/dist/RouteMount.d.ts +0 -86
- package/dist/RouteSchema.d.ts +0 -86
- package/dist/RouteSse.d.ts +0 -21
- package/dist/RouteTree.d.ts +0 -57
- package/dist/RouteTrie.d.ts +0 -20
- package/dist/RouterPattern.d.ts +0 -118
- package/dist/RouterPattern.js +0 -269
- package/dist/SchemaExtra.d.ts +0 -7
- package/dist/Socket.d.ts +0 -27
- package/dist/Sql.d.ts +0 -34
- package/dist/Sql.js +0 -5
- package/dist/SqlIntrospect.d.ts +0 -91
- package/dist/Start.d.ts +0 -44
- package/dist/StartApp.d.ts +0 -19
- package/dist/StreamExtra.d.ts +0 -28
- package/dist/System.d.ts +0 -7
- package/dist/TuplePathPattern.d.ts +0 -9
- package/dist/Unique.d.ts +0 -50
- package/dist/Values.d.ts +0 -27
- package/dist/bun/BunBlobStoreDisk.d.ts +0 -6
- package/dist/bun/BunBlobStoreDisk.js +0 -116
- package/dist/bun/BunBlobStoreS3.d.ts +0 -11
- package/dist/bun/BunBlobStoreS3.js +0 -89
- package/dist/bun/BunBlobWatcherDisk.d.ts +0 -6
- package/dist/bun/BunBlobWatcherDisk.js +0 -60
- package/dist/bun/BunBlobWatcherQueue.d.ts +0 -6
- package/dist/bun/BunBlobWatcherQueue.js +0 -17
- package/dist/bun/BunBundle.d.ts +0 -11
- package/dist/bun/BunChildProcessSpawner.d.ts +0 -3
- package/dist/bun/BunHttpServer.d.ts +0 -44
- package/dist/bun/BunHttpServer.js +0 -186
- package/dist/bun/BunHttpServer_web.d.ts +0 -60
- package/dist/bun/BunHttpServer_web.js +0 -252
- package/dist/bun/BunImportTrackerPlugin.d.ts +0 -13
- package/dist/bun/BunPlatformHttpServer.d.ts +0 -10
- package/dist/bun/BunPlatformHttpServer.js +0 -53
- package/dist/bun/BunRoute.d.ts +0 -48
- package/dist/bun/BunRuntime.d.ts +0 -2
- package/dist/bun/BunServer.d.ts +0 -40
- package/dist/bun/BunServerRequest.d.ts +0 -60
- package/dist/bun/BunServerRequest.js +0 -252
- package/dist/bun/BunSql.d.ts +0 -4
- package/dist/bun/BunSql.js +0 -81
- package/dist/bun/BunVirtualFilesPlugin.d.ts +0 -4
- package/dist/bun/_BunEnhancedResolve.d.ts +0 -45
- package/dist/bun/index.d.ts +0 -5
- package/dist/bundler/Bundle.d.ts +0 -61
- package/dist/bundler/BundleFiles.d.ts +0 -13
- package/dist/bundler/BundleHttp.d.ts +0 -45
- package/dist/bundler/BundleHttp.js +0 -176
- package/dist/bundler/BundleRoute.d.ts +0 -27
- package/dist/client/Overlay.d.ts +0 -2
- package/dist/client/ScrollState.d.ts +0 -6
- package/dist/client/index.d.ts +0 -6
- package/dist/console/Console.d.ts +0 -6
- package/dist/console/ConsoleErrors.d.ts +0 -3
- package/dist/console/ConsoleLogger.d.ts +0 -3
- package/dist/console/ConsoleMetrics.d.ts +0 -3
- package/dist/console/ConsoleProcess.d.ts +0 -3
- package/dist/console/ConsoleStore.d.ts +0 -144
- package/dist/console/ConsoleTracer.d.ts +0 -3
- package/dist/console/Simulation.d.ts +0 -2
- package/dist/console/index.d.ts +0 -3
- package/dist/console/routes/errors/route.d.ts +0 -10
- package/dist/console/routes/errors/route.js +0 -47
- package/dist/console/routes/fiberDetail.d.ts +0 -16
- package/dist/console/routes/fiberDetail.js +0 -38
- package/dist/console/routes/fibers/route.d.ts +0 -10
- package/dist/console/routes/fibers/route.js +0 -19
- package/dist/console/routes/git/route.d.ts +0 -11
- package/dist/console/routes/git/route.js +0 -33
- package/dist/console/routes/layout.d.ts +0 -9
- package/dist/console/routes/layout.js +0 -3
- package/dist/console/routes/logs/route.d.ts +0 -10
- package/dist/console/routes/logs/route.js +0 -32
- package/dist/console/routes/metrics/route.d.ts +0 -10
- package/dist/console/routes/metrics/route.js +0 -17
- package/dist/console/routes/route.d.ts +0 -6
- package/dist/console/routes/route.js +0 -5
- package/dist/console/routes/routes/route.d.ts +0 -6
- package/dist/console/routes/routes/route.js +0 -20
- package/dist/console/routes/services/route.d.ts +0 -6
- package/dist/console/routes/services/route.js +0 -12
- package/dist/console/routes/system/route.d.ts +0 -10
- package/dist/console/routes/system/route.js +0 -18
- package/dist/console/routes/traceDetail.d.ts +0 -16
- package/dist/console/routes/traceDetail.js +0 -14
- package/dist/console/routes/traces/route.d.ts +0 -10
- package/dist/console/routes/traces/route.js +0 -39
- package/dist/console/routes/tree.d.ts +0 -153
- package/dist/console/ui/Errors.d.ts +0 -4
- package/dist/console/ui/Errors.js +0 -15
- package/dist/console/ui/Fibers.d.ts +0 -24
- package/dist/console/ui/Fibers.js +0 -121
- package/dist/console/ui/Git.d.ts +0 -20
- package/dist/console/ui/Git.js +0 -95
- package/dist/console/ui/Logs.d.ts +0 -4
- package/dist/console/ui/Logs.js +0 -25
- package/dist/console/ui/Metrics.d.ts +0 -4
- package/dist/console/ui/Metrics.js +0 -26
- package/dist/console/ui/Routes.d.ts +0 -8
- package/dist/console/ui/Routes.js +0 -70
- package/dist/console/ui/Services.d.ts +0 -10
- package/dist/console/ui/Services.js +0 -246
- package/dist/console/ui/Shell.d.ts +0 -10
- package/dist/console/ui/Shell.js +0 -7
- package/dist/console/ui/System.d.ts +0 -4
- package/dist/console/ui/System.js +0 -35
- package/dist/console/ui/Traces.d.ts +0 -12
- package/dist/console/ui/Traces.js +0 -179
- package/dist/datastar/actions/fetch.d.ts +0 -30
- package/dist/datastar/actions/peek.d.ts +0 -1
- package/dist/datastar/actions/setAll.d.ts +0 -1
- package/dist/datastar/actions/toggleAll.d.ts +0 -1
- package/dist/datastar/attributes/attr.d.ts +0 -1
- package/dist/datastar/attributes/bind.d.ts +0 -1
- package/dist/datastar/attributes/class.d.ts +0 -1
- package/dist/datastar/attributes/computed.d.ts +0 -1
- package/dist/datastar/attributes/effect.d.ts +0 -1
- package/dist/datastar/attributes/indicator.d.ts +0 -1
- package/dist/datastar/attributes/init.d.ts +0 -1
- package/dist/datastar/attributes/jsonSignals.d.ts +0 -1
- package/dist/datastar/attributes/on.d.ts +0 -1
- package/dist/datastar/attributes/onIntersect.d.ts +0 -1
- package/dist/datastar/attributes/onInterval.d.ts +0 -1
- package/dist/datastar/attributes/onSignalPatch.d.ts +0 -1
- package/dist/datastar/attributes/ref.d.ts +0 -1
- package/dist/datastar/attributes/show.d.ts +0 -1
- package/dist/datastar/attributes/signals.d.ts +0 -1
- package/dist/datastar/attributes/style.d.ts +0 -1
- package/dist/datastar/attributes/text.d.ts +0 -1
- package/dist/datastar/engine.d.ts +0 -162
- package/dist/datastar/happydom.d.ts +0 -1
- package/dist/datastar/happydom.js +0 -8
- package/dist/datastar/index.d.ts +0 -24
- package/dist/datastar/load.d.ts +0 -24
- package/dist/datastar/load.js +0 -24
- package/dist/datastar/utils.d.ts +0 -51
- package/dist/datastar/watchers/patchElements.d.ts +0 -1
- package/dist/datastar/watchers/patchSignals.d.ts +0 -1
- package/dist/experimental/EncryptedCookies.d.ts +0 -48
- package/dist/experimental/SseHttpResponse.d.ts +0 -7
- package/dist/experimental/SseHttpResponse.js +0 -28
- package/dist/experimental/index.d.ts +0 -1
- package/dist/hyper/Hyper.d.ts +0 -25
- package/dist/hyper/HyperHtml.d.ts +0 -23
- package/dist/hyper/HyperHtml.test.d.ts +0 -1
- package/dist/hyper/HyperHtml.test.js +0 -197
- package/dist/hyper/HyperNode.d.ts +0 -14
- package/dist/hyper/HyperRoute.d.ts +0 -8
- package/dist/hyper/HyperRoute.test.d.ts +0 -1
- package/dist/hyper/HyperRoute.test.js +0 -83
- package/dist/hyper/html.d.ts +0 -11
- package/dist/hyper/index.d.ts +0 -6
- package/dist/hyper/jsx-runtime.d.ts +0 -7
- package/dist/index.d.ts +0 -8
- package/dist/inference_check.d.ts +0 -1
- package/dist/inference_check.js +0 -15
- package/dist/lint/plugin.d.ts +0 -86
- package/dist/lint/plugin.js +0 -341
- package/dist/middlewares/BasicAuthMiddleware.d.ts +0 -8
- package/dist/middlewares/BasicAuthMiddleware.js +0 -22
- package/dist/middlewares/index.d.ts +0 -1
- package/dist/middlewares/index.js +0 -1
- package/dist/node/Effectify.d.ts +0 -209
- package/dist/node/Effectify.js +0 -19
- package/dist/node/FileSystem.d.ts +0 -7
- package/dist/node/FileSystem.js +0 -420
- package/dist/node/NodeFileSystem.d.ts +0 -7
- package/dist/node/NodeUtils.d.ts +0 -2
- package/dist/node/PlatformError.d.ts +0 -46
- package/dist/node/PlatformError.js +0 -43
- package/dist/node/Utils.d.ts +0 -1
- package/dist/node/Utils.js +0 -19
- package/dist/repro_fail.d.ts +0 -1
- package/dist/repro_fail.js +0 -14
- package/dist/sql/bun/index.d.ts +0 -3
- package/dist/sql/mssql/docker.d.ts +0 -2
- package/dist/sql/mssql/index.d.ts +0 -21
- package/dist/testing/TestHttpClient.d.ts +0 -13
- package/dist/testing/TestHttpClient.js +0 -68
- package/dist/testing/TestLogger.d.ts +0 -13
- package/dist/testing/index.d.ts +0 -2
- package/dist/testing/utils.d.ts +0 -9
- package/dist/x/cloudflare/CloudflareTunnel.d.ts +0 -10
- package/dist/x/cloudflare/index.d.ts +0 -1
- package/dist/x/datastar/Datastar.d.ts +0 -6
- package/dist/x/datastar/Datastar.js +0 -47
- package/dist/x/datastar/index.d.ts +0 -1
- package/dist/x/datastar/index.js +0 -1
- package/dist/x/tailscale/TailscaleTunnel.d.ts +0 -15
- package/dist/x/tailscale/index.d.ts +0 -1
- package/dist/x/tailwind/TailwindPlugin.d.ts +0 -23
- package/dist/x/tailwind/compile.d.ts +0 -19
- package/dist/x/tailwind/plugin.d.ts +0 -2
- /package/src/{Sql.ts → sql/Sql.ts} +0 -0
package/dist/Unique.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export declare const ALPHABET_BASE32_CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
2
|
-
export declare const ALPHABET_BASE32_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
3
|
-
export declare const ALPHABET_BASE64_URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
4
|
-
export declare const ALPHABET_HEX = "0123456789abcdef";
|
|
5
|
-
/**
|
|
6
|
-
* Generate a random string for ids, session tokens, and API keys.
|
|
7
|
-
* It uses human-friendly crockford base32 encoding (5 bit of entropy per char)
|
|
8
|
-
*
|
|
9
|
-
* Minimal recommended length:
|
|
10
|
-
* - public ids: 16 chars (~80 bits)
|
|
11
|
-
* - API keys: 32 chars (~160 bits)
|
|
12
|
-
* - session tokens: 32-40 chars (~160-200 bits)
|
|
13
|
-
*/
|
|
14
|
-
export declare function token(length?: number): string;
|
|
15
|
-
export declare function bytes(length: number): Uint8Array;
|
|
16
|
-
export declare const UUID_NIL = "00000000-0000-0000-0000-000000000000";
|
|
17
|
-
export declare function uuid4(): string;
|
|
18
|
-
export declare function uuid7(time?: number): string;
|
|
19
|
-
/**
|
|
20
|
-
* Decode a 48-bit Unix timestamp (ms) from UUID7 or ULID.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* const bytes = Unique.uuid7Bytes()
|
|
24
|
-
* const timestamp = Unique.toTimestamp(bytes)
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* const bytes = Unique.ulidBytes()
|
|
28
|
-
* const timestamp = Unique.toTimestamp(bytes)
|
|
29
|
-
*/
|
|
30
|
-
export declare function toTimestamp(bytes: Uint8Array): number;
|
|
31
|
-
export declare function uuid7Bytes(time?: number): Uint8Array;
|
|
32
|
-
/**
|
|
33
|
-
* Convert UUID bytes to canonical (RFC9562) representation.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* Unique.formatUuid(new Uint8Array(16))
|
|
37
|
-
*/
|
|
38
|
-
export declare function formatUuid(bytes: Uint8Array): string;
|
|
39
|
-
export declare function ulid(time?: number): string;
|
|
40
|
-
export declare function ulidBytes(time?: number): Uint8Array;
|
|
41
|
-
/**
|
|
42
|
-
* Generate a nanoid-style random string.
|
|
43
|
-
*
|
|
44
|
-
* FUN_FACT: Original nanoid implementation uses base64url alphabet
|
|
45
|
-
* with non-standard custom order where charater form common words found
|
|
46
|
-
* in source code (like use, random, strict) to make gzip/brotli more efficient.
|
|
47
|
-
* It's qt lil opt from the times where web developers
|
|
48
|
-
* were competing to have the smallest possible bundle size.
|
|
49
|
-
*/
|
|
50
|
-
export declare function nanoid(size?: number, alphabet?: string): string;
|
package/dist/Values.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
type JsonPrimitives = string | number | boolean | null;
|
|
2
|
-
export type JsonObject = {
|
|
3
|
-
[key: string]: Json | undefined;
|
|
4
|
-
};
|
|
5
|
-
export type Json = JsonPrimitives | Json[] | JsonObject;
|
|
6
|
-
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
7
|
-
/**
|
|
8
|
-
* Type helper that returns `true` if type T has any method properties,
|
|
9
|
-
* otherwise returns `never`.
|
|
10
|
-
*
|
|
11
|
-
* Used internally by IsPlainObject to distinguish plain objects from
|
|
12
|
-
* class instances or objects with methods.
|
|
13
|
-
*/
|
|
14
|
-
type HasMethod<T> = {
|
|
15
|
-
[K in keyof T]: T[K] extends (...args: Array<any>) => any ? true : never;
|
|
16
|
-
}[keyof T];
|
|
17
|
-
export type IsPlainObject<T> = T extends object ? T extends Function ? false : HasMethod<T> extends never ? true : false : false;
|
|
18
|
-
export type Simplify<T> = {
|
|
19
|
-
-readonly [K in keyof T]: IsPlainObject<T[K]> extends true ? {
|
|
20
|
-
-readonly [P in keyof T[K]]: T[K][P];
|
|
21
|
-
} : T[K];
|
|
22
|
-
} extends infer U ? {
|
|
23
|
-
[K in keyof U]: U[K];
|
|
24
|
-
} : never;
|
|
25
|
-
export declare const firstValue: <T>(record: Record<string, T>) => T | undefined;
|
|
26
|
-
export declare const concatBytes: (a: Uint8Array, b: Uint8Array) => Uint8Array;
|
|
27
|
-
export {};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import * as Chunk from "effect/Chunk";
|
|
2
|
-
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Layer from "effect/Layer";
|
|
4
|
-
import * as Option from "effect/Option";
|
|
5
|
-
import * as Stream from "effect/Stream";
|
|
6
|
-
import * as NFS from "node:fs";
|
|
7
|
-
import * as NPath from "node:path";
|
|
8
|
-
import { BlobStore as BlobStoreTag } from "../BlobStore.js";
|
|
9
|
-
import * as PlatformError from "../PlatformError.js";
|
|
10
|
-
import { handleErrnoException } from "../node/NodeFileSystem.js";
|
|
11
|
-
const handleBadArgument = (method) => (cause) => new PlatformError.BadArgument({
|
|
12
|
-
module: "BlobStore",
|
|
13
|
-
method,
|
|
14
|
-
cause,
|
|
15
|
-
});
|
|
16
|
-
const handleErrno = (method) => handleErrnoException("BlobStore", method);
|
|
17
|
-
const tryPromise = (method, path, promise) => Effect.tryPromise({
|
|
18
|
-
try: promise,
|
|
19
|
-
catch: (err) => {
|
|
20
|
-
if (err instanceof Error && "code" in err) {
|
|
21
|
-
return handleErrno(method)(err, [path]);
|
|
22
|
-
}
|
|
23
|
-
return handleBadArgument(method)(err);
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
const validatePath = (directory, key) => {
|
|
27
|
-
const resolved = NPath.resolve(directory, key);
|
|
28
|
-
const root = NPath.resolve(directory);
|
|
29
|
-
if (resolved !== root && !resolved.startsWith(root + NPath.sep)) {
|
|
30
|
-
return Effect.fail(new PlatformError.BadArgument({
|
|
31
|
-
module: "BlobStore",
|
|
32
|
-
method: "ref",
|
|
33
|
-
description: `Path traversal: key "${key}" escapes directory "${directory}"`,
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
return Effect.succeed(resolved);
|
|
37
|
-
};
|
|
38
|
-
const makeRef = (directory, path, key, begin, end) => {
|
|
39
|
-
const getFile = () => {
|
|
40
|
-
const f = Bun.file(path);
|
|
41
|
-
return begin !== undefined || end !== undefined ? f.slice(begin, end) : f;
|
|
42
|
-
};
|
|
43
|
-
return {
|
|
44
|
-
key,
|
|
45
|
-
bytes: tryPromise("bytes", path, () => getFile().bytes()),
|
|
46
|
-
text: tryPromise("text", path, () => getFile().text()),
|
|
47
|
-
json: tryPromise("json", path, () => getFile().json()),
|
|
48
|
-
stat: Effect.flatMap(tryPromise("stat", path, () => Bun.file(path).stat()), (s) => Effect.succeed({
|
|
49
|
-
size: s.size,
|
|
50
|
-
lastModified: Option.fromNullable(s.mtime),
|
|
51
|
-
etag: Option.none(),
|
|
52
|
-
type: Option.fromNullable(Bun.file(path).type || null),
|
|
53
|
-
})),
|
|
54
|
-
exists: tryPromise("exists", path, () => Bun.file(path).exists()),
|
|
55
|
-
delete: tryPromise("delete", path, () => NFS.promises.unlink(path)),
|
|
56
|
-
stream: Stream.fromReadableStream(() => getFile().stream(), (err) => {
|
|
57
|
-
if (err instanceof Error && "code" in err) {
|
|
58
|
-
return handleErrno("stream")(err, [path]);
|
|
59
|
-
}
|
|
60
|
-
return handleBadArgument("stream")(err);
|
|
61
|
-
}),
|
|
62
|
-
write: (data) => tryPromise("write", path, () => Bun.write(path, data, { createPath: true }).then(() => undefined)),
|
|
63
|
-
slice: (b, e) => makeRef(directory, path, key, b, e),
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
const listEntries = (directory, options) => {
|
|
67
|
-
const baseDir = options?.prefix
|
|
68
|
-
? NPath.join(directory, options.prefix)
|
|
69
|
-
: directory;
|
|
70
|
-
return Stream.fromEffect(Effect.tryPromise({
|
|
71
|
-
try: async () => {
|
|
72
|
-
try {
|
|
73
|
-
const entries = await NFS.promises.readdir(baseDir, {
|
|
74
|
-
recursive: true,
|
|
75
|
-
withFileTypes: true,
|
|
76
|
-
});
|
|
77
|
-
return entries
|
|
78
|
-
.filter((e) => e.isFile())
|
|
79
|
-
.map((e) => {
|
|
80
|
-
const rel = NPath.join(e.parentPath, e.name);
|
|
81
|
-
const key = NPath.relative(directory, rel);
|
|
82
|
-
return {
|
|
83
|
-
key,
|
|
84
|
-
size: Option.none(),
|
|
85
|
-
lastModified: Option.none(),
|
|
86
|
-
etag: Option.none(),
|
|
87
|
-
};
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
92
|
-
return [];
|
|
93
|
-
}
|
|
94
|
-
throw err;
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
catch: (err) => {
|
|
98
|
-
if (err instanceof Error && "code" in err) {
|
|
99
|
-
return handleErrno("list")(err, [baseDir]);
|
|
100
|
-
}
|
|
101
|
-
return handleBadArgument("list")(err);
|
|
102
|
-
},
|
|
103
|
-
})).pipe(Stream.flatMap((entries) => Stream.fromChunk(Chunk.fromIterable(entries))));
|
|
104
|
-
};
|
|
105
|
-
export const layer = (config) => {
|
|
106
|
-
const directory = config?.directory ?? "/";
|
|
107
|
-
return Layer.succeed(BlobStoreTag, {
|
|
108
|
-
ref: (key) => Effect.map(validatePath(directory, key), (path) => makeRef(directory, path, key)),
|
|
109
|
-
list: (options) => listEntries(directory, options),
|
|
110
|
-
presign: (_key, _options) => Effect.fail(new PlatformError.BadArgument({
|
|
111
|
-
module: "BlobStore",
|
|
112
|
-
method: "presign",
|
|
113
|
-
description: "Presigned URLs are not supported for disk storage",
|
|
114
|
-
})),
|
|
115
|
-
});
|
|
116
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as Layer from "effect/Layer";
|
|
2
|
-
import { BlobStore as BlobStoreTag } from "../BlobStore.ts";
|
|
3
|
-
export interface S3Config {
|
|
4
|
-
readonly bucket?: string;
|
|
5
|
-
readonly endpoint?: string;
|
|
6
|
-
readonly region?: string;
|
|
7
|
-
readonly accessKeyId?: string;
|
|
8
|
-
readonly secretAccessKey?: string;
|
|
9
|
-
readonly sessionToken?: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const layer: (config?: S3Config) => Layer.Layer<BlobStoreTag>;
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import * as Chunk from "effect/Chunk";
|
|
2
|
-
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Layer from "effect/Layer";
|
|
4
|
-
import * as Option from "effect/Option";
|
|
5
|
-
import * as Stream from "effect/Stream";
|
|
6
|
-
import { BlobStore as BlobStoreTag } from "../BlobStore.js";
|
|
7
|
-
import * as PlatformError from "../PlatformError.js";
|
|
8
|
-
const handleError = (method) => (err) => {
|
|
9
|
-
if (err instanceof Error) {
|
|
10
|
-
const msg = err.message.toLowerCase();
|
|
11
|
-
let reason = "Unknown";
|
|
12
|
-
if (msg.includes("nosuchkey") || msg.includes("not found") || msg.includes("404")) {
|
|
13
|
-
reason = "NotFound";
|
|
14
|
-
}
|
|
15
|
-
else if (msg.includes("forbidden") || msg.includes("403") || msg.includes("access denied")) {
|
|
16
|
-
reason = "PermissionDenied";
|
|
17
|
-
}
|
|
18
|
-
return new PlatformError.SystemError({
|
|
19
|
-
reason,
|
|
20
|
-
module: "BlobStore",
|
|
21
|
-
method,
|
|
22
|
-
description: err.message,
|
|
23
|
-
cause: err,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return new PlatformError.BadArgument({
|
|
27
|
-
module: "BlobStore",
|
|
28
|
-
method,
|
|
29
|
-
cause: err,
|
|
30
|
-
});
|
|
31
|
-
};
|
|
32
|
-
const tryPromise = (method, promise) => Effect.tryPromise({
|
|
33
|
-
try: promise,
|
|
34
|
-
catch: handleError(method),
|
|
35
|
-
});
|
|
36
|
-
const makeRef = (client, key, begin, end) => {
|
|
37
|
-
const getFile = () => {
|
|
38
|
-
const f = client.file(key);
|
|
39
|
-
return begin !== undefined || end !== undefined ? f.slice(begin, end) : f;
|
|
40
|
-
};
|
|
41
|
-
return {
|
|
42
|
-
key,
|
|
43
|
-
bytes: tryPromise("bytes", () => getFile().bytes()),
|
|
44
|
-
text: tryPromise("text", () => getFile().text()),
|
|
45
|
-
json: tryPromise("json", () => getFile().json()),
|
|
46
|
-
stat: tryPromise("stat", () => client.file(key).stat()).pipe(Effect.map((s) => ({
|
|
47
|
-
size: s.size,
|
|
48
|
-
lastModified: Option.some(s.lastModified),
|
|
49
|
-
etag: Option.some(s.etag),
|
|
50
|
-
type: Option.fromNullable(s.type || null),
|
|
51
|
-
}))),
|
|
52
|
-
exists: tryPromise("exists", () => client.file(key).exists()),
|
|
53
|
-
delete: tryPromise("delete", () => client.file(key).delete()),
|
|
54
|
-
stream: Stream.fromReadableStream(() => getFile().stream(), handleError("stream")),
|
|
55
|
-
write: (data) => tryPromise("write", () => client.file(key).write(data).then(() => undefined)),
|
|
56
|
-
slice: (b, e) => makeRef(client, key, b, e),
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
const listEntries = (client, options) => Stream.paginateChunkEffect(undefined, (cursor) => tryPromise("list", () => client.list({
|
|
60
|
-
prefix: options?.prefix,
|
|
61
|
-
...(cursor ? { startAfter: cursor } : {}),
|
|
62
|
-
})).pipe(Effect.map((response) => {
|
|
63
|
-
const entries = (response.contents ?? []).map((item) => ({
|
|
64
|
-
key: item.key,
|
|
65
|
-
size: Option.fromNullable(item.size),
|
|
66
|
-
lastModified: Option.fromNullable(item.lastModified ? new Date(item.lastModified) : undefined),
|
|
67
|
-
etag: Option.fromNullable(item.eTag),
|
|
68
|
-
}));
|
|
69
|
-
const chunk = Chunk.fromIterable(entries);
|
|
70
|
-
const last = entries[entries.length - 1];
|
|
71
|
-
const next = response.isTruncated && last
|
|
72
|
-
? Option.some(last.key)
|
|
73
|
-
: Option.none();
|
|
74
|
-
return [chunk, next];
|
|
75
|
-
})));
|
|
76
|
-
export const layer = (config) => {
|
|
77
|
-
const client = new Bun.S3Client(config);
|
|
78
|
-
return Layer.succeed(BlobStoreTag, {
|
|
79
|
-
ref: (key) => Effect.succeed(makeRef(client, key)),
|
|
80
|
-
list: (options) => listEntries(client, options),
|
|
81
|
-
presign: (key, options) => Effect.try({
|
|
82
|
-
try: () => client.presign(key, {
|
|
83
|
-
expiresIn: options?.expiresIn,
|
|
84
|
-
method: options?.method,
|
|
85
|
-
}),
|
|
86
|
-
catch: handleError("presign"),
|
|
87
|
-
}),
|
|
88
|
-
});
|
|
89
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Layer from "effect/Layer";
|
|
3
|
-
import * as Stream from "effect/Stream";
|
|
4
|
-
import * as NFS from "node:fs";
|
|
5
|
-
import * as NPath from "node:path";
|
|
6
|
-
import * as BlobStore from "../BlobStore.js";
|
|
7
|
-
import * as PlatformError from "../PlatformError.js";
|
|
8
|
-
const watchDir = (directory, options) => {
|
|
9
|
-
const watchPath = options?.prefix
|
|
10
|
-
? NPath.join(directory, options.prefix)
|
|
11
|
-
: directory;
|
|
12
|
-
return Stream.asyncScoped((emit) => Effect.acquireRelease(Effect.sync(() => {
|
|
13
|
-
const watcher = NFS.watch(watchPath, { recursive: true }, (event, filename) => {
|
|
14
|
-
if (!filename)
|
|
15
|
-
return;
|
|
16
|
-
const key = options?.prefix
|
|
17
|
-
? NPath.join(options.prefix, filename)
|
|
18
|
-
: filename;
|
|
19
|
-
switch (event) {
|
|
20
|
-
case "rename": {
|
|
21
|
-
const fullPath = NPath.join(directory, key);
|
|
22
|
-
emit.fromEffect(Effect.tryPromise({
|
|
23
|
-
try: () => Bun.file(fullPath).exists(),
|
|
24
|
-
catch: () => new PlatformError.SystemError({
|
|
25
|
-
reason: "Unknown",
|
|
26
|
-
module: "BlobWatcher",
|
|
27
|
-
method: "watch",
|
|
28
|
-
pathOrDescriptor: fullPath,
|
|
29
|
-
}),
|
|
30
|
-
}).pipe(Effect.map((exists) => exists
|
|
31
|
-
? new BlobStore.WatchEventCreated({ key })
|
|
32
|
-
: new BlobStore.WatchEventDeleted({ key }))));
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
case "change": {
|
|
36
|
-
emit.single(new BlobStore.WatchEventUpdated({ key }));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
watcher.on("error", (error) => {
|
|
42
|
-
emit.fail(new PlatformError.SystemError({
|
|
43
|
-
module: "BlobWatcher",
|
|
44
|
-
reason: "Unknown",
|
|
45
|
-
method: "watch",
|
|
46
|
-
pathOrDescriptor: watchPath,
|
|
47
|
-
cause: error,
|
|
48
|
-
}));
|
|
49
|
-
});
|
|
50
|
-
return watcher;
|
|
51
|
-
}), (watcher) => Effect.sync(() => watcher.close())));
|
|
52
|
-
};
|
|
53
|
-
export const layer = (config) => Layer.succeed(BlobStore.BlobWatcher, {
|
|
54
|
-
watch: (options) => watchDir(config.directory, options),
|
|
55
|
-
notify: (_event) => Effect.fail(new PlatformError.BadArgument({
|
|
56
|
-
module: "BlobWatcher",
|
|
57
|
-
method: "notify",
|
|
58
|
-
description: "Disk watcher receives events from the OS, not from notify()",
|
|
59
|
-
})),
|
|
60
|
-
});
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import * as Layer from "effect/Layer";
|
|
2
|
-
import * as BlobStore from "../BlobStore.ts";
|
|
3
|
-
export interface QueueWatcherConfig {
|
|
4
|
-
readonly capacity?: number;
|
|
5
|
-
}
|
|
6
|
-
export declare const layer: (config?: QueueWatcherConfig) => Layer.Layer<BlobStore.BlobWatcher, never, never>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Layer from "effect/Layer";
|
|
3
|
-
import * as Queue from "effect/Queue";
|
|
4
|
-
import * as Stream from "effect/Stream";
|
|
5
|
-
import * as BlobStore from "../BlobStore.js";
|
|
6
|
-
export const layer = (config) => Layer.scoped(BlobStore.BlobWatcher, Effect.gen(function* () {
|
|
7
|
-
const queue = yield* Queue.bounded(config?.capacity ?? 1024);
|
|
8
|
-
return {
|
|
9
|
-
watch: (options) => {
|
|
10
|
-
const stream = Stream.fromQueue(queue);
|
|
11
|
-
if (!options?.prefix)
|
|
12
|
-
return stream;
|
|
13
|
-
return stream.pipe(Stream.filter((event) => event.key.startsWith(options.prefix)));
|
|
14
|
-
},
|
|
15
|
-
notify: (event) => Queue.offer(queue, event),
|
|
16
|
-
};
|
|
17
|
-
}));
|
package/dist/bun/BunBundle.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { BuildConfig } from "bun";
|
|
2
|
-
import { type Context, Effect, Layer } from "effect";
|
|
3
|
-
import * as Bundle from "../bundler/Bundle.ts";
|
|
4
|
-
export type BuildOptions = Omit<BuildConfig, "outdir">;
|
|
5
|
-
export declare const buildClient: (config: BuildOptions | string) => Effect.Effect<Bundle.BundleContext, Bundle.BundleError, never>;
|
|
6
|
-
export declare const buildServer: (config: BuildOptions | string) => Effect.Effect<Bundle.BundleContext, Bundle.BundleError, never>;
|
|
7
|
-
/**
|
|
8
|
-
* Given a config, build a bundle and returns every time when effect is executed.
|
|
9
|
-
*/
|
|
10
|
-
export declare function build(config: BuildOptions): Effect.Effect<Bundle.BundleContext, Bundle.BundleError>;
|
|
11
|
-
export declare function layer<T>(tag: Context.Tag<T, Bundle.BundleContext>, config: BuildOptions): Layer.Layer<T, Bundle.BundleError, never>;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import * as HttpServer from "@effect/platform/HttpServer";
|
|
2
|
-
import * as Bun from "bun";
|
|
3
|
-
import * as Context from "effect/Context";
|
|
4
|
-
import * as Effect from "effect/Effect";
|
|
5
|
-
import * as Layer from "effect/Layer";
|
|
6
|
-
import type * as Scope from "effect/Scope";
|
|
7
|
-
import * as RouteTree from "../RouteTree.ts";
|
|
8
|
-
import { WebSocketContext } from "./BunHttpServer_web.ts";
|
|
9
|
-
import * as BunRoute from "./BunRoute.ts";
|
|
10
|
-
type FetchHandler = (request: Request, server: Bun.Server<WebSocketContext>) => Response | Promise<Response>;
|
|
11
|
-
/**
|
|
12
|
-
* Basically `Omit<Bun.Serve.Options, "fetch" | "error" | "websocket">`
|
|
13
|
-
* TypeScript 5.9 cannot verify discriminated union types used in
|
|
14
|
-
* {@link Bun.serve} so we need to define them explicitly.
|
|
15
|
-
*/
|
|
16
|
-
interface ServeOptions {
|
|
17
|
-
readonly port?: number;
|
|
18
|
-
readonly hostname?: string;
|
|
19
|
-
readonly reusePort?: boolean;
|
|
20
|
-
readonly ipv6Only?: boolean;
|
|
21
|
-
readonly idleTimeout?: number;
|
|
22
|
-
readonly development?: boolean;
|
|
23
|
-
}
|
|
24
|
-
export type BunHttpServer = {
|
|
25
|
-
readonly server: Bun.Server<WebSocketContext>;
|
|
26
|
-
readonly addRoutes: (routes: BunRoute.BunRoutes) => void;
|
|
27
|
-
readonly pushHandler: (fetch: FetchHandler) => void;
|
|
28
|
-
readonly popHandler: () => void;
|
|
29
|
-
};
|
|
30
|
-
export declare const BunHttpServer: Context.Tag<BunHttpServer, BunHttpServer>;
|
|
31
|
-
export declare const make: (options: ServeOptions) => Effect.Effect<BunHttpServer, never, Scope.Scope>;
|
|
32
|
-
/**
|
|
33
|
-
* Provides HttpServer using BunHttpServer under the hood.
|
|
34
|
-
*/
|
|
35
|
-
export declare const layer: (options?: ServeOptions) => Layer.Layer<HttpServer.HttpServer | BunHttpServer>;
|
|
36
|
-
/**
|
|
37
|
-
* Registers routes provided via {@link Route.layer}
|
|
38
|
-
*/
|
|
39
|
-
export declare function layerAuto(): Layer.Layer<never, never, BunHttpServer>;
|
|
40
|
-
/**
|
|
41
|
-
* Register routes in Bun.serve.
|
|
42
|
-
*/
|
|
43
|
-
export declare function layerRoutes(tree: RouteTree.RouteTree): Layer.Layer<never, never, BunHttpServer>;
|
|
44
|
-
export {};
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import * as HttpApp from "@effect/platform/HttpApp";
|
|
2
|
-
import * as HttpServer from "@effect/platform/HttpServer";
|
|
3
|
-
import * as HttpServerError from "@effect/platform/HttpServerError";
|
|
4
|
-
import * as HttpServerRequest from "@effect/platform/HttpServerRequest";
|
|
5
|
-
import * as Socket from "@effect/platform/Socket";
|
|
6
|
-
import * as Bun from "bun";
|
|
7
|
-
import * as Config from "effect/Config";
|
|
8
|
-
import * as Context from "effect/Context";
|
|
9
|
-
import * as Deferred from "effect/Deferred";
|
|
10
|
-
import * as Effect from "effect/Effect";
|
|
11
|
-
import * as Exit from "effect/Exit";
|
|
12
|
-
import * as FiberSet from "effect/FiberSet";
|
|
13
|
-
import * as Layer from "effect/Layer";
|
|
14
|
-
import * as Option from "effect/Option";
|
|
15
|
-
import * as PathPattern from "../PathPattern.js";
|
|
16
|
-
import * as PlataformRuntime from "../PlatformRuntime.js";
|
|
17
|
-
import * as Route from "../Route.js";
|
|
18
|
-
import * as RouteHttp from "../RouteHttp.js";
|
|
19
|
-
import * as RouteTree from "../RouteTree.js";
|
|
20
|
-
import * as Unique from "../Unique.js";
|
|
21
|
-
import EmptyHTML from "./_empty.html";
|
|
22
|
-
import { makeResponse, ServerRequestImpl, } from "./BunHttpServer_web.js";
|
|
23
|
-
import * as BunRoute from "./BunRoute.js";
|
|
24
|
-
export const BunHttpServer = Context.GenericTag("effect-start/BunServer");
|
|
25
|
-
export const make = (options) => Effect.gen(function* () {
|
|
26
|
-
const port = yield* Config.number("PORT").pipe(Effect.catchTag("ConfigError", () => {
|
|
27
|
-
if (PlataformRuntime.isAgentHarness()) {
|
|
28
|
-
// use random port
|
|
29
|
-
return Effect.succeed(0);
|
|
30
|
-
}
|
|
31
|
-
return Effect.succeed(3000);
|
|
32
|
-
}));
|
|
33
|
-
const hostname = yield* Config.string("HOSTNAME").pipe(Effect.catchTag("ConfigError", () => Effect.succeed(undefined)));
|
|
34
|
-
const handlerStack = [
|
|
35
|
-
function (_request, _server) {
|
|
36
|
-
return new Response("not found", { status: 404 });
|
|
37
|
-
},
|
|
38
|
-
];
|
|
39
|
-
let currentRoutes = {};
|
|
40
|
-
// Bun HMR doesn't work on successive calls to `server.reload` if there are no routes
|
|
41
|
-
// on server start. We workaround that by passing a dummy HTMLBundle [2025-11-26]
|
|
42
|
-
// see: https://github.com/oven-sh/bun/issues/23564
|
|
43
|
-
currentRoutes[`/.BunEmptyHtml-${Unique.token(10)}`] = EmptyHTML;
|
|
44
|
-
const websocket = {
|
|
45
|
-
open(ws) {
|
|
46
|
-
Deferred.unsafeDone(ws.data.deferred, Exit.succeed(ws));
|
|
47
|
-
},
|
|
48
|
-
message(ws, message) {
|
|
49
|
-
ws.data.run(message);
|
|
50
|
-
},
|
|
51
|
-
close(ws, code, closeReason) {
|
|
52
|
-
Deferred.unsafeDone(ws.data.closeDeferred, Socket.defaultCloseCodeIsError(code)
|
|
53
|
-
? Exit.fail(new Socket.SocketCloseError({
|
|
54
|
-
reason: "Close",
|
|
55
|
-
code,
|
|
56
|
-
closeReason,
|
|
57
|
-
}))
|
|
58
|
-
: Exit.void);
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
const server = Bun.serve({
|
|
62
|
-
port,
|
|
63
|
-
hostname,
|
|
64
|
-
...options,
|
|
65
|
-
routes: currentRoutes,
|
|
66
|
-
fetch: handlerStack[0],
|
|
67
|
-
websocket,
|
|
68
|
-
});
|
|
69
|
-
yield* Effect.addFinalizer(() => Effect.sync(() => {
|
|
70
|
-
server.stop();
|
|
71
|
-
}));
|
|
72
|
-
const reload = () => {
|
|
73
|
-
server.reload({
|
|
74
|
-
fetch: handlerStack[handlerStack.length - 1],
|
|
75
|
-
routes: currentRoutes,
|
|
76
|
-
websocket,
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
return BunHttpServer.of({
|
|
80
|
-
server,
|
|
81
|
-
pushHandler(fetch) {
|
|
82
|
-
handlerStack.push(fetch);
|
|
83
|
-
reload();
|
|
84
|
-
},
|
|
85
|
-
popHandler() {
|
|
86
|
-
handlerStack.pop();
|
|
87
|
-
reload();
|
|
88
|
-
},
|
|
89
|
-
addRoutes(routes) {
|
|
90
|
-
currentRoutes = {
|
|
91
|
-
...currentRoutes,
|
|
92
|
-
...routes,
|
|
93
|
-
};
|
|
94
|
-
reload();
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
/**
|
|
99
|
-
* Provides HttpServer using BunHttpServer under the hood.
|
|
100
|
-
*/
|
|
101
|
-
export const layer = (options) => Layer.provideMerge(Layer.scoped(HttpServer.HttpServer, makeBunServer), Layer.scoped(BunHttpServer, make(options ?? {})));
|
|
102
|
-
/**
|
|
103
|
-
* Registers routes provided via {@link Route.layer}
|
|
104
|
-
*/
|
|
105
|
-
export function layerAuto() {
|
|
106
|
-
return Layer.unwrapEffect(Effect.gen(function* () {
|
|
107
|
-
const bunServer = yield* BunHttpServer;
|
|
108
|
-
const routes = yield* Effect.serviceOption(Route.Routes);
|
|
109
|
-
if (Option.isSome(routes)) {
|
|
110
|
-
return layerRoutes(routes.value);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
return Layer.empty;
|
|
114
|
-
}
|
|
115
|
-
}));
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Register routes in Bun.serve.
|
|
119
|
-
*/
|
|
120
|
-
export function layerRoutes(tree) {
|
|
121
|
-
return Layer.effectDiscard(Effect.gen(function* () {
|
|
122
|
-
const bunServer = yield* BunHttpServer;
|
|
123
|
-
const runtime = yield* Effect.runtime();
|
|
124
|
-
const toWebHandler = RouteHttp.toWebHandlerRuntime(runtime);
|
|
125
|
-
const bunRoutes = {};
|
|
126
|
-
const pathGroups = new Map();
|
|
127
|
-
for (const route of RouteTree.walk(tree)) {
|
|
128
|
-
const bunDescriptors = BunRoute.descriptors(route);
|
|
129
|
-
if (bunDescriptors) {
|
|
130
|
-
const htmlBundle = yield* Effect.promise(bunDescriptors.bunLoad);
|
|
131
|
-
bunRoutes[`${bunDescriptors.bunPrefix}/*`] = htmlBundle;
|
|
132
|
-
}
|
|
133
|
-
const path = Route.descriptor(route).path;
|
|
134
|
-
const group = pathGroups.get(path) ?? [];
|
|
135
|
-
group.push(route);
|
|
136
|
-
pathGroups.set(path, group);
|
|
137
|
-
}
|
|
138
|
-
for (const [path, routes] of pathGroups) {
|
|
139
|
-
const handler = toWebHandler(routes);
|
|
140
|
-
for (const bunPath of PathPattern.toBun(path)) {
|
|
141
|
-
bunRoutes[bunPath] = handler;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
bunServer.addRoutes(bunRoutes);
|
|
145
|
-
}));
|
|
146
|
-
}
|
|
147
|
-
const makeBunServer = Effect.gen(function* () {
|
|
148
|
-
const bunServer = yield* BunHttpServer;
|
|
149
|
-
return HttpServer.make({
|
|
150
|
-
address: {
|
|
151
|
-
_tag: "TcpAddress",
|
|
152
|
-
port: bunServer.server.port,
|
|
153
|
-
hostname: bunServer.server.hostname,
|
|
154
|
-
},
|
|
155
|
-
serve(httpApp, middleware) {
|
|
156
|
-
return Effect.gen(function* () {
|
|
157
|
-
const runFork = yield* FiberSet.makeRuntime();
|
|
158
|
-
const runtime = yield* Effect.runtime();
|
|
159
|
-
const app = HttpApp.toHandled(httpApp, (request, response) => Effect.sync(() => {
|
|
160
|
-
;
|
|
161
|
-
request.resolve(makeResponse(request, response, runtime));
|
|
162
|
-
}), middleware);
|
|
163
|
-
function handler(request, server) {
|
|
164
|
-
return new Promise((resolve, _reject) => {
|
|
165
|
-
const fiber = runFork(Effect.provideService(app, HttpServerRequest.HttpServerRequest, new ServerRequestImpl(request, resolve, removeHost(request.url), server)));
|
|
166
|
-
request.signal.addEventListener("abort", () => {
|
|
167
|
-
runFork(fiber.interruptAsFork(HttpServerError.clientAbortFiberId));
|
|
168
|
-
}, { once: true });
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
yield* Effect.acquireRelease(Effect.sync(() => {
|
|
172
|
-
bunServer.pushHandler(handler);
|
|
173
|
-
}), () => Effect.sync(() => {
|
|
174
|
-
bunServer.popHandler();
|
|
175
|
-
}));
|
|
176
|
-
});
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
const removeHost = (url) => {
|
|
181
|
-
if (url[0] === "/") {
|
|
182
|
-
return url;
|
|
183
|
-
}
|
|
184
|
-
const index = url.indexOf("/", url.indexOf("//") + 2);
|
|
185
|
-
return index === -1 ? "/" : url.slice(index);
|
|
186
|
-
};
|