1import * as Alchemy from "alchemy";
2import * as AWS from "alchemy/AWS";
3import * as Effect from "effect/Effect";
4
5const aws = AWS.providers();
6
7export default Alchemy.Stack(
8 "AwsRouterExample",
9 { providers: aws, state: Alchemy.localState() },
10 Effect.gen(function* () {
11 const tags = { Example: "aws-router", Surface: "website" };
12
13 /**
14 * One CloudFront front door shared by every site below.
15 *
16 * `alchemy deploy` creates a real distribution; `alchemy dev` runs an
17 * emulated one on a local port. Either way the sites mount onto it the
18 * same way, so there is nothing dev-specific in this file.
19 */
20 const router = yield* AWS.Website.Router("Router", {
21 invalidation: { paths: "all" },
22 tags: { ...tags, Mode: "router" },
23 });
24
25 /**
26 * Mounted at the root. `alchemy dev` runs Vite's own dev server (HMR
27 * included) and the Router proxies to it.
28 */
29 const web = yield* AWS.Website.Vite("Web", {
30 rootDir: "apps/web",
31 domain: { router },
32 tags: { ...tags, Site: "web" },
33 });
34
35 /**
36 * Mounted at `/docs`. The path prefix is NOT stripped — a site served
37 * under `/docs` is addressed as `/docs/...` at the edge, so Vite's
38 * `base` has to match the mount point for asset URLs to resolve.
39 */
40 const docs = yield* AWS.Website.Vite("Docs", {
41 rootDir: "apps/docs",
42 vite: { base: "/docs/" },
43 domain: { router, path: "/docs" },
44 tags: { ...tags, Site: "docs" },
45 });
46
47 return {
48 /** `https://<id>.cloudfront.net` deployed, `http://localhost:<port>` in dev. */
49 url: router.url,
50 web: web.url,
51 docs: docs.url,
52 distributionId: router.distribution.distributionId,
53 };
54 }),
55);