raktajs 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // src/forge/build.ts
3
- import { mkdirSync } from "fs";
4
- import { join as join2, resolve } from "path";
3
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
4
+ import { join as join3, resolve } from "path";
5
5
 
6
6
  // src/router/manifest.ts
7
7
  import { existsSync as existsSync2, readFileSync, writeFileSync } from "fs";
@@ -116,14 +116,219 @@ function readManifest(manifestPath) {
116
116
  return parsed;
117
117
  }
118
118
 
119
+ // src/forge/clientEntry.ts
120
+ import { existsSync as existsSync3, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
121
+ import { dirname, join as join2, relative as relative2 } from "path";
122
+ function toModuleSpecifier(fromFile, targetFile) {
123
+ const relativePath = relative2(dirname(fromFile), targetFile).replace(/\\/g, "/");
124
+ if (relativePath.startsWith(".")) {
125
+ return relativePath;
126
+ }
127
+ return `./${relativePath}`;
128
+ }
129
+ function toCssImportSpecifier(entryPath, projectRoot) {
130
+ const candidates = [
131
+ join2(projectRoot, "styles", "globals.css"),
132
+ join2(projectRoot, "styles", "globals.scss"),
133
+ join2(projectRoot, "styles", "globals.sass")
134
+ ];
135
+ const stylePath = candidates.find((candidate) => existsSync3(candidate));
136
+ if (!stylePath) {
137
+ return null;
138
+ }
139
+ return toModuleSpecifier(entryPath, stylePath);
140
+ }
141
+ function getPageRoutes(manifest) {
142
+ return manifest.routes.filter((route) => route.kind === "page");
143
+ }
144
+ function buildRouteImports(entryPath, appDir, pageRoutes) {
145
+ const routeEntries = pageRoutes.map((route) => {
146
+ const pagePath = join2(appDir, route.filePath);
147
+ return ` ${JSON.stringify(route.urlPattern)}: () => import("${toModuleSpecifier(entryPath, pagePath)}"),`;
148
+ }).join(`
149
+ `);
150
+ return `const routeModules = {
151
+ ${routeEntries}
152
+ } as const;`;
153
+ }
154
+ function buildRouteTable(pageRoutes) {
155
+ const routeEntries = pageRoutes.map((route) => ` ${JSON.stringify(route.urlPattern)}: routeModules[${JSON.stringify(route.urlPattern)}],`).join(`
156
+ `);
157
+ return `const routes = {
158
+ ${routeEntries}
159
+ } as const;`;
160
+ }
161
+ function findExistingModule(basePathWithoutExtension) {
162
+ const candidates = [".tsx", ".ts", ".jsx", ".js"].map((extension) => `${basePathWithoutExtension}${extension}`);
163
+ return candidates.find((candidate) => existsSync3(candidate));
164
+ }
165
+ function buildStarterGlobalLoaders(entryPath, appDir) {
166
+ const mascotPath = findExistingModule(join2(appDir, "components", "raktaShrimpMascot"));
167
+ const gamePath = findExistingModule(join2(appDir, "components", "shrimpRunGame"));
168
+ const loaders = [];
169
+ if (mascotPath !== undefined) {
170
+ loaders.push(` const mascotModule = await import("${toModuleSpecifier(entryPath, mascotPath)}");
171
+ (globalThis as typeof globalThis & Record<string, unknown>).RaktaShrimpMascot = mascotModule.default;`);
172
+ }
173
+ if (gamePath !== undefined) {
174
+ loaders.push(` const gameModule = await import("${toModuleSpecifier(entryPath, gamePath)}");
175
+ (globalThis as typeof globalThis & Record<string, unknown>).ShrimpRunGame = gameModule.default;`);
176
+ }
177
+ if (loaders.length === 0) {
178
+ return `async function loadRaktaGlobals(): Promise<void> {
179
+ return;
180
+ }`;
181
+ }
182
+ return `async function loadRaktaGlobals(): Promise<void> {
183
+ ${loaders.join(`
184
+
185
+ `)}
186
+ }`;
187
+ }
188
+ function buildClientEntrySource(options, entryPath) {
189
+ const pageRoutes = getPageRoutes(options.manifest);
190
+ const routeModules = buildRouteImports(entryPath, options.appDir, pageRoutes);
191
+ const routeTable = buildRouteTable(pageRoutes);
192
+ const cssImportSpecifier = toCssImportSpecifier(entryPath, options.projectRoot);
193
+ const cssImport = cssImportSpecifier !== null ? `import "${cssImportSpecifier}";
194
+ ` : "";
195
+ const starterGlobalLoaders = buildStarterGlobalLoaders(entryPath, options.appDir);
196
+ return `import React, { useEffect, useState } from "react";
197
+ import { createRoot } from "react-dom/client";
198
+ import * as ReactHooks from "react";
199
+ ${cssImport}
200
+ (globalThis as typeof globalThis & Record<string, unknown>).useCallback = ReactHooks.useCallback;
201
+ (globalThis as typeof globalThis & Record<string, unknown>).useEffect = ReactHooks.useEffect;
202
+ (globalThis as typeof globalThis & Record<string, unknown>).useRef = ReactHooks.useRef;
203
+ (globalThis as typeof globalThis & Record<string, unknown>).useState = ReactHooks.useState;
204
+
205
+ ${starterGlobalLoaders}
206
+
207
+ await loadRaktaGlobals();
208
+
209
+ ${routeModules}
210
+
211
+ ${routeTable}
212
+
213
+ type RoutePath = keyof typeof routes;
214
+ type PageModule = { default: React.ComponentType };
215
+
216
+ function normalizePathname(pathname: string): string {
217
+ if (pathname.length > 1 && pathname.endsWith("/")) {
218
+ return pathname.slice(0, -1);
219
+ }
220
+
221
+ return pathname;
222
+ }
223
+
224
+ function resolveRouteLoader(pathname: string): () => Promise<PageModule> {
225
+ const normalizedPathname = normalizePathname(pathname) as RoutePath;
226
+
227
+ return routes[normalizedPathname] ?? routes["/"];
228
+ }
229
+
230
+ function navigate(to: string): void {
231
+ window.history.pushState({ source: "rakta-click", to }, "", to);
232
+ window.dispatchEvent(new PopStateEvent("popstate", { state: { to } }));
233
+ }
234
+
235
+ function App(): React.ReactElement {
236
+ const [pathname, setPathname] = useState(() => window.location.pathname);
237
+ const [Page, setPage] = useState<React.ComponentType | null>(null);
238
+
239
+ useEffect(() => {
240
+ function handlePopState(): void {
241
+ setPathname(window.location.pathname);
242
+ }
243
+
244
+ function handleClick(event: MouseEvent): void {
245
+ const target = event.target;
246
+
247
+ if (!(target instanceof Element)) {
248
+ return;
249
+ }
250
+
251
+ const clickElement = target.closest("click");
252
+
253
+ if (!clickElement) {
254
+ return;
255
+ }
256
+
257
+ const to = clickElement.getAttribute("to");
258
+
259
+ if (!to || to.startsWith("http://") || to.startsWith("https://")) {
260
+ return;
261
+ }
262
+
263
+ event.preventDefault();
264
+ navigate(to);
265
+ setPathname(window.location.pathname);
266
+ }
267
+
268
+ window.addEventListener("popstate", handlePopState);
269
+ document.addEventListener("click", handleClick);
270
+
271
+ return () => {
272
+ window.removeEventListener("popstate", handlePopState);
273
+ document.removeEventListener("click", handleClick);
274
+ };
275
+ }, []);
276
+
277
+ useEffect(() => {
278
+ let isCurrent = true;
279
+
280
+ resolveRouteLoader(pathname)().then((pageModule) => {
281
+ if (isCurrent) {
282
+ setPage(() => pageModule.default);
283
+ }
284
+ });
285
+
286
+ return () => {
287
+ isCurrent = false;
288
+ };
289
+ }, [pathname]);
290
+
291
+ if (!Page) {
292
+ return React.createElement("main", {
293
+ style: {
294
+ minHeight: "100vh",
295
+ display: "grid",
296
+ placeItems: "center",
297
+ background: "#050505",
298
+ color: "#f8fafc",
299
+ fontFamily: "ui-sans-serif, system-ui, sans-serif",
300
+ },
301
+ }, "Loading Rakta.js...");
302
+ }
303
+
304
+ return React.createElement(Page);
305
+ }
306
+
307
+ const rootElement = document.getElementById("rakta-root");
308
+
309
+ if (!rootElement) {
310
+ throw new Error("Rakta.js root element #rakta-root was not found.");
311
+ }
312
+
313
+ createRoot(rootElement).render(React.createElement(App));
314
+ `;
315
+ }
316
+ function writeClientEntry(options) {
317
+ mkdirSync(options.workDir, { recursive: true });
318
+ const entryPath = join2(options.workDir, "client-entry.tsx");
319
+ const entrySource = buildClientEntrySource(options, entryPath);
320
+ writeFileSync2(entryPath, entrySource, "utf-8");
321
+ return entryPath;
322
+ }
323
+
119
324
  // src/forge/build.ts
120
325
  async function buildProject(options) {
121
326
  const startMs = Date.now();
122
327
  const artifacts = [];
123
328
  const errors = [];
124
- mkdirSync(resolve(options.outDir), { recursive: true });
329
+ mkdirSync2(resolve(options.outDir), { recursive: true });
125
330
  const manifest = generateManifest(options.appDir);
126
- const manifestPath = join2(options.outDir, "route-manifest.json");
331
+ const manifestPath = join3(options.outDir, "route-manifest.json");
127
332
  writeManifest(manifest, manifestPath);
128
333
  const manifestContent = JSON.stringify(manifest);
129
334
  artifacts.push({
@@ -131,15 +336,21 @@ async function buildProject(options) {
131
336
  sizeBytes: new TextEncoder().encode(manifestContent).byteLength,
132
337
  kind: "manifest"
133
338
  });
339
+ const entryPoint = existsSync4(options.entryPoint) ? options.entryPoint : writeClientEntry({
340
+ projectRoot: options.projectRoot,
341
+ appDir: options.appDir,
342
+ workDir: join3(options.projectRoot, ".rakta"),
343
+ manifest
344
+ });
134
345
  const buildResult = await Bun.build({
135
- entrypoints: [options.entryPoint],
346
+ entrypoints: [entryPoint],
136
347
  outdir: options.outDir,
137
348
  target: options.target,
138
349
  minify: options.minify,
139
350
  sourcemap: options.sourcemap ? "external" : "none",
140
351
  splitting: options.splitting,
141
352
  naming: {
142
- entry: "[name].[ext]",
353
+ entry: "app.[ext]",
143
354
  chunk: "chunks/[name]-[hash].[ext]",
144
355
  asset: "assets/[name]-[hash].[ext]"
145
356
  }
@@ -172,8 +383,8 @@ async function buildProject(options) {
172
383
  };
173
384
  }
174
385
  // src/forge/devServer.ts
175
- import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
176
- import { join as join3 } from "path";
386
+ import { existsSync as existsSync5, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
387
+ import { join as join4 } from "path";
177
388
 
178
389
  // src/render/modes.ts
179
390
  var RENDER_MODE_DESCRIPTORS = {
@@ -281,15 +492,18 @@ function isRoadmapMode(mode) {
281
492
 
282
493
  // src/render/renderer.ts
283
494
  function buildHtmlShell(options) {
495
+ const title = options.title ?? options.appName;
496
+ const faviconPath = options.faviconPath ?? "/favicon.ico";
497
+ const descriptionMeta = options.description !== undefined ? `<meta name="description" content="${options.description}" />` : "";
284
498
  return `
285
499
  <!DOCTYPE html>
286
500
  <html lang="${options.lang}">
287
501
  <head>
288
502
  <meta charset="UTF-8" />
289
503
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
290
- <title>
291
- ${options.appName}
292
- </title>
504
+ <title>${title}</title>
505
+ ${descriptionMeta}
506
+ <link rel="icon" href="${faviconPath}" sizes="any" />
293
507
  <link rel="stylesheet" href="${options.cssPath}" />
294
508
  </head>
295
509
  <body>
@@ -395,18 +609,55 @@ function resolveDevPort(port) {
395
609
  return port > 0 ? port : DEFAULT_DEV_PORT;
396
610
  }
397
611
  function isReadableFile(filePath) {
398
- return existsSync3(filePath) && statSync2(filePath).isFile();
612
+ return existsSync5(filePath) && statSync2(filePath).isFile();
613
+ }
614
+ async function buildDevClientBundle(options, manifest) {
615
+ const workDir = join4(options.projectRoot, ".rakta");
616
+ const clientOutDir = join4(workDir, "dev");
617
+ const clientEntry = writeClientEntry({
618
+ projectRoot: options.projectRoot,
619
+ appDir: options.appDir,
620
+ workDir,
621
+ manifest
622
+ });
623
+ const buildResult = await Bun.build({
624
+ entrypoints: [clientEntry],
625
+ outdir: clientOutDir,
626
+ target: "browser",
627
+ sourcemap: "external",
628
+ naming: {
629
+ entry: "app.[ext]",
630
+ chunk: "chunks/[name]-[hash].[ext]",
631
+ asset: "assets/[name]-[hash].[ext]"
632
+ }
633
+ });
634
+ if (!buildResult.success) {
635
+ const buildErrors = buildResult.logs.map((buildLog) => buildLog.message).join(`
636
+ `);
637
+ throw new Error(`Failed to build Rakta.js client bundle.
638
+ ${buildErrors}`);
639
+ }
640
+ return clientOutDir;
399
641
  }
400
- function startDevServer(options) {
642
+ async function startDevServer(options) {
401
643
  const manifest = generateManifest(options.appDir);
402
644
  const resolvedPort = resolveDevPort(options.port);
645
+ const clientOutDir = await buildDevClientBundle(options, manifest);
403
646
  const server = Bun.serve({
404
647
  port: resolvedPort,
405
648
  hostname: options.host,
406
649
  async fetch(request) {
407
650
  const url = new URL(request.url);
408
651
  const { pathname } = url;
409
- const publicPath = join3(options.publicDir, pathname);
652
+ if (clientOutDir.length > 0) {
653
+ const clientBundlePath = join4(clientOutDir, pathname);
654
+ if (isReadableFile(clientBundlePath)) {
655
+ return new Response(readFileSync2(clientBundlePath), {
656
+ headers: { "Content-Type": resolveMime(clientBundlePath) }
657
+ });
658
+ }
659
+ }
660
+ const publicPath = join4(options.publicDir, pathname);
410
661
  if (isReadableFile(publicPath)) {
411
662
  return new Response(readFileSync2(publicPath), {
412
663
  headers: { "Content-Type": resolveMime(pathname) }
@@ -414,7 +665,7 @@ function startDevServer(options) {
414
665
  }
415
666
  const apiMatch = matchRoute(pathname, manifest.routes.filter((route) => route.kind === "api"));
416
667
  if (apiMatch) {
417
- const modulePath = join3(options.appDir, apiMatch.entry.filePath);
668
+ const modulePath = join4(options.appDir, apiMatch.entry.filePath);
418
669
  const routeModule = await import(modulePath);
419
670
  const method = request.method.toUpperCase();
420
671
  const handler = routeModule[method];
@@ -441,8 +692,10 @@ function startDevServer(options) {
441
692
  timestampMs: Date.now()
442
693
  }, {
443
694
  appName: options.appName,
695
+ title: options.seo.defaultTitle,
696
+ description: options.seo.defaultDescription,
444
697
  scriptPath: "/app.js",
445
- cssPath: "/globals.css",
698
+ cssPath: "/app.css",
446
699
  lang: "en"
447
700
  });
448
701
  if (result.kind === "failure") {
@@ -463,8 +716,8 @@ function startDevServer(options) {
463
716
  };
464
717
  }
465
718
  // src/forge/inspect.ts
466
- import { existsSync as existsSync4, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
467
- import { join as join4 } from "path";
719
+ import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
720
+ import { join as join5 } from "path";
468
721
  function detectArtifactKind(filename) {
469
722
  if (filename === "route-manifest.json")
470
723
  return "manifest";
@@ -482,13 +735,13 @@ function formatBytes(bytes) {
482
735
  return `${(bytes / 1048576).toFixed(2)} MB`;
483
736
  }
484
737
  function scanDirectory2(dirPath) {
485
- if (!existsSync4(dirPath))
738
+ if (!existsSync6(dirPath))
486
739
  return [];
487
740
  const collected = [];
488
741
  function walk(current) {
489
742
  const entries = readdirSync2(current, { withFileTypes: true });
490
743
  for (const entry of entries) {
491
- const full = join4(current, entry.name);
744
+ const full = join5(current, entry.name);
492
745
  if (entry.isDirectory()) {
493
746
  walk(full);
494
747
  } else if (entry.isFile()) {
@@ -505,7 +758,7 @@ function scanDirectory2(dirPath) {
505
758
  }
506
759
  function inspectBuild(options) {
507
760
  const artifacts = scanDirectory2(options.outDir);
508
- const manifestPath = join4(options.outDir, "route-manifest.json");
761
+ const manifestPath = join5(options.outDir, "route-manifest.json");
509
762
  const manifest = readManifest(manifestPath);
510
763
  const emptyManifest = {
511
764
  version: "1",
@@ -579,4 +832,4 @@ export {
579
832
  buildProject
580
833
  };
581
834
 
582
- //# debugId=B67DA786A474431864756E2164756E21
835
+ //# debugId=1A92A1766DE1CB8664756E2164756E21
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["..\\..\\src\\forge\\build.ts", "..\\..\\src\\router\\manifest.ts", "..\\..\\src\\router\\scanner.ts", "..\\..\\src\\forge\\devServer.ts", "..\\..\\src\\render\\modes.ts", "..\\..\\src\\render\\renderer.ts", "..\\..\\src\\router\\matcher.ts", "..\\..\\src\\forge\\inspect.ts"],
3
+ "sources": ["..\\..\\src\\forge\\build.ts", "..\\..\\src\\router\\manifest.ts", "..\\..\\src\\router\\scanner.ts", "..\\..\\src\\forge\\clientEntry.ts", "..\\..\\src\\forge\\devServer.ts", "..\\..\\src\\render\\modes.ts", "..\\..\\src\\render\\renderer.ts", "..\\..\\src\\router\\matcher.ts", "..\\..\\src\\forge\\inspect.ts"],
4
4
  "sourcesContent": [
5
- "import { mkdirSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { generateManifest, writeManifest } from \"../router/manifest\";\nimport type {\n\tForgeBuildArtifact,\n\tForgeBuildOptions,\n\tForgeBuildResult,\n} from \"./types\";\n\n/**\n * Runs the Rakta.js Forge build pipeline.\n * Uses Bun.build for bundling. Generates a route manifest alongside the bundle.\n */\nexport async function buildProject(\n\toptions: ForgeBuildOptions,\n): Promise<ForgeBuildResult> {\n\tconst startMs = Date.now();\n\tconst artifacts: ForgeBuildArtifact[] = [];\n\tconst errors: string[] = [];\n\n\tmkdirSync(resolve(options.outDir), { recursive: true });\n\n\t// Generate and write route manifest\n\tconst manifest = generateManifest(options.appDir);\n\tconst manifestPath = join(options.outDir, \"route-manifest.json\");\n\twriteManifest(manifest, manifestPath);\n\n\tconst manifestContent = JSON.stringify(manifest);\n\tartifacts.push({\n\t\toutputPath: manifestPath,\n\t\tsizeBytes: new TextEncoder().encode(manifestContent).byteLength,\n\t\tkind: \"manifest\",\n\t});\n\n\t// Build JavaScript bundle\n\tconst buildResult = await Bun.build({\n\t\tentrypoints: [options.entryPoint],\n\t\toutdir: options.outDir,\n\t\ttarget: options.target,\n\t\tminify: options.minify,\n\t\tsourcemap: options.sourcemap ? \"external\" : \"none\",\n\t\tsplitting: options.splitting,\n\t\tnaming: {\n\t\t\tentry: \"[name].[ext]\",\n\t\t\tchunk: \"chunks/[name]-[hash].[ext]\",\n\t\t\tasset: \"assets/[name]-[hash].[ext]\",\n\t\t},\n\t});\n\n\tif (!buildResult.success) {\n\t\tfor (const log of buildResult.logs) {\n\t\t\terrors.push(log.message);\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tartifacts,\n\t\t\tmanifest,\n\t\t\tbuildMs: Date.now() - startMs,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tfor (const output of buildResult.outputs) {\n\t\tartifacts.push({\n\t\t\toutputPath: output.path,\n\t\t\tsizeBytes: output.size,\n\t\t\tkind: output.path.endsWith(\".css\") ? \"stylesheet\" : \"script\",\n\t\t});\n\t}\n\n\treturn {\n\t\tsuccess: true,\n\t\tartifacts,\n\t\tmanifest,\n\t\tbuildMs: Date.now() - startMs,\n\t\terrors: [],\n\t};\n}\n",
5
+ "import { existsSync, mkdirSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { generateManifest, writeManifest } from \"../router/manifest\";\nimport { writeClientEntry } from \"./clientEntry\";\nimport type {\n\tForgeBuildArtifact,\n\tForgeBuildOptions,\n\tForgeBuildResult,\n} from \"./types\";\n\n/**\n * Runs the Rakta.js Forge build pipeline.\n * Uses Bun.build for bundling. Generates a route manifest alongside the bundle.\n */\nexport async function buildProject(\n\toptions: ForgeBuildOptions,\n): Promise<ForgeBuildResult> {\n\tconst startMs = Date.now();\n\tconst artifacts: ForgeBuildArtifact[] = [];\n\tconst errors: string[] = [];\n\n\tmkdirSync(resolve(options.outDir), { recursive: true });\n\n\t// Generate and write route manifest\n\tconst manifest = generateManifest(options.appDir);\n\tconst manifestPath = join(options.outDir, \"route-manifest.json\");\n\twriteManifest(manifest, manifestPath);\n\n\tconst manifestContent = JSON.stringify(manifest);\n\tartifacts.push({\n\t\toutputPath: manifestPath,\n\t\tsizeBytes: new TextEncoder().encode(manifestContent).byteLength,\n\t\tkind: \"manifest\",\n\t});\n\n\tconst entryPoint = existsSync(options.entryPoint)\n\t\t? options.entryPoint\n\t\t: writeClientEntry({\n\t\t\t\tprojectRoot: options.projectRoot,\n\t\t\t\tappDir: options.appDir,\n\t\t\t\tworkDir: join(options.projectRoot, \".rakta\"),\n\t\t\t\tmanifest,\n\t\t\t});\n\n\t// Build JavaScript bundle\n\tconst buildResult = await Bun.build({\n\t\tentrypoints: [entryPoint],\n\t\toutdir: options.outDir,\n\t\ttarget: options.target,\n\t\tminify: options.minify,\n\t\tsourcemap: options.sourcemap ? \"external\" : \"none\",\n\t\tsplitting: options.splitting,\n\t\tnaming: {\n\t\t\tentry: \"app.[ext]\",\n\t\t\tchunk: \"chunks/[name]-[hash].[ext]\",\n\t\t\tasset: \"assets/[name]-[hash].[ext]\",\n\t\t},\n\t});\n\n\tif (!buildResult.success) {\n\t\tfor (const log of buildResult.logs) {\n\t\t\terrors.push(log.message);\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tartifacts,\n\t\t\tmanifest,\n\t\t\tbuildMs: Date.now() - startMs,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tfor (const output of buildResult.outputs) {\n\t\tartifacts.push({\n\t\t\toutputPath: output.path,\n\t\t\tsizeBytes: output.size,\n\t\t\tkind: output.path.endsWith(\".css\") ? \"stylesheet\" : \"script\",\n\t\t});\n\t}\n\n\treturn {\n\t\tsuccess: true,\n\t\tartifacts,\n\t\tmanifest,\n\t\tbuildMs: Date.now() - startMs,\n\t\terrors: [],\n\t};\n}\n",
6
6
  "import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { scanRoutes } from \"./scanner\";\nimport type { RouteManifest } from \"./types\";\n\nexport function generateManifest(appDir: string): RouteManifest {\n\tconst routes = scanRoutes({ appDir });\n\n\tconst manifest: RouteManifest = {\n\t\tversion: \"1\",\n\t\tgeneratedAt: new Date().toISOString(),\n\t\troutes,\n\t};\n\n\treturn manifest;\n}\n\nexport function writeManifest(\n\tmanifest: RouteManifest,\n\toutputPath: string,\n): void {\n\twriteFileSync(outputPath, JSON.stringify(manifest, null, 2), \"utf-8\");\n}\n\nexport function readManifest(manifestPath: string): RouteManifest | null {\n\tif (!existsSync(manifestPath)) return null;\n\n\tconst raw = readFileSync(manifestPath, \"utf-8\");\n\n\tconst parsed: unknown = JSON.parse(raw);\n\tif (\n\t\ttypeof parsed !== \"object\" ||\n\t\tparsed === null ||\n\t\t!(\"version\" in parsed) ||\n\t\t!(\"routes\" in parsed)\n\t) {\n\t\treturn null;\n\t}\n\n\treturn parsed as RouteManifest;\n}\n\nexport function printManifest(manifest: RouteManifest): void {\n\tconst pageRoutes = manifest.routes.filter((route) => route.kind === \"page\");\n\tconst apiRoutes = manifest.routes.filter((route) => route.kind === \"api\");\n\tconst layoutRoutes = manifest.routes.filter(\n\t\t(route) => route.kind === \"layout\",\n\t);\n\tconst specialRoutes = manifest.routes.filter((route) =>\n\t\t[\"loading\", \"not-found\", \"error\"].includes(route.kind),\n\t);\n\n\tconst line = \"─\".repeat(56);\n\n\tconsole.log(`\\n Rakta.js Route Manifest`);\n\tconsole.log(` ${line}`);\n\tconsole.log(` Generated: ${manifest.generatedAt}`);\n\tconsole.log(` Total: ${manifest.routes.length} routes\\n`);\n\n\tif (pageRoutes.length > 0) {\n\t\tconsole.log(\" Pages:\");\n\t\tfor (const route of pageRoutes) {\n\t\t\tconst dynamic = route.isDynamic\n\t\t\t\t? ` [params: ${route.paramNames.join(\", \")}]`\n\t\t\t\t: \"\";\n\t\t\tconsole.log(` GET ${route.urlPattern}${dynamic}`);\n\t\t}\n\t\tconsole.log(\"\");\n\t}\n\n\tif (apiRoutes.length > 0) {\n\t\tconsole.log(\" API Routes:\");\n\t\tfor (const route of apiRoutes) {\n\t\t\tconst dynamic = route.isDynamic\n\t\t\t\t? ` [params: ${route.paramNames.join(\", \")}]`\n\t\t\t\t: \"\";\n\t\t\tconsole.log(` ANY ${route.urlPattern}${dynamic}`);\n\t\t}\n\t\tconsole.log(\"\");\n\t}\n\n\tif (layoutRoutes.length > 0) {\n\t\tconsole.log(\" Layouts:\");\n\t\tfor (const route of layoutRoutes) {\n\t\t\tconsole.log(\n\t\t\t\t` ${route.urlPattern === \"/\" ? \"root\" : route.urlPattern}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(\"\");\n\t}\n\n\tif (specialRoutes.length > 0) {\n\t\tconsole.log(\" Special:\");\n\t\tfor (const route of specialRoutes) {\n\t\t\tconsole.log(` [${route.kind}] ${route.filePath}`);\n\t\t}\n\t\tconsole.log(\"\");\n\t}\n\n\tconsole.log(` ${line}\\n`);\n}\n",
7
7
  "import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport type { RouteKind, RouteManifestEntry, RouteSegment } from \"./types.js\";\n\nconst FILE_TO_KIND: Record<string, RouteKind> = {\n\t\"page.tsx\": \"page\",\n\t\"page.ts\": \"page\",\n\t\"page.jsx\": \"page\",\n\t\"page.js\": \"page\",\n\t\"layout.tsx\": \"layout\",\n\t\"layout.ts\": \"layout\",\n\t\"layout.jsx\": \"layout\",\n\t\"layout.js\": \"layout\",\n\t\"loading.tsx\": \"loading\",\n\t\"loading.ts\": \"loading\",\n\t\"loading.jsx\": \"loading\",\n\t\"loading.js\": \"loading\",\n\t\"notFound.tsx\": \"notFound\",\n\t\"notFound.ts\": \"notFound\",\n\t\"notFound.jsx\": \"notFound\",\n\t\"notFound.js\": \"notFound\",\n\t\"error.tsx\": \"error\",\n\t\"error.ts\": \"error\",\n\t\"error.jsx\": \"error\",\n\t\"error.js\": \"error\",\n\t\"route.ts\": \"api\",\n\t\"route.js\": \"api\",\n};\n\nfunction parseSegment(raw: string): RouteSegment {\n\tconst isDynamic = raw.startsWith(\"[\") && raw.endsWith(\"]\");\n\tconst paramName = isDynamic ? raw.slice(1, -1) : \"\";\n\n\treturn { raw, isDynamic, paramName };\n}\n\nfunction collectParamNames(segments: RouteSegment[]): string[] {\n\treturn segments\n\t\t.filter((segment) => segment.isDynamic && segment.paramName.length > 0)\n\t\t.map((segment) => segment.paramName);\n}\n\nfunction segmentsToUrlPattern(segments: RouteSegment[]): string {\n\tif (segments.length === 0) return \"/\";\n\tconst parts = segments.map((segment) =>\n\t\tsegment.isDynamic && segment.paramName\n\t\t\t? `:${segment.paramName}`\n\t\t\t: segment.raw,\n\t);\n\treturn `/${parts.join(\"/\")}`;\n}\n\nfunction scanDirectory(\n\tdirPath: string,\n\tappRoot: string,\n\tresults: RouteManifestEntry[],\n): void {\n\tif (!existsSync(dirPath)) return;\n\n\tconst entries = readdirSync(dirPath);\n\n\tfor (const entryName of entries) {\n\t\tconst fullPath = join(dirPath, entryName);\n\t\tconst stats = statSync(fullPath);\n\n\t\tif (stats.isDirectory()) {\n\t\t\tscanDirectory(fullPath, appRoot, results);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!stats.isFile()) continue;\n\n\t\tconst kind = FILE_TO_KIND[entryName];\n\t\tif (!kind) continue;\n\n\t\t// Get path relative to app root, using forward slashes\n\t\tconst relativePath = relative(appRoot, fullPath).replace(/\\\\/g, \"/\");\n\n\t\t// Extract directory segments (all parts except the filename)\n\t\tconst dirRelative = relative(appRoot, dirPath).replace(/\\\\/g, \"/\");\n\t\tconst rawSegments = dirRelative === \"\" ? [] : dirRelative.split(\"/\");\n\n\t\tconst segments: RouteSegment[] = rawSegments.map(parseSegment);\n\t\tconst urlPattern = segmentsToUrlPattern(segments);\n\t\tconst paramNames = collectParamNames(segments);\n\t\tconst isDynamic = paramNames.length > 0;\n\n\t\tresults.push({\n\t\t\tfilePath: relativePath,\n\t\t\turlPattern,\n\t\t\tkind,\n\t\t\tsegments,\n\t\t\tisDynamic,\n\t\t\tparamNames,\n\t\t});\n\t}\n}\n\nexport interface ScanOptions {\n\tappDir: string;\n}\n\nexport function scanRoutes(options: ScanOptions): RouteManifestEntry[] {\n\tconst results: RouteManifestEntry[] = [];\n\tscanDirectory(options.appDir, options.appDir, results);\n\n\t// Sort: static routes before dynamic, shorter patterns first\n\tresults.sort((routeA, routeB) => {\n\t\tif (routeA.isDynamic !== routeB.isDynamic) {\n\t\t\treturn routeA.isDynamic ? 1 : -1;\n\t\t}\n\t\treturn routeA.urlPattern.localeCompare(routeB.urlPattern);\n\t});\n\n\treturn results;\n}\n",
8
- "import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveRouteMode } from \"../render/modes\";\nimport { render } from \"../render/renderer\";\nimport { generateManifest } from \"../router/manifest\";\nimport { matchRoute } from \"../router/matcher\";\nimport type { ForgeDevServerHandle, ForgeDevServerOptions } from \"./types\";\n\nconst DEFAULT_DEV_PORT = 3000;\n\nconst MIME_MAP: Readonly<Record<string, string>> = {\n\t\".html\": \"text/html; charset=utf-8\",\n\t\".js\": \"application/javascript; charset=utf-8\",\n\t\".mjs\": \"application/javascript; charset=utf-8\",\n\t\".css\": \"text/css; charset=utf-8\",\n\t\".json\": \"application/json; charset=utf-8\",\n\t\".png\": \"image/png\",\n\t\".jpg\": \"image/jpeg\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".webp\": \"image/webp\",\n\t\".svg\": \"image/svg+xml\",\n\t\".ico\": \"image/x-icon\",\n\t\".woff\": \"font/woff\",\n\t\".woff2\": \"font/woff2\",\n\t\".ttf\": \"font/ttf\",\n};\n\nfunction resolveMime(filePath: string): string {\n\tconst ext = filePath.slice(filePath.lastIndexOf(\".\")).toLowerCase();\n\treturn MIME_MAP[ext] ?? \"application/octet-stream\";\n}\n\nfunction resolveDevPort(port: number): number {\n\treturn port > 0 ? port : DEFAULT_DEV_PORT;\n}\n\nfunction isReadableFile(filePath: string): boolean {\n\treturn existsSync(filePath) && statSync(filePath).isFile();\n}\n\ninterface ApiRouteExports {\n\tGET?: (request: Request) => Promise<Response>;\n\tPOST?: (request: Request) => Promise<Response>;\n\tPUT?: (request: Request) => Promise<Response>;\n\tPATCH?: (request: Request) => Promise<Response>;\n\tDELETE?: (request: Request) => Promise<Response>;\n\tHEAD?: (request: Request) => Promise<Response>;\n\tOPTIONS?: (request: Request) => Promise<Response>;\n}\n\n/**\n * Starts the Rakta.js Forge development server.\n * Powered by Bun.serve. HMR is a roadmap feature (v0.2.0).\n */\nexport function startDevServer(\n\toptions: ForgeDevServerOptions,\n): ForgeDevServerHandle {\n\tconst manifest = generateManifest(options.appDir);\n\tconst resolvedPort = resolveDevPort(options.port);\n\n\tconst server = Bun.serve({\n\t\tport: resolvedPort,\n\t\thostname: options.host,\n\n\t\tasync fetch(request: Request): Promise<Response> {\n\t\t\tconst url = new URL(request.url);\n\t\t\tconst { pathname } = url;\n\n\t\t\t// Serve static files from public dir\n\t\t\tconst publicPath = join(options.publicDir, pathname);\n\t\t\tif (isReadableFile(publicPath)) {\n\t\t\t\treturn new Response(readFileSync(publicPath), {\n\t\t\t\t\theaders: { \"Content-Type\": resolveMime(pathname) },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Match API routes\n\t\t\tconst apiMatch = matchRoute(\n\t\t\t\tpathname,\n\t\t\t\tmanifest.routes.filter((route) => route.kind === \"api\"),\n\t\t\t);\n\n\t\t\tif (apiMatch) {\n\t\t\t\tconst modulePath = join(options.appDir, apiMatch.entry.filePath);\n\t\t\t\tconst routeModule = (await import(modulePath)) as ApiRouteExports;\n\t\t\t\tconst method = request.method.toUpperCase() as keyof ApiRouteExports;\n\t\t\t\tconst handler = routeModule[method];\n\n\t\t\t\tif (typeof handler !== \"function\") {\n\t\t\t\t\treturn new Response(\"Method not allowed\", { status: 405 });\n\t\t\t\t}\n\n\t\t\t\treturn await handler(request);\n\t\t\t}\n\n\t\t\t// Resolve render mode and serve HTML shell for page routes\n\t\t\tconst resolved = resolveRouteMode(pathname, options.renderConfig);\n\n\t\t\tconst searchParams: Record<string, string> = {};\n\t\t\turl.searchParams.forEach((value, key) => {\n\t\t\t\tsearchParams[key] = value;\n\t\t\t});\n\n\t\t\tconst requestHeaders: Record<string, string> = {};\n\t\t\trequest.headers.forEach((value, key) => {\n\t\t\t\trequestHeaders[key] = value;\n\t\t\t});\n\n\t\t\tconst result = await render(\n\t\t\t\t{\n\t\t\t\t\troutePath: pathname,\n\t\t\t\t\tmode: resolved.mode,\n\t\t\t\t\tparams: {},\n\t\t\t\t\tsearchParams,\n\t\t\t\t\trequestHeaders,\n\t\t\t\t\ttimestampMs: Date.now(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tappName: options.appName,\n\t\t\t\t\tscriptPath: \"/app.js\",\n\t\t\t\t\tcssPath: \"/globals.css\",\n\t\t\t\t\tlang: \"en\",\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (result.kind === \"failure\") {\n\t\t\t\treturn new Response(result.reason, { status: result.httpStatus });\n\t\t\t}\n\n\t\t\treturn new Response(result.html, {\n\t\t\t\tstatus: result.httpStatus,\n\t\t\t\theaders: result.responseHeaders,\n\t\t\t});\n\t\t},\n\t});\n\n\tconst serverPort =\n\t\ttypeof server.port === \"number\" ? server.port : resolvedPort;\n\n\treturn {\n\t\tport: serverPort,\n\t\thost: options.host,\n\t\turl: `http://${options.host}:${serverPort}`,\n\t\tstop: () => server.stop(),\n\t};\n}\n",
8
+ "import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport type { RouteManifest, RouteManifestEntry } from \"../router/types\";\n\nexport interface ClientEntryOptions {\n\treadonly projectRoot: string;\n\treadonly appDir: string;\n\treadonly workDir: string;\n\treadonly manifest: RouteManifest;\n}\n\nfunction toModuleSpecifier(fromFile: string, targetFile: string): string {\n\tconst relativePath = relative(dirname(fromFile), targetFile).replace(\n\t\t/\\\\/g,\n\t\t\"/\",\n\t);\n\n\tif (relativePath.startsWith(\".\")) {\n\t\treturn relativePath;\n\t}\n\n\treturn `./${relativePath}`;\n}\n\nfunction toCssImportSpecifier(\n\tentryPath: string,\n\tprojectRoot: string,\n): string | null {\n\tconst candidates = [\n\t\tjoin(projectRoot, \"styles\", \"globals.css\"),\n\t\tjoin(projectRoot, \"styles\", \"globals.scss\"),\n\t\tjoin(projectRoot, \"styles\", \"globals.sass\"),\n\t];\n\n\tconst stylePath = candidates.find((candidate) => existsSync(candidate));\n\n\tif (!stylePath) {\n\t\treturn null;\n\t}\n\n\treturn toModuleSpecifier(entryPath, stylePath);\n}\n\nfunction getPageRoutes(manifest: RouteManifest): RouteManifestEntry[] {\n\treturn manifest.routes.filter((route) => route.kind === \"page\");\n}\n\nfunction buildRouteImports(\n\tentryPath: string,\n\tappDir: string,\n\tpageRoutes: ReadonlyArray<RouteManifestEntry>,\n): string {\n\tconst routeEntries = pageRoutes\n\t\t.map((route) => {\n\t\t\tconst pagePath = join(appDir, route.filePath);\n\t\t\treturn ` ${JSON.stringify(route.urlPattern)}: () => import(\"${toModuleSpecifier(entryPath, pagePath)}\"),`;\n\t\t})\n\t\t.join(\"\\n\");\n\n\treturn `const routeModules = {\\n${routeEntries}\\n} as const;`;\n}\n\nfunction buildRouteTable(\n\tpageRoutes: ReadonlyArray<RouteManifestEntry>,\n): string {\n\tconst routeEntries = pageRoutes\n\t\t.map(\n\t\t\t(route) =>\n\t\t\t\t` ${JSON.stringify(route.urlPattern)}: routeModules[${JSON.stringify(route.urlPattern)}],`,\n\t\t)\n\t\t.join(\"\\n\");\n\n\treturn `const routes = {\\n${routeEntries}\\n} as const;`;\n}\n\nfunction findExistingModule(\n\tbasePathWithoutExtension: string,\n): string | undefined {\n\tconst candidates = [\".tsx\", \".ts\", \".jsx\", \".js\"].map(\n\t\t(extension) => `${basePathWithoutExtension}${extension}`,\n\t);\n\n\treturn candidates.find((candidate) => existsSync(candidate));\n}\n\nfunction buildStarterGlobalLoaders(entryPath: string, appDir: string): string {\n\tconst mascotPath = findExistingModule(\n\t\tjoin(appDir, \"components\", \"raktaShrimpMascot\"),\n\t);\n\tconst gamePath = findExistingModule(\n\t\tjoin(appDir, \"components\", \"shrimpRunGame\"),\n\t);\n\tconst loaders: string[] = [];\n\n\tif (mascotPath !== undefined) {\n\t\tloaders.push(` const mascotModule = await import(\"${toModuleSpecifier(entryPath, mascotPath)}\");\n (globalThis as typeof globalThis & Record<string, unknown>).RaktaShrimpMascot = mascotModule.default;`);\n\t}\n\n\tif (gamePath !== undefined) {\n\t\tloaders.push(` const gameModule = await import(\"${toModuleSpecifier(entryPath, gamePath)}\");\n (globalThis as typeof globalThis & Record<string, unknown>).ShrimpRunGame = gameModule.default;`);\n\t}\n\n\tif (loaders.length === 0) {\n\t\treturn `async function loadRaktaGlobals(): Promise<void> {\n return;\n}`;\n\t}\n\n\treturn `async function loadRaktaGlobals(): Promise<void> {\n${loaders.join(\"\\n\\n\")}\n}`;\n}\n\nfunction buildClientEntrySource(\n\toptions: ClientEntryOptions,\n\tentryPath: string,\n): string {\n\tconst pageRoutes = getPageRoutes(options.manifest);\n\tconst routeModules = buildRouteImports(entryPath, options.appDir, pageRoutes);\n\tconst routeTable = buildRouteTable(pageRoutes);\n\tconst cssImportSpecifier = toCssImportSpecifier(\n\t\tentryPath,\n\t\toptions.projectRoot,\n\t);\n\tconst cssImport =\n\t\tcssImportSpecifier !== null ? `import \"${cssImportSpecifier}\";\\n` : \"\";\n\tconst starterGlobalLoaders = buildStarterGlobalLoaders(\n\t\tentryPath,\n\t\toptions.appDir,\n\t);\n\n\treturn `import React, { useEffect, useState } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport * as ReactHooks from \"react\";\n${cssImport}\n(globalThis as typeof globalThis & Record<string, unknown>).useCallback = ReactHooks.useCallback;\n(globalThis as typeof globalThis & Record<string, unknown>).useEffect = ReactHooks.useEffect;\n(globalThis as typeof globalThis & Record<string, unknown>).useRef = ReactHooks.useRef;\n(globalThis as typeof globalThis & Record<string, unknown>).useState = ReactHooks.useState;\n\n${starterGlobalLoaders}\n\nawait loadRaktaGlobals();\n\n${routeModules}\n\n${routeTable}\n\ntype RoutePath = keyof typeof routes;\ntype PageModule = { default: React.ComponentType };\n\nfunction normalizePathname(pathname: string): string {\n if (pathname.length > 1 && pathname.endsWith(\"/\")) {\n return pathname.slice(0, -1);\n }\n\n return pathname;\n}\n\nfunction resolveRouteLoader(pathname: string): () => Promise<PageModule> {\n const normalizedPathname = normalizePathname(pathname) as RoutePath;\n\n return routes[normalizedPathname] ?? routes[\"/\"];\n}\n\nfunction navigate(to: string): void {\n window.history.pushState({ source: \"rakta-click\", to }, \"\", to);\n window.dispatchEvent(new PopStateEvent(\"popstate\", { state: { to } }));\n}\n\nfunction App(): React.ReactElement {\n const [pathname, setPathname] = useState(() => window.location.pathname);\n const [Page, setPage] = useState<React.ComponentType | null>(null);\n\n useEffect(() => {\n function handlePopState(): void {\n setPathname(window.location.pathname);\n }\n\n function handleClick(event: MouseEvent): void {\n const target = event.target;\n\n if (!(target instanceof Element)) {\n return;\n }\n\n const clickElement = target.closest(\"click\");\n\n if (!clickElement) {\n return;\n }\n\n const to = clickElement.getAttribute(\"to\");\n\n if (!to || to.startsWith(\"http://\") || to.startsWith(\"https://\")) {\n return;\n }\n\n event.preventDefault();\n navigate(to);\n setPathname(window.location.pathname);\n }\n\n window.addEventListener(\"popstate\", handlePopState);\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n document.removeEventListener(\"click\", handleClick);\n };\n }, []);\n\n useEffect(() => {\n let isCurrent = true;\n\n resolveRouteLoader(pathname)().then((pageModule) => {\n if (isCurrent) {\n setPage(() => pageModule.default);\n }\n });\n\n return () => {\n isCurrent = false;\n };\n }, [pathname]);\n\n if (!Page) {\n return React.createElement(\"main\", {\n style: {\n minHeight: \"100vh\",\n display: \"grid\",\n placeItems: \"center\",\n background: \"#050505\",\n color: \"#f8fafc\",\n fontFamily: \"ui-sans-serif, system-ui, sans-serif\",\n },\n }, \"Loading Rakta.js...\");\n }\n\n return React.createElement(Page);\n}\n\nconst rootElement = document.getElementById(\"rakta-root\");\n\nif (!rootElement) {\n throw new Error(\"Rakta.js root element #rakta-root was not found.\");\n}\n\ncreateRoot(rootElement).render(React.createElement(App));\n`;\n}\n\nexport function writeClientEntry(options: ClientEntryOptions): string {\n\tmkdirSync(options.workDir, { recursive: true });\n\n\tconst entryPath = join(options.workDir, \"client-entry.tsx\");\n\tconst entrySource = buildClientEntrySource(options, entryPath);\n\n\twriteFileSync(entryPath, entrySource, \"utf-8\");\n\n\treturn entryPath;\n}\n",
9
+ "import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveRouteMode } from \"../render/modes\";\nimport { render } from \"../render/renderer\";\nimport { generateManifest } from \"../router/manifest\";\nimport { matchRoute } from \"../router/matcher\";\nimport { writeClientEntry } from \"./clientEntry\";\nimport type { ForgeDevServerHandle, ForgeDevServerOptions } from \"./types\";\n\nconst DEFAULT_DEV_PORT = 3000;\n\nconst MIME_MAP: Readonly<Record<string, string>> = {\n\t\".html\": \"text/html; charset=utf-8\",\n\t\".js\": \"application/javascript; charset=utf-8\",\n\t\".mjs\": \"application/javascript; charset=utf-8\",\n\t\".css\": \"text/css; charset=utf-8\",\n\t\".json\": \"application/json; charset=utf-8\",\n\t\".png\": \"image/png\",\n\t\".jpg\": \"image/jpeg\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".webp\": \"image/webp\",\n\t\".svg\": \"image/svg+xml\",\n\t\".ico\": \"image/x-icon\",\n\t\".woff\": \"font/woff\",\n\t\".woff2\": \"font/woff2\",\n\t\".ttf\": \"font/ttf\",\n};\n\nfunction resolveMime(filePath: string): string {\n\tconst ext = filePath.slice(filePath.lastIndexOf(\".\")).toLowerCase();\n\treturn MIME_MAP[ext] ?? \"application/octet-stream\";\n}\n\nfunction resolveDevPort(port: number): number {\n\treturn port > 0 ? port : DEFAULT_DEV_PORT;\n}\n\nfunction isReadableFile(filePath: string): boolean {\n\treturn existsSync(filePath) && statSync(filePath).isFile();\n}\n\nasync function buildDevClientBundle(\n\toptions: ForgeDevServerOptions,\n\tmanifest: ReturnType<typeof generateManifest>,\n): Promise<string> {\n\tconst workDir = join(options.projectRoot, \".rakta\");\n\tconst clientOutDir = join(workDir, \"dev\");\n\tconst clientEntry = writeClientEntry({\n\t\tprojectRoot: options.projectRoot,\n\t\tappDir: options.appDir,\n\t\tworkDir,\n\t\tmanifest,\n\t});\n\n\tconst buildResult = await Bun.build({\n\t\tentrypoints: [clientEntry],\n\t\toutdir: clientOutDir,\n\t\ttarget: \"browser\",\n\t\tsourcemap: \"external\",\n\t\tnaming: {\n\t\t\tentry: \"app.[ext]\",\n\t\t\tchunk: \"chunks/[name]-[hash].[ext]\",\n\t\t\tasset: \"assets/[name]-[hash].[ext]\",\n\t\t},\n\t});\n\n\tif (!buildResult.success) {\n\t\tconst buildErrors = buildResult.logs\n\t\t\t.map((buildLog) => buildLog.message)\n\t\t\t.join(\"\\n\");\n\n\t\tthrow new Error(`Failed to build Rakta.js client bundle.\\n${buildErrors}`);\n\t}\n\n\treturn clientOutDir;\n}\n\ninterface ApiRouteExports {\n\tGET?: (request: Request) => Promise<Response>;\n\tPOST?: (request: Request) => Promise<Response>;\n\tPUT?: (request: Request) => Promise<Response>;\n\tPATCH?: (request: Request) => Promise<Response>;\n\tDELETE?: (request: Request) => Promise<Response>;\n\tHEAD?: (request: Request) => Promise<Response>;\n\tOPTIONS?: (request: Request) => Promise<Response>;\n}\n\n/**\n * Starts the Rakta.js Forge development server.\n * Powered by Bun.serve. HMR is a roadmap feature (v0.2.0).\n */\nexport async function startDevServer(\n\toptions: ForgeDevServerOptions,\n): Promise<ForgeDevServerHandle> {\n\tconst manifest = generateManifest(options.appDir);\n\tconst resolvedPort = resolveDevPort(options.port);\n\tconst clientOutDir = await buildDevClientBundle(options, manifest);\n\n\tconst server = Bun.serve({\n\t\tport: resolvedPort,\n\t\thostname: options.host,\n\n\t\tasync fetch(request: Request): Promise<Response> {\n\t\t\tconst url = new URL(request.url);\n\t\t\tconst { pathname } = url;\n\n\t\t\tif (clientOutDir.length > 0) {\n\t\t\t\tconst clientBundlePath = join(clientOutDir, pathname);\n\n\t\t\t\tif (isReadableFile(clientBundlePath)) {\n\t\t\t\t\treturn new Response(readFileSync(clientBundlePath), {\n\t\t\t\t\t\theaders: { \"Content-Type\": resolveMime(clientBundlePath) },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Serve static files from public dir\n\t\t\tconst publicPath = join(options.publicDir, pathname);\n\t\t\tif (isReadableFile(publicPath)) {\n\t\t\t\treturn new Response(readFileSync(publicPath), {\n\t\t\t\t\theaders: { \"Content-Type\": resolveMime(pathname) },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Match API routes\n\t\t\tconst apiMatch = matchRoute(\n\t\t\t\tpathname,\n\t\t\t\tmanifest.routes.filter((route) => route.kind === \"api\"),\n\t\t\t);\n\n\t\t\tif (apiMatch) {\n\t\t\t\tconst modulePath = join(options.appDir, apiMatch.entry.filePath);\n\t\t\t\tconst routeModule = (await import(modulePath)) as ApiRouteExports;\n\t\t\t\tconst method = request.method.toUpperCase() as keyof ApiRouteExports;\n\t\t\t\tconst handler = routeModule[method];\n\n\t\t\t\tif (typeof handler !== \"function\") {\n\t\t\t\t\treturn new Response(\"Method not allowed\", { status: 405 });\n\t\t\t\t}\n\n\t\t\t\treturn await handler(request);\n\t\t\t}\n\n\t\t\t// Resolve render mode and serve HTML shell for page routes\n\t\t\tconst resolved = resolveRouteMode(pathname, options.renderConfig);\n\n\t\t\tconst searchParams: Record<string, string> = {};\n\t\t\turl.searchParams.forEach((value, key) => {\n\t\t\t\tsearchParams[key] = value;\n\t\t\t});\n\n\t\t\tconst requestHeaders: Record<string, string> = {};\n\t\t\trequest.headers.forEach((value, key) => {\n\t\t\t\trequestHeaders[key] = value;\n\t\t\t});\n\n\t\t\tconst result = await render(\n\t\t\t\t{\n\t\t\t\t\troutePath: pathname,\n\t\t\t\t\tmode: resolved.mode,\n\t\t\t\t\tparams: {},\n\t\t\t\t\tsearchParams,\n\t\t\t\t\trequestHeaders,\n\t\t\t\t\ttimestampMs: Date.now(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tappName: options.appName,\n\t\t\t\t\ttitle: options.seo.defaultTitle,\n\t\t\t\t\tdescription: options.seo.defaultDescription,\n\t\t\t\t\tscriptPath: \"/app.js\",\n\t\t\t\t\tcssPath: \"/app.css\",\n\t\t\t\t\tlang: \"en\",\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (result.kind === \"failure\") {\n\t\t\t\treturn new Response(result.reason, { status: result.httpStatus });\n\t\t\t}\n\n\t\t\treturn new Response(result.html, {\n\t\t\t\tstatus: result.httpStatus,\n\t\t\t\theaders: result.responseHeaders,\n\t\t\t});\n\t\t},\n\t});\n\n\tconst serverPort =\n\t\ttypeof server.port === \"number\" ? server.port : resolvedPort;\n\n\treturn {\n\t\tport: serverPort,\n\t\thost: options.host,\n\t\turl: `http://${options.host}:${serverPort}`,\n\t\tstop: () => server.stop(),\n\t};\n}\n",
9
10
  "import type {\n\tRenderConfig,\n\tRenderMode,\n\tRenderModeDescriptor,\n\tResolvedRouteMode,\n} from \"./types\";\n\nexport const RENDER_MODE_DESCRIPTORS: Readonly<\n\tRecord<RenderMode, RenderModeDescriptor>\n> = {\n\tcsr: {\n\t\tmode: \"csr\",\n\t\tlabel: \"Client-Side Rendering\",\n\t\tshortLabel: \"CSR\",\n\t\tdescription:\n\t\t\t\"React renders entirely in the browser. The server sends a minimal HTML shell with a JS bundle. No server required at runtime.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: false,\n\t},\n\tssr: {\n\t\tmode: \"ssr\",\n\t\tlabel: \"Server-Side Rendering\",\n\t\tshortLabel: \"SSR\",\n\t\tdescription:\n\t\t\t\"React renders to HTML on the server per request. The client receives full HTML and then hydrates. Requires a running Node/Bun server.\",\n\t\tserverRequired: true,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: true, // Roadmap: v0.2.0\n\t},\n\tssg: {\n\t\tmode: \"ssg\",\n\t\tlabel: \"Static Site Generation\",\n\t\tshortLabel: \"SSG\",\n\t\tdescription:\n\t\t\t\"Pages are fully rendered at build time. Output is static HTML files. No server required at runtime.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: true,\n\t\tclientHydration: false,\n\t\troadmap: true, // Roadmap: v0.2.0\n\t},\n\tcsg: {\n\t\tmode: \"csg\",\n\t\tlabel: \"Client-Side Generation\",\n\t\tshortLabel: \"CSG\",\n\t\tdescription:\n\t\t\t\"A static shell is generated at build time, data is fetched and rendered on the client. Combines SSG speed with dynamic data.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: true,\n\t\tclientHydration: true,\n\t\troadmap: true, // Roadmap: v0.2.0\n\t},\n\tspa: {\n\t\tmode: \"spa\",\n\t\tlabel: \"Single Page Application\",\n\t\tshortLabel: \"SPA\",\n\t\tdescription:\n\t\t\t\"A single HTML entry point is served for all routes. React handles all routing client-side. Equivalent to a standard Vite SPA.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: false,\n\t},\n\thybrid: {\n\t\tmode: \"hybrid\",\n\t\tlabel: \"Hybrid Rendering\",\n\t\tshortLabel: \"Hybrid\",\n\t\tdescription:\n\t\t\t\"Different routes use different render modes. Configured via the `render.routes` map in rakta.config.ts. The top-level mode is the fallback.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: false,\n\t},\n};\n\n/**\n * Returns true if the pathname matches a given route pattern.\n * Supports exact paths and simple :param segments (e.g. /blog/:slug).\n */\nfunction pathMatchesPattern(pathname: string, pattern: string): boolean {\n\tif (pattern === pathname) return true;\n\n\tconst patternParts = pattern.split(\"/\");\n\tconst pathParts = pathname.split(\"/\");\n\n\tif (patternParts.length !== pathParts.length) return false;\n\n\tfor (let i = 0; i < patternParts.length; i++) {\n\t\tconst pp = patternParts[i];\n\t\tconst path = pathParts[i];\n\t\tif (pp === undefined || path === undefined) return false;\n\t\tif (pp.startsWith(\":\")) continue; // dynamic segment — always matches\n\t\tif (pp !== path) return false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Resolves the render mode for the given pathname using the provided config.\n * Route-specific overrides take priority. The most specific (longest) matching\n * pattern wins. Falls back to `config.defaultMode`.\n */\nexport function resolveRouteMode(\n\tpathname: string,\n\tconfig: RenderConfig,\n): ResolvedRouteMode {\n\tconst patterns = Object.keys(config.routes).sort(\n\t\t(a, b) => b.length - a.length, // longest pattern first (most specific)\n\t);\n\n\tfor (const pattern of patterns) {\n\t\tconst overrideMode = config.routes[pattern];\n\t\tif (overrideMode !== undefined && pathMatchesPattern(pathname, pattern)) {\n\t\t\treturn {\n\t\t\t\troutePath: pathname,\n\t\t\t\tmode: overrideMode,\n\t\t\t\tsource: \"route-override\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\troutePath: pathname,\n\t\tmode: config.defaultMode,\n\t\tsource: \"default\",\n\t};\n}\n\nexport function getModeDescriptor(mode: RenderMode): RenderModeDescriptor {\n\treturn RENDER_MODE_DESCRIPTORS[mode];\n}\n\nexport function isRoadmapMode(mode: RenderMode): boolean {\n\treturn RENDER_MODE_DESCRIPTORS[mode].roadmap;\n}\n\nexport function requiresServer(mode: RenderMode): boolean {\n\treturn RENDER_MODE_DESCRIPTORS[mode].serverRequired;\n}\n\nexport function isBuildTimeMode(mode: RenderMode): boolean {\n\treturn RENDER_MODE_DESCRIPTORS[mode].buildTimeGenerated;\n}\n",
10
- "import { isRoadmapMode } from \"./modes\";\nimport type {\n\tRenderContext,\n\tRenderFailure,\n\tRenderMode,\n\tRenderResult,\n\tRenderSuccess,\n} from \"./types\";\n\nexport interface RendererOptions {\n\treadonly appName: string;\n\treadonly scriptPath: string;\n\treadonly cssPath: string;\n\treadonly lang: string;\n}\n\nfunction buildHtmlShell(options: RendererOptions): string {\n\treturn `\n <!DOCTYPE html>\n <html lang=\"${options.lang}\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>\n ${options.appName}\n </title>\n <link rel=\"stylesheet\" href=\"${options.cssPath}\" />\n </head>\n <body>\n <div id=\"rakta-root\"></div>\n <script type=\"module\" src=\"${options.scriptPath}\"></script>\n </body>\n </html>`;\n}\n\nfunction makeSuccess(\n\thtml: string,\n\tmode: RenderMode,\n\trenderMs: number,\n\thttpStatus: number = 200,\n\tfromCache: boolean = false,\n): RenderSuccess {\n\treturn {\n\t\tkind: \"success\",\n\t\thtml,\n\t\tmode,\n\t\thttpStatus,\n\t\tresponseHeaders: { \"Content-Type\": \"text/html; charset=utf-8\" },\n\t\tfromCache,\n\t\trenderMs,\n\t};\n}\n\nfunction makeFailure(\n\treason: string,\n\tmode: RenderMode,\n\thttpStatus: number = 500,\n): RenderFailure {\n\treturn { kind: \"failure\", reason, mode, httpStatus };\n}\n\n/**\n * Render a page using the resolved mode from the context.\n * Roadmap modes (ssr, ssg, csg) fall back to a CSR shell in v0.1.0.\n */\nexport async function render(\n\tcontext: RenderContext,\n\toptions: RendererOptions,\n): Promise<RenderResult> {\n\tconst startMs = Date.now();\n\n\t// Roadmap modes: fall back to CSR shell with a warning\n\tif (isRoadmapMode(context.mode)) {\n\t\tconsole.warn(\n\t\t\t`[Rakta.js] Render mode \"${context.mode}\" is a roadmap feature (v0.2.0). ` +\n\t\t\t\t`Falling back to CSR for: ${context.routePath}`,\n\t\t);\n\t\treturn makeSuccess(buildHtmlShell(options), \"csr\", Date.now() - startMs);\n\t}\n\n\tswitch (context.mode) {\n\t\tcase \"csr\":\n\t\tcase \"spa\":\n\t\t\treturn makeSuccess(\n\t\t\t\tbuildHtmlShell(options),\n\t\t\t\tcontext.mode,\n\t\t\t\tDate.now() - startMs,\n\t\t\t);\n\n\t\tcase \"hybrid\":\n\t\t\t// Hybrid resolution happens upstream in Tide. If it reaches the renderer\n\t\t\t// as hybrid, the route had no specific override - fall back to CSR.\n\t\t\treturn makeSuccess(buildHtmlShell(options), \"csr\", Date.now() - startMs);\n\n\t\tcase \"ssr\":\n\t\tcase \"ssg\":\n\t\tcase \"csg\":\n\t\t\t// These are already caught by isRoadmapMode above, but TypeScript\n\t\t\t// requires an exhaustive switch for the RenderMode union.\n\t\t\treturn makeFailure(\n\t\t\t\t`Render mode \"${context.mode}\" is not yet implemented.`,\n\t\t\t\tcontext.mode,\n\t\t\t\t501,\n\t\t\t);\n\t}\n}\n\nexport function renderNotFound(options: RendererOptions): RenderSuccess {\n\treturn makeSuccess(buildHtmlShell(options), \"csr\", 0, 404);\n}\n\nexport function renderServerError(\n\treason: string,\n\tmode: RenderMode,\n): RenderFailure {\n\treturn makeFailure(reason, mode, 500);\n}\n",
11
+ "import { isRoadmapMode } from \"./modes\";\nimport type {\n\tRenderContext,\n\tRenderFailure,\n\tRenderMode,\n\tRenderResult,\n\tRenderSuccess,\n} from \"./types\";\n\nexport interface RendererOptions {\n\treadonly appName: string;\n\treadonly title?: string | undefined;\n\treadonly description?: string | undefined;\n\treadonly faviconPath?: string | undefined;\n\treadonly scriptPath: string;\n\treadonly cssPath: string;\n\treadonly lang: string;\n}\n\nfunction buildHtmlShell(options: RendererOptions): string {\n\tconst title = options.title ?? options.appName;\n\tconst faviconPath = options.faviconPath ?? \"/favicon.ico\";\n\tconst descriptionMeta =\n\t\toptions.description !== undefined\n\t\t\t? `<meta name=\"description\" content=\"${options.description}\" />`\n\t\t\t: \"\";\n\n\treturn `\n <!DOCTYPE html>\n <html lang=\"${options.lang}\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${title}</title>\n ${descriptionMeta}\n <link rel=\"icon\" href=\"${faviconPath}\" sizes=\"any\" />\n <link rel=\"stylesheet\" href=\"${options.cssPath}\" />\n </head>\n <body>\n <div id=\"rakta-root\"></div>\n <script type=\"module\" src=\"${options.scriptPath}\"></script>\n </body>\n </html>`;\n}\n\nfunction makeSuccess(\n\thtml: string,\n\tmode: RenderMode,\n\trenderMs: number,\n\thttpStatus: number = 200,\n\tfromCache: boolean = false,\n): RenderSuccess {\n\treturn {\n\t\tkind: \"success\",\n\t\thtml,\n\t\tmode,\n\t\thttpStatus,\n\t\tresponseHeaders: { \"Content-Type\": \"text/html; charset=utf-8\" },\n\t\tfromCache,\n\t\trenderMs,\n\t};\n}\n\nfunction makeFailure(\n\treason: string,\n\tmode: RenderMode,\n\thttpStatus: number = 500,\n): RenderFailure {\n\treturn { kind: \"failure\", reason, mode, httpStatus };\n}\n\n/**\n * Render a page using the resolved mode from the context.\n * Roadmap modes (ssr, ssg, csg) fall back to a CSR shell in v0.1.0.\n */\nexport async function render(\n\tcontext: RenderContext,\n\toptions: RendererOptions,\n): Promise<RenderResult> {\n\tconst startMs = Date.now();\n\n\t// Roadmap modes: fall back to CSR shell with a warning\n\tif (isRoadmapMode(context.mode)) {\n\t\tconsole.warn(\n\t\t\t`[Rakta.js] Render mode \"${context.mode}\" is a roadmap feature (v0.2.0). ` +\n\t\t\t\t`Falling back to CSR for: ${context.routePath}`,\n\t\t);\n\t\treturn makeSuccess(buildHtmlShell(options), \"csr\", Date.now() - startMs);\n\t}\n\n\tswitch (context.mode) {\n\t\tcase \"csr\":\n\t\tcase \"spa\":\n\t\t\treturn makeSuccess(\n\t\t\t\tbuildHtmlShell(options),\n\t\t\t\tcontext.mode,\n\t\t\t\tDate.now() - startMs,\n\t\t\t);\n\n\t\tcase \"hybrid\":\n\t\t\t// Hybrid resolution happens upstream in Tide. If it reaches the renderer\n\t\t\t// as hybrid, the route had no specific override - fall back to CSR.\n\t\t\treturn makeSuccess(buildHtmlShell(options), \"csr\", Date.now() - startMs);\n\n\t\tcase \"ssr\":\n\t\tcase \"ssg\":\n\t\tcase \"csg\":\n\t\t\t// These are already caught by isRoadmapMode above, but TypeScript\n\t\t\t// requires an exhaustive switch for the RenderMode union.\n\t\t\treturn makeFailure(\n\t\t\t\t`Render mode \"${context.mode}\" is not yet implemented.`,\n\t\t\t\tcontext.mode,\n\t\t\t\t501,\n\t\t\t);\n\t}\n}\n\nexport function renderNotFound(options: RendererOptions): RenderSuccess {\n\treturn makeSuccess(buildHtmlShell(options), \"csr\", 0, 404);\n}\n\nexport function renderServerError(\n\treason: string,\n\tmode: RenderMode,\n): RenderFailure {\n\treturn makeFailure(reason, mode, 500);\n}\n",
11
12
  "import type {\n\tMatchedRoute,\n\tRouteManifestEntry,\n\tRouteSegment,\n} from \"./types.js\";\n\nfunction escapeRegex(text: string): string {\n\treturn text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildPatternRegex(segments: RouteSegment[]): {\n\tregex: RegExp;\n\tparamNames: string[];\n} {\n\tconst paramNames: string[] = [];\n\n\tconst parts = segments.map((segment) => {\n\t\tif (segment.isDynamic && segment.paramName) {\n\t\t\tparamNames.push(segment.paramName);\n\t\t\t// Match any non-slash sequence for the param\n\t\t\treturn \"([^/]+)\";\n\t\t}\n\t\treturn escapeRegex(segment.raw);\n\t});\n\n\tconst pattern = parts.length === 0 ? \"\" : `/${parts.join(\"/\")}`;\n\tconst regex = new RegExp(`^${pattern || \"/\"}$`);\n\n\treturn { regex, paramNames };\n}\n\nexport function matchRoute(\n\tpathname: string,\n\troutes: RouteManifestEntry[],\n): MatchedRoute | null {\n\t// Normalize pathname: strip trailing slash unless root\n\tconst normalized =\n\t\tpathname !== \"/\" && pathname.endsWith(\"/\")\n\t\t\t? pathname.slice(0, -1)\n\t\t\t: pathname;\n\n\tfor (const entry of routes) {\n\t\t// Only match pages and api routes\n\t\tif (entry.kind !== \"page\" && entry.kind !== \"api\") continue;\n\n\t\tconst { regex, paramNames } = buildPatternRegex(entry.segments);\n\t\tconst match = regex.exec(normalized);\n\n\t\tif (!match) continue;\n\n\t\tconst params: Record<string, string> = {};\n\t\tparamNames.forEach((name, index) => {\n\t\t\tconst captured = match[index + 1];\n\t\t\tif (captured !== undefined) {\n\t\t\t\tparams[name] = decodeURIComponent(captured);\n\t\t\t}\n\t\t});\n\n\t\treturn { entry, params };\n\t}\n\n\treturn null;\n}\n\nexport function findLayoutsForPathname(\n\tpathname: string,\n\troutes: RouteManifestEntry[],\n): RouteManifestEntry[] {\n\tconst layoutRoutes = routes.filter((route) => route.kind === \"layout\");\n\n\treturn layoutRoutes.filter((layout) => {\n\t\tif (layout.urlPattern === \"/\") return true;\n\t\treturn (\n\t\t\tpathname === layout.urlPattern ||\n\t\t\tpathname.startsWith(`${layout.urlPattern}/`)\n\t\t);\n\t});\n}\n\nexport function findSpecialRoute(\n\tkind: \"loading\" | \"not-found\" | \"error\",\n\tpathname: string,\n\troutes: RouteManifestEntry[],\n): RouteManifestEntry | null {\n\tconst candidates = routes.filter((route) => route.kind === kind);\n\n\t// Find the most specific match (longest matching prefix)\n\tlet best: RouteManifestEntry | null = null;\n\tlet bestLength = -1;\n\n\tfor (const candidate of candidates) {\n\t\tconst prefix = candidate.urlPattern === \"/\" ? \"\" : candidate.urlPattern;\n\t\tif (pathname.startsWith(prefix) && prefix.length > bestLength) {\n\t\t\tbest = candidate;\n\t\t\tbestLength = prefix.length;\n\t\t}\n\t}\n\n\treturn best;\n}\n",
12
13
  "import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveRouteMode } from \"../render/modes\";\nimport type { RenderConfig } from \"../render/types\";\nimport { readManifest } from \"../router/manifest\";\nimport type {\n\tArtifactKind,\n\tForgeBuildArtifact,\n\tForgeInspectReport,\n\tForgeRouteModeEntry,\n} from \"./types\";\n\nexport interface InspectOptions {\n\treadonly outDir: string;\n\treadonly renderConfig: RenderConfig;\n}\n\nfunction detectArtifactKind(filename: string): ArtifactKind {\n\tif (filename === \"route-manifest.json\") return \"manifest\";\n\tif (filename.endsWith(\".css\")) return \"stylesheet\";\n\tif (filename.endsWith(\".js\") || filename.endsWith(\".mjs\")) return \"script\";\n\treturn \"asset\";\n}\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1_048_576) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / 1_048_576).toFixed(2)} MB`;\n}\n\nfunction scanDirectory(dirPath: string): ForgeBuildArtifact[] {\n\tif (!existsSync(dirPath)) return [];\n\tconst collected: ForgeBuildArtifact[] = [];\n\n\tfunction walk(current: string): void {\n\t\tconst entries = readdirSync(current, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst full = join(current, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\twalk(full);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\tcollected.push({\n\t\t\t\t\toutputPath: full,\n\t\t\t\t\tsizeBytes: statSync(full).size,\n\t\t\t\t\tkind: detectArtifactKind(entry.name),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(dirPath);\n\treturn collected;\n}\n\nexport function inspectBuild(options: InspectOptions): ForgeInspectReport {\n\tconst artifacts = scanDirectory(options.outDir);\n\tconst manifestPath = join(options.outDir, \"route-manifest.json\");\n\tconst manifest = readManifest(manifestPath);\n\n\tconst emptyManifest = {\n\t\tversion: \"1\" as const,\n\t\tgeneratedAt: new Date().toISOString(),\n\t\troutes: [],\n\t};\n\n\tconst routeModes: ForgeRouteModeEntry[] = (manifest ?? emptyManifest).routes\n\t\t.filter((r) => r.kind === \"page\" || r.kind === \"api\")\n\t\t.map((r) => {\n\t\t\tconst resolved = resolveRouteMode(r.urlPattern, options.renderConfig);\n\t\t\treturn {\n\t\t\t\tpattern: r.urlPattern,\n\t\t\t\tmode: resolved.mode,\n\t\t\t\tsource: resolved.source,\n\t\t\t};\n\t\t});\n\n\treturn {\n\t\tbuildDir: options.outDir,\n\t\tartifacts,\n\t\tmanifest: manifest ?? emptyManifest,\n\t\trouteModes,\n\t\ttotalSizeBytes: artifacts.reduce((sum, a) => sum + a.sizeBytes, 0),\n\t\tinspectedAt: new Date().toISOString(),\n\t};\n}\n\nexport function printInspectReport(report: ForgeInspectReport): void {\n\tconst sep = \"─\".repeat(58);\n\tconsole.log(`\n \\n Rakta.js Forge - Build Inspection\n `);\n\tconsole.log(`\n ${sep}\n `);\n\tconsole.log(`\n Directory: ${report.buildDir}\n `);\n\tconsole.log(`\n Inspected: ${report.inspectedAt}\n `);\n\tconsole.log(`\n Total size: ${formatBytes(report.totalSizeBytes)}\\n\n `);\n\n\tif (report.artifacts.length > 0) {\n\t\tconsole.log(\"Artifacts:\");\n\t\tfor (const artifact of report.artifacts) {\n\t\t\tconst rel = artifact.outputPath\n\t\t\t\t.replace(report.buildDir, \".\")\n\t\t\t\t.replace(/\\\\/g, \"/\");\n\t\t\tconsole.log(`\n [${artifact.kind.padEnd(10)}] \n ${rel.padEnd(38)} \n ${formatBytes(artifact.sizeBytes)}`);\n\t\t}\n\t\tconsole.log(\"\");\n\t}\n\n\tif (report.routeModes.length > 0) {\n\t\tconsole.log(\"Route Render Modes:\");\n\t\tfor (const rm of report.routeModes) {\n\t\t\tconst src = rm.source === \"route-override\" ? \"(override)\" : \"(default) \";\n\t\t\tconsole.log(`\n ${rm.mode.toUpperCase().padEnd(8)} \n ${rm.pattern.padEnd(36)} ${src}`);\n\t\t}\n\t\tconsole.log(\"\");\n\t}\n\n\tconsole.log(`${sep}\\n`);\n}\n"
13
14
  ],
14
- "mappings": "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",
15
- "debugId": "B67DA786A474431864756E2164756E21",
15
+ "mappings": "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",
16
+ "debugId": "1A92A1766DE1CB8664756E2164756E21",
16
17
  "names": []
17
18
  }