@effect/platform-cloudflare 0.0.0 → 4.1.3
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/AGENTS.md +434 -0
- package/CLAUDE.md +434 -0
- package/LICENSE +21 -0
- package/README.md +506 -0
- package/ai-docs/README.md +44 -0
- package/ai-docs/package.json +36 -0
- package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
- package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +52 -0
- package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
- package/ai-docs/src/01_effect/01_basics/index.md +7 -0
- package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
- package/ai-docs/src/01_effect/02_schema/index.md +7 -0
- package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
- package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
- package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
- package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
- package/ai-docs/src/01_effect/03_services/index.md +5 -0
- package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
- package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
- package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
- package/ai-docs/src/01_effect/04_errors/index.md +1 -0
- package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
- package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
- package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
- package/ai-docs/src/01_effect/05_resources/index.md +3 -0
- package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
- package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
- package/ai-docs/src/01_effect/06_running/index.md +1 -0
- package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
- package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
- package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
- package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
- package/ai-docs/src/03_stream/30_encoding.ts +163 -0
- package/ai-docs/src/03_stream/index.md +4 -0
- package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
- package/ai-docs/src/04_integration/index.md +5 -0
- package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
- package/ai-docs/src/05_batching/index.md +3 -0
- package/ai-docs/src/06_schedule/10_schedules.ts +111 -0
- package/ai-docs/src/06_schedule/index.md +3 -0
- package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
- package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
- package/ai-docs/src/07_datetime/index.md +5 -0
- package/ai-docs/src/08_observability/10_logging.ts +66 -0
- package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
- package/ai-docs/src/08_observability/index.md +7 -0
- package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
- package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
- package/ai-docs/src/09_testing/index.md +1 -0
- package/ai-docs/src/10_predicate/01_basics.ts +14 -0
- package/ai-docs/src/10_predicate/index.md +9 -0
- package/ai-docs/src/40_sql/10_basics.ts +175 -0
- package/ai-docs/src/40_sql/index.md +6 -0
- package/ai-docs/src/50_http-client/10_basics.ts +102 -0
- package/ai-docs/src/50_http-client/index.md +3 -0
- package/ai-docs/src/51_http-server/10_basics.ts +118 -0
- package/ai-docs/src/51_http-server/20_testing.ts +100 -0
- package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
- package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
- package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
- package/ai-docs/src/51_http-server/fixtures/api/Users.ts +107 -0
- package/ai-docs/src/51_http-server/fixtures/domain/User.ts +21 -0
- package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
- package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +37 -0
- package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +80 -0
- package/ai-docs/src/51_http-server/fixtures/server/Users.ts +183 -0
- package/ai-docs/src/51_http-server/index.md +3 -0
- package/ai-docs/src/52_graphql/10_basics.ts +117 -0
- package/ai-docs/src/52_graphql/20_testing.ts +45 -0
- package/ai-docs/src/52_graphql/30_batching.ts +118 -0
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +124 -0
- package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
- package/ai-docs/src/52_graphql/index.md +6 -0
- package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
- package/ai-docs/src/60_child-process/index.md +3 -0
- package/ai-docs/src/70_cli/10_basics.ts +162 -0
- package/ai-docs/src/70_cli/index.md +5 -0
- package/ai-docs/src/71_ai/10_language-model.ts +156 -0
- package/ai-docs/src/71_ai/20_tools.ts +226 -0
- package/ai-docs/src/71_ai/30_chat.ts +158 -0
- package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
- package/ai-docs/src/71_ai/index.md +5 -0
- package/ai-docs/src/80_cluster/10_entities.ts +97 -0
- package/ai-docs/src/80_cluster/index.md +4 -0
- package/ai-docs/src/index.md +10 -0
- package/ai-docs/tsconfig.json +28 -0
- package/dist/AlchemyCloudflareCluster.d.ts +134 -0
- package/dist/AlchemyCloudflareCluster.d.ts.map +1 -0
- package/dist/AlchemyCloudflareCluster.js +111 -0
- package/dist/AlchemyCloudflareCluster.js.map +1 -0
- package/dist/CloudflareCluster.d.ts +196 -0
- package/dist/CloudflareCluster.d.ts.map +1 -0
- package/dist/CloudflareCluster.js +533 -0
- package/dist/CloudflareCluster.js.map +1 -0
- package/dist/CloudflareDurableObjectPrograms.d.ts +279 -0
- package/dist/CloudflareDurableObjectPrograms.d.ts.map +1 -0
- package/dist/CloudflareDurableObjectPrograms.js +295 -0
- package/dist/CloudflareDurableObjectPrograms.js.map +1 -0
- package/dist/CloudflareDurableObjects.d.ts +149 -0
- package/dist/CloudflareDurableObjects.d.ts.map +1 -0
- package/dist/CloudflareDurableObjects.js +337 -0
- package/dist/CloudflareDurableObjects.js.map +1 -0
- package/dist/CloudflarePersistedQueue.d.ts +36 -0
- package/dist/CloudflarePersistedQueue.d.ts.map +1 -0
- package/dist/CloudflarePersistedQueue.js +122 -0
- package/dist/CloudflarePersistedQueue.js.map +1 -0
- package/dist/CloudflareWorkflowEngine.d.ts +72 -0
- package/dist/CloudflareWorkflowEngine.d.ts.map +1 -0
- package/dist/CloudflareWorkflowEngine.js +187 -0
- package/dist/CloudflareWorkflowEngine.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/alchemyCluster.d.ts +2 -0
- package/dist/internal/alchemyCluster.d.ts.map +1 -0
- package/dist/internal/alchemyCluster.js +75 -0
- package/dist/internal/alchemyCluster.js.map +1 -0
- package/dist/internal/boundedMap.d.ts +3 -0
- package/dist/internal/boundedMap.d.ts.map +1 -0
- package/dist/internal/boundedMap.js +15 -0
- package/dist/internal/boundedMap.js.map +1 -0
- package/dist/internal/cluster.d.ts +57 -0
- package/dist/internal/cluster.d.ts.map +1 -0
- package/dist/internal/cluster.js +2 -0
- package/dist/internal/cluster.js.map +1 -0
- package/dist/internal/clusterName.d.ts +2 -0
- package/dist/internal/clusterName.d.ts.map +1 -0
- package/dist/internal/clusterName.js +16 -0
- package/dist/internal/clusterName.js.map +1 -0
- package/dist/internal/entityKeepAlive.d.ts +2 -0
- package/dist/internal/entityKeepAlive.d.ts.map +1 -0
- package/dist/internal/entityKeepAlive.js +73 -0
- package/dist/internal/entityKeepAlive.js.map +1 -0
- package/dist/internal/entityMailbox.d.ts +2 -0
- package/dist/internal/entityMailbox.d.ts.map +1 -0
- package/dist/internal/entityMailbox.js +160 -0
- package/dist/internal/entityMailbox.js.map +1 -0
- package/dist/internal/entityRegistry.d.ts +16 -0
- package/dist/internal/entityRegistry.d.ts.map +1 -0
- package/dist/internal/entityRegistry.js +22 -0
- package/dist/internal/entityRegistry.js.map +1 -0
- package/dist/internal/entityReply.d.ts +2 -0
- package/dist/internal/entityReply.d.ts.map +1 -0
- package/dist/internal/entityReply.js +35 -0
- package/dist/internal/entityReply.js.map +1 -0
- package/dist/internal/entityRuntime.d.ts +2 -0
- package/dist/internal/entityRuntime.d.ts.map +1 -0
- package/dist/internal/entityRuntime.js +823 -0
- package/dist/internal/entityRuntime.js.map +1 -0
- package/dist/internal/entitySql.d.ts +2 -0
- package/dist/internal/entitySql.d.ts.map +1 -0
- package/dist/internal/entitySql.js +29 -0
- package/dist/internal/entitySql.js.map +1 -0
- package/dist/internal/entityStorage.d.ts +2 -0
- package/dist/internal/entityStorage.d.ts.map +1 -0
- package/dist/internal/entityStorage.js +98 -0
- package/dist/internal/entityStorage.js.map +1 -0
- package/dist/internal/entityWire.d.ts +2 -0
- package/dist/internal/entityWire.d.ts.map +1 -0
- package/dist/internal/entityWire.js +146 -0
- package/dist/internal/entityWire.js.map +1 -0
- package/dist/internal/queueRuntime.d.ts +2 -0
- package/dist/internal/queueRuntime.d.ts.map +1 -0
- package/dist/internal/queueRuntime.js +88 -0
- package/dist/internal/queueRuntime.js.map +1 -0
- package/dist/internal/queueStorage.d.ts +2 -0
- package/dist/internal/queueStorage.d.ts.map +1 -0
- package/dist/internal/queueStorage.js +129 -0
- package/dist/internal/queueStorage.js.map +1 -0
- package/dist/internal/registry.d.ts +10 -0
- package/dist/internal/registry.d.ts.map +1 -0
- package/dist/internal/registry.js +24 -0
- package/dist/internal/registry.js.map +1 -0
- package/dist/internal/singletonRegistry.d.ts +2 -0
- package/dist/internal/singletonRegistry.d.ts.map +1 -0
- package/dist/internal/singletonRegistry.js +9 -0
- package/dist/internal/singletonRegistry.js.map +1 -0
- package/dist/internal/singletonRuntime.d.ts +2 -0
- package/dist/internal/singletonRuntime.d.ts.map +1 -0
- package/dist/internal/singletonRuntime.js +42 -0
- package/dist/internal/singletonRuntime.js.map +1 -0
- package/dist/internal/singletonStorage.d.ts +2 -0
- package/dist/internal/singletonStorage.d.ts.map +1 -0
- package/dist/internal/singletonStorage.js +34 -0
- package/dist/internal/singletonStorage.js.map +1 -0
- package/dist/internal/transport.d.ts +2 -0
- package/dist/internal/transport.d.ts.map +1 -0
- package/dist/internal/transport.js +49 -0
- package/dist/internal/transport.js.map +1 -0
- package/dist/internal/workflowRegistry.d.ts +2 -0
- package/dist/internal/workflowRegistry.d.ts.map +1 -0
- package/dist/internal/workflowRegistry.js +29 -0
- package/dist/internal/workflowRegistry.js.map +1 -0
- package/dist/internal/workflowRuntime.d.ts +2 -0
- package/dist/internal/workflowRuntime.d.ts.map +1 -0
- package/dist/internal/workflowRuntime.js +322 -0
- package/dist/internal/workflowRuntime.js.map +1 -0
- package/dist/internal/workflowStorage.d.ts +2 -0
- package/dist/internal/workflowStorage.d.ts.map +1 -0
- package/dist/internal/workflowStorage.js +113 -0
- package/dist/internal/workflowStorage.js.map +1 -0
- package/dist/internal/workflowWire.d.ts +2 -0
- package/dist/internal/workflowWire.d.ts.map +1 -0
- package/dist/internal/workflowWire.js +52 -0
- package/dist/internal/workflowWire.js.map +1 -0
- package/package.json +77 -1
- package/src/AlchemyCloudflareCluster.ts +200 -0
- package/src/CloudflareCluster.ts +704 -0
- package/src/CloudflareDurableObjectPrograms.ts +543 -0
- package/src/CloudflareDurableObjects.ts +430 -0
- package/src/CloudflarePersistedQueue.ts +189 -0
- package/src/CloudflareWorkflowEngine.ts +220 -0
- package/src/index.ts +38 -0
- package/src/internal/alchemyCluster.ts +120 -0
- package/src/internal/boundedMap.ts +15 -0
- package/src/internal/cluster.ts +57 -0
- package/src/internal/clusterName.ts +19 -0
- package/src/internal/entityKeepAlive.ts +121 -0
- package/src/internal/entityMailbox.ts +324 -0
- package/src/internal/entityRegistry.ts +46 -0
- package/src/internal/entityReply.ts +54 -0
- package/src/internal/entityRuntime.ts +1318 -0
- package/src/internal/entitySql.ts +60 -0
- package/src/internal/entityStorage.ts +168 -0
- package/src/internal/entityWire.ts +204 -0
- package/src/internal/queueRuntime.ts +174 -0
- package/src/internal/queueStorage.ts +255 -0
- package/src/internal/registry.ts +31 -0
- package/src/internal/singletonRegistry.ts +21 -0
- package/src/internal/singletonRuntime.ts +88 -0
- package/src/internal/singletonStorage.ts +64 -0
- package/src/internal/transport.ts +67 -0
- package/src/internal/workflowRegistry.ts +78 -0
- package/src/internal/workflowRuntime.ts +443 -0
- package/src/internal/workflowStorage.ts +234 -0
- package/src/internal/workflowWire.ts +123 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "../tsconfig.base.json",
|
|
4
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"rootDir": ".",
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"declaration": false,
|
|
9
|
+
"declarationMap": false,
|
|
10
|
+
"composite": false,
|
|
11
|
+
"incremental": false,
|
|
12
|
+
"types": ["node"],
|
|
13
|
+
"plugins": [
|
|
14
|
+
{
|
|
15
|
+
"name": "@effect/language-service",
|
|
16
|
+
"effectFn": ["untraced"],
|
|
17
|
+
"namespaceImportPackages": [],
|
|
18
|
+
"diagnosticSeverity": {
|
|
19
|
+
"floatingEffect": "off",
|
|
20
|
+
"globalJson": "off",
|
|
21
|
+
"globalJsonInEffect": "off",
|
|
22
|
+
"unstableApiUsage": "off",
|
|
23
|
+
"effectFnOpportunity": "error"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploys the Cloudflare cluster with Alchemy v2 ("Infrastructure as
|
|
3
|
+
* Effects").
|
|
4
|
+
*
|
|
5
|
+
* `make` runs inside an Effect-native `Cloudflare.Worker` init program. It
|
|
6
|
+
* registers the four cluster Durable Object classes on the hosting Worker
|
|
7
|
+
* (bindings, class exports, and SQLite migrations are all owned by Alchemy),
|
|
8
|
+
* builds the cluster layer together with the user's handler layer into the
|
|
9
|
+
* isolate-lifetime scope, and returns a handle for wiring the built context
|
|
10
|
+
* into the Worker's handlers. The user never declares or re-exports Durable
|
|
11
|
+
* Object classes.
|
|
12
|
+
*
|
|
13
|
+
* The Wrangler path (`CloudflareDurableObjects` + `CloudflareCluster.layer`)
|
|
14
|
+
* never imports this module; `@alchemy.run/cloudflare` is an optional peer
|
|
15
|
+
* dependency needed only here.
|
|
16
|
+
*
|
|
17
|
+
* **Example** (Declaring a cluster)
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import * as Cloudflare from "@alchemy.run/cloudflare"
|
|
21
|
+
* import { Effect, Layer } from "effect"
|
|
22
|
+
* import { make } from "@effect/platform-cloudflare/AlchemyCloudflareCluster"
|
|
23
|
+
* import { CloudflareCluster } from "@effect/platform-cloudflare"
|
|
24
|
+
*
|
|
25
|
+
* export default Cloudflare.Worker("MyApp", {
|
|
26
|
+
* main: import.meta.url
|
|
27
|
+
* }, Effect.gen(function*() {
|
|
28
|
+
* const cluster = yield* make({
|
|
29
|
+
* entities: [Counter],
|
|
30
|
+
* layer: Layer.mergeAll(CounterLayer, MaintenanceLayer, NightlyReport)
|
|
31
|
+
* })
|
|
32
|
+
*
|
|
33
|
+
* yield* Cloudflare.Workers.cron("0 * * * *", cluster.wake("hourly-maintenance"))
|
|
34
|
+
* // A ClusterCron fires only after a Cron Trigger wakes its seed singleton
|
|
35
|
+
* yield* Cloudflare.Workers.cron(
|
|
36
|
+
* "30 * * * *",
|
|
37
|
+
* cluster.wake(CloudflareCluster.clusterCronSingletonName("nightly-report"))
|
|
38
|
+
* )
|
|
39
|
+
*
|
|
40
|
+
* return {
|
|
41
|
+
* fetch: cluster.provide(handler)
|
|
42
|
+
* }
|
|
43
|
+
* }).pipe(Effect.provide(Cloudflare.Workers.CronEventSourceLive)))
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @stability experimental
|
|
47
|
+
* @since 4.1.3
|
|
48
|
+
*/
|
|
49
|
+
import * as Cloudflare from "@alchemy.run/cloudflare";
|
|
50
|
+
import type * as Entity from "effect/cluster/Entity";
|
|
51
|
+
import type { Sharding } from "effect/cluster/Sharding";
|
|
52
|
+
import type * as Duration from "effect/Duration";
|
|
53
|
+
import * as Effect from "effect/Effect";
|
|
54
|
+
import type * as Layer from "effect/Layer";
|
|
55
|
+
import type { PersistedQueueFactory } from "effect/persistence/PersistedQueue";
|
|
56
|
+
import type { WorkflowEngine } from "effect/workflow/WorkflowEngine";
|
|
57
|
+
import type { Cluster } from "./internal/cluster.ts";
|
|
58
|
+
declare global {
|
|
59
|
+
var __ALCHEMY_RUNTIME__: boolean | undefined;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The services `make` builds on top of the user layer: the cluster `Sharding`
|
|
63
|
+
* service, the workflow engine, and the persisted queue factory.
|
|
64
|
+
*
|
|
65
|
+
* @stability experimental
|
|
66
|
+
* @category models
|
|
67
|
+
* @since 4.1.3
|
|
68
|
+
*/
|
|
69
|
+
export type ClusterServices = Sharding | WorkflowEngine | PersistedQueueFactory;
|
|
70
|
+
export type {
|
|
71
|
+
/**
|
|
72
|
+
* The handle returned by {@link make}.
|
|
73
|
+
*
|
|
74
|
+
* **Gotchas**
|
|
75
|
+
*
|
|
76
|
+
* Namespace bindings and `context` are available only in the deployed runtime.
|
|
77
|
+
* Reading them during plan evaluation throws a diagnostic; `provide` and
|
|
78
|
+
* `wake` remain inert during planning.
|
|
79
|
+
*
|
|
80
|
+
* @stability experimental
|
|
81
|
+
* @category models
|
|
82
|
+
* @since 4.1.3
|
|
83
|
+
*/
|
|
84
|
+
Cluster } from "./internal/cluster.ts";
|
|
85
|
+
/**
|
|
86
|
+
* The entity definitions and handler layer the cluster is built from.
|
|
87
|
+
*
|
|
88
|
+
* @stability experimental
|
|
89
|
+
* @category models
|
|
90
|
+
* @since 4.1.3
|
|
91
|
+
*/
|
|
92
|
+
export interface MakeOptions<ROut, E, RIn> {
|
|
93
|
+
/**
|
|
94
|
+
* The complete set of entity definitions the Worker serves, as in
|
|
95
|
+
* `CloudflareCluster.LayerOptions`.
|
|
96
|
+
*/
|
|
97
|
+
readonly entities: ReadonlyArray<Entity.Entity<any, any>>;
|
|
98
|
+
/**
|
|
99
|
+
* The user's merged handler layers: entity handlers, singletons, workflow
|
|
100
|
+
* handlers, and any services they need.
|
|
101
|
+
*/
|
|
102
|
+
readonly layer: Layer.Layer<ROut, E, RIn>;
|
|
103
|
+
/**
|
|
104
|
+
* Interval of the entity keep-alive heartbeat alarm, as in
|
|
105
|
+
* `CloudflareCluster.LayerOptions`. Defaults to 30 seconds.
|
|
106
|
+
*/
|
|
107
|
+
readonly keepAliveHeartbeat?: Duration.Input | undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Builds the Cloudflare cluster inside an Effect-native Alchemy Worker.
|
|
111
|
+
*
|
|
112
|
+
* **Details**
|
|
113
|
+
*
|
|
114
|
+
* Always registers all four Durable Object classes (entity, workflow, durable
|
|
115
|
+
* queue, singleton) on the hosting Worker, so Alchemy owns their bindings and
|
|
116
|
+
* SQLite migrations across deploys. At runtime it builds
|
|
117
|
+
* `CloudflareCluster.layer` merged with the user's handler layer into the
|
|
118
|
+
* isolate-lifetime Scope — the Scope is never closed, so do not wrap the
|
|
119
|
+
* Worker init program in `Effect.provide(layer)` for cluster services.
|
|
120
|
+
*
|
|
121
|
+
* The returned handle exposes `provide` for the Worker's handlers, `wake` for
|
|
122
|
+
* user-declared Cron Triggers
|
|
123
|
+
* (`Cloudflare.Workers.cron(expr, cluster.wake("name"))`), and the four
|
|
124
|
+
* native namespace bindings as escape hatches.
|
|
125
|
+
*
|
|
126
|
+
* A `ClusterCron` fires only after a Cron Trigger wakes its seed singleton.
|
|
127
|
+
* Pass `CloudflareCluster.clusterCronSingletonName(name)` to `wake` for it.
|
|
128
|
+
*
|
|
129
|
+
* @stability experimental
|
|
130
|
+
* @category constructors
|
|
131
|
+
* @since 4.1.3
|
|
132
|
+
*/
|
|
133
|
+
export declare const make: <ROut, E, RIn>(options: MakeOptions<ROut, E, RIn>) => Effect.Effect<Cluster<ROut | ClusterServices>, E, Cloudflare.Worker | Exclude<RIn, ClusterServices>>;
|
|
134
|
+
//# sourceMappingURL=AlchemyCloudflareCluster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlchemyCloudflareCluster.d.ts","sourceRoot":"","sources":["../src/AlchemyCloudflareCluster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,OAAO,KAAK,UAAU,MAAM,yBAAyB,CAAA;AACrD,OAAO,KAAK,KAAK,MAAM,MAAM,uBAAuB,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AASpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAEpD,OAAO,CAAC,MAAM,CAAC;IAGb,IAAI,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7C;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,cAAc,GAAG,qBAAqB,CAAA;AAE/E,YAAY;AACV;;;;;;;;;;;;GAYG;AACH,OAAO,EACR,MAAM,uBAAuB,CAAA;AAE9B;;;;;;GAMG;AACH,MAAM,WAAW,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG;IACvC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;IACzD;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;IACzC;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;CACzD;AA+CD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAC9B,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,KAC/B,MAAM,CAAC,MAAM,CAChB,OAAO,CAAC,IAAI,GAAG,eAAe,CAAC,EAC/B,CAAC,EACD,UAAU,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAC9B,CAAA"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploys the Cloudflare cluster with Alchemy v2 ("Infrastructure as
|
|
3
|
+
* Effects").
|
|
4
|
+
*
|
|
5
|
+
* `make` runs inside an Effect-native `Cloudflare.Worker` init program. It
|
|
6
|
+
* registers the four cluster Durable Object classes on the hosting Worker
|
|
7
|
+
* (bindings, class exports, and SQLite migrations are all owned by Alchemy),
|
|
8
|
+
* builds the cluster layer together with the user's handler layer into the
|
|
9
|
+
* isolate-lifetime scope, and returns a handle for wiring the built context
|
|
10
|
+
* into the Worker's handlers. The user never declares or re-exports Durable
|
|
11
|
+
* Object classes.
|
|
12
|
+
*
|
|
13
|
+
* The Wrangler path (`CloudflareDurableObjects` + `CloudflareCluster.layer`)
|
|
14
|
+
* never imports this module; `@alchemy.run/cloudflare` is an optional peer
|
|
15
|
+
* dependency needed only here.
|
|
16
|
+
*
|
|
17
|
+
* **Example** (Declaring a cluster)
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import * as Cloudflare from "@alchemy.run/cloudflare"
|
|
21
|
+
* import { Effect, Layer } from "effect"
|
|
22
|
+
* import { make } from "@effect/platform-cloudflare/AlchemyCloudflareCluster"
|
|
23
|
+
* import { CloudflareCluster } from "@effect/platform-cloudflare"
|
|
24
|
+
*
|
|
25
|
+
* export default Cloudflare.Worker("MyApp", {
|
|
26
|
+
* main: import.meta.url
|
|
27
|
+
* }, Effect.gen(function*() {
|
|
28
|
+
* const cluster = yield* make({
|
|
29
|
+
* entities: [Counter],
|
|
30
|
+
* layer: Layer.mergeAll(CounterLayer, MaintenanceLayer, NightlyReport)
|
|
31
|
+
* })
|
|
32
|
+
*
|
|
33
|
+
* yield* Cloudflare.Workers.cron("0 * * * *", cluster.wake("hourly-maintenance"))
|
|
34
|
+
* // A ClusterCron fires only after a Cron Trigger wakes its seed singleton
|
|
35
|
+
* yield* Cloudflare.Workers.cron(
|
|
36
|
+
* "30 * * * *",
|
|
37
|
+
* cluster.wake(CloudflareCluster.clusterCronSingletonName("nightly-report"))
|
|
38
|
+
* )
|
|
39
|
+
*
|
|
40
|
+
* return {
|
|
41
|
+
* fetch: cluster.provide(handler)
|
|
42
|
+
* }
|
|
43
|
+
* }).pipe(Effect.provide(Cloudflare.Workers.CronEventSourceLive)))
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @stability experimental
|
|
47
|
+
* @since 4.1.3
|
|
48
|
+
*/
|
|
49
|
+
import * as Cloudflare from "@alchemy.run/cloudflare";
|
|
50
|
+
import * as Effect from "effect/Effect";
|
|
51
|
+
import { makeClusterDurableQueueProgram, makeClusterEntityProgram, makeClusterSingletonProgram, makeClusterWorkflowProgram } from "./CloudflareDurableObjectPrograms.js";
|
|
52
|
+
import { inertClusterHandle, makeClusterHandle } from "./internal/alchemyCluster.js";
|
|
53
|
+
// One alchemy Durable Object class per cluster program. The outer effect
|
|
54
|
+
// resolves the instance state; the inner effect runs per activation, under
|
|
55
|
+
// alchemy's blockConcurrencyWhile, once the shared isolate init (and so the
|
|
56
|
+
// user's handler registrations) has completed. The program handle is the RPC
|
|
57
|
+
// shape: every method returns an Effect and `alarm` matches alchemy's hook.
|
|
58
|
+
// `fetch` is omitted on purpose: cluster RPCs use the native bindings, so
|
|
59
|
+
// alchemy's default 404 stands in for the Wrangler classes' rejection.
|
|
60
|
+
const durableObject = (className, program) => Cloudflare.DurableObject()(className, Effect.map(Cloudflare.DurableObjectState, state => program(state.raw)));
|
|
61
|
+
const ClusterEntity = /*#__PURE__*/durableObject("ClusterEntity", makeClusterEntityProgram);
|
|
62
|
+
const ClusterWorkflow = /*#__PURE__*/durableObject("ClusterWorkflow", makeClusterWorkflowProgram);
|
|
63
|
+
const ClusterDurableQueue = /*#__PURE__*/durableObject("ClusterDurableQueue", makeClusterDurableQueueProgram);
|
|
64
|
+
const ClusterSingleton = /*#__PURE__*/durableObject("ClusterSingleton", makeClusterSingletonProgram);
|
|
65
|
+
const makeUnsafe = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
66
|
+
// Register the four Durable Object classes on the hosting Worker. At plan
|
|
67
|
+
// time this declares the bindings and class exports Alchemy deploys; at
|
|
68
|
+
// runtime it resolves the same bindings in every isolate, Worker and
|
|
69
|
+
// Durable Object alike.
|
|
70
|
+
yield* ClusterEntity;
|
|
71
|
+
yield* ClusterWorkflow;
|
|
72
|
+
yield* ClusterDurableQueue;
|
|
73
|
+
yield* ClusterSingleton;
|
|
74
|
+
if (!globalThis.__ALCHEMY_RUNTIME__) {
|
|
75
|
+
// Plan/deploy evaluation only discovers the declarations above.
|
|
76
|
+
return inertClusterHandle();
|
|
77
|
+
}
|
|
78
|
+
const env = yield* Cloudflare.WorkerEnvironment;
|
|
79
|
+
return yield* makeClusterHandle({
|
|
80
|
+
entities: options.entities,
|
|
81
|
+
layer: options.layer,
|
|
82
|
+
env,
|
|
83
|
+
keepAliveHeartbeat: options.keepAliveHeartbeat
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
/**
|
|
87
|
+
* Builds the Cloudflare cluster inside an Effect-native Alchemy Worker.
|
|
88
|
+
*
|
|
89
|
+
* **Details**
|
|
90
|
+
*
|
|
91
|
+
* Always registers all four Durable Object classes (entity, workflow, durable
|
|
92
|
+
* queue, singleton) on the hosting Worker, so Alchemy owns their bindings and
|
|
93
|
+
* SQLite migrations across deploys. At runtime it builds
|
|
94
|
+
* `CloudflareCluster.layer` merged with the user's handler layer into the
|
|
95
|
+
* isolate-lifetime Scope — the Scope is never closed, so do not wrap the
|
|
96
|
+
* Worker init program in `Effect.provide(layer)` for cluster services.
|
|
97
|
+
*
|
|
98
|
+
* The returned handle exposes `provide` for the Worker's handlers, `wake` for
|
|
99
|
+
* user-declared Cron Triggers
|
|
100
|
+
* (`Cloudflare.Workers.cron(expr, cluster.wake("name"))`), and the four
|
|
101
|
+
* native namespace bindings as escape hatches.
|
|
102
|
+
*
|
|
103
|
+
* A `ClusterCron` fires only after a Cron Trigger wakes its seed singleton.
|
|
104
|
+
* Pass `CloudflareCluster.clusterCronSingletonName(name)` to `wake` for it.
|
|
105
|
+
*
|
|
106
|
+
* @stability experimental
|
|
107
|
+
* @category constructors
|
|
108
|
+
* @since 4.1.3
|
|
109
|
+
*/
|
|
110
|
+
export const make = makeUnsafe;
|
|
111
|
+
//# sourceMappingURL=AlchemyCloudflareCluster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlchemyCloudflareCluster.js","names":[],"sources":["../src/AlchemyCloudflareCluster.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,OAAO,KAAK,UAAU,MAAM,yBAAyB;AAIrD,OAAO,KAAK,MAAM,MAAM,eAAe;AAIvC,SAEE,8BAA8B,EAC9B,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,QACrB,sCAAsC;AAC7C,SAAS,kBAAkB,EAAE,iBAAiB,QAAQ,8BAA8B;AA6DpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,aAAa,GAAG,CACpB,SAAiB,EACjB,OAAmE,KAEnE,UAAU,CAAC,aAAa,EAAS,CAC/B,SAAS,EACT,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,kBAAkB,EAAG,KAAK,IAAK,OAAO,CAAC,KAAK,CAAC,GAAgC,CAAC,CAAC,CACtG;AAEH,MAAM,aAAa,gBAAG,aAAa,CAAC,eAAe,EAAE,wBAAwB,CAAC;AAC9E,MAAM,eAAe,gBAAG,aAAa,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;AACpF,MAAM,mBAAmB,gBAAG,aAAa,CAAC,qBAAqB,EAAE,8BAA8B,CAAC;AAChG,MAAM,gBAAgB,gBAAG,aAAa,CAAC,kBAAkB,EAAE,2BAA2B,CAAC;AAEvF,MAAM,UAAU,gBAAG,MAAM,CAAC,UAAU,CAAC,WAAU,OAAmC;EAChF;EACA;EACA;EACA;EACA,OAAO,aAAa;EACpB,OAAO,eAAe;EACtB,OAAO,mBAAmB;EAC1B,OAAO,gBAAgB;EAEvB,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE;IACnC;IACA,OAAO,kBAAkB,EAAE;EAC7B;EAEA,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC,iBAAiB;EAC/C,OAAO,OAAO,iBAAiB,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;IACpB,GAAG;IACH,kBAAkB,EAAE,OAAO,CAAC;GAC7B,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,OAAO,MAAM,IAAI,GAMb,UAAiB","ignoreList":[]}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import type * as Entity from "effect/cluster/Entity";
|
|
2
|
+
import { Sharding } from "effect/cluster/Sharding";
|
|
3
|
+
import * as Context from "effect/Context";
|
|
4
|
+
import * as Duration from "effect/Duration";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Layer from "effect/Layer";
|
|
7
|
+
import type { PersistedQueueFactory } from "effect/persistence/PersistedQueue";
|
|
8
|
+
import type * as SqlClient from "effect/sql/SqlClient";
|
|
9
|
+
import type { WorkflowEngine } from "effect/workflow/WorkflowEngine";
|
|
10
|
+
/**
|
|
11
|
+
* A Durable Object name decoded back into its entity address parts.
|
|
12
|
+
*
|
|
13
|
+
* @stability experimental
|
|
14
|
+
* @category models
|
|
15
|
+
* @since 4.1.3
|
|
16
|
+
*/
|
|
17
|
+
export interface ClusterName {
|
|
18
|
+
readonly type: string;
|
|
19
|
+
readonly id: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Encodes an entity address into the Durable Object name used with
|
|
23
|
+
* `getByName`.
|
|
24
|
+
*
|
|
25
|
+
* **Details**
|
|
26
|
+
*
|
|
27
|
+
* The name is the entity type length-prefixed as `` `${type.length}:${type}${id}` ``,
|
|
28
|
+
* which keeps `(type, id)` pairs collision-free without restricting the
|
|
29
|
+
* characters an entity id may contain. Workflow, queue, and singleton names use
|
|
30
|
+
* the same scheme on their own namespaces.
|
|
31
|
+
*
|
|
32
|
+
* @stability experimental
|
|
33
|
+
* @category encoding
|
|
34
|
+
* @since 4.1.3
|
|
35
|
+
*/
|
|
36
|
+
export declare const encodeName: (type: string, id: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* Decodes a Durable Object name produced by {@link encodeName} back into its
|
|
39
|
+
* entity address parts.
|
|
40
|
+
*
|
|
41
|
+
* **Details**
|
|
42
|
+
*
|
|
43
|
+
* Returns `undefined` for names that were not produced by {@link encodeName},
|
|
44
|
+
* including non-canonical length prefixes. A Durable Object uses this to
|
|
45
|
+
* recover its own address from `ctx.id.name`.
|
|
46
|
+
*
|
|
47
|
+
* @stability experimental
|
|
48
|
+
* @category decoding
|
|
49
|
+
* @since 4.1.3
|
|
50
|
+
*/
|
|
51
|
+
export declare const decodeName: (name: string) => ClusterName | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Returns the singleton name of the seed singleton that `ClusterCron.make`
|
|
54
|
+
* registers for the cron job with the given name.
|
|
55
|
+
*
|
|
56
|
+
* **When to use**
|
|
57
|
+
*
|
|
58
|
+
* Use to wake a `ClusterCron` from a Worker Cron Trigger, by passing the
|
|
59
|
+
* result to `cluster.wake` with Alchemy or by prefixing it with `Singleton/`
|
|
60
|
+
* for `getByName` on the singleton namespace with Wrangler.
|
|
61
|
+
*
|
|
62
|
+
* **Details**
|
|
63
|
+
*
|
|
64
|
+
* The result is `"ClusterCron/<name>"`, the singleton name without the
|
|
65
|
+
* `Singleton/` Durable Object name prefix.
|
|
66
|
+
*
|
|
67
|
+
* **Gotchas**
|
|
68
|
+
*
|
|
69
|
+
* A singleton runs only when its Durable Object is woken, so a `ClusterCron`
|
|
70
|
+
* never schedules its first run until a Cron Trigger wakes this singleton.
|
|
71
|
+
* Each later run is scheduled through a destination alarm.
|
|
72
|
+
*
|
|
73
|
+
* @stability experimental
|
|
74
|
+
* @category encoding
|
|
75
|
+
* @since 4.1.3
|
|
76
|
+
*/
|
|
77
|
+
export declare const clusterCronSingletonName: (name: string) => string;
|
|
78
|
+
/**
|
|
79
|
+
* The Durable Object namespace bindings and entity definitions the cluster
|
|
80
|
+
* layer is built from.
|
|
81
|
+
*
|
|
82
|
+
* **Details**
|
|
83
|
+
*
|
|
84
|
+
* `entities` is the complete set of entity definitions the Worker serves.
|
|
85
|
+
* Handlers are attached per entity type with `Entity.toLayer`; a client or
|
|
86
|
+
* handler registration for an entity type outside this set fails at the
|
|
87
|
+
* Worker, before any Durable Object is contacted.
|
|
88
|
+
*
|
|
89
|
+
* `keepAliveHeartbeat` (default 30 seconds) is the interval of the alarm an
|
|
90
|
+
* entity Durable Object keeps armed while it holds `Entity.keepAlive` or runs
|
|
91
|
+
* a persisted request. Cloudflare never re-creates an evicted object on its
|
|
92
|
+
* own, so this alarm is what rebuilds a kept-alive entity and replays an
|
|
93
|
+
* interrupted request after a restart or deploy. It bounds recovery latency;
|
|
94
|
+
* it is not a liveness check.
|
|
95
|
+
*
|
|
96
|
+
* @stability experimental
|
|
97
|
+
* @category layers
|
|
98
|
+
* @since 4.1.3
|
|
99
|
+
*/
|
|
100
|
+
export interface LayerOptions {
|
|
101
|
+
readonly entities: ReadonlyArray<Entity.Entity<any, any>>;
|
|
102
|
+
readonly entityNamespace: DurableObjectNamespace;
|
|
103
|
+
readonly workflowNamespace: DurableObjectNamespace;
|
|
104
|
+
readonly queueNamespace: DurableObjectNamespace;
|
|
105
|
+
readonly singletonNamespace: DurableObjectNamespace;
|
|
106
|
+
readonly keepAliveHeartbeat?: Duration.Input | undefined;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Builds the cluster on Cloudflare Durable Objects.
|
|
110
|
+
*
|
|
111
|
+
* **Details**
|
|
112
|
+
*
|
|
113
|
+
* Provides the cluster `Sharding` service on top of the four same-Worker
|
|
114
|
+
* Durable Object namespace bindings, plus the `WorkflowEngine` backed by the
|
|
115
|
+
* workflow class and the `PersistedQueueFactory` backed by the queue class, so
|
|
116
|
+
* the `DurableQueue` user API works out of the box. `Entity.client` resolves
|
|
117
|
+
* an entity to its Durable Object by
|
|
118
|
+
* encoding `(type, id)` with {@link encodeName} and calling `getByName`; an
|
|
119
|
+
* unknown entity type or a bad encode fails at the Worker before any Durable
|
|
120
|
+
* Object is contacted. Entity handlers registered with `Entity.toLayer` are
|
|
121
|
+
* recorded per `EntityType` at Worker init and built once per Durable Object
|
|
122
|
+
* wake; workflow handlers registered with `Workflow.toLayer` follow the same
|
|
123
|
+
* pattern on the workflow class.
|
|
124
|
+
*
|
|
125
|
+
* @stability experimental
|
|
126
|
+
* @category layers
|
|
127
|
+
* @since 4.1.3
|
|
128
|
+
*/
|
|
129
|
+
export declare const layer: (options: LayerOptions) => Layer.Layer<Sharding | WorkflowEngine | PersistedQueueFactory>;
|
|
130
|
+
declare const DurableObjectSqlClient_base: Context.ServiceClass<DurableObjectSqlClient, "@effect/platform-cloudflare/CloudflareCluster/DurableObjectSqlClient", SqlClient.SqlClient>;
|
|
131
|
+
/**
|
|
132
|
+
* An `SqlClient` on the current entity Durable Object's own SQLite storage.
|
|
133
|
+
*
|
|
134
|
+
* **When to use**
|
|
135
|
+
*
|
|
136
|
+
* Use to keep rows next to the entity's mailbox from an entity handler build
|
|
137
|
+
* or handler, such as state that must survive eviction and commit atomically
|
|
138
|
+
* with each step. Register the handlers with `Entity.toLayer` and read the
|
|
139
|
+
* client with {@link DurableObjectSqlClient.orDie} in the build.
|
|
140
|
+
*
|
|
141
|
+
* **Details**
|
|
142
|
+
*
|
|
143
|
+
* Each entity Durable Object provides this service, an `@effect/sql-sqlite-do`
|
|
144
|
+
* client, to its handler build and handlers, including handlers registered
|
|
145
|
+
* with `Entity.toLayerQueue`. Yielding the tag directly leaves it as a layer
|
|
146
|
+
* requirement; `orDie` has none. It is a separate tag, so any
|
|
147
|
+
* `SqlClient` from the Worker layer (a D1 database, say) stays reachable inside
|
|
148
|
+
* the handlers. To run code written against `SqlClient.SqlClient`, provide this
|
|
149
|
+
* client as that service locally.
|
|
150
|
+
*
|
|
151
|
+
* `withTransaction` uses the object's storage transaction, so several rows
|
|
152
|
+
* commit or roll back together. Rows live and die with the entity's Durable
|
|
153
|
+
* Object and cannot be queried from outside it.
|
|
154
|
+
*
|
|
155
|
+
* **Gotchas**
|
|
156
|
+
*
|
|
157
|
+
* - Outside an entity Durable Object, `orDie` dies on the first handler build.
|
|
158
|
+
* In tests, provide this service from any SQL layer.
|
|
159
|
+
* - Table names starting with `cluster_` are reserved for the entity mailbox.
|
|
160
|
+
* - A row, like an encoded message, cannot exceed 2 MB.
|
|
161
|
+
* - A storage transaction closes the Durable Object's input gate until it
|
|
162
|
+
* finishes, so timers and I/O awaited inside `withTransaction` never
|
|
163
|
+
* resume. Keep transactions to SQL work.
|
|
164
|
+
* - Mailbox writes wait for an open transaction to finish, so a rollback never
|
|
165
|
+
* takes another handler's stored reply with it.
|
|
166
|
+
*
|
|
167
|
+
* **Example** (Storing rows from entity handlers)
|
|
168
|
+
*
|
|
169
|
+
* ```ts
|
|
170
|
+
* import { CloudflareCluster } from "@effect/platform-cloudflare"
|
|
171
|
+
* import { Effect } from "effect"
|
|
172
|
+
*
|
|
173
|
+
* const JournalLayer = Journal.toLayer(Effect.gen(function*() {
|
|
174
|
+
* const sql = yield* CloudflareCluster.DurableObjectSqlClient.orDie
|
|
175
|
+
* yield* sql`CREATE TABLE IF NOT EXISTS journal (entry TEXT NOT NULL)`.pipe(Effect.orDie)
|
|
176
|
+
* return Journal.of({
|
|
177
|
+
* Append: ({ payload }) => sql`INSERT INTO journal (entry) VALUES (${payload.entry})`.pipe(Effect.orDie)
|
|
178
|
+
* })
|
|
179
|
+
* }))
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @stability experimental
|
|
183
|
+
* @category services
|
|
184
|
+
* @since 4.1.3
|
|
185
|
+
*/
|
|
186
|
+
export declare class DurableObjectSqlClient extends DurableObjectSqlClient_base {
|
|
187
|
+
/**
|
|
188
|
+
* Gets the current entity's SQL client, or dies if no client is provided.
|
|
189
|
+
*
|
|
190
|
+
* @stability experimental
|
|
191
|
+
* @since 4.1.3
|
|
192
|
+
*/
|
|
193
|
+
static readonly orDie: Effect.Effect<SqlClient.SqlClient>;
|
|
194
|
+
}
|
|
195
|
+
export {};
|
|
196
|
+
//# sourceMappingURL=CloudflareCluster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloudflareCluster.d.ts","sourceRoot":"","sources":["../src/CloudflareCluster.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,KAAK,MAAM,MAAM,uBAAuB,CAAA;AAKpD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAEzC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AAO9E,OAAO,KAAK,KAAK,SAAS,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAepE;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAA4B,CAAA;AAEnF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,GAAG,SAA+B,CAAA;AAExF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,wBAAwB,SAAU,MAAM,KAAG,MAA+B,CAAA;AAEvF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;IACzD,QAAQ,CAAC,eAAe,EAAE,sBAAsB,CAAA;IAChD,QAAQ,CAAC,iBAAiB,EAAE,sBAAsB,CAAA;IAClD,QAAQ,CAAC,cAAc,EAAE,sBAAsB,CAAA;IAC/C,QAAQ,CAAC,kBAAkB,EAAE,sBAAsB,CAAA;IACnD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;CACzD;AAybD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,KAAK,YACP,YAAY,KACpB,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,cAAc,GAAG,qBAAqB,CAK7D,CAAA;;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,qBAAa,sBAAuB,SAAQ,2BAE3C;IACC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAWxD;CACF"}
|