1import * as Namespace from "../../Namespace.ts";
2import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
3
4/** The framework-integration package that drives the Octane build. */
5export const OCTANE_FRAMEWORK_SPECIFIER =
6 "@alchemy.run/frontend-frameworks/octane";
7
8/** The Node container deploy target for the Octane build. */
9export const OCTANE_NODE_TARGET_SPECIFIER =
10 "@alchemy.run/frontend-frameworks/octane/node";
11
12export interface OctaneProps extends FrameworkSiteProps {}
13
14/**
15 * Deploy an [OctaneJS](https://octanejs.dev) application to Railway:
16 * Octane's SSR server plus client assets on one `Railway.Service`.
17 *
18 * `Railway.Website.Octane` selects hosting and automatically wraps Octane's
19 * default native Node output. Keep compiler and route settings in
20 * `octane.config.ts` without an adapter. The legacy Node marker adapter
21 * remains optional for existing projects.
22 *
23 * During `alchemy dev` the site is Octane/Vite's own dev server and no
24 * cloud resources are created. `Alchemy.remote()` opts back into the live
25 * Service path.
26 *
27 * ### Creating Octane Sites
28 * **Example:** Basic Octane App
29 * ```typescript
30 * const site = yield* Railway.Website.Octane("Web", {
31 * rootDir: "./app",
32 * });
33 * ```
34 *
35 * ### Server Configuration
36 * **Example:** Process Environment
37 * ```typescript
38 * const site = yield* Railway.Website.Octane("Web", {
39 * rootDir: "./app",
40 * env: {
41 * API_BASE: "https://api.example.com",
42 * },
43 * });
44 * ```
45 *
46 * @resource
47 * @product Website
48 */
49export const Octane = (id: string, props: OctaneProps = {}) =>
50 makeFrameworkSite(id, props, {
51 name: "Octane",
52 framework: OCTANE_FRAMEWORK_SPECIFIER,
53 target: OCTANE_NODE_TARGET_SPECIFIER,
54 }).pipe(Namespace.push(id));