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.
- package/Ai.ts +7 -0
- package/Assets.ts +21 -0
- package/Binding.ts +40 -0
- package/CHANGELOG.md +14 -1
- package/D1.ts +8 -0
- package/DoState.ts +3 -0
- package/Hyperdrive.ts +11 -0
- package/Images.ts +101 -0
- package/Kv.ts +65 -0
- package/NativeRequest.ts +3 -0
- package/R2.ts +7 -0
- package/Worker.ts +54 -0
- package/WorkerLoader.ts +29 -0
- package/{Actor.ts → actor/Actor.ts} +2 -2
- package/actor/ActorRegistry.ts +361 -0
- package/{Audition.ts → actor/Audition.ts} +1 -1
- package/{Client.ts → actor/Client.ts} +2 -2
- package/{ClientDirectory.ts → actor/ClientDirectory.ts} +3 -3
- package/actor/index.ts +11 -0
- package/asset_forwarding.ts +13 -0
- package/commands/sync-env.ts +30 -0
- package/dist/Ai.d.ts +6 -0
- package/dist/Ai.js +6 -0
- package/dist/Ai.js.map +1 -0
- package/dist/Assets.d.ts +11 -0
- package/dist/Assets.js +14 -0
- package/dist/Assets.js.map +1 -0
- package/dist/Binding.d.ts +2 -0
- package/dist/Binding.js +19 -0
- package/dist/Binding.js.map +1 -0
- package/dist/D1.d.ts +7 -0
- package/dist/D1.js +7 -0
- package/dist/D1.js.map +1 -0
- package/dist/DoState.d.ts +5 -0
- package/dist/DoState.js +4 -0
- package/dist/DoState.js.map +1 -0
- package/dist/Hyperdrive.d.ts +7 -0
- package/dist/Hyperdrive.js +7 -0
- package/dist/Hyperdrive.js.map +1 -0
- package/dist/Images.d.ts +39 -0
- package/dist/Images.js +60 -0
- package/dist/Images.js.map +1 -0
- package/dist/Kv.d.ts +17 -0
- package/dist/Kv.js +32 -0
- package/dist/Kv.js.map +1 -0
- package/dist/NativeRequest.d.ts +5 -0
- package/dist/NativeRequest.js +4 -0
- package/dist/NativeRequest.js.map +1 -0
- package/dist/R2.d.ts +6 -0
- package/dist/R2.js +6 -0
- package/dist/R2.js.map +1 -0
- package/dist/Worker.d.ts +14 -0
- package/dist/Worker.js +25 -0
- package/dist/Worker.js.map +1 -0
- package/dist/WorkerLoader.d.ts +9 -0
- package/dist/WorkerLoader.js +22 -0
- package/dist/WorkerLoader.js.map +1 -0
- package/dist/{Actor.d.ts → actor/Actor.d.ts} +1 -1
- package/dist/{Actor.js → actor/Actor.js} +1 -1
- package/dist/actor/Actor.js.map +1 -0
- package/dist/actor/ActorRegistry.d.ts +23 -0
- package/dist/actor/ActorRegistry.js +153 -0
- package/dist/actor/ActorRegistry.js.map +1 -0
- package/dist/actor/ActorTransport.js.map +1 -0
- package/dist/{Audition.js → actor/Audition.js} +1 -1
- package/dist/actor/Audition.js.map +1 -0
- package/dist/{Client.js → actor/Client.js} +2 -2
- package/dist/actor/Client.js.map +1 -0
- package/dist/{ClientDirectory.d.ts → actor/ClientDirectory.d.ts} +1 -1
- package/dist/{ClientDirectory.js → actor/ClientDirectory.js} +2 -2
- package/dist/actor/ClientDirectory.js.map +1 -0
- package/dist/actor/ClientHandle.js.map +1 -0
- package/dist/actor/F.js.map +1 -0
- package/dist/actor/Method.js.map +1 -0
- package/dist/actor/Protocol.js.map +1 -0
- package/dist/actor/errors.js.map +1 -0
- package/dist/actor/index.d.ts +11 -0
- package/dist/actor/index.js +12 -0
- package/dist/actor/index.js.map +1 -0
- package/dist/asset_forwarding.d.ts +4 -0
- package/dist/asset_forwarding.js +9 -0
- package/dist/asset_forwarding.js.map +1 -0
- package/dist/commands/sync-env.d.ts +8 -0
- package/dist/commands/sync-env.js +32 -0
- package/dist/commands/sync-env.js.map +1 -0
- package/dist/index.d.ts +12 -11
- package/dist/index.js +12 -11
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +2 -0
- package/dist/main.js +10 -0
- package/dist/main.js.map +1 -0
- package/dist/package.json +51 -0
- package/dist/platform/KeyValueStore.d.ts +6 -0
- package/dist/platform/KeyValueStore.js +96 -0
- package/dist/platform/KeyValueStore.js.map +1 -0
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +2 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/socket_util.d.ts +4 -0
- package/dist/socket_util.js +18 -0
- package/dist/socket_util.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{Accumulator.js → util/Accumulator.js} +1 -1
- package/dist/util/Accumulator.js.map +1 -0
- package/dist/util/Diagnostic.js.map +1 -0
- package/dist/util/Mutex.js.map +1 -0
- package/dist/util/boundLayer.js.map +1 -0
- package/dist/util/logCause.js.map +1 -0
- package/dist/util/phantom.js.map +1 -0
- package/dist/util/schema.js.map +1 -0
- package/index.ts +12 -11
- package/main.ts +19 -0
- package/package.json +23 -2
- package/platform/KeyValueStore.ts +112 -0
- package/platform/index.ts +1 -0
- package/socket_util.ts +20 -0
- package/tsconfig.json +3 -2
- package/{Accumulator.ts → util/Accumulator.ts} +1 -1
- package/_constants.ts +0 -1
- package/dist/Accumulator.js.map +0 -1
- package/dist/Actor.js.map +0 -1
- package/dist/ActorTransport.js.map +0 -1
- package/dist/Audition.js.map +0 -1
- package/dist/Client.js.map +0 -1
- package/dist/ClientDirectory.js.map +0 -1
- package/dist/ClientHandle.js.map +0 -1
- package/dist/F.js.map +0 -1
- package/dist/Method.js.map +0 -1
- package/dist/Protocol.js.map +0 -1
- package/dist/_constants.d.ts +0 -1
- package/dist/_constants.js +0 -2
- package/dist/_constants.js.map +0 -1
- package/dist/_util/Diagnostic.js.map +0 -1
- package/dist/_util/Mutex.js.map +0 -1
- package/dist/_util/boundLayer.js.map +0 -1
- package/dist/_util/logCause.js.map +0 -1
- package/dist/_util/phantom.js.map +0 -1
- package/dist/_util/schema.js.map +0 -1
- package/dist/errors.js.map +0 -1
- /package/{ActorTransport.ts → actor/ActorTransport.ts} +0 -0
- /package/{ClientHandle.ts → actor/ClientHandle.ts} +0 -0
- /package/{F.ts → actor/F.ts} +0 -0
- /package/{Method.ts → actor/Method.ts} +0 -0
- /package/{Protocol.ts → actor/Protocol.ts} +0 -0
- /package/{errors.ts → actor/errors.ts} +0 -0
- /package/dist/{ActorTransport.d.ts → actor/ActorTransport.d.ts} +0 -0
- /package/dist/{ActorTransport.js → actor/ActorTransport.js} +0 -0
- /package/dist/{Audition.d.ts → actor/Audition.d.ts} +0 -0
- /package/dist/{Client.d.ts → actor/Client.d.ts} +0 -0
- /package/dist/{ClientHandle.d.ts → actor/ClientHandle.d.ts} +0 -0
- /package/dist/{ClientHandle.js → actor/ClientHandle.js} +0 -0
- /package/dist/{F.d.ts → actor/F.d.ts} +0 -0
- /package/dist/{F.js → actor/F.js} +0 -0
- /package/dist/{Method.d.ts → actor/Method.d.ts} +0 -0
- /package/dist/{Method.js → actor/Method.js} +0 -0
- /package/dist/{Protocol.d.ts → actor/Protocol.d.ts} +0 -0
- /package/dist/{Protocol.js → actor/Protocol.js} +0 -0
- /package/dist/{errors.d.ts → actor/errors.d.ts} +0 -0
- /package/dist/{errors.js → actor/errors.js} +0 -0
- /package/dist/{Accumulator.d.ts → util/Accumulator.d.ts} +0 -0
- /package/dist/{_util → util}/Diagnostic.d.ts +0 -0
- /package/dist/{_util → util}/Diagnostic.js +0 -0
- /package/dist/{_util → util}/Mutex.d.ts +0 -0
- /package/dist/{_util → util}/Mutex.js +0 -0
- /package/dist/{_util → util}/boundLayer.d.ts +0 -0
- /package/dist/{_util → util}/boundLayer.js +0 -0
- /package/dist/{_util → util}/logCause.d.ts +0 -0
- /package/dist/{_util → util}/logCause.js +0 -0
- /package/dist/{_util → util}/phantom.d.ts +0 -0
- /package/dist/{_util → util}/phantom.js +0 -0
- /package/dist/{_util → util}/schema.d.ts +0 -0
- /package/dist/{_util → util}/schema.js +0 -0
- /package/{_util → util}/Diagnostic.ts +0 -0
- /package/{_util → util}/Mutex.ts +0 -0
- /package/{_util → util}/boundLayer.ts +0 -0
- /package/{_util → util}/logCause.ts +0 -0
- /package/{_util → util}/phantom.ts +0 -0
- /package/{_util → util}/schema.ts +0 -0
package/Ai.ts
ADDED
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
|
|
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
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
|
+
}
|
package/NativeRequest.ts
ADDED
package/R2.ts
ADDED
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
|
+
}
|
package/WorkerLoader.ts
ADDED
|
@@ -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 "
|
|
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 "
|
|
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
|
|