1import { frameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
2
3/** The framework-integration package that drives the Waku build. */
4export const WAKU_FRAMEWORK_SPECIFIER = "@alchemy.run/frontend-frameworks/waku";
5
6/** The Node container deploy target for the Waku build. */
7export const WAKU_NODE_TARGET_SPECIFIER =
8 "@alchemy.run/frontend-frameworks/waku/node";
9
10const wakuOptions = (props: WakuProps) =>
11 props.waku !== undefined ? { waku: props.waku } : undefined;
12
13export interface WakuProps extends FrameworkSiteProps {
14 /**
15 * Serializable Waku config merged OVER the project's own
16 * `waku.config.*`.
17 */
18 waku?: {
19 /**
20 * Source directory, relative to `rootDir` (waku's `srcDir`).
21 * @default the project's `waku.config.*` value, or `"src"`
22 */
23 srcDir?: string;
24 /**
25 * Build output directory (waku's `distDir`).
26 * @default the project's `waku.config.*` value, or `"dist"`
27 */
28 distDir?: string;
29 /** Public base path the site deploys under (waku's `basePath`). */
30 basePath?: string;
31 };
32}
33
34/**
35 * Deploy a [Waku](https://waku.gg) application to Fly: the RSC server on a
36 * Machine, static assets (SSG pages included) baked into the image.
37 * Prerendered pages are served extensionless (`/about`).
38 *
39 *
40 * ### Creating Waku Sites
41 * **Example:** Basic Waku App
42 * ```typescript
43 * const site = yield* Fly.Website.Waku("Web", {
44 * rootDir: "./app",
45 * });
46 * ```
47 *
48 * **Example:** Custom Domain
49 * ```typescript
50 * const site = yield* Fly.Website.Waku("Web", {
51 * rootDir: "./app",
52 * domain: "app.example.com",
53 * });
54 * ```
55 *
56 * @resource
57 * @product Website
58 */
59export const Waku = (id: string, props: WakuProps = {}) =>
60 frameworkSite(id, props, {
61 name: "Waku",
62 framework: WAKU_FRAMEWORK_SPECIFIER,
63 target: WAKU_NODE_TARGET_SPECIFIER,
64 options: wakuOptions(props),
65 htmlHandling: "drop-trailing-slash",
66 });