1import * as FrameworkCore from "../core/index.ts";
2import * as Effect from "effect/Effect";
3import vocsCloudflareTarget from "./cloudflare.ts";
4import {
5 makeWakuSourceProvider,
6 SourceProviderError,
7 type SourceProvider,
8 type WakuBuildChildConfig,
9 type WakuSourceOptions,
10} from "../waku/source.ts";
11import { make as vocsFrameworkLayer } from "./Vocs.ts";
12
13const PROVIDER = "@alchemy.run/frontend-frameworks/vocs/source";
14
15export interface VocsSourceOptions {
16 readonly rootDir?: string;
17 /** Vocs build output directory, used to exclude generated files from the input hash. */
18 readonly outDir?: string;
19 readonly memo?: WakuSourceOptions["memo"];
20}
21
22export const buildInChild = (config: WakuBuildChildConfig) =>
23 Effect.gen(function* () {
24 const framework = yield* FrameworkCore.Framework;
25 return yield* framework.build({ root: config.rootDir });
26 }).pipe(
27 Effect.provide(
28 vocsFrameworkLayer({
29 root: config.rootDir,
30 target: vocsCloudflareTarget({
31 worker: {
32 compatibilityDate: config.compatibilityDate,
33 compatibilityFlags: config.compatibilityFlags,
34 },
35 }),
36 }),
37 ),
38 );
39
40export const makeVocsSourceProvider = (
41 options: VocsSourceOptions,
42): SourceProvider =>
43 makeWakuSourceProvider(
44 { ...options, distDir: options.outDir },
45 {
46 provider: PROVIDER,
47 framework: "vocs",
48 displayName: "Vocs",
49 buildModule: import.meta.url,
50 layer: ({ root, target }) =>
51 vocsFrameworkLayer({
52 root,
53 target: vocsCloudflareTarget({ worker: target.config }),
54 }),
55 },
56 );
57
58const sourceModule = {
59 make: (
60 options: unknown,
61 ): Effect.Effect<SourceProvider, SourceProviderError> => {
62 if (
63 options !== undefined &&
64 (typeof options !== "object" || options === null)
65 ) {
66 return Effect.fail(
67 new SourceProviderError({
68 provider: PROVIDER,
69 message: `Invalid options for ${PROVIDER}: expected an object, got ${typeof options}`,
70 }),
71 );
72 }
73 return Effect.succeed(
74 makeVocsSourceProvider((options ?? {}) as VocsSourceOptions),
75 );
76 },
77};
78
79export default sourceModule;