| 1 | import * as Alchemy from "alchemy"; |
| 2 | import * as AWS from "alchemy/AWS"; |
| 3 | import * as Effect from "effect/Effect"; |
| 4 | |
| 5 | const aws = AWS.providers(); |
| 6 | |
| 7 | export 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 | ); |