| 1 | import * as FrameworkCore from "../core/index.ts"; |
| 2 | import * as Effect from "effect/Effect"; |
| 3 | import vocsCloudflareTarget from "./cloudflare.ts"; |
| 4 | import { |
| 5 | makeWakuSourceProvider, |
| 6 | SourceProviderError, |
| 7 | type SourceProvider, |
| 8 | type WakuBuildChildConfig, |
| 9 | type WakuSourceOptions, |
| 10 | } from "../waku/source.ts"; |
| 11 | import { make as vocsFrameworkLayer } from "./Vocs.ts"; |
| 12 | |
| 13 | const PROVIDER = "@alchemy.run/frontend-frameworks/vocs/source"; |
| 14 | |
| 15 | export 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 | |
| 22 | export 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 | |
| 40 | export 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 | |
| 58 | const 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 | |
| 79 | export default sourceModule; |