1import * as Effect from "effect/Effect";
2import * as Layer from "effect/Layer";
3import {
4 AnalyticsEngine,
5 Assets,
6 Browser,
7 Cache,
8 D1,
9 DispatchNamespace,
10 Hyperdrive,
11 Images,
12 KvNamespace,
13 Queue,
14 R2Bucket,
15 RateLimit,
16 SecretsStore,
17 SendEmail,
18 Stream,
19 Workflows,
20} from "./bindings/index.ts";
21import * as Docker from "./Docker.ts";
22import {
23 Globals,
24 Internet,
25 Loopback,
26 LoopbackServer,
27 Storage,
28} from "./globals/index.ts";
29import * as Paths from "./internal/Paths.ts";
30import * as WorkerProxy from "./proxy/WorkerProxy.ts";
31import { Registry, RegistryProxy } from "./registry/index.ts";
32import {
33 Access,
34 RemoteBindings,
35 RemoteWorker,
36} from "./remote-bindings/index.ts";
37import * as Runtime from "./Runtime.ts";
38import * as Workerd from "./workerd/Workerd.ts";
39
40export interface RuntimeConfig {
41 api: ApiConfig;
42 storage?: StorageConfig;
43}
44
45export interface ApiConfig {
46 accountId: string | Effect.Effect<string>;
47}
48
49export interface StorageConfig {
50 directory: string;
51}
52
53export const layerRemoteBindings = ({ accountId }: ApiConfig) =>
54 RemoteBindings.RemoteBindingsLive.pipe(
55 Layer.provide(
56 RemoteWorker.layer(
57 Effect.isEffect(accountId) ? accountId : Effect.succeed(accountId),
58 ),
59 ),
60 Layer.provide(Access.layer),
61 );
62
63export const layerStorage = (config: StorageConfig | undefined) =>
64 config ? Storage.layerDisk(config.directory) : Storage.layerTemp();
65
66export const layerLoopback = () =>
67 Layer.provide(Loopback.LoopbackLive, LoopbackServer.LoopbackServerLive);
68
69export const layerLocalBindings = () =>
70 Layer.mergeAll(
71 AnalyticsEngine.AnalyticsEngineLive,
72 Assets.AssetsLive,
73 Browser.BrowserLive,
74 Cache.CacheLive,
75 D1.D1Live,
76 DispatchNamespace.DispatchNamespaceLive,
77 Hyperdrive.HyperdriveLive,
78 Images.ImagesLive,
79 KvNamespace.KvNamespaceLive,
80 Queue.QueueLive,
81 R2Bucket.R2BucketLive,
82 RateLimit.RateLimitLive,
83 SecretsStore.SecretsStoreLive,
84 SendEmail.SendEmailLive,
85 Stream.StreamLive,
86 Workflows.WorkflowsLive,
87 );
88
89export type BindingServices =
90 | AnalyticsEngine.AnalyticsEngine
91 | Assets.Assets
92 | Browser.Browser
93 | Cache.Cache
94 | D1.D1
95 | DispatchNamespace.DispatchNamespace
96 | Hyperdrive.Hyperdrive
97 | Images.Images
98 | KvNamespace.KvNamespace
99 | Loopback.Loopback
100 | Queue.Queue
101 | R2Bucket.R2Bucket
102 | RateLimit.RateLimit
103 | RemoteBindings.RemoteBindings
104 | RegistryProxy.RegistryProxy
105 | SecretsStore.SecretsStore
106 | SendEmail.SendEmail
107 | Stream.Stream
108 | Workflows.Workflows;
109
110export type RuntimeServices = Runtime.Runtime | BindingServices;
111
112export const layerProxy = () => WorkerProxy.WorkerProxyLive;
113
114export const layerRegistry = () =>
115 RegistryProxy.RegistryProxyLive.pipe(Layer.provide(Registry.RegistryLive));
116
117export const layerRuntime = (config: RuntimeConfig) =>
118 Runtime.RuntimeLive.pipe(
119 Layer.provideMerge(layerLocalBindings()),
120 Layer.provideMerge(layerRemoteBindings(config.api)),
121 Layer.provideMerge(WorkerProxy.WorkerProxyLive),
122 Layer.provide(Globals.GlobalsLive),
123 Layer.provideMerge(layerLoopback()),
124 Layer.provide(layerStorage(config.storage)),
125 Layer.provide(Internet.InternetLive),
126 Layer.provideMerge(layerRegistry()),
127 Layer.provide(Paths.PathsLive),
128 Layer.provide(Docker.DockerLive),
129 Layer.provide(Workerd.WorkerdLive),
130 );