alchemy 2.0.0-beta.43 → 2.0.0-beta.44

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.
Files changed (207) hide show
  1. package/bin/cli.js +18 -5
  2. package/bin/exec.js +315 -233
  3. package/bin/exec.js.map +1 -1
  4. package/lib/Auth/Lock.js +2 -2
  5. package/lib/Auth/Lock.js.map +1 -1
  6. package/lib/Bundle/Bundle.d.ts +11 -0
  7. package/lib/Bundle/Bundle.d.ts.map +1 -1
  8. package/lib/Bundle/Bundle.js +19 -12
  9. package/lib/Bundle/Bundle.js.map +1 -1
  10. package/lib/Bundle/BundleAnalyzerPlugin.d.ts +25 -0
  11. package/lib/Bundle/BundleAnalyzerPlugin.d.ts.map +1 -0
  12. package/lib/Bundle/BundleAnalyzerPlugin.js +16 -0
  13. package/lib/Bundle/BundleAnalyzerPlugin.js.map +1 -0
  14. package/lib/Bundle/RawPlugin.d.ts +36 -0
  15. package/lib/Bundle/RawPlugin.d.ts.map +1 -0
  16. package/lib/Bundle/RawPlugin.js +80 -0
  17. package/lib/Bundle/RawPlugin.js.map +1 -0
  18. package/lib/Bundle/index.d.ts +2 -0
  19. package/lib/Bundle/index.d.ts.map +1 -1
  20. package/lib/Bundle/index.js +2 -0
  21. package/lib/Bundle/index.js.map +1 -1
  22. package/lib/Cli/commands/dev.d.ts +3 -2
  23. package/lib/Cli/commands/dev.d.ts.map +1 -1
  24. package/lib/Cli/commands/dev.js +9 -1
  25. package/lib/Cli/commands/dev.js.map +1 -1
  26. package/lib/Cli/exec.d.ts.map +1 -1
  27. package/lib/Cli/exec.js +2 -1
  28. package/lib/Cli/exec.js.map +1 -1
  29. package/lib/Cloudflare/Local.d.ts +2 -0
  30. package/lib/Cloudflare/Local.d.ts.map +1 -0
  31. package/lib/Cloudflare/Local.js +9 -0
  32. package/lib/Cloudflare/Local.js.map +1 -0
  33. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  34. package/lib/Cloudflare/Providers.js +3 -1
  35. package/lib/Cloudflare/Providers.js.map +1 -1
  36. package/lib/Cloudflare/Workers/DurableObjectBridge.d.ts.map +1 -1
  37. package/lib/Cloudflare/Workers/DurableObjectBridge.js +0 -1
  38. package/lib/Cloudflare/Workers/DurableObjectBridge.js.map +1 -1
  39. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts +22 -3
  40. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  41. package/lib/Cloudflare/Workers/LocalWorkerProvider.js +413 -21
  42. package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
  43. package/lib/Cloudflare/Workers/Worker.d.ts +6 -19
  44. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  45. package/lib/Cloudflare/Workers/Worker.js +3 -4
  46. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  47. package/lib/Cloudflare/Workers/WorkerBridge.d.ts.map +1 -1
  48. package/lib/Cloudflare/Workers/WorkerBridge.js +3 -5
  49. package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -1
  50. package/lib/Cloudflare/Workers/WorkerBundle.d.ts +1 -2
  51. package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
  52. package/lib/Cloudflare/Workers/WorkerBundle.js +3 -6
  53. package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
  54. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts +184 -0
  55. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts.map +1 -0
  56. package/lib/Cloudflare/Zaraz/ZarazConfig.js +216 -0
  57. package/lib/Cloudflare/Zaraz/ZarazConfig.js.map +1 -0
  58. package/lib/Cloudflare/Zaraz/ZarazEventTypes.d.ts +188 -0
  59. package/lib/Cloudflare/Zaraz/ZarazEventTypes.d.ts.map +1 -0
  60. package/lib/Cloudflare/Zaraz/ZarazEventTypes.js +4 -0
  61. package/lib/Cloudflare/Zaraz/ZarazEventTypes.js.map +1 -0
  62. package/lib/Cloudflare/Zaraz/index.d.ts +3 -0
  63. package/lib/Cloudflare/Zaraz/index.d.ts.map +1 -0
  64. package/lib/Cloudflare/Zaraz/index.js +2 -0
  65. package/lib/Cloudflare/Zaraz/index.js.map +1 -0
  66. package/lib/Cloudflare/index.d.ts +1 -0
  67. package/lib/Cloudflare/index.d.ts.map +1 -1
  68. package/lib/Cloudflare/index.js +1 -0
  69. package/lib/Cloudflare/index.js.map +1 -1
  70. package/lib/Local/RpcProvider.d.ts +54 -0
  71. package/lib/Local/RpcProvider.d.ts.map +1 -0
  72. package/lib/Local/RpcProvider.js +57 -0
  73. package/lib/Local/RpcProvider.js.map +1 -0
  74. package/lib/Local/RpcProviderProxy.d.ts +19 -0
  75. package/lib/Local/RpcProviderProxy.d.ts.map +1 -0
  76. package/lib/Local/RpcProviderProxy.js +48 -0
  77. package/lib/Local/RpcProviderProxy.js.map +1 -0
  78. package/lib/Local/RpcSerialization.d.ts +34 -0
  79. package/lib/Local/RpcSerialization.d.ts.map +1 -0
  80. package/lib/Local/RpcSerialization.js +120 -0
  81. package/lib/Local/RpcSerialization.js.map +1 -0
  82. package/lib/Local/RpcServer.d.ts +63 -0
  83. package/lib/Local/RpcServer.d.ts.map +1 -0
  84. package/lib/Local/RpcServer.js +72 -0
  85. package/lib/Local/RpcServer.js.map +1 -0
  86. package/lib/Local/RpcServerBun.d.ts +3 -0
  87. package/lib/Local/RpcServerBun.d.ts.map +1 -0
  88. package/lib/Local/RpcServerBun.js +47 -0
  89. package/lib/Local/RpcServerBun.js.map +1 -0
  90. package/lib/Local/RpcServerEnvironment.d.ts +20 -0
  91. package/lib/Local/RpcServerEnvironment.d.ts.map +1 -0
  92. package/lib/Local/RpcServerEnvironment.js +22 -0
  93. package/lib/Local/RpcServerEnvironment.js.map +1 -0
  94. package/lib/Local/RpcServerNode.d.ts +3 -0
  95. package/lib/Local/RpcServerNode.d.ts.map +1 -0
  96. package/lib/Local/RpcServerNode.js +43 -0
  97. package/lib/Local/RpcServerNode.js.map +1 -0
  98. package/lib/Local/RpcServerSession.d.ts +27 -0
  99. package/lib/Local/RpcServerSession.d.ts.map +1 -0
  100. package/lib/Local/RpcServerSession.js +68 -0
  101. package/lib/Local/RpcServerSession.js.map +1 -0
  102. package/lib/Local/RpcSpawner.d.ts +21 -0
  103. package/lib/Local/RpcSpawner.d.ts.map +1 -0
  104. package/lib/Local/RpcSpawner.js +132 -0
  105. package/lib/Local/RpcSpawner.js.map +1 -0
  106. package/lib/Util/PlatformServices.d.ts +7 -0
  107. package/lib/Util/PlatformServices.d.ts.map +1 -1
  108. package/lib/Util/PlatformServices.js +22 -11
  109. package/lib/Util/PlatformServices.js.map +1 -1
  110. package/lib/Util/camel.d.ts.map +1 -1
  111. package/lib/Util/camel.js +2 -3
  112. package/lib/Util/camel.js.map +1 -1
  113. package/lib/Util/data.d.ts +5 -0
  114. package/lib/Util/data.d.ts.map +1 -1
  115. package/lib/Util/data.js +29 -0
  116. package/lib/Util/data.js.map +1 -1
  117. package/lib/Util/stable.d.ts.map +1 -1
  118. package/lib/Util/stable.js +3 -6
  119. package/lib/Util/stable.js.map +1 -1
  120. package/lib/tsconfig.test.tsbuildinfo +1 -1
  121. package/package.json +12 -14
  122. package/src/Auth/Lock.ts +2 -2
  123. package/src/Bundle/Bundle.ts +35 -13
  124. package/src/Bundle/BundleAnalyzerPlugin.ts +33 -0
  125. package/src/Bundle/RawPlugin.ts +82 -0
  126. package/src/Bundle/index.ts +2 -0
  127. package/src/Cli/commands/dev.ts +51 -37
  128. package/src/Cli/exec.ts +12 -7
  129. package/src/Cloudflare/Local.ts +23 -0
  130. package/src/Cloudflare/Providers.ts +3 -0
  131. package/src/Cloudflare/Workers/DurableObjectBridge.ts +0 -1
  132. package/src/Cloudflare/Workers/LocalWorkerProvider.ts +547 -21
  133. package/src/Cloudflare/Workers/Worker.ts +11 -22
  134. package/src/Cloudflare/Workers/WorkerBridge.ts +3 -5
  135. package/src/Cloudflare/Workers/WorkerBundle.ts +4 -8
  136. package/src/Cloudflare/Zaraz/ZarazConfig.ts +403 -0
  137. package/src/Cloudflare/Zaraz/ZarazEventTypes.ts +257 -0
  138. package/src/Cloudflare/Zaraz/index.ts +25 -0
  139. package/src/Cloudflare/index.ts +1 -0
  140. package/src/Local/RpcProvider.ts +102 -0
  141. package/src/Local/RpcProviderProxy.ts +86 -0
  142. package/src/Local/RpcSerialization.ts +225 -0
  143. package/src/Local/RpcServer.ts +138 -0
  144. package/src/Local/RpcServerBun.ts +59 -0
  145. package/src/Local/RpcServerEnvironment.ts +55 -0
  146. package/src/Local/RpcServerNode.ts +58 -0
  147. package/src/Local/RpcServerSession.ts +87 -0
  148. package/src/Local/RpcSpawner.ts +196 -0
  149. package/src/Util/PlatformServices.ts +41 -27
  150. package/src/Util/camel.ts +3 -5
  151. package/src/Util/data.ts +38 -0
  152. package/src/Util/stable.ts +4 -10
  153. package/lib/Cloudflare/Local/Sidecar.d.ts +0 -63
  154. package/lib/Cloudflare/Local/Sidecar.d.ts.map +0 -1
  155. package/lib/Cloudflare/Local/Sidecar.js +0 -50
  156. package/lib/Cloudflare/Local/Sidecar.js.map +0 -1
  157. package/lib/Cloudflare/Local/SidecarHandlers.d.ts +0 -8
  158. package/lib/Cloudflare/Local/SidecarHandlers.d.ts.map +0 -1
  159. package/lib/Cloudflare/Local/SidecarHandlers.js +0 -381
  160. package/lib/Cloudflare/Local/SidecarHandlers.js.map +0 -1
  161. package/lib/Cloudflare/Local/SidecarServer.d.ts +0 -2
  162. package/lib/Cloudflare/Local/SidecarServer.d.ts.map +0 -1
  163. package/lib/Cloudflare/Local/SidecarServer.js +0 -34
  164. package/lib/Cloudflare/Local/SidecarServer.js.map +0 -1
  165. package/lib/Sidecar/Lock.d.ts +0 -23
  166. package/lib/Sidecar/Lock.d.ts.map +0 -1
  167. package/lib/Sidecar/Lock.js +0 -39
  168. package/lib/Sidecar/Lock.js.map +0 -1
  169. package/lib/Sidecar/RpcClient.d.ts +0 -15
  170. package/lib/Sidecar/RpcClient.d.ts.map +0 -1
  171. package/lib/Sidecar/RpcClient.js +0 -78
  172. package/lib/Sidecar/RpcClient.js.map +0 -1
  173. package/lib/Sidecar/RpcHandler.d.ts +0 -51
  174. package/lib/Sidecar/RpcHandler.d.ts.map +0 -1
  175. package/lib/Sidecar/RpcHandler.js +0 -87
  176. package/lib/Sidecar/RpcHandler.js.map +0 -1
  177. package/lib/Sidecar/RpcPaths.d.ts +0 -19
  178. package/lib/Sidecar/RpcPaths.d.ts.map +0 -1
  179. package/lib/Sidecar/RpcPaths.js +0 -31
  180. package/lib/Sidecar/RpcPaths.js.map +0 -1
  181. package/lib/Sidecar/RpcServer.d.ts +0 -30
  182. package/lib/Sidecar/RpcServer.d.ts.map +0 -1
  183. package/lib/Sidecar/RpcServer.js +0 -105
  184. package/lib/Sidecar/RpcServer.js.map +0 -1
  185. package/lib/Sidecar/RpcServerBun.d.ts +0 -4
  186. package/lib/Sidecar/RpcServerBun.d.ts.map +0 -1
  187. package/lib/Sidecar/RpcServerBun.js +0 -28
  188. package/lib/Sidecar/RpcServerBun.js.map +0 -1
  189. package/lib/Sidecar/RpcServerNode.d.ts +0 -4
  190. package/lib/Sidecar/RpcServerNode.d.ts.map +0 -1
  191. package/lib/Sidecar/RpcServerNode.js +0 -39
  192. package/lib/Sidecar/RpcServerNode.js.map +0 -1
  193. package/lib/Sidecar/RpcServices.d.ts +0 -6
  194. package/lib/Sidecar/RpcServices.d.ts.map +0 -1
  195. package/lib/Sidecar/RpcServices.js +0 -29
  196. package/lib/Sidecar/RpcServices.js.map +0 -1
  197. package/src/Cloudflare/Local/Sidecar.ts +0 -81
  198. package/src/Cloudflare/Local/SidecarHandlers.ts +0 -491
  199. package/src/Cloudflare/Local/SidecarServer.ts +0 -70
  200. package/src/Sidecar/Lock.ts +0 -66
  201. package/src/Sidecar/RpcClient.ts +0 -142
  202. package/src/Sidecar/RpcHandler.ts +0 -205
  203. package/src/Sidecar/RpcPaths.ts +0 -39
  204. package/src/Sidecar/RpcServer.ts +0 -153
  205. package/src/Sidecar/RpcServerBun.ts +0 -41
  206. package/src/Sidecar/RpcServerNode.ts +0 -51
  207. package/src/Sidecar/RpcServices.ts +0 -48
@@ -1,491 +0,0 @@
1
- import {
2
- Runtime,
3
- type BindingHook,
4
- type BindingServices,
5
- type HyperdriveOrigin,
6
- type Module,
7
- type Assets as RuntimeAssets,
8
- type DurableObjectNamespace as RuntimeDurableObjectNamespace,
9
- type RuntimeServices,
10
- } from "@distilled.cloud/cloudflare-runtime";
11
- import {
12
- Ai,
13
- Assets,
14
- Browser,
15
- D1,
16
- Data,
17
- DurableObjectNamespace,
18
- Hyperdrive,
19
- Images,
20
- Json,
21
- KvNamespace,
22
- R2Bucket,
23
- Service,
24
- Text,
25
- VersionMetadata,
26
- WasmModule,
27
- WorkerLoader,
28
- } from "@distilled.cloud/cloudflare-runtime/bindings";
29
- import * as LocalProxy from "@distilled.cloud/cloudflare-runtime/proxy/LocalProxy";
30
- import * as Cause from "effect/Cause";
31
- import * as Effect from "effect/Effect";
32
- import * as Exit from "effect/Exit";
33
- import * as Fiber from "effect/Fiber";
34
- import * as Hash from "effect/Hash";
35
- import * as Layer from "effect/Layer";
36
- import * as Path from "effect/Path";
37
- import * as Redacted from "effect/Redacted";
38
- import * as Result from "effect/Result";
39
- import * as Scope from "effect/Scope";
40
- import * as Stream from "effect/Stream";
41
- import type * as Bundle from "../../Bundle/Bundle.ts";
42
- import { InstanceId } from "../../InstanceId.ts";
43
- import { Stack } from "../../Stack.ts";
44
- import { Stage } from "../../Stage.ts";
45
- import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
46
- import { getCompatibility } from "../Workers/Compatibility.ts";
47
- import * as Vite from "../Workers/Vite.ts";
48
- import type { Worker, WorkerAssetsConfig } from "../Workers/Worker.ts";
49
- import { getCronBindings } from "../Workers/WorkerAsyncBindings.ts";
50
- import type { WorkerBinding } from "../Workers/WorkerBinding.ts";
51
- import {
52
- WorkerBundle,
53
- type WorkerBundleOptions,
54
- } from "../Workers/WorkerBundle.ts";
55
- import { createWorkerName } from "../Workers/WorkerName.ts";
56
- import {
57
- ServeError,
58
- ServeResult,
59
- Sidecar,
60
- ValidationError,
61
- type ReconcileOptions,
62
- } from "./Sidecar.ts";
63
-
64
- export const SidecarHandlers = Layer.effect(
65
- Sidecar,
66
- Effect.gen(function* () {
67
- const { accountId } = yield* CloudflareEnvironment;
68
- const bundler = yield* WorkerBundle;
69
- const runtime = yield* Runtime;
70
- const path = yield* Path.Path;
71
- const localProxy = yield* LocalProxy.LocalProxy;
72
-
73
- const toRuntimeModules = Effect.fn(function* (bundle: Bundle.BundleOutput) {
74
- const modules: Module[] = [];
75
- for (const file of bundle.files) {
76
- const ext = path.extname(file.path);
77
- const type = moduleTypeFromExtension(ext);
78
- if (type === "SourceMap") continue;
79
- if (type === "Data" || type === "Wasm") {
80
- if (!(file.content instanceof Uint8Array)) {
81
- return yield* new ValidationError({
82
- message: `Expected Uint8Array for ${file.path} (${type})`,
83
- value: file.content,
84
- });
85
- }
86
- modules.push({
87
- name: file.path,
88
- type,
89
- content: file.content,
90
- });
91
- } else {
92
- if (typeof file.content !== "string") {
93
- return yield* new ValidationError({
94
- message: `Expected string for ${file.path} (${type})`,
95
- value: file.content,
96
- });
97
- }
98
- modules.push({
99
- name: file.path,
100
- type,
101
- content: file.content,
102
- });
103
- }
104
- }
105
- return modules;
106
- });
107
-
108
- const serveScoped = Effect.fnUntraced(function* (
109
- worker: WorkerConfig,
110
- bundle: Bundle.BundleOutput,
111
- ) {
112
- const scope = yield* Effect.flatMap(Effect.scope, Scope.fork);
113
- const address = yield* runtime
114
- .start({
115
- name: worker.name,
116
- compatibilityDate: worker.compatibility.date,
117
- compatibilityFlags: worker.compatibility.flags,
118
- bindings: worker.workerBindings as never,
119
- hyperdrives: worker.hyperdrives,
120
- durableObjectNamespaces: toRuntimeDurableObjectNamespaces(
121
- worker.durableObjectNamespaces,
122
- ),
123
- modules: yield* toRuntimeModules(bundle),
124
- assets: toRuntimeAssets(worker.assets),
125
- })
126
- .pipe(Scope.provide(scope));
127
- const previous = workerdScopes.get(worker.id);
128
- if (previous) {
129
- yield* Effect.forkDetach(Scope.close(previous, Exit.void));
130
- }
131
- workerdScopes.set(worker.id, scope);
132
- yield* localProxy.setLocalAddress(worker.id, address);
133
- return address;
134
- });
135
-
136
- const buildConfig = Effect.fn(function* ({
137
- id,
138
- props,
139
- bindings,
140
- stack,
141
- instanceId,
142
- }: ReconcileOptions) {
143
- const name = yield* createWorkerName(id, props.name).pipe(
144
- Effect.provideService(Stack, stack),
145
- Effect.provideService(Stage, stack.stage),
146
- Effect.provideService(InstanceId, instanceId),
147
- );
148
- const compatibility = getCompatibility(props);
149
- const workerBindings: BindingHook<BindingServices>[] = [];
150
- const durableObjectNamespaces: Record<string, string> = {};
151
- const hyperdrives: Record<string, Required<HyperdriveOrigin>> = {};
152
- for (const { data } of bindings) {
153
- for (const binding of data.bindings ?? []) {
154
- if (binding.type === "durable_object_namespace") {
155
- durableObjectNamespaces[binding.name] = binding.className!;
156
- }
157
- workerBindings.push(yield* toRuntimeBinding(binding));
158
- }
159
- if (data.hyperdrives) {
160
- for (const [id, origin] of Object.entries(data.hyperdrives)) {
161
- hyperdrives[id] = {
162
- scheme: origin.scheme,
163
- host: origin.host,
164
- port: origin.port,
165
- user: origin.user,
166
- database: origin.database,
167
- password: Redacted.isRedacted(origin.password)
168
- ? Redacted.value(origin.password)
169
- : origin.password,
170
- sslmode: origin.sslmode,
171
- };
172
- }
173
- }
174
- }
175
- for (const [key, value] of Object.entries(props.env ?? {})) {
176
- if (value === undefined) continue;
177
- if (Redacted.isRedacted(value)) {
178
- workerBindings.push(Text.binding(key, Redacted.value(value)));
179
- } else if (typeof value === "string") {
180
- workerBindings.push(Text.binding(key, value));
181
- } else {
182
- workerBindings.push(Json.binding(key, value));
183
- }
184
- }
185
- return {
186
- id,
187
- name,
188
- compatibility,
189
- workerBindings,
190
- durableObjectNamespaces,
191
- hyperdrives,
192
- bundleOptions: {
193
- id,
194
- main: props.main,
195
- compatibility,
196
- entry: props.isExternal
197
- ? { kind: "external" }
198
- : { kind: "effect", exports: (props.exports ?? {}) as any },
199
- stack: { name: stack.name, stage: stack.stage },
200
- userOptions: props.build,
201
- } satisfies WorkerBundleOptions,
202
- assets: props.assets,
203
- };
204
- });
205
-
206
- type WorkerConfig = Effect.Success<ReturnType<typeof buildConfig>>;
207
-
208
- const runServer = Effect.fnUntraced(function* (worker: WorkerConfig) {
209
- let start = Date.now();
210
- let status: "start" | "update" = "start";
211
- yield* bundler.watch(worker.bundleOptions).pipe(
212
- Stream.tap((event) => {
213
- if (event._tag === "Start") {
214
- start = Date.now();
215
- if (status === "update") {
216
- return Effect.log(`[${worker.id}] Rebuilding`);
217
- }
218
- } else if (event._tag === "Error") {
219
- return Effect.logError(`[${worker.id}] Bundle error`, event.error);
220
- }
221
- return Effect.void;
222
- }),
223
- Stream.filterMap((event) =>
224
- event._tag === "Success"
225
- ? Result.succeed(event.output)
226
- : Result.failVoid,
227
- ),
228
- Stream.mapEffect((bundle) =>
229
- serveScoped(worker, bundle).pipe(
230
- Effect.exit,
231
- Effect.tap((exit) => {
232
- if (exit._tag === "Success") {
233
- const message = Effect.log(
234
- `[${worker.id}] ${status === "update" ? "Updated" : "Started"} in ${Math.round(Date.now() - start)}ms`,
235
- );
236
- status = "update";
237
- return message;
238
- } else {
239
- return Effect.logError(
240
- `[${worker.id}] Error`,
241
- Cause.squash(exit.cause),
242
- );
243
- }
244
- }),
245
- ),
246
- ),
247
- Stream.runDrain,
248
- Effect.forkScoped,
249
- );
250
- });
251
-
252
- const rootScope = yield* Effect.scope;
253
- const workerdScopes = new Map<string, Scope.Closeable>();
254
-
255
- const context = yield* Effect.context<RuntimeServices>();
256
- const instances = new Map<
257
- string,
258
- {
259
- hash: number;
260
- fiber: Fiber.Fiber<ServeResult, ServeError>;
261
- scope: Scope.Closeable;
262
- }
263
- >();
264
-
265
- const runInstance = Effect.fn(function* (options: ReconcileOptions) {
266
- const { id, props, bindings } = options;
267
- const config = yield* buildConfig(options);
268
- const url = yield* localProxy.registerWorker(id);
269
- if (props.vite) {
270
- console.log("starting vite dev server", id);
271
- const devServer = yield* Vite.viteDev(
272
- props.vite.rootDir,
273
- props.env ?? {},
274
- {
275
- compatibilityDate: config.compatibility.date,
276
- compatibilityFlags: config.compatibility.flags,
277
- worker: {
278
- name: config.name,
279
- bindings: config.workerBindings,
280
- durableObjectNamespaces: toRuntimeDurableObjectNamespaces(
281
- config.durableObjectNamespaces,
282
- ),
283
- hyperdrives: config.hyperdrives,
284
- assets: toRuntimeAssets(config.assets),
285
- },
286
- context,
287
- },
288
- );
289
- console.log("vite dev server started", id);
290
- const localAddress = devServer.resolvedUrls!.local[0].slice(0, -1);
291
- yield* localProxy.setLocalAddress(id, localAddress);
292
- } else {
293
- yield* runServer(config);
294
- }
295
- return {
296
- workerId: config.name,
297
- workerName: config.name,
298
- logpush: undefined,
299
- url,
300
- tags: [],
301
- durableObjectNamespaces: config.durableObjectNamespaces,
302
- domains: [],
303
- crons: Array.from(
304
- new Set([...getCronBindings(bindings), ...(props.crons ?? [])]),
305
- ),
306
- accountId,
307
- } satisfies Worker["Attributes"];
308
- });
309
-
310
- return Sidecar.of({
311
- diff: Effect.fn(function* (options) {
312
- const hash = Hash.structure(options);
313
- return {
314
- action: instances.get(options.id)?.hash === hash ? "noop" : "update",
315
- };
316
- }),
317
- reconcile: Effect.fn(function* (options) {
318
- const hash = Hash.structure(options);
319
- const existing = instances.get(options.id);
320
- if (existing) {
321
- if (existing.hash === hash) {
322
- yield* Effect.log(
323
- `[${options.id}] No changes, using existing instance`,
324
- );
325
- return yield* Fiber.join(existing.fiber);
326
- }
327
- yield* Effect.log(
328
- `[${options.id}] Changes detected, interrupting existing instance`,
329
- );
330
- yield* Fiber.interrupt(existing.fiber);
331
- yield* Scope.close(existing.scope, Exit.void);
332
- instances.delete(options.id);
333
- }
334
- const scope = yield* Scope.fork(rootScope);
335
- const fiber = yield* runInstance(options).pipe(
336
- Effect.forkDetach,
337
- Scope.provide(scope),
338
- );
339
- instances.set(options.id, { hash, fiber, scope });
340
- return yield* Fiber.join(fiber).pipe(
341
- Effect.onExit((exit) =>
342
- Effect.sync(() => {
343
- if (exit._tag === "Failure") {
344
- instances.delete(options.id);
345
- }
346
- }),
347
- ),
348
- );
349
- }),
350
- delete: Effect.fn(function* (id) {
351
- const existing = instances.get(id);
352
- if (existing) {
353
- yield* Fiber.interrupt(existing.fiber);
354
- yield* Scope.close(existing.scope, Exit.void);
355
- instances.delete(id);
356
- }
357
- }),
358
- });
359
- }),
360
- );
361
-
362
- const toRuntimeBinding = Effect.fnUntraced(function* (b: WorkerBinding) {
363
- const unsupported = () =>
364
- new ValidationError({
365
- message: `${b.type} bindings are not supported in local mode`,
366
- value: b,
367
- });
368
- switch (b.type) {
369
- case "ai":
370
- return Ai.remote(b.name);
371
- case "analytics_engine":
372
- return yield* unsupported();
373
- case "artifacts":
374
- return yield* unsupported();
375
- case "assets":
376
- return Assets.binding(b.name);
377
- case "browser":
378
- return Browser.binding(b.name);
379
- case "d1":
380
- return D1.remote(b.name, b.id);
381
- case "data_blob":
382
- return Data.binding(b.name, Buffer.from(b.part));
383
- case "dispatch_namespace":
384
- return yield* unsupported();
385
- case "durable_object_namespace":
386
- return DurableObjectNamespace.local({
387
- name: b.name,
388
- className: b.className!,
389
- scriptName: b.scriptName,
390
- });
391
- case "hyperdrive":
392
- return Hyperdrive.binding(b.name, b.id);
393
- case "images":
394
- return Images.remote(b.name);
395
- case "inherit":
396
- return yield* unsupported();
397
- case "json":
398
- return Json.binding(b.name, b.json);
399
- case "kv_namespace":
400
- return KvNamespace.remote(b.name, b.namespaceId);
401
- case "mtls_certificate":
402
- return yield* unsupported();
403
- case "pipelines":
404
- return yield* unsupported();
405
- case "plain_text":
406
- return Text.binding(b.name, b.text);
407
- case "queue":
408
- return yield* unsupported();
409
- case "r2_bucket":
410
- return R2Bucket.remote(b.name, b.bucketName, b.jurisdiction);
411
- case "ratelimit":
412
- return yield* unsupported();
413
- case "secret_key":
414
- return yield* unsupported();
415
- case "secret_text":
416
- return Text.binding(b.name, b.text);
417
- case "secrets_store_secret":
418
- return yield* unsupported();
419
- case "send_email":
420
- return yield* unsupported();
421
- case "service":
422
- return Service.local({ name: b.name, scriptName: b.service });
423
- case "text_blob":
424
- return Data.binding(b.name, Buffer.from(b.part));
425
- case "vectorize":
426
- return yield* unsupported();
427
- case "version_metadata":
428
- return VersionMetadata.binding(b.name);
429
- case "wasm_module":
430
- return WasmModule.binding(b.name, Buffer.from(b.part));
431
- case "worker_loader":
432
- return WorkerLoader.binding(b.name);
433
- case "workflow":
434
- return yield* unsupported();
435
- default:
436
- return yield* unsupported();
437
- }
438
- });
439
-
440
- const toRuntimeAssets = (
441
- assets: WorkerAssetsConfig | undefined,
442
- ): RuntimeAssets | undefined => {
443
- if (!assets) return undefined;
444
- if (typeof assets === "string") {
445
- return {
446
- directory: assets,
447
- };
448
- }
449
- return {
450
- directory: "directory" in assets ? assets.directory : assets.path,
451
- headers: assets.config?.headers,
452
- redirects: assets.config?.redirects,
453
- htmlHandling: assets.config?.htmlHandling,
454
- notFoundHandling: assets.config?.notFoundHandling,
455
- runWorkerFirst: assets.config?.runWorkerFirst,
456
- serveDirectly: assets.config?.serveDirectly,
457
- };
458
- };
459
-
460
- const toRuntimeDurableObjectNamespaces = (
461
- namespaces: Record<string, string>,
462
- ): RuntimeDurableObjectNamespace[] => {
463
- return Object.entries(namespaces).map(([className, namespaceId]) => ({
464
- className,
465
- uniqueKey: namespaceId,
466
- sql: true,
467
- }));
468
- };
469
-
470
- const moduleTypeFromExtension = (ext: string): Module["type"] | "SourceMap" => {
471
- switch (ext) {
472
- case ".wasm":
473
- return "Wasm";
474
- case ".txt":
475
- case ".html":
476
- case ".sql":
477
- case ".custom":
478
- return "Text";
479
- case ".bin":
480
- return "Data";
481
- case ".mjs":
482
- case ".js":
483
- return "ESModule";
484
- case ".cjs":
485
- return "CommonJsModule";
486
- case ".map":
487
- return "SourceMap";
488
- default:
489
- return "Text";
490
- }
491
- };
@@ -1,70 +0,0 @@
1
- import {
2
- layerLocalProxy,
3
- layerRuntime,
4
- } from "@distilled.cloud/cloudflare-runtime/RuntimeServices";
5
- import * as Effect from "effect/Effect";
6
- import * as Layer from "effect/Layer";
7
- import * as Path from "effect/Path";
8
- import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
9
- import * as AlchemyContext from "../../AlchemyContext.ts";
10
- import { AuthProviders } from "../../Auth/AuthProvider.ts";
11
- import { CredentialsStoreLive } from "../../Auth/Credentials.ts";
12
- import { ProfileLive } from "../../Auth/Profile.ts";
13
- import * as RpcServer from "../../Sidecar/RpcServer.ts";
14
- import * as RpcServices from "../../Sidecar/RpcServices.ts";
15
- import {
16
- httpServer,
17
- PlatformServices,
18
- runMain,
19
- } from "../../Util/PlatformServices.ts";
20
- import { CloudflareAuth } from "../Auth/AuthProvider.ts";
21
- import * as CloudflareEnvironment from "../CloudflareEnvironment.ts";
22
- import * as Credentials from "../Credentials.ts";
23
- import { Sidecar, SidecarSchema } from "./Sidecar.ts";
24
- import { SidecarHandlers } from "./SidecarHandlers.ts";
25
-
26
- const apiServices = Layer.merge(
27
- Credentials.fromAuthProvider(),
28
- CloudflareEnvironment.fromProfile(),
29
- ).pipe(
30
- Layer.provide(CloudflareAuth),
31
- Layer.provide(Layer.succeed(AuthProviders, {})),
32
- Layer.provide(ProfileLive),
33
- Layer.provide(CredentialsStoreLive),
34
- );
35
-
36
- const runtimeServices = SidecarHandlers.pipe(
37
- Layer.provide(layerLocalProxy(1337)),
38
- Layer.provide(
39
- Layer.unwrap(
40
- Effect.gen(function* () {
41
- const { accountId } =
42
- yield* CloudflareEnvironment.CloudflareEnvironment;
43
- const { dotAlchemy } = yield* AlchemyContext.AlchemyContext;
44
- const path = yield* Path.Path;
45
- return layerRuntime({
46
- api: {
47
- accountId,
48
- },
49
- storage: {
50
- directory: path.join(dotAlchemy, "local"),
51
- },
52
- });
53
- }),
54
- ),
55
- ),
56
- Layer.provide(
57
- Layer.mergeAll(apiServices, FetchHttpClient.layer, httpServer()),
58
- ),
59
- );
60
-
61
- const services = Layer.provideMerge(
62
- Layer.provideMerge(runtimeServices, RpcServices.layer(import.meta.url)),
63
- PlatformServices,
64
- );
65
-
66
- RpcServer.makeRpcServer(Sidecar, SidecarSchema).pipe(
67
- Effect.provide(services),
68
- Effect.scoped,
69
- runMain,
70
- );
@@ -1,66 +0,0 @@
1
- import * as lockfile from "@alchemy.run/node-utils";
2
- import * as Context from "effect/Context";
3
- import * as Effect from "effect/Effect";
4
- import type * as Fiber from "effect/Fiber";
5
- import * as Layer from "effect/Layer";
6
- import * as Schema from "effect/Schema";
7
- import type * as Scope from "effect/Scope";
8
- import * as RpcPaths from "./RpcPaths.ts";
9
-
10
- export class LockError extends Schema.TaggedErrorClass<LockError>()(
11
- "LockError",
12
- {
13
- reason: Schema.Literals(["Conflict", "PlatformError"]),
14
- message: Schema.String,
15
- cause: Schema.optional(Schema.DefectWithStack),
16
- },
17
- ) {}
18
-
19
- export class Lock extends Context.Service<
20
- Lock,
21
- {
22
- readonly check: Effect.Effect<boolean>;
23
- readonly acquire: Effect.Effect<
24
- Fiber.Fiber<never, LockError>,
25
- LockError,
26
- Scope.Scope
27
- >;
28
- }
29
- >()("Lock") {}
30
-
31
- const STALE_MS = 10_000;
32
- const UPDATE_MS = 1_000;
33
-
34
- const make = Effect.gen(function* () {
35
- const paths = yield* RpcPaths.RpcPaths;
36
-
37
- const check = Effect.tryPromise(() =>
38
- lockfile.check(paths.lock, { stale: STALE_MS, realpath: false }),
39
- ).pipe(Effect.orElseSucceed(() => false));
40
-
41
- const acquire = Effect.gen(function* () {
42
- yield* Effect.acquireRelease(
43
- Effect.tryPromise({
44
- try: () =>
45
- lockfile.lock(paths.lock, {
46
- stale: STALE_MS,
47
- update: UPDATE_MS,
48
- retries: 0,
49
- realpath: false,
50
- }),
51
- catch: (cause) =>
52
- new LockError({
53
- reason: "Conflict",
54
- message: "Lock already held by another process",
55
- cause,
56
- }),
57
- }),
58
- (release) => Effect.promise(() => release().catch(() => {})),
59
- );
60
- return yield* Effect.never;
61
- }).pipe(Effect.forkScoped);
62
-
63
- return Lock.of({ check, acquire });
64
- });
65
-
66
- export const LockLive = Layer.effect(Lock, make);