1import type { InputProps } from "../../Input.ts";
2import * as Namespace from "../../Namespace.ts";
3import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
4
5/** The framework-integration package that drives the TanStack Start build. */
6export const TANSTACK_START_FRAMEWORK_SPECIFIER =
7 "@alchemy.run/frontend-frameworks/tanstack-start";
8
9/** The AWS Lambda deploy target for the TanStack Start build. */
10export const TANSTACK_START_AWS_TARGET_SPECIFIER =
11 "@alchemy.run/frontend-frameworks/tanstack-start/aws";
12
13export interface TanStackStartProps extends FrameworkSiteProps {}
14
15/**
16 * Deploy a [TanStack Start](https://tanstack.com/start) application to AWS:
17 * the SSR server on a streaming Lambda Function URL, client assets in S3,
18 * and a CloudFront distribution whose edge router serves uploaded files from
19 * S3 and forwards everything else to the server.
20 *
21 * The build runs through
22 * `@alchemy.run/frontend-frameworks/tanstack-start` with the
23 * `@alchemy.run/frontend-frameworks/tanstack-start/aws` deploy target — both
24 * must be installed in your project, alongside `@tanstack/react-start` (or
25 * `@tanstack/solid-start`) and `vite`.
26 *
27 * Your `vite.config.ts` needs no adapter wiring: TanStack Start is pure
28 * Vite, so the integration drives the project's own `vite build`, forces the
29 * SSR bundle to be self-contained, and wraps its fetch handler as a
30 * streaming Lambda handler.
31 *
32 * ### Creating TanStack Start Sites
33 * **Example:** Basic TanStack Start App
34 * ```typescript
35 * const site = yield* AWS.Website.TanStackStart("Web", {
36 * rootDir: "./app",
37 * });
38 * ```
39 *
40 * **Example:** Custom Domain
41 * ```typescript
42 * const site = yield* AWS.Website.TanStackStart("Web", {
43 * rootDir: "./app",
44 * domain: {
45 * name: "app.example.com",
46 * hostedZoneId: zone.hostedZoneId,
47 * },
48 * });
49 * ```
50 *
51 * ### Server Configuration
52 * **Example:** Tune The Server Function
53 * ```typescript
54 * const site = yield* AWS.Website.TanStackStart("Web", {
55 * rootDir: "./app",
56 * memorySize: 2048,
57 * env: {
58 * API_BASE: api.url,
59 * },
60 * });
61 * ```
62 *
63 * **Example:** Read An Environment Variable From A Server Function
64 * ```typescript
65 * // src/routes/index.tsx
66 * const getApiBase = createServerFn({ method: "GET" }).handler(() => ({
67 * apiBase: process.env.API_BASE,
68 * }));
69 * ```
70 *
71 * ### Shared Router
72 * **Example:** Serve Through An Existing Router
73 * ```typescript
74 * const router = yield* AWS.Website.Router("FrontDoor", {});
75 *
76 * const site = yield* AWS.Website.TanStackStart("Web", {
77 * rootDir: "./app",
78 * domain: { router },
79 * });
80 * ```
81 *
82 * @resource
83 */
84export const TanStackStart = (
85 id: string,
86 props: InputProps<TanStackStartProps> = {},
87) =>
88 makeFrameworkSite(id, props, {
89 name: "TanStackStart",
90 framework: TANSTACK_START_FRAMEWORK_SPECIFIER,
91 target: TANSTACK_START_AWS_TARGET_SPECIFIER,
92 }).pipe(Namespace.push(id));