1import * as Namespace from "../../Namespace.ts";
2import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
3
4/** The framework-integration package that drives the Waku build. */
5export const WAKU_FRAMEWORK_SPECIFIER = "@alchemy.run/frontend-frameworks/waku";
6
7/** The Node container deploy target for the Waku build. */
8export const WAKU_NODE_TARGET_SPECIFIER =
9 "@alchemy.run/frontend-frameworks/waku/node";
10
11const wakuOptions = (props: WakuProps) =>
12 props.waku !== undefined ? { waku: props.waku } : undefined;
13
14export interface WakuProps extends FrameworkSiteProps {
15 /**
16 * Serializable Waku config merged OVER the project's own
17 * `waku.config.*`.
18 */
19 waku?: {
20 srcDir?: string;
21 distDir?: string;
22 basePath?: string;
23 };
24}
25
26/**
27 * Deploy a [Waku](https://waku.gg) application to Railway: the RSC server
28 * plus SSG pages on one `Railway.Service`. The Node deploy target selects
29 * waku's `node` adapter; do not set `unstable_adapter`. SSG pages are
30 * served extensionless (`/about`).
31 *
32 * During `alchemy dev` the site is Waku's own dev server and no cloud
33 * resources are created. `Alchemy.remote()` opts back into the live
34 * Service path.
35 *
36 * ### Creating Waku Sites
37 * **Example:** Basic Waku App
38 * ```typescript
39 * const site = yield* Railway.Website.Waku("Web", {
40 * rootDir: "./app",
41 * });
42 * ```
43 *
44 * ### Server Configuration
45 * **Example:** Process Environment
46 * ```typescript
47 * const site = yield* Railway.Website.Waku("Web", {
48 * rootDir: "./app",
49 * env: {
50 * API_BASE: "https://api.example.com",
51 * },
52 * });
53 * ```
54 *
55 * @resource
56 * @product Website
57 */
58export const Waku = (id: string, props: WakuProps = {}) =>
59 makeFrameworkSite(id, props, {
60 name: "Waku",
61 framework: WAKU_FRAMEWORK_SPECIFIER,
62 target: WAKU_NODE_TARGET_SPECIFIER,
63 options: wakuOptions(props),
64 }).pipe(Namespace.push(id));