alchemy 2.0.0-beta.36 → 2.0.0-beta.37
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/bin/exec.js +166 -43
- package/bin/exec.js.map +1 -1
- package/lib/AWS/Lambda/Function.d.ts.map +1 -1
- package/lib/AWS/Lambda/Function.js +22 -2
- package/lib/AWS/Lambda/Function.js.map +1 -1
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +6 -1
- package/lib/Apply.js.map +1 -1
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.d.ts +54 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.js +17 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.js.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.d.ts +37 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js +45 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/index.d.ts +3 -0
- package/lib/Cloudflare/AnalyticsEngine/index.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/index.js +3 -0
- package/lib/Cloudflare/AnalyticsEngine/index.js.map +1 -0
- package/lib/Cloudflare/D1/D1Connection.d.ts +47 -3
- package/lib/Cloudflare/D1/D1Connection.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Connection.js +62 -5
- package/lib/Cloudflare/D1/D1Connection.js.map +1 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js +9 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js.map +1 -1
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +4 -1
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.js +16 -0
- package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +6 -1
- package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Api.js +23 -1
- package/lib/Cloudflare/StateStore/Api.js.map +1 -1
- package/lib/Cloudflare/StateStore/Store.d.ts +16 -1
- package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Store.js +22 -5
- package/lib/Cloudflare/StateStore/Store.js.map +1 -1
- package/lib/Cloudflare/Workers/CronEventSource.d.ts +35 -0
- package/lib/Cloudflare/Workers/CronEventSource.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/CronEventSource.js +55 -0
- package/lib/Cloudflare/Workers/CronEventSource.js.map +1 -0
- package/lib/Cloudflare/Workers/InferEnv.d.ts +37 -2
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +2 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.d.ts +76 -3
- package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.js +197 -13
- package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +22 -2
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +174 -43
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.js +15 -5
- package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.d.ts +50 -47
- package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.js +41 -35
- package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
- package/lib/Cloudflare/Workers/index.d.ts +1 -0
- package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/index.js +1 -0
- package/lib/Cloudflare/Workers/index.js.map +1 -1
- package/lib/Cloudflare/index.d.ts +1 -0
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +1 -0
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Deploy.d.ts +4 -1
- package/lib/Deploy.d.ts.map +1 -1
- package/lib/Deploy.js +2 -2
- package/lib/Deploy.js.map +1 -1
- package/lib/Destroy.d.ts +4 -1
- package/lib/Destroy.d.ts.map +1 -1
- package/lib/Destroy.js +2 -2
- package/lib/Destroy.js.map +1 -1
- package/lib/Output.d.ts +45 -5
- package/lib/Output.d.ts.map +1 -1
- package/lib/Output.js +100 -4
- package/lib/Output.js.map +1 -1
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +93 -12
- package/lib/Plan.js.map +1 -1
- package/lib/Platform.d.ts.map +1 -1
- package/lib/Platform.js +16 -3
- package/lib/Platform.js.map +1 -1
- package/lib/Ref.d.ts +4 -1
- package/lib/Ref.d.ts.map +1 -1
- package/lib/Ref.js +1 -1
- package/lib/Ref.js.map +1 -1
- package/lib/Resource.d.ts +8 -0
- package/lib/Resource.d.ts.map +1 -1
- package/lib/Resource.js +10 -0
- package/lib/Resource.js.map +1 -1
- package/lib/RuntimeContext.d.ts +3 -1
- package/lib/RuntimeContext.d.ts.map +1 -1
- package/lib/RuntimeContext.js.map +1 -1
- package/lib/Secret.d.ts +50 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +23 -0
- package/lib/Secret.js.map +1 -0
- package/lib/Serverless/Function.d.ts +9 -1
- package/lib/Serverless/Function.d.ts.map +1 -1
- package/lib/Stack.d.ts +14 -5
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +31 -19
- package/lib/Stack.js.map +1 -1
- package/lib/State/HttpStateApi.d.ts +15 -1
- package/lib/State/HttpStateApi.d.ts.map +1 -1
- package/lib/State/HttpStateApi.js +11 -0
- package/lib/State/HttpStateApi.js.map +1 -1
- package/lib/State/HttpStateStore.d.ts.map +1 -1
- package/lib/State/HttpStateStore.js +11 -0
- package/lib/State/HttpStateStore.js.map +1 -1
- package/lib/State/InMemoryState.d.ts +2 -2
- package/lib/State/InMemoryState.d.ts.map +1 -1
- package/lib/State/InMemoryState.js +12 -6
- package/lib/State/InMemoryState.js.map +1 -1
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +11 -2
- package/lib/State/LocalState.js.map +1 -1
- package/lib/State/State.d.ts +21 -0
- package/lib/State/State.d.ts.map +1 -1
- package/lib/Test/Bun.d.ts.map +1 -1
- package/lib/Test/Bun.js +30 -7
- package/lib/Test/Bun.js.map +1 -1
- package/lib/Test/Core.d.ts +17 -2
- package/lib/Test/Core.d.ts.map +1 -1
- package/lib/Test/Core.js +29 -11
- package/lib/Test/Core.js.map +1 -1
- package/lib/Test/Vitest.d.ts.map +1 -1
- package/lib/Test/Vitest.js +24 -5
- package/lib/Test/Vitest.js.map +1 -1
- package/lib/Util/LocalhostDns.d.ts +14 -10
- package/lib/Util/LocalhostDns.d.ts.map +1 -1
- package/lib/Util/LocalhostDns.js +27 -36
- package/lib/Util/LocalhostDns.js.map +1 -1
- package/lib/Util/effect.d.ts +7 -0
- package/lib/Util/effect.d.ts.map +1 -1
- package/lib/Util/effect.js +6 -0
- package/lib/Util/effect.js.map +1 -1
- package/lib/Variable.d.ts +29 -0
- package/lib/Variable.d.ts.map +1 -0
- package/lib/Variable.js +9 -0
- package/lib/Variable.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +6 -7
- package/src/AWS/Lambda/Function.ts +30 -2
- package/src/Apply.ts +8 -1
- package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.ts +82 -0
- package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.ts +106 -0
- package/src/Cloudflare/AnalyticsEngine/index.ts +2 -0
- package/src/Cloudflare/D1/D1Connection.ts +95 -12
- package/src/Cloudflare/Local/SidecarHandlers.ts +9 -1
- package/src/Cloudflare/Providers.ts +5 -0
- package/src/Cloudflare/R2/R2Bucket.ts +31 -0
- package/src/Cloudflare/StateStore/Api.ts +34 -1
- package/src/Cloudflare/StateStore/Store.ts +40 -10
- package/src/Cloudflare/Workers/CronEventSource.ts +89 -0
- package/src/Cloudflare/Workers/InferEnv.ts +94 -20
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +9 -1
- package/src/Cloudflare/Workers/Rpc.ts +227 -18
- package/src/Cloudflare/Workers/Worker.ts +277 -63
- package/src/Cloudflare/Workers/WorkerBundle.ts +15 -5
- package/src/Cloudflare/Workers/Workflow.ts +74 -70
- package/src/Cloudflare/Workers/index.ts +1 -0
- package/src/Cloudflare/index.ts +1 -0
- package/src/Deploy.ts +5 -1
- package/src/Destroy.ts +5 -1
- package/src/Output.ts +121 -12
- package/src/Plan.ts +101 -12
- package/src/Platform.ts +19 -4
- package/src/Ref.ts +10 -5
- package/src/Resource.ts +22 -0
- package/src/RuntimeContext.ts +1 -0
- package/src/Secret.ts +87 -0
- package/src/Serverless/Function.ts +10 -1
- package/src/Stack.ts +52 -29
- package/src/State/HttpStateApi.ts +21 -0
- package/src/State/HttpStateStore.ts +21 -0
- package/src/State/InMemoryState.ts +29 -8
- package/src/State/LocalState.ts +28 -4
- package/src/State/State.ts +21 -0
- package/src/Test/Bun.ts +43 -7
- package/src/Test/Core.ts +29 -8
- package/src/Test/Vitest.ts +33 -4
- package/src/Util/LocalhostDns.ts +30 -36
- package/src/Util/effect.ts +25 -0
- package/src/Variable.ts +44 -0
- package/src/index.ts +3 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type * as cf from "@cloudflare/workers-types";
|
|
2
|
+
import * as Context from "effect/Context";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
import * as Binding from "../../Binding.ts";
|
|
6
|
+
import { RuntimeContext } from "../../RuntimeContext.ts";
|
|
7
|
+
/**
|
|
8
|
+
* Subscribe to Cloudflare Cron Triggers with an Effect handler.
|
|
9
|
+
*
|
|
10
|
+
* This wires both pieces of a scheduled Worker:
|
|
11
|
+
*
|
|
12
|
+
* - **Runtime**: registers a `scheduled` listener on the Worker.
|
|
13
|
+
* - **Deploy-time**: attaches the cron expression to the host Worker.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* yield* Cloudflare.cron("0 12 * * *").subscribe((controller) =>
|
|
18
|
+
* Effect.log(`scheduled at ${controller.scheduledTime}`),
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const cron: (expression: string) => {
|
|
23
|
+
subscribe: <Req = never>(process: (controller: cf.ScheduledController) => Effect.Effect<void, unknown, Req>) => Effect.Effect<void, never, CronEventSource>;
|
|
24
|
+
};
|
|
25
|
+
export type CronEventSourceService = <Req = never>(expression: string, process: (controller: cf.ScheduledController) => Effect.Effect<void, unknown, Req>) => Effect.Effect<void, never, never>;
|
|
26
|
+
declare const CronEventSource_base: Context.ServiceClass<CronEventSource, "Cloudflare.Workers.CronEventSource", CronEventSourceService>;
|
|
27
|
+
export declare class CronEventSource extends CronEventSource_base {
|
|
28
|
+
}
|
|
29
|
+
declare const CronEventSourcePolicy_base: Binding.Policy<CronEventSourcePolicy, "Policy<Cloudflare.Workers.CronEventSource>", (expression: string) => Effect.Effect<void>>;
|
|
30
|
+
export declare class CronEventSourcePolicy extends CronEventSourcePolicy_base {
|
|
31
|
+
}
|
|
32
|
+
export declare const CronEventSourcePolicyLive: Layer.Layer<CronEventSourcePolicy, never, never>;
|
|
33
|
+
export declare const CronEventSourceLive: Layer.Layer<CronEventSource, never, RuntimeContext<import("../../RuntimeContext.ts").BaseRuntimeContext> | CronEventSourcePolicy>;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=CronEventSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CronEventSource.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/CronEventSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAIzD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI,GAAI,YAAY,MAAM;gBACzB,GAAG,mBACJ,CACP,UAAU,EAAE,EAAE,CAAC,mBAAmB,KAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC;CAExC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,GAAG,GAAG,KAAK,EAC/C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CACP,UAAU,EAAE,EAAE,CAAC,mBAAmB,KAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,KACnC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;;AAEvC,qBAAa,eAAgB,SAAQ,oBAGI;CAAG;2IAI7B,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;AAF7C,qBAAa,qBAAsB,SAAQ,0BAGF;CAAG;AAE5C,eAAO,MAAM,yBAAyB,kDAarC,CAAC;AAEF,eAAO,MAAM,mBAAmB,mIAuB/B,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as Context from "effect/Context";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Layer from "effect/Layer";
|
|
4
|
+
import * as Binding from "../../Binding.js";
|
|
5
|
+
import { RuntimeContext } from "../../RuntimeContext.js";
|
|
6
|
+
import { isWorker, isWorkerEvent } from "./Worker.js";
|
|
7
|
+
/**
|
|
8
|
+
* Subscribe to Cloudflare Cron Triggers with an Effect handler.
|
|
9
|
+
*
|
|
10
|
+
* This wires both pieces of a scheduled Worker:
|
|
11
|
+
*
|
|
12
|
+
* - **Runtime**: registers a `scheduled` listener on the Worker.
|
|
13
|
+
* - **Deploy-time**: attaches the cron expression to the host Worker.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* yield* Cloudflare.cron("0 12 * * *").subscribe((controller) =>
|
|
18
|
+
* Effect.log(`scheduled at ${controller.scheduledTime}`),
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export const cron = (expression) => ({
|
|
23
|
+
subscribe: (process) => CronEventSource.use((source) => source(expression, process)),
|
|
24
|
+
});
|
|
25
|
+
export class CronEventSource extends Context.Service()("Cloudflare.Workers.CronEventSource") {
|
|
26
|
+
}
|
|
27
|
+
export class CronEventSourcePolicy extends Binding.Policy()("Cloudflare.Workers.CronEventSource") {
|
|
28
|
+
}
|
|
29
|
+
export const CronEventSourcePolicyLive = CronEventSourcePolicy.layer.succeed(Effect.fnUntraced(function* (host, expression) {
|
|
30
|
+
if (isWorker(host)) {
|
|
31
|
+
yield* host.bind(`Cron(${expression})`, {
|
|
32
|
+
crons: [expression],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return yield* Effect.die(`Cloudflare.cron(...).subscribe(...) is only supported on ` +
|
|
37
|
+
`Cloudflare.Worker hosts (got '${host.Type}').`);
|
|
38
|
+
}
|
|
39
|
+
}));
|
|
40
|
+
export const CronEventSourceLive = Layer.effect(CronEventSource, Effect.gen(function* () {
|
|
41
|
+
const policy = yield* CronEventSourcePolicy;
|
|
42
|
+
return Effect.fn(function* (expression, process) {
|
|
43
|
+
yield* policy(expression);
|
|
44
|
+
const ctx = (yield* RuntimeContext);
|
|
45
|
+
yield* ctx.listen((event) => {
|
|
46
|
+
if (!isWorkerEvent(event) || event.type !== "scheduled")
|
|
47
|
+
return;
|
|
48
|
+
const controller = event.input;
|
|
49
|
+
if (controller.cron !== expression)
|
|
50
|
+
return;
|
|
51
|
+
return process(controller).pipe(Effect.catchCause(() => Effect.void));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}));
|
|
55
|
+
//# sourceMappingURL=CronEventSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CronEventSource.js","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/CronEventSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,CAAC;IAC3C,SAAS,EAAE,CACT,OAEsC,EACtC,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;CAClE,CAAC,CAAC;AASH,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,OAAO,EAGjD,CAAC,oCAAoC,CAAC;CAAG;AAE5C,MAAM,OAAO,qBAAsB,SAAQ,OAAO,CAAC,MAAM,EAGtD,CAAC,oCAAoC,CAAC;CAAG;AAE5C,MAAM,CAAC,MAAM,yBAAyB,GAAG,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAC1E,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAkB,EAAE,UAAkB;IACjE,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,UAAU,GAAG,EAAE;YACtC,KAAK,EAAE,CAAC,UAAU,CAAC;SACpB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CACtB,2DAA2D;YACzD,iCAAiC,IAAI,CAAC,IAAI,KAAK,CAClD,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,CAC7C,eAAe,EACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,qBAAqB,CAAC;IAC5C,OAAO,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EACxB,UAAkB,EAClB,OAEsC;QAEtC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE1B,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,cAAc,CAA+B,CAAC;QAClE,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAY,CAAC,KAAK,EAAE,EAAE;YACrC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO;YAEhE,MAAM,UAAU,GAAG,KAAK,CAAC,KAA+B,CAAC;YACzD,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU;gBAAE,OAAO;YAE3C,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAA2B,CAAC;AAC/B,CAAC,CAAC,CACH,CAAC"}
|
|
@@ -1,10 +1,45 @@
|
|
|
1
1
|
import type * as Effect from "effect/Effect";
|
|
2
|
+
import type * as Stream from "effect/Stream";
|
|
3
|
+
import type { Rpc } from "../../Platform.ts";
|
|
2
4
|
import type { UnwrapEffect } from "../../Util/effect.ts";
|
|
3
5
|
import type * as Cloudflare from "../index.ts";
|
|
6
|
+
import type { RpcErrorEnvelope, RpcStreamEnvelope } from "./Rpc.ts";
|
|
4
7
|
import type { Worker } from "./Worker.ts";
|
|
5
8
|
export type InferEnv<W> = W extends Worker<infer Bindings> | Effect.Effect<Worker<infer Bindings>, any, any> ? {
|
|
6
9
|
[K in keyof Bindings]: GetBindingType<UnwrapEffect<Bindings[K]>>;
|
|
7
10
|
} : never;
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Cloudflare service-binding wire shape for an Effect-native Worker.
|
|
13
|
+
*
|
|
14
|
+
* Effect/Stream return values are encoded as envelopes on the wire (see
|
|
15
|
+
* `RpcErrorEnvelope`, `RpcStreamEnvelope`), so the mapped types reflect what
|
|
16
|
+
* the raw binding actually resolves to. `fetch` is dropped from the user
|
|
17
|
+
* shape and re-introduced via `Service` so callers get the standard
|
|
18
|
+
* `(input, init?) => Promise<Response>` signature.
|
|
19
|
+
*
|
|
20
|
+
* Use {@link toPromiseApi} to wrap a binding into a Promise<T>-flavored view
|
|
21
|
+
* where envelopes are decoded for you.
|
|
22
|
+
*/
|
|
23
|
+
export type RpcWireShape<Shape> = {
|
|
24
|
+
[K in keyof Shape as K extends "fetch" ? never : K]: Shape[K] extends (...args: infer A) => Effect.Effect<infer T, any, any> ? (...args: A) => Promise<T | RpcErrorEnvelope> : Shape[K] extends (...args: infer A) => Stream.Stream<any, any, any> ? (...args: A) => Promise<RpcStreamEnvelope | RpcErrorEnvelope> : Shape[K] extends Effect.Effect<infer T, any, any> ? Promise<T | RpcErrorEnvelope> : Shape[K] extends Stream.Stream<any, any, any> ? Promise<RpcStreamEnvelope | RpcErrorEnvelope> : Shape[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : Promise<Shape[K]>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Recover the user's RPC `Shape` from any of the forms a caller might pass
|
|
28
|
+
* to {@link toPromiseApi}:
|
|
29
|
+
*
|
|
30
|
+
* - the Worker class value's type, e.g. `typeof Backend`, which extends
|
|
31
|
+
* `Effect.Effect<Worker & Rpc<Shape>, …>`
|
|
32
|
+
* - the unwrapped `Worker & Rpc<Shape>` type
|
|
33
|
+
* - a bare `Shape` (when the caller types it explicitly)
|
|
34
|
+
*/
|
|
35
|
+
export type ExtractRpcShape<W> = W extends Effect.Effect<infer R, any, any> ? R extends Rpc<infer Shape> ? Shape : R : W extends Rpc<infer Shape> ? Shape : W;
|
|
36
|
+
/**
|
|
37
|
+
* Promise-flavored consumer view returned by {@link toPromiseApi}: error
|
|
38
|
+
* envelopes are thrown as exceptions and stream envelopes are unwrapped to
|
|
39
|
+
* their raw `ReadableStream<Uint8Array>` body.
|
|
40
|
+
*/
|
|
41
|
+
export type RpcPromiseShape<Shape> = {
|
|
42
|
+
[K in keyof Shape as K extends "fetch" ? never : K]: Shape[K] extends (...args: infer A) => Effect.Effect<infer T, any, any> ? (...args: A) => Promise<T> : Shape[K] extends (...args: infer A) => Stream.Stream<any, any, any> ? (...args: A) => Promise<ReadableStream<Uint8Array>> : Shape[K] extends Effect.Effect<infer T, any, any> ? Promise<T> : Shape[K] extends Stream.Stream<any, any, any> ? Promise<ReadableStream<Uint8Array>> : Shape[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : Promise<Shape[K]>;
|
|
43
|
+
};
|
|
44
|
+
export type GetBindingType<T> = T extends Cloudflare.Assets ? Service : T extends Rpc<infer Shape extends object> ? RpcWireShape<Shape> & Service : T extends Cloudflare.D1Database ? D1Database : T extends Cloudflare.R2Bucket ? R2Bucket : T extends Cloudflare.KVNamespace ? KVNamespace : T extends Cloudflare.Queue ? Queue<unknown> : T extends Cloudflare.AiGateway ? Ai : T extends Cloudflare.AnalyticsEngineDataset ? AnalyticsEngineDataset : T extends Cloudflare.Artifacts ? Artifacts : T extends Cloudflare.Images ? ImagesBinding : T extends Cloudflare.Hyperdrive ? Hyperdrive : T extends Cloudflare.DurableObjectNamespaceLike ? DurableObjectNamespace<Exclude<T["Shape"], undefined>> : never;
|
|
10
45
|
//# sourceMappingURL=InferEnv.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InferEnv.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/InferEnv.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,KAAK,UAAU,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,SACvB,MAAM,CAAC,MAAM,QAAQ,CAAC,GACtB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAC/C;KACG,CAAC,IAAI,MAAM,QAAQ,GAAG,cAAc,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;CACjE,GACD,KAAK,CAAC;AAEV,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"InferEnv.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/InferEnv.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalWorkerProvider.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/LocalWorkerProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,
|
|
1
|
+
{"version":3,"file":"LocalWorkerProvider.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/LocalWorkerProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAEL,MAAM,EAGP,MAAM,aAAa,CAAC;AAGrB,eAAO,MAAM,mBAAmB,qJAgH7B,CAAC"}
|
|
@@ -5,7 +5,7 @@ import { Stack } from "../../Stack.js";
|
|
|
5
5
|
import { CloudflareEnvironment } from "../CloudflareEnvironment.js";
|
|
6
6
|
import { Sidecar } from "../Local/Sidecar.js";
|
|
7
7
|
import { getCompatibility } from "./Compatibility.js";
|
|
8
|
-
import { Worker } from "./Worker.js";
|
|
8
|
+
import { getCronBindings, Worker, } from "./Worker.js";
|
|
9
9
|
import { createWorkerName } from "./WorkerName.js";
|
|
10
10
|
export const LocalWorkerProvider = () => Provider.effect(Worker, Effect.gen(function* () {
|
|
11
11
|
const { accountId } = yield* CloudflareEnvironment;
|
|
@@ -95,6 +95,7 @@ export const LocalWorkerProvider = () => Provider.effect(Worker, Effect.gen(func
|
|
|
95
95
|
tags: [],
|
|
96
96
|
durableObjectNamespaces,
|
|
97
97
|
domains: [],
|
|
98
|
+
crons: Array.from(new Set([...getCronBindings(bindings), ...(props.crons ?? [])])),
|
|
98
99
|
accountId,
|
|
99
100
|
};
|
|
100
101
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalWorkerProvider.js","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/LocalWorkerProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"LocalWorkerProvider.js","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/LocalWorkerProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import * as Cause from "effect/Cause";
|
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
4
|
import * as Stream from "effect/Stream";
|
|
5
5
|
import * as Socket from "effect/unstable/socket/Socket";
|
|
6
|
+
import type { ExtractRpcShape, RpcPromiseShape } from "./InferEnv.ts";
|
|
6
7
|
export declare const StreamTag = "~alchemy/rpc/stream";
|
|
7
8
|
export declare const ErrorTag = "~alchemy/rpc/error";
|
|
8
9
|
export declare const StreamErrorTag = "~alchemy/rpc/stream-error";
|
|
@@ -61,7 +62,50 @@ export declare const decodeRpcValue: (value: unknown) => unknown;
|
|
|
61
62
|
* error channel so that remote `Effect.fail(...)` values are recoverable.
|
|
62
63
|
*/
|
|
63
64
|
export declare const decodeRpcResult: (value: unknown) => Effect.Effect<unknown, unknown>;
|
|
64
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Wrap a Cloudflare service-binding stub (or an `Effect` that resolves
|
|
67
|
+
* to one — useful when the stub depends on a service like
|
|
68
|
+
* `WorkerEnvironment` that's only available at *exec* phase) into an
|
|
69
|
+
* Effect-typed RPC client.
|
|
70
|
+
*
|
|
71
|
+
* `Service.fetch`/`Service.connect` are passed through eagerly when the
|
|
72
|
+
* stub is already resolved; everything else is treated as an RPC method
|
|
73
|
+
* whose dispatch is deferred until call time, so the user effect runs in
|
|
74
|
+
* the right runtime layer (which is what `bindWorker` actually wants —
|
|
75
|
+
* its methods are called at exec, even though it's *defined* at init).
|
|
76
|
+
*/
|
|
77
|
+
export declare const makeRpcStub: <Shape>(stubSource: unknown | Effect.Effect<unknown, never, never>) => Shape;
|
|
78
|
+
/**
|
|
79
|
+
* Wrap a raw Cloudflare service binding (the wire-typed view emitted by
|
|
80
|
+
* `InferEnv`) into a Promise-flavored API for non-Effect consumers.
|
|
81
|
+
*
|
|
82
|
+
* Effect-native worker methods serialize their results as envelopes:
|
|
83
|
+
* `Effect.fail` becomes `RpcErrorEnvelope`, `Stream` becomes
|
|
84
|
+
* `RpcStreamEnvelope`, and `Effect.succeed`/raw values pass through. This
|
|
85
|
+
* proxy auto-decodes those envelopes — error envelopes are thrown so the
|
|
86
|
+
* caller's `await` rejects, and stream envelopes are unwrapped to their raw
|
|
87
|
+
* `ReadableStream<Uint8Array>` body.
|
|
88
|
+
*
|
|
89
|
+
* `Service.fetch` and `Service.connect` pass through untouched, so the
|
|
90
|
+
* returned proxy is still a usable `Service` binding.
|
|
91
|
+
*
|
|
92
|
+
* For Effect-to-Effect cross-worker calls, prefer `bindWorker(Worker)` —
|
|
93
|
+
* it preserves typed errors and decoded streams.
|
|
94
|
+
*
|
|
95
|
+
* The generic parameter is the Worker *class* (or its Effect form), the
|
|
96
|
+
* same value you would pass to `bindWorker`. Shape is recovered from the
|
|
97
|
+
* embedded `Rpc<Shape>`.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import * as Cloudflare from "alchemy/Cloudflare";
|
|
102
|
+
* import Backend from "./backend.ts";
|
|
103
|
+
*
|
|
104
|
+
* const backend = Cloudflare.toPromiseApi<typeof Backend>(env.BACKEND);
|
|
105
|
+
* const greeting = await backend.hello(key); // throws on Effect.fail
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare const toPromiseApi: <W>(stub: any) => RpcPromiseShape<ExtractRpcShape<W>> & Service;
|
|
65
109
|
/**
|
|
66
110
|
* Create a DurableObjectBridge class that proxies RPC method calls through
|
|
67
111
|
* the Effect runtime, encoding success/fail/stream results as RPC envelopes.
|
|
@@ -82,6 +126,35 @@ export declare const makeDurableObjectBridge: (DurableObject: abstract new (stat
|
|
|
82
126
|
webSocketError?(ws: cf.WebSocket, error: unknown): void | Promise<void>;
|
|
83
127
|
};
|
|
84
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* Create a `WorkerBridge` class — a `WorkerEntrypoint` subclass that
|
|
131
|
+
* Cloudflare instantiates per request and dispatches both standard
|
|
132
|
+
* handlers (`fetch`/`scheduled`/…) and RPC method calls into.
|
|
133
|
+
*
|
|
134
|
+
* The bridge is intentionally layer-ignorant: all runtime-layer plumbing
|
|
135
|
+
* (services, scope, `WorkerExecutionContext`) lives in the platform's
|
|
136
|
+
* `runtimeContext.exports` flow, which builds:
|
|
137
|
+
*
|
|
138
|
+
* - `getDefault()` → `{ fetch, scheduled, … }` — handler dispatchers
|
|
139
|
+
* that the bridge forwards `(input, env, ctx)` to.
|
|
140
|
+
* - `getRpc()` → `{ method: (args, ctx) => Promise<envelope> }` —
|
|
141
|
+
* pre-wrapped RPC dispatchers that already run the user effect with
|
|
142
|
+
* the right runtime layer and envelope-encode the result.
|
|
143
|
+
*
|
|
144
|
+
* Cloudflare's script-validate step requires standard handler methods
|
|
145
|
+
* (`fetch`/`scheduled`/etc.) to be visible on the class prototype. We
|
|
146
|
+
* declare static stubs there and override them per-instance with
|
|
147
|
+
* closure-bound forwarders that capture `ctx`/`env` from the constructor
|
|
148
|
+
* (prototype-level `this` doesn't survive the proxy + RPC dispatch
|
|
149
|
+
* round-trip in some Cloudflare runtime versions).
|
|
150
|
+
*/
|
|
151
|
+
export declare const makeWorkerBridge: (WorkerEntrypoint: abstract new (ctx: unknown, env: unknown) => {
|
|
152
|
+
fetch?(request: cf.Request): Promise<cf.Response> | cf.Response;
|
|
153
|
+
}, ExportedHandlerMethods: ReadonlyArray<string>, getDefault: () => Promise<Record<string, any>>, getRpc: () => Promise<Record<string, any>>) => {
|
|
154
|
+
new (ctx: unknown, env: unknown): {
|
|
155
|
+
fetch?(request: cf.Request): Promise<cf.Response> | cf.Response;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
85
158
|
/**
|
|
86
159
|
* Create a WorkflowBridge class that extends `WorkflowEntrypoint` and
|
|
87
160
|
* delegates the `run(event, step)` call to the Effect-native workflow body
|
|
@@ -93,9 +166,9 @@ export declare const makeDurableObjectBridge: (DurableObject: abstract new (stat
|
|
|
93
166
|
*/
|
|
94
167
|
export declare const makeWorkflowBridge: (WorkflowEntrypoint: abstract new (ctx: unknown, env: unknown) => {
|
|
95
168
|
run(event: any, step: any): Promise<unknown>;
|
|
96
|
-
}, getExport: (name: string) => Promise<(env: unknown) => Effect.Effect<Effect.Effect<unknown, never, any>>>) => (className: string) => {
|
|
169
|
+
}, getExport: (name: string) => Promise<(env: unknown) => Effect.Effect<(input: unknown) => Effect.Effect<unknown, never, any>>>) => (className: string) => {
|
|
97
170
|
new (ctx: unknown, env: unknown): {
|
|
98
|
-
readonly
|
|
171
|
+
readonly fn: Promise<(input: unknown) => Effect.Effect<unknown, never, any>>;
|
|
99
172
|
readonly env: unknown;
|
|
100
173
|
run(event: any, step: any): Promise<unknown>;
|
|
101
174
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rpc.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/Rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"Rpc.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/Workers/Rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import * as Option from "effect/Option";
|
|
|
5
5
|
import * as Sink from "effect/Sink";
|
|
6
6
|
import * as Stream from "effect/Stream";
|
|
7
7
|
import * as Socket from "effect/unstable/socket/Socket";
|
|
8
|
+
import { isYieldableEffect } from "../../Util/effect.js";
|
|
8
9
|
import { fromCloudflareFetcher } from "../Fetcher.js";
|
|
9
10
|
import { serveWebRequest } from "./HttpServer.js";
|
|
10
11
|
import { fromWebSocket } from "./WebSocket.js";
|
|
@@ -108,17 +109,116 @@ export const decodeRpcResult = (value) => {
|
|
|
108
109
|
}
|
|
109
110
|
return Effect.succeed(decodeRpcValue(value));
|
|
110
111
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Wrap a Cloudflare service-binding stub (or an `Effect` that resolves
|
|
114
|
+
* to one — useful when the stub depends on a service like
|
|
115
|
+
* `WorkerEnvironment` that's only available at *exec* phase) into an
|
|
116
|
+
* Effect-typed RPC client.
|
|
117
|
+
*
|
|
118
|
+
* `Service.fetch`/`Service.connect` are passed through eagerly when the
|
|
119
|
+
* stub is already resolved; everything else is treated as an RPC method
|
|
120
|
+
* whose dispatch is deferred until call time, so the user effect runs in
|
|
121
|
+
* the right runtime layer (which is what `bindWorker` actually wants —
|
|
122
|
+
* its methods are called at exec, even though it's *defined* at init).
|
|
123
|
+
*/
|
|
124
|
+
export const makeRpcStub = (stubSource) => {
|
|
125
|
+
const isLazy = isYieldableEffect(stubSource);
|
|
126
|
+
const eagerFetcher = isLazy
|
|
127
|
+
? undefined
|
|
128
|
+
: fromCloudflareFetcher(stubSource);
|
|
129
|
+
const proxyTarget = eagerFetcher ?? {};
|
|
130
|
+
return new Proxy(proxyTarget, {
|
|
131
|
+
get: (target, prop) => {
|
|
132
|
+
if (!isLazy && prop in target)
|
|
133
|
+
return target[prop];
|
|
134
|
+
if (typeof prop !== "string" && typeof prop !== "symbol") {
|
|
135
|
+
return target[prop];
|
|
136
|
+
}
|
|
137
|
+
return (...args) => Effect.gen(function* () {
|
|
138
|
+
const stub = isLazy
|
|
139
|
+
? yield* stubSource
|
|
140
|
+
: stubSource;
|
|
141
|
+
return yield* Effect.tryPromise({
|
|
142
|
+
try: () => stub[prop](...args),
|
|
143
|
+
catch: (cause) => new RpcCallError({ method: String(prop), cause }),
|
|
144
|
+
}).pipe(Effect.flatMap(decodeRpcResult));
|
|
145
|
+
});
|
|
146
|
+
},
|
|
120
147
|
});
|
|
121
148
|
};
|
|
149
|
+
/**
|
|
150
|
+
* Wrap a raw Cloudflare service binding (the wire-typed view emitted by
|
|
151
|
+
* `InferEnv`) into a Promise-flavored API for non-Effect consumers.
|
|
152
|
+
*
|
|
153
|
+
* Effect-native worker methods serialize their results as envelopes:
|
|
154
|
+
* `Effect.fail` becomes `RpcErrorEnvelope`, `Stream` becomes
|
|
155
|
+
* `RpcStreamEnvelope`, and `Effect.succeed`/raw values pass through. This
|
|
156
|
+
* proxy auto-decodes those envelopes — error envelopes are thrown so the
|
|
157
|
+
* caller's `await` rejects, and stream envelopes are unwrapped to their raw
|
|
158
|
+
* `ReadableStream<Uint8Array>` body.
|
|
159
|
+
*
|
|
160
|
+
* `Service.fetch` and `Service.connect` pass through untouched, so the
|
|
161
|
+
* returned proxy is still a usable `Service` binding.
|
|
162
|
+
*
|
|
163
|
+
* For Effect-to-Effect cross-worker calls, prefer `bindWorker(Worker)` —
|
|
164
|
+
* it preserves typed errors and decoded streams.
|
|
165
|
+
*
|
|
166
|
+
* The generic parameter is the Worker *class* (or its Effect form), the
|
|
167
|
+
* same value you would pass to `bindWorker`. Shape is recovered from the
|
|
168
|
+
* embedded `Rpc<Shape>`.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* import * as Cloudflare from "alchemy/Cloudflare";
|
|
173
|
+
* import Backend from "./backend.ts";
|
|
174
|
+
*
|
|
175
|
+
* const backend = Cloudflare.toPromiseApi<typeof Backend>(env.BACKEND);
|
|
176
|
+
* const greeting = await backend.hello(key); // throws on Effect.fail
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
export const toPromiseApi = (stub) => new Proxy(stub, {
|
|
180
|
+
get: (target, prop) => {
|
|
181
|
+
// `Service` methods (fetch/connect) and any non-string keys (Symbol.dispose, etc.)
|
|
182
|
+
// pass through to the underlying Cloudflare binding unchanged.
|
|
183
|
+
if (typeof prop !== "string" || prop === "fetch" || prop === "connect") {
|
|
184
|
+
const value = target[prop];
|
|
185
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
186
|
+
}
|
|
187
|
+
return async (...args) => {
|
|
188
|
+
const result = await target[prop](...args);
|
|
189
|
+
if (isRpcErrorEnvelope(result)) {
|
|
190
|
+
throw decodeRpcThrowable(result.error);
|
|
191
|
+
}
|
|
192
|
+
if (isRpcStreamEnvelope(result)) {
|
|
193
|
+
return result.body;
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
/**
|
|
200
|
+
* Reconstruct a throwable from {@link encodeRpcError}'s wire form. Plain
|
|
201
|
+
* `Error` payloads are rebuilt as `Error` instances so `.message`/`.name`/
|
|
202
|
+
* `.stack` survive. Tagged errors (anything with a `_tag`) and primitives
|
|
203
|
+
* are thrown as-is so `try { ... } catch (e) { if (e._tag === ...) }` keeps
|
|
204
|
+
* working.
|
|
205
|
+
*/
|
|
206
|
+
const decodeRpcThrowable = (error) => {
|
|
207
|
+
if (error === null || typeof error !== "object")
|
|
208
|
+
return error;
|
|
209
|
+
const obj = error;
|
|
210
|
+
if ("_tag" in obj)
|
|
211
|
+
return obj;
|
|
212
|
+
if (typeof obj.message === "string" || typeof obj.name === "string") {
|
|
213
|
+
const e = new Error(typeof obj.message === "string" ? obj.message : "");
|
|
214
|
+
if (typeof obj.name === "string")
|
|
215
|
+
e.name = obj.name;
|
|
216
|
+
if (typeof obj.stack === "string")
|
|
217
|
+
e.stack = obj.stack;
|
|
218
|
+
return e;
|
|
219
|
+
}
|
|
220
|
+
return error;
|
|
221
|
+
};
|
|
122
222
|
/**
|
|
123
223
|
* Create a DurableObjectBridge class that proxies RPC method calls through
|
|
124
224
|
* the Effect runtime, encoding success/fail/stream results as RPC envelopes.
|
|
@@ -202,6 +302,90 @@ export const makeDurableObjectBridge = (DurableObject, getExport) => (className)
|
|
|
202
302
|
});
|
|
203
303
|
}
|
|
204
304
|
};
|
|
305
|
+
/**
|
|
306
|
+
* Create a `WorkerBridge` class — a `WorkerEntrypoint` subclass that
|
|
307
|
+
* Cloudflare instantiates per request and dispatches both standard
|
|
308
|
+
* handlers (`fetch`/`scheduled`/…) and RPC method calls into.
|
|
309
|
+
*
|
|
310
|
+
* The bridge is intentionally layer-ignorant: all runtime-layer plumbing
|
|
311
|
+
* (services, scope, `WorkerExecutionContext`) lives in the platform's
|
|
312
|
+
* `runtimeContext.exports` flow, which builds:
|
|
313
|
+
*
|
|
314
|
+
* - `getDefault()` → `{ fetch, scheduled, … }` — handler dispatchers
|
|
315
|
+
* that the bridge forwards `(input, env, ctx)` to.
|
|
316
|
+
* - `getRpc()` → `{ method: (args, ctx) => Promise<envelope> }` —
|
|
317
|
+
* pre-wrapped RPC dispatchers that already run the user effect with
|
|
318
|
+
* the right runtime layer and envelope-encode the result.
|
|
319
|
+
*
|
|
320
|
+
* Cloudflare's script-validate step requires standard handler methods
|
|
321
|
+
* (`fetch`/`scheduled`/etc.) to be visible on the class prototype. We
|
|
322
|
+
* declare static stubs there and override them per-instance with
|
|
323
|
+
* closure-bound forwarders that capture `ctx`/`env` from the constructor
|
|
324
|
+
* (prototype-level `this` doesn't survive the proxy + RPC dispatch
|
|
325
|
+
* round-trip in some Cloudflare runtime versions).
|
|
326
|
+
*/
|
|
327
|
+
export const makeWorkerBridge = (WorkerEntrypoint, ExportedHandlerMethods, getDefault, getRpc) => {
|
|
328
|
+
class WorkerBridge extends WorkerEntrypoint {
|
|
329
|
+
constructor(ctx, env) {
|
|
330
|
+
super(ctx, env);
|
|
331
|
+
// Override handler methods per-instance with closure-bound forwarders.
|
|
332
|
+
// We read `this.ctx`/`this.env` at *call time* rather than capturing
|
|
333
|
+
// the constructor args because Cloudflare's runtime appears to
|
|
334
|
+
// populate those instance fields differently depending on whether
|
|
335
|
+
// the entrypoint is invoked via direct fetch or RPC — `super(ctx, env)`
|
|
336
|
+
// alone isn't enough to guarantee they survive into the call.
|
|
337
|
+
const self = this;
|
|
338
|
+
// Cloudflare invokes `WorkerEntrypoint.fetch(request)` with only the
|
|
339
|
+
// primary input on the *parameter list* — `env`/`ctx` live on `this`
|
|
340
|
+
// (and the runtime sometimes passes `(request, undefined, undefined)`
|
|
341
|
+
// anyway for legacy compat). Other handlers, including `scheduled`, may
|
|
342
|
+
// receive the classic `(input, env, ctx)` arguments. The platform's
|
|
343
|
+
// underlying handler dispatch (`handle("fetch")`, `handle("scheduled")`,
|
|
344
|
+
// etc.) follows the plain-export signature `(input, env, context)`, so
|
|
345
|
+
// prefer explicit handler args when Cloudflare provides them and fall
|
|
346
|
+
// back to the WorkerEntrypoint instance fields.
|
|
347
|
+
for (const method of ExportedHandlerMethods) {
|
|
348
|
+
this[method] = async (input, envArg, ctxArg) => {
|
|
349
|
+
const def = await getDefault();
|
|
350
|
+
return def?.[method]?.(input, envArg ?? self.env, ctxArg ?? self.ctx);
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
// RPC method dispatch — anything Cloudflare RPC tries to invoke that
|
|
354
|
+
// isn't an own property goes through the dispatcher table built by
|
|
355
|
+
// the platform's exports flow.
|
|
356
|
+
return new Proxy(this, {
|
|
357
|
+
get: (target, prop) => {
|
|
358
|
+
if (typeof prop !== "string")
|
|
359
|
+
return target[prop];
|
|
360
|
+
if (prop in target)
|
|
361
|
+
return target[prop];
|
|
362
|
+
return async (...args) => {
|
|
363
|
+
const rpc = await getRpc();
|
|
364
|
+
const dispatcher = rpc?.[prop];
|
|
365
|
+
if (typeof dispatcher !== "function") {
|
|
366
|
+
throw new Error(`Method "${prop}" not found on worker. ` +
|
|
367
|
+
`Make sure it's returned from the worker's default export.`);
|
|
368
|
+
}
|
|
369
|
+
return dispatcher(args, self.ctx);
|
|
370
|
+
};
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
// Stub prototype methods so Cloudflare's script-validate detects the
|
|
376
|
+
// standard handler set; per-instance overrides above are what actually
|
|
377
|
+
// run.
|
|
378
|
+
for (const method of ExportedHandlerMethods) {
|
|
379
|
+
Object.defineProperty(WorkerBridge.prototype, method, {
|
|
380
|
+
value: function () {
|
|
381
|
+
throw new Error(`Bridge method '${method}' was called before instance setup`);
|
|
382
|
+
},
|
|
383
|
+
writable: true,
|
|
384
|
+
configurable: true,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return WorkerBridge;
|
|
388
|
+
};
|
|
205
389
|
/**
|
|
206
390
|
* Create a WorkflowBridge class that extends `WorkflowEntrypoint` and
|
|
207
391
|
* delegates the `run(event, step)` call to the Effect-native workflow body
|
|
@@ -212,16 +396,16 @@ export const makeDurableObjectBridge = (DurableObject, getExport) => (className)
|
|
|
212
396
|
* instead of receiving callback parameters.
|
|
213
397
|
*/
|
|
214
398
|
export const makeWorkflowBridge = (WorkflowEntrypoint, getExport) => (className) => class WorkflowBridge extends WorkflowEntrypoint {
|
|
215
|
-
|
|
399
|
+
fn;
|
|
216
400
|
env;
|
|
217
401
|
constructor(ctx, env) {
|
|
218
402
|
super(ctx, env);
|
|
219
403
|
this.env = env;
|
|
220
|
-
this.
|
|
404
|
+
this.fn = getExport(className).then((factory) => Effect.runPromise(factory(env)));
|
|
221
405
|
}
|
|
222
406
|
async run(event, step) {
|
|
223
|
-
const
|
|
224
|
-
return Effect.runPromise(
|
|
407
|
+
const fn = await this.fn;
|
|
408
|
+
return Effect.runPromise(fn(event.payload).pipe(Effect.provideService(WorkflowEventService, wrapWorkflowEvent(event)), Effect.provideService(WorkflowStep, wrapWorkflowStep(step))));
|
|
225
409
|
}
|
|
226
410
|
};
|
|
227
411
|
import { WorkflowEvent as WorkflowEventService, WorkflowStep, } from "./Workflow.js";
|