1/**
2 * Single-process cluster layer for durable entities and workflows. It wires
3 * `Sharding` with no-op runner communication, no-op runner health checks,
4 * SQL-backed message storage, environment-based sharding configuration, and
5 * either SQL-backed or in-memory runner storage.
6 *
7 * This layer is meant for local, embedded, or small single-node setups where the
8 * process handles all cluster work itself. It still requires a SQL client
9 * because mailbox messages and replies are stored in SQL.
10 *
11 * @stability unstable
12 * @since 4.0.0
13 */
14import * as Layer from "effect/Layer"
15import type { ConfigError } from "../Config.ts"
16import type * as Crypto from "../Crypto.ts"
17import type * as SqlClient from "../sql/SqlClient.ts"
18import type * as MessageStorage from "./MessageStorage.ts"
19import * as RunnerHealth from "./RunnerHealth.ts"
20import * as Runners from "./Runners.ts"
21import * as RunnerStorage from "./RunnerStorage.ts"
22import * as Sharding from "./Sharding.ts"
23import * as ShardingConfig from "./ShardingConfig.ts"
24import * as SqlMessageStorage from "./SqlMessageStorage.ts"
25import * as SqlRunnerStorage from "./SqlRunnerStorage.ts"
26
27/**
28 * Provides a SQL-backed single-node cluster for running durable
29 * entities and workflows.
30 *
31 * **When to use**
32 *
33 * Use to run durable cluster entities and workflows in a local, embedded, or
34 * small single-node process while keeping mailbox and reply state in SQL.
35 *
36 * **Details**
37 *
38 * The layer provides `Sharding`, `Runners`, and `MessageStorage`. It loads
39 * `ShardingConfig` from environment variables and overlays
40 * `options.shardingConfig` when provided. Message storage is always SQL-backed;
41 * runner storage is SQL-backed by default and switches to in-memory storage
42 * when `runnerStorage` is set to `"memory"`.
43 *
44 * **Gotchas**
45 *
46 * - Even when `runnerStorage` is `"memory"`, message storage remains
47 * SQL-backed, so callers must still provide `SqlClient` and `Crypto.Crypto`
48 * (used to hash over-length message deduplication keys).
49 * - Runner communication and runner health are no-op services, so this layer is
50 * for single-process use rather than multi-runner coordination.
51 *
52 * @see {@link ShardingConfig.layerFromEnv} for loading environment configuration before applying `shardingConfig` overrides
53 * @see {@link SqlMessageStorage.layer} for the SQL-backed message storage that this layer provides
54 * @see {@link SqlRunnerStorage.layer} for the default SQL-backed runner storage selected when `runnerStorage` is omitted or `"sql"`
55 * @see {@link RunnerStorage.layerMemory} for the in-memory runner storage selected by `runnerStorage: "memory"`
56 *
57 * @stability unstable
58 * @category layers
59 * @since 4.0.0
60 */
61export const layer = (options?: {
62 readonly shardingConfig?: Partial<ShardingConfig.ShardingConfig["Service"]> | undefined
63 readonly runnerStorage?: "memory" | "sql" | undefined
64}): Layer.Layer<
65 | Sharding.Sharding
66 | Runners.Runners
67 | MessageStorage.MessageStorage,
68 ConfigError,
69 SqlClient.SqlClient | Crypto.Crypto
70> =>
71 Sharding.layer.pipe(
72 Layer.provideMerge(Runners.layerNoop),
73 Layer.provideMerge(SqlMessageStorage.layer),
74 Layer.provide([
75 options?.runnerStorage === "memory" ? RunnerStorage.layerMemory : Layer.orDie(SqlRunnerStorage.layer),
76 RunnerHealth.layerNoop
77 ]),
78 Layer.provide(ShardingConfig.layerFromEnv(options?.shardingConfig))
79 )