liminal 0.17.9 → 0.17.11

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 (178) hide show
  1. package/Ai.ts +7 -0
  2. package/Assets.ts +21 -0
  3. package/Binding.ts +40 -0
  4. package/CHANGELOG.md +14 -1
  5. package/D1.ts +8 -0
  6. package/DoState.ts +3 -0
  7. package/Hyperdrive.ts +11 -0
  8. package/Images.ts +101 -0
  9. package/Kv.ts +65 -0
  10. package/NativeRequest.ts +3 -0
  11. package/R2.ts +7 -0
  12. package/Worker.ts +54 -0
  13. package/WorkerLoader.ts +29 -0
  14. package/{Actor.ts → actor/Actor.ts} +2 -2
  15. package/actor/ActorRegistry.ts +361 -0
  16. package/{Audition.ts → actor/Audition.ts} +1 -1
  17. package/{Client.ts → actor/Client.ts} +2 -2
  18. package/{ClientDirectory.ts → actor/ClientDirectory.ts} +3 -3
  19. package/actor/index.ts +11 -0
  20. package/asset_forwarding.ts +13 -0
  21. package/commands/sync-env.ts +30 -0
  22. package/dist/Ai.d.ts +6 -0
  23. package/dist/Ai.js +6 -0
  24. package/dist/Ai.js.map +1 -0
  25. package/dist/Assets.d.ts +11 -0
  26. package/dist/Assets.js +14 -0
  27. package/dist/Assets.js.map +1 -0
  28. package/dist/Binding.d.ts +2 -0
  29. package/dist/Binding.js +19 -0
  30. package/dist/Binding.js.map +1 -0
  31. package/dist/D1.d.ts +7 -0
  32. package/dist/D1.js +7 -0
  33. package/dist/D1.js.map +1 -0
  34. package/dist/DoState.d.ts +5 -0
  35. package/dist/DoState.js +4 -0
  36. package/dist/DoState.js.map +1 -0
  37. package/dist/Hyperdrive.d.ts +7 -0
  38. package/dist/Hyperdrive.js +7 -0
  39. package/dist/Hyperdrive.js.map +1 -0
  40. package/dist/Images.d.ts +39 -0
  41. package/dist/Images.js +60 -0
  42. package/dist/Images.js.map +1 -0
  43. package/dist/Kv.d.ts +17 -0
  44. package/dist/Kv.js +32 -0
  45. package/dist/Kv.js.map +1 -0
  46. package/dist/NativeRequest.d.ts +5 -0
  47. package/dist/NativeRequest.js +4 -0
  48. package/dist/NativeRequest.js.map +1 -0
  49. package/dist/R2.d.ts +6 -0
  50. package/dist/R2.js +6 -0
  51. package/dist/R2.js.map +1 -0
  52. package/dist/Worker.d.ts +14 -0
  53. package/dist/Worker.js +25 -0
  54. package/dist/Worker.js.map +1 -0
  55. package/dist/WorkerLoader.d.ts +9 -0
  56. package/dist/WorkerLoader.js +22 -0
  57. package/dist/WorkerLoader.js.map +1 -0
  58. package/dist/{Actor.d.ts → actor/Actor.d.ts} +1 -1
  59. package/dist/{Actor.js → actor/Actor.js} +1 -1
  60. package/dist/actor/Actor.js.map +1 -0
  61. package/dist/actor/ActorRegistry.d.ts +23 -0
  62. package/dist/actor/ActorRegistry.js +153 -0
  63. package/dist/actor/ActorRegistry.js.map +1 -0
  64. package/dist/actor/ActorTransport.js.map +1 -0
  65. package/dist/{Audition.js → actor/Audition.js} +1 -1
  66. package/dist/actor/Audition.js.map +1 -0
  67. package/dist/{Client.js → actor/Client.js} +2 -2
  68. package/dist/actor/Client.js.map +1 -0
  69. package/dist/{ClientDirectory.d.ts → actor/ClientDirectory.d.ts} +1 -1
  70. package/dist/{ClientDirectory.js → actor/ClientDirectory.js} +2 -2
  71. package/dist/actor/ClientDirectory.js.map +1 -0
  72. package/dist/actor/ClientHandle.js.map +1 -0
  73. package/dist/actor/F.js.map +1 -0
  74. package/dist/actor/Method.js.map +1 -0
  75. package/dist/actor/Protocol.js.map +1 -0
  76. package/dist/actor/errors.js.map +1 -0
  77. package/dist/actor/index.d.ts +11 -0
  78. package/dist/actor/index.js +12 -0
  79. package/dist/actor/index.js.map +1 -0
  80. package/dist/asset_forwarding.d.ts +4 -0
  81. package/dist/asset_forwarding.js +9 -0
  82. package/dist/asset_forwarding.js.map +1 -0
  83. package/dist/commands/sync-env.d.ts +8 -0
  84. package/dist/commands/sync-env.js +32 -0
  85. package/dist/commands/sync-env.js.map +1 -0
  86. package/dist/index.d.ts +12 -11
  87. package/dist/index.js +12 -11
  88. package/dist/index.js.map +1 -1
  89. package/dist/main.d.ts +2 -0
  90. package/dist/main.js +10 -0
  91. package/dist/main.js.map +1 -0
  92. package/dist/package.json +51 -0
  93. package/dist/platform/KeyValueStore.d.ts +6 -0
  94. package/dist/platform/KeyValueStore.js +96 -0
  95. package/dist/platform/KeyValueStore.js.map +1 -0
  96. package/dist/platform/index.d.ts +1 -0
  97. package/dist/platform/index.js +2 -0
  98. package/dist/platform/index.js.map +1 -0
  99. package/dist/socket_util.d.ts +4 -0
  100. package/dist/socket_util.js +18 -0
  101. package/dist/socket_util.js.map +1 -0
  102. package/dist/tsconfig.tsbuildinfo +1 -1
  103. package/dist/{Accumulator.js → util/Accumulator.js} +1 -1
  104. package/dist/util/Accumulator.js.map +1 -0
  105. package/dist/util/Diagnostic.js.map +1 -0
  106. package/dist/util/Mutex.js.map +1 -0
  107. package/dist/util/boundLayer.js.map +1 -0
  108. package/dist/util/logCause.js.map +1 -0
  109. package/dist/util/phantom.js.map +1 -0
  110. package/dist/util/schema.js.map +1 -0
  111. package/index.ts +12 -11
  112. package/main.ts +19 -0
  113. package/package.json +23 -2
  114. package/platform/KeyValueStore.ts +112 -0
  115. package/platform/index.ts +1 -0
  116. package/socket_util.ts +20 -0
  117. package/tsconfig.json +3 -2
  118. package/{Accumulator.ts → util/Accumulator.ts} +1 -1
  119. package/_constants.ts +0 -1
  120. package/dist/Accumulator.js.map +0 -1
  121. package/dist/Actor.js.map +0 -1
  122. package/dist/ActorTransport.js.map +0 -1
  123. package/dist/Audition.js.map +0 -1
  124. package/dist/Client.js.map +0 -1
  125. package/dist/ClientDirectory.js.map +0 -1
  126. package/dist/ClientHandle.js.map +0 -1
  127. package/dist/F.js.map +0 -1
  128. package/dist/Method.js.map +0 -1
  129. package/dist/Protocol.js.map +0 -1
  130. package/dist/_constants.d.ts +0 -1
  131. package/dist/_constants.js +0 -2
  132. package/dist/_constants.js.map +0 -1
  133. package/dist/_util/Diagnostic.js.map +0 -1
  134. package/dist/_util/Mutex.js.map +0 -1
  135. package/dist/_util/boundLayer.js.map +0 -1
  136. package/dist/_util/logCause.js.map +0 -1
  137. package/dist/_util/phantom.js.map +0 -1
  138. package/dist/_util/schema.js.map +0 -1
  139. package/dist/errors.js.map +0 -1
  140. /package/{ActorTransport.ts → actor/ActorTransport.ts} +0 -0
  141. /package/{ClientHandle.ts → actor/ClientHandle.ts} +0 -0
  142. /package/{F.ts → actor/F.ts} +0 -0
  143. /package/{Method.ts → actor/Method.ts} +0 -0
  144. /package/{Protocol.ts → actor/Protocol.ts} +0 -0
  145. /package/{errors.ts → actor/errors.ts} +0 -0
  146. /package/dist/{ActorTransport.d.ts → actor/ActorTransport.d.ts} +0 -0
  147. /package/dist/{ActorTransport.js → actor/ActorTransport.js} +0 -0
  148. /package/dist/{Audition.d.ts → actor/Audition.d.ts} +0 -0
  149. /package/dist/{Client.d.ts → actor/Client.d.ts} +0 -0
  150. /package/dist/{ClientHandle.d.ts → actor/ClientHandle.d.ts} +0 -0
  151. /package/dist/{ClientHandle.js → actor/ClientHandle.js} +0 -0
  152. /package/dist/{F.d.ts → actor/F.d.ts} +0 -0
  153. /package/dist/{F.js → actor/F.js} +0 -0
  154. /package/dist/{Method.d.ts → actor/Method.d.ts} +0 -0
  155. /package/dist/{Method.js → actor/Method.js} +0 -0
  156. /package/dist/{Protocol.d.ts → actor/Protocol.d.ts} +0 -0
  157. /package/dist/{Protocol.js → actor/Protocol.js} +0 -0
  158. /package/dist/{errors.d.ts → actor/errors.d.ts} +0 -0
  159. /package/dist/{errors.js → actor/errors.js} +0 -0
  160. /package/dist/{Accumulator.d.ts → util/Accumulator.d.ts} +0 -0
  161. /package/dist/{_util → util}/Diagnostic.d.ts +0 -0
  162. /package/dist/{_util → util}/Diagnostic.js +0 -0
  163. /package/dist/{_util → util}/Mutex.d.ts +0 -0
  164. /package/dist/{_util → util}/Mutex.js +0 -0
  165. /package/dist/{_util → util}/boundLayer.d.ts +0 -0
  166. /package/dist/{_util → util}/boundLayer.js +0 -0
  167. /package/dist/{_util → util}/logCause.d.ts +0 -0
  168. /package/dist/{_util → util}/logCause.js +0 -0
  169. /package/dist/{_util → util}/phantom.d.ts +0 -0
  170. /package/dist/{_util → util}/phantom.js +0 -0
  171. /package/dist/{_util → util}/schema.d.ts +0 -0
  172. /package/dist/{_util → util}/schema.js +0 -0
  173. /package/{_util → util}/Diagnostic.ts +0 -0
  174. /package/{_util → util}/Mutex.ts +0 -0
  175. /package/{_util → util}/boundLayer.ts +0 -0
  176. /package/{_util → util}/logCause.ts +0 -0
  177. /package/{_util → util}/phantom.ts +0 -0
  178. /package/{_util → util}/schema.ts +0 -0
package/Ai.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { Context } from "effect"
2
+
3
+ import * as Binding from "./Binding.ts"
4
+
5
+ export class Ai extends Context.Service<Ai, globalThis.Ai>()("liminal/Ai") {}
6
+
7
+ export const layer = Binding.layer(Ai, ["run"])
package/Assets.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { Effect, Context } from "effect"
2
+ import { HttpServerResponse } from "effect/unstable/http"
3
+
4
+ import * as Binding from "./Binding.ts"
5
+ import { NativeRequest } from "./NativeRequest.ts"
6
+
7
+ export class Assets extends Context.Service<
8
+ Assets,
9
+ {
10
+ readonly fetch: typeof fetch
11
+ }
12
+ >()("liminal/Assets") {}
13
+
14
+ export const layer = Binding.layer(Assets, ["fetch"])
15
+
16
+ export const forward = Effect.gen({ self: this }, function* () {
17
+ const assets = yield* Assets
18
+ const request = yield* NativeRequest
19
+ const response = yield* Effect.promise(() => assets.fetch(request))
20
+ return HttpServerResponse.fromWeb(response)
21
+ })
package/Binding.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { env } from "cloudflare:workers"
2
+ import { Context, Layer, Effect, Schema as S, SchemaIssue } from "effect"
3
+
4
+ export const layer =
5
+ <Self, Identifier extends string, Shape, ROut = never, E = never, RIn = never>(
6
+ tag: Context.ServiceClass<Self, Identifier, Shape>,
7
+ keys: ReadonlyArray<string>,
8
+ derive?: (resource: Shape) => Layer.Layer<ROut, E, RIn> | undefined,
9
+ ) =>
10
+ (binding: string) =>
11
+ Effect.gen(function* () {
12
+ const resolved = (env as never)[binding]
13
+ if (!resolved) {
14
+ return yield* Effect.fail(
15
+ new S.SchemaError(
16
+ new SchemaIssue.Pointer(
17
+ [binding],
18
+ new SchemaIssue.MissingKey({
19
+ messageMissingKey: `Missing binding "${binding}" on env`,
20
+ }),
21
+ ),
22
+ ),
23
+ )
24
+ }
25
+ for (const key of keys) {
26
+ if (!(key in resolved)) {
27
+ return yield* Effect.fail(
28
+ new S.SchemaError(
29
+ new SchemaIssue.Pointer(
30
+ [key],
31
+ new SchemaIssue.MissingKey({
32
+ messageMissingKey: `Expected key \`${key}\` on binding \`${binding}\``,
33
+ }),
34
+ ),
35
+ ),
36
+ )
37
+ }
38
+ }
39
+ return Layer.mergeAll(Layer.succeed(tag, resolved), derive?.(resolved) ?? Layer.empty)
40
+ }).pipe(Layer.unwrap)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # liminal
2
2
 
3
+ ## 0.17.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 01eb088: Move everything cloudflare-related directly into liminal.
8
+
9
+ ## 0.17.10
10
+
11
+ ### Patch Changes
12
+
13
+ - 9583d0e: Rework the module structure for bindings.
14
+
3
15
  ## 0.17.9
4
16
 
5
17
  ### Patch Changes
@@ -28,7 +40,8 @@
28
40
 
29
41
  ### Patch Changes
30
42
 
31
- - 7a05f2b: Improve built-in logging. Add AI resource. Resolve issue in which client listener suspense propagated suspense to streams and calls.
43
+ - 7a05f2b: Improve built-in logging. Add AI resource. Resolve issue in which client listener suspense propagated
44
+ suspense to streams and calls.
32
45
 
33
46
  ## 0.17.4
34
47
 
package/D1.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { D1Client } from "@effect/sql-d1"
2
+ import { Context } from "effect"
3
+
4
+ import * as Binding from "./Binding.ts"
5
+
6
+ export class D1 extends Context.Service<D1, D1Database>()("liminal/D1") {}
7
+
8
+ export const layer = Binding.layer(D1, ["exec"], (db) => D1Client.layer({ db }))
package/DoState.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Context } from "effect"
2
+
3
+ export class DoState extends Context.Service<DoState, globalThis.DurableObjectState<{}>>()("liminal/DoState") {}
package/Hyperdrive.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Effect, Redacted, Context } from "effect"
2
+
3
+ import * as Binding from "./Binding.ts"
4
+
5
+ export class Hyperdrive extends Context.Service<Hyperdrive, globalThis.Hyperdrive>()("liminal/Hyperdrive") {}
6
+
7
+ export const layer = Binding.layer(Hyperdrive, ["connectionString"])
8
+
9
+ export const connectionString = Hyperdrive.asEffect().pipe(
10
+ Effect.map(({ connectionString }) => Redacted.make(connectionString)),
11
+ )
package/Images.ts ADDED
@@ -0,0 +1,101 @@
1
+ import { Data, Context, Pipeable, Function, Effect } from "effect"
2
+
3
+ import * as Binding from "./Binding.ts"
4
+
5
+ export class Images extends Context.Service<Images, globalThis.ImagesBinding>()("liminal/ImageTransformer") {}
6
+
7
+ export const layer = Binding.layer(Images, ["transform", "draw", "output"])
8
+
9
+ const TypeId = "~liminal/Images/Transformation" as const
10
+
11
+ export interface Steps extends Pipeable.Pipeable {
12
+ readonly [TypeId]: typeof TypeId
13
+ readonly steps: ReadonlyArray<Step>
14
+ }
15
+
16
+ export interface DrawOptions {
17
+ image: ReadableStream<Uint8Array> | ImageTransformer
18
+ options?: ImageDrawOptions | undefined
19
+ }
20
+
21
+ export type Step = Data.TaggedEnum<{
22
+ Transform: {
23
+ transform: ImageTransform
24
+ }
25
+ Draw: DrawOptions
26
+ }>
27
+
28
+ export const empty: Steps = {
29
+ [TypeId]: TypeId,
30
+ steps: [],
31
+ pipe() {
32
+ return Pipeable.pipeArguments(this, arguments)
33
+ },
34
+ }
35
+
36
+ export const transform: {
37
+ (transform: ImageTransform): (steps: Steps) => Steps
38
+ (steps: Steps, transform: ImageTransform): Steps
39
+ } = Function.dual(2, (steps: Steps, transform: ImageTransform) => ({
40
+ [TypeId]: TypeId,
41
+ steps: [
42
+ ...steps.steps,
43
+ {
44
+ _tag: "Transform",
45
+ transform,
46
+ },
47
+ ],
48
+ pipe() {
49
+ return Pipeable.pipeArguments(this, arguments)
50
+ },
51
+ }))
52
+
53
+ export const draw: {
54
+ (draw: DrawOptions): (steps: Steps) => Steps
55
+ (steps: Steps, draw: DrawOptions): Steps
56
+ } = Function.dual(2, (steps: Steps, draw: DrawOptions) => ({
57
+ [TypeId]: TypeId,
58
+ steps: [
59
+ ...steps.steps,
60
+ {
61
+ _tag: "Draw",
62
+ ...draw,
63
+ },
64
+ ],
65
+ pipe() {
66
+ return Pipeable.pipeArguments(this, arguments)
67
+ },
68
+ }))
69
+
70
+ export interface ProcessConfig {
71
+ readonly stream: ReadableStream<Uint8Array>
72
+ readonly inputOptions?: ImageInputOptions | undefined
73
+ readonly outputOptions: ImageOutputOptions
74
+ }
75
+
76
+ export const process: {
77
+ (config: ProcessConfig): (steps: Steps) => Effect.Effect<ImageTransformationResult, never, Images>
78
+ (steps: Steps, config: ProcessConfig): Effect.Effect<ImageTransformationResult, never, Images>
79
+ } = Function.dual(
80
+ 2,
81
+ Effect.fnUntraced(function* ({ steps }: Steps, { stream, inputOptions, outputOptions }: ProcessConfig) {
82
+ const images = yield* Images
83
+ let transformer = images.input(stream, inputOptions)
84
+ for (let i = 0; i < steps.length; i++) {
85
+ const step = steps[i]!
86
+ switch (step._tag) {
87
+ case "Draw": {
88
+ const { image, options } = step
89
+ transformer = transformer.draw(image, options)
90
+ break
91
+ }
92
+ case "Transform": {
93
+ const { transform } = step
94
+ transformer = transformer.transform(transform)
95
+ break
96
+ }
97
+ }
98
+ }
99
+ return yield* Effect.promise(() => transformer.output(outputOptions))
100
+ }),
101
+ )
package/Kv.ts ADDED
@@ -0,0 +1,65 @@
1
+ import { Effect, Schema as S, Option, Context, Layer } from "effect"
2
+
3
+ import * as Binding from "./Binding.ts"
4
+
5
+ export interface Kv<
6
+ Self,
7
+ Id extends string,
8
+ Key extends S.Top & { Encoded: string },
9
+ Value extends S.Top,
10
+ > extends Context.Service<Self, KVNamespace> {
11
+ new (_: never): Context.ServiceClass<Self, Id, KVNamespace>
12
+
13
+ ""?: [Key, Value]
14
+
15
+ readonly put: (key: Key["Type"], value: Value["Type"]) => Effect.Effect<void, S.SchemaError, Self>
16
+
17
+ readonly get: (key: Key["Type"]) => Effect.Effect<Option.Option<Value["Type"]>, S.SchemaError, Self>
18
+
19
+ readonly remove: (key: Key["Type"]) => Effect.Effect<void, S.SchemaError, Self>
20
+
21
+ readonly layer: (binding: string) => Layer.Layer<Self, S.SchemaError>
22
+ }
23
+
24
+ export const Kv =
25
+ <Self>() =>
26
+ <Id extends string, Key extends S.Top & { Encoded: string }, Value extends S.Top>(
27
+ id: Id,
28
+ definition: {
29
+ readonly key: Key
30
+ readonly value: Value
31
+ },
32
+ ): Kv<Self, Id, Key, Value> => {
33
+ const tag = Context.Service<Self, KVNamespace>()(id)
34
+
35
+ const { key, value } = definition
36
+ const encodeKey = S.encodeEffect(key)
37
+ const encodeValue = S.encodeEffect(S.fromJsonString(S.toCodecJson(value)))
38
+ const decodeValue = S.decodeUnknownEffect(S.fromJsonString(S.toCodecJson(value)))
39
+
40
+ const put = Effect.fnUntraced(function* (key: Key["Type"], value: Value["Type"]) {
41
+ const kv = yield* tag
42
+ const keyEncoded = yield* encodeKey(key)
43
+ const valueEncoded = yield* encodeValue(value)
44
+ yield* Effect.promise(() => kv.put(keyEncoded, valueEncoded))
45
+ })
46
+
47
+ const get = Effect.fnUntraced(function* (key: Key["Type"]) {
48
+ const kv = yield* tag
49
+ const keyEncoded = yield* encodeKey(key)
50
+ const valueEncoded = yield* Effect.promise(() => kv.get(keyEncoded))
51
+ if (valueEncoded) {
52
+ return yield* decodeValue(valueEncoded).pipe(Effect.map(Option.some))
53
+ }
54
+ return Option.none()
55
+ })
56
+
57
+ const remove = Effect.fnUntraced(function* (key: Key["Type"]) {
58
+ const kv = yield* tag
59
+ const keyEncoded = yield* encodeKey(key)
60
+ yield* Effect.promise(() => kv.delete(keyEncoded))
61
+ })
62
+
63
+ const layer = Binding.layer(tag, ["put", "get", "delete"])
64
+ return Object.assign(tag, { definition, put, get, remove, layer }) as never
65
+ }
@@ -0,0 +1,3 @@
1
+ import { Context } from "effect"
2
+
3
+ export class NativeRequest extends Context.Service<NativeRequest, Request>()("liminal/NativeRequest") {}
package/R2.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { Context } from "effect"
2
+
3
+ import * as Binding from "./Binding.ts"
4
+
5
+ export class R2 extends Context.Service<R2, R2Bucket>()("liminal/R2") {}
6
+
7
+ export const layer = Binding.layer(R2, ["put", "get"])
package/Worker.ts ADDED
@@ -0,0 +1,54 @@
1
+ import { env } from "cloudflare:workers"
2
+ import { Context, Layer, Scope, Effect, ManagedRuntime, ConfigProvider } from "effect"
3
+ import {
4
+ HttpServerRequest,
5
+ HttpServerResponse,
6
+ HttpServerError,
7
+ HttpClient,
8
+ FetchHttpClient,
9
+ } from "effect/unstable/http"
10
+
11
+ import { NativeRequest } from "./NativeRequest.ts"
12
+ import * as Diagnostic from "./util/Diagnostic.ts"
13
+ import { logCause } from "./util/logCause.ts"
14
+
15
+ const { span } = Diagnostic.module("cloudflare.Entry")
16
+
17
+ export class ExecutionContext extends Context.Service<ExecutionContext, globalThis.ExecutionContext>()(
18
+ "liminal/ExecutionContext",
19
+ ) {}
20
+
21
+ export interface WorkerConfig<ROut, E> {
22
+ readonly prelude: Layer.Layer<ROut, E>
23
+ readonly handler: Effect.Effect<
24
+ HttpServerResponse.HttpServerResponse,
25
+ HttpServerError.HttpServerError,
26
+ ExecutionContext | HttpServerRequest.HttpServerRequest | HttpClient.HttpClient | NativeRequest | ROut | Scope.Scope
27
+ >
28
+ }
29
+
30
+ export const make = <ROut, E>({ handler, prelude: layer }: WorkerConfig<ROut, E>) => {
31
+ const runtime = ManagedRuntime.make(
32
+ Layer.mergeAll(FetchHttpClient.layer, ConfigProvider.layer(ConfigProvider.fromUnknown(env))),
33
+ )
34
+ const fetch = (request: Request, _env: unknown, ctx: globalThis.ExecutionContext): Promise<Response> =>
35
+ handler.pipe(
36
+ Effect.map(HttpServerResponse.toWeb),
37
+ Effect.provide([
38
+ layer,
39
+ Layer.succeed(ExecutionContext, ctx),
40
+ Layer.succeed(NativeRequest, request),
41
+ Layer.succeed(HttpServerRequest.HttpServerRequest, HttpServerRequest.fromWeb(request)),
42
+ ]),
43
+ Effect.scoped,
44
+ Effect.tapCause(logCause),
45
+ span("fetch"),
46
+ // Solves crashes between HMRs.
47
+ // Without this, in-flight requests use an old memoMap; new requests use a new one.
48
+ // Aka. cross-contamination.
49
+ // TODO: investigate whether better-solved by https://github.com/dmmulroy/effect-cloudflare/blob/main/src/internal/wrangler.ts
50
+ Effect.provideService(Layer.CurrentMemoMap, runtime.memoMap),
51
+ runtime.runPromise,
52
+ )
53
+ return { fetch }
54
+ }
@@ -0,0 +1,29 @@
1
+ import { absurd, Effect, Context } from "effect"
2
+ import { HttpServerResponse } from "effect/unstable/http"
3
+
4
+ import * as Binding from "./Binding.ts"
5
+
6
+ export class WorkerLoader extends Context.Service<WorkerLoader, globalThis.WorkerLoader>()("liminal/WorkerLoader") {}
7
+
8
+ export const layer = Binding.layer(WorkerLoader, ["load"])
9
+
10
+ export const load = (id: string, code: string) =>
11
+ Effect.gen({ self: this }, function* () {
12
+ const loader = yield* WorkerLoader
13
+ return loader.get(id, () => ({
14
+ compatibilityDate: "2026-04-21",
15
+ mainModule: "main.js",
16
+ modules: { "main.js": code },
17
+ allowExperimental: true,
18
+ globalOutbound: null,
19
+ }))
20
+ })
21
+
22
+ export const run = (id: string, request: Request) =>
23
+ Effect.gen({ self: this }, function* () {
24
+ const loader = yield* WorkerLoader
25
+ const worker = loader.get(id, () => absurd<never>(null!))
26
+ return yield* Effect.tryPromise(() => worker.getEntrypoint().fetch(request)).pipe(
27
+ Effect.map(HttpServerResponse.fromWeb),
28
+ )
29
+ })
@@ -1,10 +1,10 @@
1
1
  import { Context, Schema as S, Effect } from "effect"
2
2
 
3
- import type { TopFromString } from "./_util/schema.ts"
3
+ import type { TopFromString } from "../util/schema.ts"
4
4
  import type * as ActorClient from "./Client.ts"
5
5
  import type { ClientHandle, Sender } from "./ClientHandle.ts"
6
6
 
7
- import * as Diagnostic from "./_util/Diagnostic.ts"
7
+ import * as Diagnostic from "../util/Diagnostic.ts"
8
8
  import * as Method from "./Method.ts"
9
9
  import { type ProtocolDefinition } from "./Protocol.ts"
10
10