1import * as Namespace from "../../Namespace.ts";
2import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
3
4/** The framework-integration package that drives the TanStack Start build. */
5export const TANSTACK_START_FRAMEWORK_SPECIFIER =
6 "@alchemy.run/frontend-frameworks/tanstack-start";
7
8/** The Node container deploy target for the TanStack Start build. */
9export const TANSTACK_START_NODE_TARGET_SPECIFIER =
10 "@alchemy.run/frontend-frameworks/tanstack-start/node";
11
12export interface TanStackStartProps extends FrameworkSiteProps {}
13
14/**
15 * Deploy a [TanStack Start](https://tanstack.com/start) application to a
16 * Hetzner Cloud Server: the SSR server as a systemd unit on port 3000,
17 * static assets baked into the unit.
18 *
19 * The build runs through
20 * `@alchemy.run/frontend-frameworks/tanstack-start` with the
21 * `@alchemy.run/frontend-frameworks/tanstack-start/node` deploy target —
22 * both must be installed in your project, alongside `@tanstack/react-start`
23 * (or `@tanstack/solid-start`) and `vite`.
24 *
25 * Your `vite.config.ts` needs no adapter wiring: TanStack Start is pure
26 * Vite, so the integration drives the project's own `vite build`, forces
27 * the SSR bundle to be self-contained, and wraps its fetch handler as a
28 * Node HTTP server.
29 *
30 *
31 * ### Creating TanStack Start Sites
32 * **Example:** Basic TanStack Start App
33 * ```typescript
34 * const site = yield* Hetzner.Website.TanStackStart("Web", {
35 * rootDir: "./app",
36 * });
37 * ```
38 *
39 * **Example:** Custom Domain
40 * ```typescript
41 * const site = yield* Hetzner.Website.TanStackStart("Web", {
42 * rootDir: "./app",
43 * domain: "app.example.com",
44 * zone,
45 * });
46 * ```
47 *
48 * ### Server Configuration
49 * **Example:** Process Environment
50 * ```typescript
51 * const site = yield* Hetzner.Website.TanStackStart("Web", {
52 * rootDir: "./app",
53 * env: {
54 * API_BASE: "https://api.example.com",
55 * },
56 * });
57 * ```
58 *
59 * **Example:** Read An Environment Variable From A Server Function
60 * ```typescript
61 * // src/routes/index.tsx
62 * const getApiBase = createServerFn({ method: "GET" }).handler(() => ({
63 * apiBase: process.env.API_BASE,
64 * }));
65 * ```
66 *
67 * @resource
68 * @product Website
69 */
70export const TanStackStart = (id: string, props: TanStackStartProps = {}) =>
71 makeFrameworkSite(id, props, {
72 name: "TanStackStart",
73 framework: TANSTACK_START_FRAMEWORK_SPECIFIER,
74 target: TANSTACK_START_NODE_TARGET_SPECIFIER,
75 }).pipe(Namespace.push(id));