reroute-js 0.0.6 → 0.0.8

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.
package/elysia/index.js CHANGED
@@ -31,11 +31,11 @@ var exports_path = {};
31
31
  __export(exports_path, {
32
32
  stripStart: () => stripStart,
33
33
  stripEnd: () => stripEnd,
34
- join: () => join,
34
+ join: () => join2,
35
35
  extname: () => extname,
36
36
  basename: () => basename
37
37
  });
38
- function join(...parts) {
38
+ function join2(...parts) {
39
39
  return parts.join("/").replace(/\/+/g, "/");
40
40
  }
41
41
  function extname(p) {
@@ -53,9 +53,6 @@ function stripEnd(p, ch) {
53
53
  return p.endsWith(ch) ? p.slice(0, -ch.length) : p;
54
54
  }
55
55
 
56
- // packages/elysia/src/plugin.ts
57
- import { watch as fsWatch } from "node:fs";
58
-
59
56
  // packages/core/src/bundler/hash.ts
60
57
  async function generateContentHash(content) {
61
58
  const data = new TextEncoder().encode(content);
@@ -65,7 +62,100 @@ async function generateContentHash(content) {
65
62
  hex += b.toString(16).padStart(2, "0");
66
63
  return hex.slice(0, 8);
67
64
  }
65
+ // packages/cli/src/libs/tailwind.ts
66
+ import { spawn } from "node:child_process";
67
+ import { existsSync, readFileSync } from "node:fs";
68
+ import { join } from "node:path";
69
+ function isTailwindAvailable(cwd) {
70
+ const packageJsonPath = join(cwd, "package.json");
71
+ if (!existsSync(packageJsonPath)) {
72
+ return false;
73
+ }
74
+ try {
75
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
76
+ const deps = {
77
+ ...packageJson.dependencies,
78
+ ...packageJson.devDependencies
79
+ };
80
+ return "@tailwindcss/cli" in deps;
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
85
+ function getTailwindPaths(cwd) {
86
+ const input = join(cwd, "src/client/theme.css");
87
+ const output = join(cwd, ".reroute/theme.css");
88
+ return { input, output };
89
+ }
90
+ function hasTailwindInput(cwd) {
91
+ const { input } = getTailwindPaths(cwd);
92
+ if (!existsSync(input)) {
93
+ return false;
94
+ }
95
+ try {
96
+ const content = readFileSync(input, "utf-8");
97
+ return content.includes('@import "tailwindcss"');
98
+ } catch {
99
+ return false;
100
+ }
101
+ }
102
+ function resolveTailwindBin(cwd) {
103
+ const pathsToTry = [
104
+ join(cwd, "node_modules/.bin/tailwindcss"),
105
+ join(cwd, "../node_modules/.bin/tailwindcss"),
106
+ join(cwd, "../../node_modules/.bin/tailwindcss"),
107
+ join(cwd, "../../../node_modules/.bin/tailwindcss")
108
+ ];
109
+ for (const binPath of pathsToTry) {
110
+ if (existsSync(binPath)) {
111
+ return binPath;
112
+ }
113
+ }
114
+ return join(cwd, "node_modules/.bin/tailwindcss");
115
+ }
116
+ async function buildTailwind(cwd) {
117
+ const { input, output } = getTailwindPaths(cwd);
118
+ return new Promise((resolve, reject) => {
119
+ const tailwindBin = resolveTailwindBin(cwd);
120
+ const args = ["-i", input, "-o", output];
121
+ console.log(`[reroute/tailwind] build start: -i ${input} -o ${output}`);
122
+ const tailwind = spawn(tailwindBin, args, {
123
+ cwd,
124
+ stdio: "pipe"
125
+ });
126
+ tailwind.stdout?.on("data", (data) => {
127
+ const line = data.toString().trim();
128
+ if (line) {
129
+ console.log(`[reroute/tailwind] ${line}`);
130
+ }
131
+ });
132
+ tailwind.stderr?.on("data", (data) => {
133
+ const line = data.toString().trim();
134
+ if (line) {
135
+ console.log(`[reroute/tailwind] ${line}`);
136
+ }
137
+ });
138
+ tailwind.on("close", (code) => {
139
+ if (code === 0) {
140
+ console.log("[reroute/tailwind] build done");
141
+ resolve();
142
+ } else {
143
+ reject(new Error(`Tailwind CSS build failed with code ${code}`));
144
+ }
145
+ });
146
+ tailwind.on("error", (error) => {
147
+ reject(error);
148
+ });
149
+ });
150
+ }
68
151
  // packages/core/src/bundler/transpile.ts
152
+ function isWatchMode() {
153
+ try {
154
+ return Array.isArray(process.execArgv) && process.execArgv.includes("--watch") || Array.isArray(process.argv) && process.argv.includes("--watch");
155
+ } catch {
156
+ return false;
157
+ }
158
+ }
69
159
  async function transpileFile(filePath, originalPath, options, bundleCache) {
70
160
  const src = await Bun.file(filePath).text();
71
161
  const cacheKey = `${filePath}-${await generateContentHash(src)}`;
@@ -73,6 +163,16 @@ async function transpileFile(filePath, originalPath, options, bundleCache) {
73
163
  return bundleCache.get(cacheKey);
74
164
  }
75
165
  console.log(`[reroute] Building ${originalPath}${options.minify ? " (minified)" : ""}...`);
166
+ try {
167
+ if (isWatchMode()) {
168
+ const cwd = typeof process !== "undefined" && process.cwd ? process.cwd() : "";
169
+ if (cwd && isTailwindAvailable(cwd) && hasTailwindInput(cwd)) {
170
+ await buildTailwind(cwd);
171
+ }
172
+ }
173
+ } catch (e) {
174
+ console.warn("[reroute/tailwind] rebuild failed:", e);
175
+ }
76
176
  async function doBuild(sm) {
77
177
  return await Bun.build({
78
178
  entrypoints: [filePath],
@@ -82,7 +182,7 @@ async function transpileFile(filePath, originalPath, options, bundleCache) {
82
182
  splitting: false,
83
183
  sourcemap: sm,
84
184
  define: {
85
- "process.env.NODE_ENV": options.minify ? '"production"' : '"development"'
185
+ "process.env.BUN_ENV": options.minify ? '"production"' : '"development"'
86
186
  }
87
187
  });
88
188
  }
@@ -124,10 +224,10 @@ async function transpileFile(filePath, originalPath, options, bundleCache) {
124
224
  async function getBundleUrlsFor(modules, clientDir, prefix, options, bundleCache) {
125
225
  const mods = Array.isArray(modules) ? modules : [modules];
126
226
  const urls = [];
127
- const { join: join2 } = await Promise.resolve().then(() => exports_path);
227
+ const { join: join3 } = await Promise.resolve().then(() => exports_path);
128
228
  for (const mod of mods) {
129
229
  const rel = mod.replace(/^\.\//, "");
130
- const fullPath = join2(clientDir, rel);
230
+ const fullPath = join3(clientDir, rel);
131
231
  try {
132
232
  const bundleInfo = await transpileFile(fullPath, rel, options, bundleCache);
133
233
  const base = basename(rel, extname(rel));
@@ -139,171 +239,16 @@ async function getBundleUrlsFor(modules, clientDir, prefix, options, bundleCache
139
239
  }
140
240
  return urls;
141
241
  }
142
- // packages/core/src/content/builder.ts
143
- import { mkdir, readdir } from "node:fs/promises";
144
- import { pathToFileURL } from "node:url";
145
- async function sha8(text) {
146
- const data = new TextEncoder().encode(text);
147
- const buf = await crypto.subtle.digest("SHA-256", data);
148
- let hex = "";
149
- for (const b of new Uint8Array(buf))
150
- hex += b.toString(16).padStart(2, "0");
151
- return hex.slice(0, 8);
152
- }
153
- async function buildChunkFor(absSrc, cwd, collection, name) {
154
- try {
155
- const result = await Bun.build({
156
- entrypoints: [absSrc],
157
- target: "browser",
158
- format: "esm",
159
- splitting: false,
160
- sourcemap: "none",
161
- minify: false,
162
- define: { "process.env.NODE_ENV": '"production"' }
163
- });
164
- if (!result.success)
165
- return null;
166
- const code = await result.outputs[0]?.text();
167
- const hash2 = await sha8(code);
168
- const relDir = join(".reroute", "chunks", collection);
169
- const absDir = join(cwd, relDir);
170
- const outFile = `${name}.${hash2}.js`;
171
- const outPath = join(absDir, outFile);
172
- await mkdir(absDir, { recursive: true });
173
- const exists = await Bun.file(outPath).exists();
174
- if (!exists)
175
- await Bun.write(outPath, code);
176
- const url = `/${join(relDir, outFile).replace(/\\+/g, "/")}`;
177
- return { outPath, url, code };
178
- } catch (e) {
179
- console.error("[reroute] Failed to build content chunk:", absSrc, e);
180
- return null;
181
- }
182
- }
183
- async function getMetaFor(absSrc, isWatchMode) {
184
- try {
185
- const url = pathToFileURL(absSrc).href + (isWatchMode ? `?t=${Date.now()}` : "");
186
- const m = await import(url);
187
- return m.meta || m.frontmatter || {};
188
- } catch {
189
- return {};
190
- }
191
- }
192
- async function rebuildContentArtifacts(cwd, clientDir, isWatchMode = true) {
193
- const routesRoot = join(clientDir, "routes");
194
- const items = [];
195
- try {
196
- const entries = await readdir(routesRoot, { withFileTypes: true });
197
- for (const dir of entries) {
198
- if (!dir.isDirectory())
199
- continue;
200
- const collection = dir.name;
201
- const contentDir = join(routesRoot, collection, "content");
202
- let contentFiles = [];
203
- try {
204
- const list = await readdir(contentDir, { withFileTypes: true });
205
- contentFiles = list.filter((e) => e.isFile() && /\.(tsx|ts)$/.test(e.name) && !e.name.startsWith("_")).map((e) => e.name);
206
- } catch {
207
- continue;
208
- }
209
- for (const file of contentFiles) {
210
- const name = file.replace(/\.(tsx|ts)$/, "");
211
- const absSrc = join(contentDir, file);
212
- const chunk = await buildChunkFor(absSrc, cwd, collection, name);
213
- if (!chunk)
214
- continue;
215
- const meta = await getMetaFor(absSrc, isWatchMode);
216
- items.push({
217
- collection,
218
- name,
219
- slug: name,
220
- href: `/${collection}/${name}`,
221
- moduleUrl: chunk.url,
222
- meta
223
- });
224
- }
225
- }
226
- } catch (e) {
227
- console.error("[reroute] Failed to scan content routes:", e);
228
- return;
229
- }
230
- try {
231
- const lines = [];
232
- lines.push("// \uD83D\uDEA8 Auto-generated by Reroute - DO NOT EDIT \uD83D\uDEA8");
233
- lines.push("/* eslint-disable */");
234
- lines.push("// @ts-nocheck");
235
- lines.push("");
236
- lines.push("export const contents = [");
237
- for (const e of items) {
238
- lines.push(" { collection: '" + e.collection + "', slug: '" + e.slug + "', name: '" + e.name + "', href: '" + e.href + "', module: '" + e.moduleUrl + "', meta: " + JSON.stringify(e.meta || {}) + " },");
239
- }
240
- lines.push("] as const;");
241
- lines.push("");
242
- lines.push("export const byCollection: Record<string, any[]> = {};");
243
- lines.push("for (const c of contents) { (byCollection[c.collection] ||= []).push(c as any); }");
244
- lines.push("");
245
- lines.push("export const byCollectionAndName: Record<string, Record<string, any>> = {};");
246
- lines.push("for (const c of contents) { ((byCollectionAndName[c.collection] ||= {})[c.name] = c as any); }");
247
- lines.push("");
248
- lines.push("export type Collections = keyof typeof byCollection;");
249
- lines.push("export type Names<C extends Collections> = keyof (typeof byCollectionAndName)[C];");
250
- lines.push("export type ContentEntry = (typeof contents)[number];");
251
- lines.push("");
252
- lines.push("export function getContentEntry<C extends string, N extends string>(collection: C, name: N) {");
253
- lines.push(" const m = (byCollectionAndName as any)[collection];");
254
- lines.push(" return m ? (m as Record<string, any>)[name] : undefined;");
255
- lines.push("}");
256
- lines.push("");
257
- await mkdir(join(cwd, ".reroute"), { recursive: true });
258
- await Bun.write(join(cwd, ".reroute", "content.ts"), lines.join(`
259
- `));
260
- } catch (e) {
261
- console.error("[reroute] Failed to write .reroute/content.ts:", e);
262
- }
263
- try {
264
- const byCol = new Map;
265
- for (const it of items) {
266
- const arr = byCol.get(it.collection) || [];
267
- arr.push(it);
268
- byCol.set(it.collection, arr);
269
- }
270
- await mkdir(join(cwd, ".reroute", "collections"), { recursive: true });
271
- for (const [collection, list] of byCol) {
272
- const js = [];
273
- js.push("// \uD83D\uDEA8 Auto-generated by Reroute - DO NOT EDIT \uD83D\uDEA8");
274
- js.push("");
275
- js.push("export const items = [");
276
- for (const e of list) {
277
- js.push(` { collection: '${e.collection}', slug: '${e.slug}', name: '${e.name}', href: '${e.href}', module: '${e.moduleUrl}', meta: ${JSON.stringify(e.meta || {})} },`);
278
- }
279
- js.push("];");
280
- js.push("");
281
- js.push("export const byName = {};");
282
- js.push("for (const it of items) { byName[it.name] = it; }");
283
- js.push("");
284
- js.push("export function get(collectionName, name) {");
285
- js.push(` if (collectionName !== '${collection}') return undefined;`);
286
- js.push(" return byName[name];");
287
- js.push("}");
288
- js.push("");
289
- await Bun.write(join(cwd, ".reroute", "collections", `${collection}.js`), js.join(`
290
- `));
291
- }
292
- } catch (e) {
293
- console.error("[reroute] Failed to write .reroute/collections/*:", e);
294
- }
295
- console.log("[reroute] Content artifacts up-to-date");
296
- }
297
242
  // packages/core/src/content/discovery.ts
298
- import { readdir as readdir2, stat as stat2 } from "node:fs/promises";
243
+ import { readdir, stat as stat2 } from "node:fs/promises";
299
244
 
300
245
  // packages/core/src/content/metadata.ts
301
246
  import { stat } from "node:fs/promises";
302
- import { pathToFileURL as pathToFileURL2 } from "node:url";
303
- async function getContentMeta(absPath, isWatchMode) {
247
+ import { pathToFileURL } from "node:url";
248
+ async function getContentMeta(absPath, isWatchMode2) {
304
249
  try {
305
- const url = pathToFileURL2(absPath).href;
306
- const mod = await import(`${url}${isWatchMode ? `?t=${Date.now()}` : ""}`);
250
+ const url = pathToFileURL(absPath).href;
251
+ const mod = await import(`${url}${isWatchMode2 ? `?t=${Date.now()}` : ""}`);
307
252
  const meta = mod.meta || mod.frontmatter || {};
308
253
  if (meta && typeof meta === "object")
309
254
  return meta;
@@ -339,10 +284,10 @@ function escapeHtml(input) {
339
284
  async function listContentFiles(dir, baseRel) {
340
285
  const out = [];
341
286
  try {
342
- const entries = await readdir2(dir, { withFileTypes: true });
287
+ const entries = await readdir(dir, { withFileTypes: true });
343
288
  for (const entry of entries) {
344
- const full = join(dir, entry.name);
345
- const rel = join(baseRel, entry.name);
289
+ const full = join2(dir, entry.name);
290
+ const rel = join2(baseRel, entry.name);
346
291
  if (entry.isDirectory()) {
347
292
  const nested = await listContentFiles(full, rel);
348
293
  out.push(...nested);
@@ -355,19 +300,19 @@ async function listContentFiles(dir, baseRel) {
355
300
  } catch {}
356
301
  return out;
357
302
  }
358
- async function buildContentDTOs(collectionPath, clientDir, prefix, isWatchMode) {
303
+ async function buildContentDTOs(collectionPath, clientDir, prefix, isWatchMode2) {
359
304
  const normalized = stripStart(stripEnd(collectionPath, "/"), "/");
360
- const contentRelDir = join("routes", normalized, "content");
361
- const contentAbsDir = join(clientDir, contentRelDir);
305
+ const contentRelDir = join2("routes", normalized, "content");
306
+ const contentAbsDir = join2(clientDir, contentRelDir);
362
307
  const files = await listContentFiles(contentAbsDir, "");
363
308
  const items = [];
364
309
  for (const rel of files) {
365
- const fullRelPath = join(contentRelDir, rel);
366
- const absPath = join(clientDir, fullRelPath);
310
+ const fullRelPath = join2(contentRelDir, rel);
311
+ const absPath = join2(clientDir, fullRelPath);
367
312
  const noExt = rel.replace(/\.(tsx|ts)$/, "");
368
313
  const name = basename(noExt);
369
314
  const moduleUrl = `${prefix}/${fullRelPath}`.replace(/\/+/g, "/");
370
- const meta = await getContentMeta(absPath, isWatchMode);
315
+ const meta = await getContentMeta(absPath, isWatchMode2);
371
316
  const href = `/${normalized}/${name}`.replace(/\\+/g, "/");
372
317
  items.push({
373
318
  slug: noExt,
@@ -381,13 +326,13 @@ async function buildContentDTOs(collectionPath, clientDir, prefix, isWatchMode)
381
326
  return items;
382
327
  }
383
328
  async function discoverCollections(clientDir) {
384
- const root = join(clientDir, "routes");
329
+ const root = join2(clientDir, "routes");
385
330
  const collections = new Set;
386
331
  try {
387
- const entries = await readdir2(root, { withFileTypes: true });
332
+ const entries = await readdir(root, { withFileTypes: true });
388
333
  for (const entry of entries) {
389
334
  if (entry.isDirectory()) {
390
- const contentDir = join(root, entry.name, "content");
335
+ const contentDir = join2(root, entry.name, "content");
391
336
  try {
392
337
  await stat2(contentDir);
393
338
  collections.add(entry.name);
@@ -400,18 +345,18 @@ async function discoverCollections(clientDir) {
400
345
  // packages/core/src/content/registry.ts
401
346
  async function generateContentRegistry(cwd) {
402
347
  try {
403
- const p = join(cwd, ".reroute", "content.ts");
348
+ const p = join2(cwd, ".reroute", "content.ts");
404
349
  const exists = await Bun.file(p).exists();
405
350
  console.log(exists ? "[reroute] Content registry up-to-date" : "[reroute] Warning: .reroute/content.ts not found");
406
351
  } catch {}
407
352
  }
408
353
  // packages/core/src/ssr/data.ts
409
- import { pathToFileURL as pathToFileURL4 } from "node:url";
354
+ import { pathToFileURL as pathToFileURL3 } from "node:url";
410
355
 
411
356
  // packages/core/src/ssr/modules.ts
412
- import { readdir as readdir3, stat as stat3 } from "node:fs/promises";
413
- import { pathToFileURL as pathToFileURL3 } from "node:url";
414
- async function importContentModuleForPath(pathname, clientDir, cwd, isWatchMode) {
357
+ import { readdir as readdir2, stat as stat3 } from "node:fs/promises";
358
+ import { pathToFileURL as pathToFileURL2 } from "node:url";
359
+ async function importContentModuleForPath(pathname, clientDir, cwd, isWatchMode2) {
415
360
  try {
416
361
  const parts = pathname.split("/").filter(Boolean);
417
362
  if (parts.length < 2)
@@ -419,51 +364,51 @@ async function importContentModuleForPath(pathname, clientDir, cwd, isWatchMode)
419
364
  const collection = parts[0];
420
365
  const name = parts[1];
421
366
  try {
422
- const registryPath = join(cwd, ".reroute", "content.ts");
423
- const reg = await import(pathToFileURL3(registryPath).href + (isWatchMode ? `?t=${Date.now()}` : ""));
367
+ const registryPath = join2(cwd, ".reroute", "content.ts");
368
+ const reg = await import(pathToFileURL2(registryPath).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
424
369
  const get = reg?.getContentEntry;
425
370
  const entry = typeof get === "function" ? get(collection, name) : undefined;
426
371
  const moduleUrl = entry?.module;
427
372
  if (moduleUrl?.endsWith(".js")) {
428
- const abs = join(cwd, moduleUrl.replace(/^\//, ""));
429
- const href = pathToFileURL3(abs).href + (isWatchMode ? `?t=${Date.now()}` : "");
373
+ const abs = join2(cwd, moduleUrl.replace(/^\//, ""));
374
+ const href = pathToFileURL2(abs).href + (isWatchMode2 ? `?t=${Date.now()}` : "");
430
375
  const mod = await import(href);
431
376
  return mod;
432
377
  }
433
378
  } catch {}
434
379
  try {
435
- const chunkDir = join(cwd, ".reroute", "chunks", collection);
436
- const files = await readdir3(chunkDir);
380
+ const chunkDir = join2(cwd, ".reroute", "chunks", collection);
381
+ const files = await readdir2(chunkDir);
437
382
  const matches = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
438
383
  if (matches.length) {
439
384
  let latest = matches[0];
440
385
  let latestM = 0;
441
386
  for (const f of matches) {
442
387
  try {
443
- const s = await stat3(join(chunkDir, f));
388
+ const s = await stat3(join2(chunkDir, f));
444
389
  if (s.mtimeMs >= latestM) {
445
390
  latestM = s.mtimeMs;
446
391
  latest = f;
447
392
  }
448
393
  } catch {}
449
394
  }
450
- const absChunk = join(chunkDir, latest);
451
- const href = pathToFileURL3(absChunk).href + (isWatchMode ? `?t=${Date.now()}` : "");
395
+ const absChunk = join2(chunkDir, latest);
396
+ const href = pathToFileURL2(absChunk).href + (isWatchMode2 ? `?t=${Date.now()}` : "");
452
397
  const mod = await import(href);
453
398
  return mod;
454
399
  }
455
400
  } catch {}
456
401
  try {
457
- const srcTsx = join(clientDir, "routes", collection, "content", `${name}.tsx`);
458
- const srcTs = join(clientDir, "routes", collection, "content", `${name}.ts`);
402
+ const srcTsx = join2(clientDir, "routes", collection, "content", `${name}.tsx`);
403
+ const srcTs = join2(clientDir, "routes", collection, "content", `${name}.ts`);
459
404
  let absSrc = null;
460
405
  if (await Bun.file(srcTsx).exists())
461
406
  absSrc = srcTsx;
462
407
  else if (await Bun.file(srcTs).exists())
463
408
  absSrc = srcTs;
464
409
  if (absSrc) {
465
- const href = pathToFileURL3(absSrc).href;
466
- const mod = await (isWatchMode ? import(`${href}?t=${Date.now()}`) : import(href));
410
+ const href = pathToFileURL2(absSrc).href;
411
+ const mod = await (isWatchMode2 ? import(`${href}?t=${Date.now()}`) : import(href));
467
412
  return mod;
468
413
  }
469
414
  } catch {}
@@ -472,7 +417,7 @@ async function importContentModuleForPath(pathname, clientDir, cwd, isWatchMode)
472
417
  }
473
418
 
474
419
  // packages/core/src/ssr/seed.ts
475
- async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
420
+ async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode2) {
476
421
  try {
477
422
  const parts = pathname.split("/").filter(Boolean);
478
423
  if (parts.length < 2)
@@ -480,7 +425,7 @@ async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
480
425
  const collection = parts[0];
481
426
  const name = parts[1];
482
427
  const key = `${collection}:${name}`;
483
- const mod = await importContentModuleForPath(pathname, clientDir, cwd, isWatchMode);
428
+ const mod = await importContentModuleForPath(pathname, clientDir, cwd, isWatchMode2);
484
429
  if (!mod)
485
430
  return;
486
431
  const C = mod.default || mod;
@@ -500,9 +445,9 @@ async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
500
445
 
501
446
  // packages/core/src/ssr/data.ts
502
447
  async function computeSSRDataForPath(params) {
503
- const { pathname, clientDir, cwd, isWatchMode } = params;
448
+ const { pathname, clientDir, cwd, isWatchMode: isWatchMode2 } = params;
504
449
  try {
505
- await seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode);
450
+ await seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode2);
506
451
  } catch {}
507
452
  try {
508
453
  const parts = pathname.split("/").filter(Boolean);
@@ -517,15 +462,15 @@ async function computeSSRDataForPath(params) {
517
462
  }
518
463
  } catch {}
519
464
  try {
520
- const routesPath = join(cwd, ".reroute", "routes.ts");
521
- const m = await import(pathToFileURL4(routesPath).href + (isWatchMode ? `?t=${Date.now()}` : ""));
465
+ const routesPath = join2(cwd, ".reroute", "routes.ts");
466
+ const m = await import(pathToFileURL3(routesPath).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
522
467
  const match = typeof m.matchRoute === "function" ? m.matchRoute(pathname) : null;
523
468
  const r = match?.route;
524
469
  const paramsValue = match?.params || {};
525
470
  if (r && typeof r.path === "string") {
526
471
  try {
527
- const abs = join(clientDir, "routes", String(r.path));
528
- const mod = await import(pathToFileURL4(abs).href + (isWatchMode ? `?t=${Date.now()}` : ""));
472
+ const abs = join2(clientDir, "routes", String(r.path));
473
+ const mod = await import(pathToFileURL3(abs).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
529
474
  const ssr = mod?.ssr;
530
475
  const dataFn = ssr?.data;
531
476
  if (typeof dataFn === "function") {
@@ -537,8 +482,8 @@ async function computeSSRDataForPath(params) {
537
482
  return null;
538
483
  }
539
484
  // packages/core/src/ssr/render.ts
540
- import { readdir as readdir4, stat as stat4 } from "node:fs/promises";
541
- import { pathToFileURL as pathToFileURL5 } from "node:url";
485
+ import { readdir as readdir3, stat as stat4 } from "node:fs/promises";
486
+ import { pathToFileURL as pathToFileURL4 } from "node:url";
542
487
 
543
488
  // node_modules/dedent/dist/dedent.mjs
544
489
  function ownKeys(object, enumerableOnly) {
@@ -662,7 +607,7 @@ import { renderToString } from "react-dom/server";
662
607
 
663
608
  // packages/core/src/template/html.ts
664
609
  async function loadIndexHtml(clientDir) {
665
- const templatePath = join(clientDir, "index.html");
610
+ const templatePath = join2(clientDir, "index.html");
666
611
  try {
667
612
  const content = await Bun.file(templatePath).text();
668
613
  return content;
@@ -739,7 +684,7 @@ async function renderSSRDocument(options) {
739
684
  rootComponent,
740
685
  clientDir,
741
686
  cwd,
742
- isWatchMode,
687
+ isWatchMode: isWatchMode2,
743
688
  bundleUrl,
744
689
  head = "",
745
690
  lang = "en",
@@ -761,7 +706,7 @@ async function renderSSRDocument(options) {
761
706
  let modulePath = "";
762
707
  let isContentCollection = false;
763
708
  try {
764
- const maybeDir = join(clientDir, "routes", collection, "content");
709
+ const maybeDir = join2(clientDir, "routes", collection, "content");
765
710
  const s = await stat4(maybeDir);
766
711
  isContentCollection = typeof s?.isDirectory === "function" ? s.isDirectory() : true;
767
712
  } catch {
@@ -771,8 +716,8 @@ async function renderSSRDocument(options) {
771
716
  throw new Error("skip-content-preload");
772
717
  }
773
718
  try {
774
- const registryPath = join(cwd, ".reroute", "content.ts");
775
- const reg = await import(pathToFileURL5(registryPath).href + (isWatchMode ? `?t=${Date.now()}` : ""));
719
+ const registryPath = join2(cwd, ".reroute", "content.ts");
720
+ const reg = await import(pathToFileURL4(registryPath).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
776
721
  const get = reg?.getContentEntry;
777
722
  const entry = typeof get === "function" ? get(collection, name) : undefined;
778
723
  const moduleUrl = entry?.module;
@@ -782,33 +727,33 @@ async function renderSSRDocument(options) {
782
727
  } catch {}
783
728
  if (!modulePath) {
784
729
  try {
785
- const chunkDir = join(cwd, ".reroute", "chunks", collection);
786
- const files = await readdir4(chunkDir);
730
+ const chunkDir = join2(cwd, ".reroute", "chunks", collection);
731
+ const files = await readdir3(chunkDir);
787
732
  const candidates = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
788
733
  if (candidates.length) {
789
734
  let latest = candidates[0];
790
735
  let latestM = 0;
791
736
  for (const candidateName of candidates) {
792
737
  try {
793
- const s = await stat4(join(chunkDir, candidateName));
738
+ const s = await stat4(join2(chunkDir, candidateName));
794
739
  if (s.mtimeMs >= latestM) {
795
740
  latestM = s.mtimeMs;
796
741
  latest = candidateName;
797
742
  }
798
743
  } catch {}
799
744
  }
800
- modulePath = `/${join(".reroute", "chunks", collection, latest).replace(/\\+/g, "/")}`;
745
+ modulePath = `/${join2(".reroute", "chunks", collection, latest).replace(/\\+/g, "/")}`;
801
746
  }
802
747
  } catch {}
803
748
  }
804
749
  if (!modulePath) {
805
- const tsx = join(clientDir, "routes", collection, "content", `${name}.tsx`);
806
- const ts = join(clientDir, "routes", collection, "content", `${name}.ts`);
750
+ const tsx = join2(clientDir, "routes", collection, "content", `${name}.tsx`);
751
+ const ts = join2(clientDir, "routes", collection, "content", `${name}.ts`);
807
752
  let srcUrl = "";
808
753
  if (await Bun.file(tsx).exists()) {
809
- srcUrl = `/${join("routes", collection, "content", `${name}.tsx`).replace(/\\+/g, "/")}`;
754
+ srcUrl = `/${join2("routes", collection, "content", `${name}.tsx`).replace(/\\+/g, "/")}`;
810
755
  } else if (await Bun.file(ts).exists()) {
811
- srcUrl = `/${join("routes", collection, "content", `${name}.ts`).replace(/\\+/g, "/")}`;
756
+ srcUrl = `/${join2("routes", collection, "content", `${name}.ts`).replace(/\\+/g, "/")}`;
812
757
  }
813
758
  if (srcUrl) {
814
759
  modulePath = srcUrl;
@@ -826,7 +771,7 @@ async function renderSSRDocument(options) {
826
771
  }
827
772
  }
828
773
  } catch {}
829
- await seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode);
774
+ await seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode2);
830
775
  const __SSR_DATA__ = {};
831
776
  try {
832
777
  try {
@@ -846,15 +791,15 @@ async function renderSSRDocument(options) {
846
791
  }
847
792
  } catch {}
848
793
  try {
849
- const routesPath = join(cwd, ".reroute", "routes.ts");
850
- const m = await import(pathToFileURL5(routesPath).href + (isWatchMode ? `?t=${Date.now()}` : ""));
794
+ const routesPath = join2(cwd, ".reroute", "routes.ts");
795
+ const m = await import(pathToFileURL4(routesPath).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
851
796
  const match = typeof m.matchRoute === "function" ? m.matchRoute(pathname) : null;
852
797
  const r = match?.route;
853
798
  const params = match?.params || {};
854
799
  if (r && typeof r.path === "string") {
855
800
  try {
856
- const abs = join(clientDir, "routes", String(r.path));
857
- const mod = await import(pathToFileURL5(abs).href + (isWatchMode ? `?t=${Date.now()}` : ""));
801
+ const abs = join2(clientDir, "routes", String(r.path));
802
+ const mod = await import(pathToFileURL4(abs).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
858
803
  const ssr = mod?.ssr;
859
804
  const dataFn = ssr?.data;
860
805
  if (typeof dataFn === "function") {
@@ -870,8 +815,8 @@ async function renderSSRDocument(options) {
870
815
  } catch {}
871
816
  let __byCollectionForSSR = {};
872
817
  try {
873
- const p = join(cwd, ".reroute", "content.ts");
874
- const mod = await import(pathToFileURL5(p).href + (isWatchMode ? `?t=${Date.now()}` : ""));
818
+ const p = join2(cwd, ".reroute", "content.ts");
819
+ const mod = await import(pathToFileURL4(p).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
875
820
  __byCollectionForSSR = mod?.byCollection || {};
876
821
  try {
877
822
  globalThis.__REROUTE_COLLECTIONS__ = __byCollectionForSSR;
@@ -885,10 +830,10 @@ async function renderSSRDocument(options) {
885
830
  let inlineStyleTag = "";
886
831
  try {
887
832
  const candidates = [
888
- join(clientDir, "..", ".reroute", "theme.css"),
889
- join(clientDir, "..", "..", ".reroute", "theme.css"),
890
- join(clientDir, "..", "..", "..", ".reroute", "theme.css"),
891
- join(clientDir, "..", "..", "..", "..", ".reroute", "theme.css")
833
+ join2(clientDir, "..", ".reroute", "theme.css"),
834
+ join2(clientDir, "..", "..", ".reroute", "theme.css"),
835
+ join2(clientDir, "..", "..", "..", ".reroute", "theme.css"),
836
+ join2(clientDir, "..", "..", "..", "..", ".reroute", "theme.css")
892
837
  ];
893
838
  let cssPath = "";
894
839
  for (const p of candidates) {
@@ -971,7 +916,7 @@ async function renderSSRDocument(options) {
971
916
  </script>`;
972
917
  } catch {}
973
918
  hydrationScript += scripts.map((src) => `<script type="module" src="${src}"></script>`).join("");
974
- if (isWatchMode) {
919
+ if (isWatchMode2) {
975
920
  hydrationScript += `<script type="module" src="/__reroute_watch.js"></script>`;
976
921
  }
977
922
  let perPageHead = "";
@@ -996,8 +941,8 @@ ${ssrHead}`;
996
941
  }
997
942
  } catch {}
998
943
  try {
999
- const routesPath = join(cwd, ".reroute", "routes.ts");
1000
- const m = await import(pathToFileURL5(routesPath).href + (isWatchMode ? `?t=${Date.now()}` : ""));
944
+ const routesPath = join2(cwd, ".reroute", "routes.ts");
945
+ const m = await import(pathToFileURL4(routesPath).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
1001
946
  const match = typeof m.matchRoute === "function" ? m.matchRoute(pathname) : null;
1002
947
  const r = match?.route;
1003
948
  if (!r) {
@@ -1005,8 +950,8 @@ ${ssrHead}`;
1005
950
  }
1006
951
  if (r && typeof r.path === "string") {
1007
952
  try {
1008
- const abs = join(clientDir, "routes", String(r.path));
1009
- const mod = await import(pathToFileURL5(abs).href + (isWatchMode ? `?t=${Date.now()}` : ""));
953
+ const abs = join2(clientDir, "routes", String(r.path));
954
+ const mod = await import(pathToFileURL4(abs).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
1010
955
  const meta = mod?.meta;
1011
956
  const ssr = mod?.ssr;
1012
957
  if (meta)
@@ -1040,8 +985,8 @@ ${ssrHead}`;
1040
985
  }
1041
986
  if (chosen && typeof chosen.path === "string") {
1042
987
  try {
1043
- const abs = join(clientDir, "routes", String(chosen.path));
1044
- const mod = await import(pathToFileURL5(abs).href + (isWatchMode ? `?t=${Date.now()}` : ""));
988
+ const abs = join2(clientDir, "routes", String(chosen.path));
989
+ const mod = await import(pathToFileURL4(abs).href + (isWatchMode2 ? `?t=${Date.now()}` : ""));
1045
990
  const meta = mod?.meta;
1046
991
  const ssr = mod?.ssr;
1047
992
  if (meta)
@@ -1074,82 +1019,6 @@ ${ssrHead}`;
1074
1019
  status: statusOverride || 200
1075
1020
  };
1076
1021
  }
1077
- // packages/core/src/tailwind.ts
1078
- import { spawn } from "node:child_process";
1079
- import { existsSync, readFileSync } from "node:fs";
1080
- import { join as join2 } from "node:path";
1081
- function isTailwindAvailable(cwd) {
1082
- const packageJsonPath = join2(cwd, "package.json");
1083
- if (!existsSync(packageJsonPath))
1084
- return false;
1085
- try {
1086
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
1087
- const deps = {
1088
- ...packageJson.dependencies,
1089
- ...packageJson.devDependencies
1090
- };
1091
- return !!deps && "@tailwindcss/cli" in deps;
1092
- } catch {
1093
- return false;
1094
- }
1095
- }
1096
- function getTailwindPaths(cwd) {
1097
- const input = join2(cwd, "src/client/theme.css");
1098
- const output = join2(cwd, ".reroute/theme.css");
1099
- return { input, output };
1100
- }
1101
- function hasTailwindInput(cwd) {
1102
- const { input } = getTailwindPaths(cwd);
1103
- if (!existsSync(input))
1104
- return false;
1105
- try {
1106
- const content = readFileSync(input, "utf-8");
1107
- return content.includes('@import "tailwindcss"');
1108
- } catch {
1109
- return false;
1110
- }
1111
- }
1112
- function resolveTailwindBin(cwd) {
1113
- const pathsToTry = [
1114
- join2(cwd, "node_modules/.bin/tailwindcss"),
1115
- join2(cwd, "../node_modules/.bin/tailwindcss"),
1116
- join2(cwd, "../../node_modules/.bin/tailwindcss"),
1117
- join2(cwd, "../../../node_modules/.bin/tailwindcss")
1118
- ];
1119
- for (const binPath of pathsToTry)
1120
- if (existsSync(binPath))
1121
- return binPath;
1122
- return join2(cwd, "node_modules/.bin/tailwindcss");
1123
- }
1124
- async function buildTailwind(cwd) {
1125
- const { input, output } = getTailwindPaths(cwd);
1126
- if (!isTailwindAvailable(cwd) || !hasTailwindInput(cwd))
1127
- return;
1128
- await new Promise((resolve, reject) => {
1129
- const tailwindBin = resolveTailwindBin(cwd);
1130
- const args = ["-i", input, "-o", output];
1131
- const tailwind = spawn(tailwindBin, args, { cwd, stdio: "inherit" });
1132
- tailwind.on("close", (code) => code === 0 ? resolve() : reject(new Error(`Tailwind CSS build failed with code ${code}`)));
1133
- tailwind.on("error", (error) => reject(error));
1134
- });
1135
- }
1136
- function watchTailwind(cwd) {
1137
- if (!isTailwindAvailable(cwd) || !hasTailwindInput(cwd))
1138
- return null;
1139
- const { input, output } = getTailwindPaths(cwd);
1140
- const tailwindBin = resolveTailwindBin(cwd);
1141
- const args = ["-i", input, "-o", output, "--watch"];
1142
- console.log("[reroute/tailwind] Starting Tailwind CSS v4 in watch mode...");
1143
- const child = spawn(tailwindBin, args, { cwd, stdio: "inherit" });
1144
- child.on("error", (e) => console.error("[reroute/tailwind] Error:", e));
1145
- const stop = () => {
1146
- try {
1147
- console.log("[reroute/tailwind] Stopping Tailwind CSS...");
1148
- child.kill();
1149
- } catch {}
1150
- };
1151
- return { process: child, stop };
1152
- }
1153
1022
  // packages/core/src/utils/cache.ts
1154
1023
  class LRUCache {
1155
1024
  cache;
@@ -1241,7 +1110,7 @@ function registerArtifactsRoutes(app, cwd) {
1241
1110
  const sub = String(params["*"] || "").replace(/^\/+/, "");
1242
1111
  if (!sub)
1243
1112
  throw new NotFoundError;
1244
- const abs = join(cwd, ".reroute", sub);
1113
+ const abs = join2(cwd, ".reroute", sub);
1245
1114
  try {
1246
1115
  const exists = await Bun.file(abs).exists();
1247
1116
  if (!exists)
@@ -1269,12 +1138,12 @@ function registerArtifactsRoutes(app, cwd) {
1269
1138
 
1270
1139
  // packages/elysia/src/routes/content.ts
1271
1140
  import { NotFoundError as NotFoundError2 } from "elysia";
1272
- function registerContentRoutes(app, clientDir, prefix, isWatchMode) {
1141
+ function registerContentRoutes(app, clientDir, prefix, isWatchMode2) {
1273
1142
  app.get("/__content/*", async ({ params, set }) => {
1274
1143
  const collectionPath = String(params["*"] || "").trim();
1275
1144
  if (!collectionPath)
1276
1145
  throw new NotFoundError2;
1277
- const items = await buildContentDTOs(collectionPath, clientDir, prefix, isWatchMode);
1146
+ const items = await buildContentDTOs(collectionPath, clientDir, prefix, isWatchMode2);
1278
1147
  const body = JSON.stringify({ collection: collectionPath, items });
1279
1148
  set.status = 200;
1280
1149
  set.headers["content-type"] = "application/json; charset=utf-8";
@@ -1336,7 +1205,7 @@ function jsonError(message, status = 500) {
1336
1205
  }
1337
1206
 
1338
1207
  // packages/elysia/src/routes/dev.ts
1339
- function registerDevRoutes(app, liveReloadClients, isWatchMode, opts) {
1208
+ function registerDevRoutes(app, liveReloadClients, isWatchMode2, opts) {
1340
1209
  app.get("/__reroute_preload", async ({ query }) => {
1341
1210
  const rawSrc = String(query.src || "").trim();
1342
1211
  const key = String(query.key || "").trim();
@@ -1358,7 +1227,7 @@ function registerDevRoutes(app, liveReloadClients, isWatchMode, opts) {
1358
1227
  return new Response(code, {
1359
1228
  headers: {
1360
1229
  "content-type": "application/javascript; charset=utf-8",
1361
- "cache-control": isWatchMode ? "no-cache" : "public, max-age=31536000, immutable"
1230
+ "cache-control": isWatchMode2 ? "no-cache" : "public, max-age=31536000, immutable"
1362
1231
  }
1363
1232
  });
1364
1233
  });
@@ -1376,14 +1245,14 @@ function registerDevRoutes(app, liveReloadClients, isWatchMode, opts) {
1376
1245
  pathname,
1377
1246
  clientDir: opts?.clientDir || "",
1378
1247
  cwd: opts?.cwd || "",
1379
- isWatchMode
1248
+ isWatchMode: isWatchMode2
1380
1249
  });
1381
1250
  return jsonWithCache({ data: data2 }, opts?.dataCacheControl || "no-cache", headers);
1382
1251
  } catch (_e) {
1383
1252
  return jsonError("failed", 500);
1384
1253
  }
1385
1254
  });
1386
- if (!isWatchMode)
1255
+ if (!isWatchMode2)
1387
1256
  return app;
1388
1257
  console.log("[reroute] Registering SSE endpoint at /__reroute_watch");
1389
1258
  app.get("/__reroute_watch", () => {
@@ -1455,7 +1324,7 @@ function registerSSRRoutes(app, options) {
1455
1324
  rootComponent,
1456
1325
  clientDir,
1457
1326
  cwd,
1458
- isWatchMode,
1327
+ isWatchMode: isWatchMode2,
1459
1328
  getBundleUrl,
1460
1329
  head = "",
1461
1330
  lang = "en",
@@ -1480,7 +1349,7 @@ function registerSSRRoutes(app, options) {
1480
1349
  rootComponent,
1481
1350
  clientDir,
1482
1351
  cwd,
1483
- isWatchMode,
1352
+ isWatchMode: isWatchMode2,
1484
1353
  bundleUrl,
1485
1354
  head,
1486
1355
  lang,
@@ -1513,7 +1382,7 @@ function registerSSRRoutes(app, options) {
1513
1382
  pathname: p,
1514
1383
  clientDir,
1515
1384
  cwd,
1516
- isWatchMode
1385
+ isWatchMode: isWatchMode2
1517
1386
  });
1518
1387
  return jsonWithCache({ data: data2 }, dataCacheControl || "no-cache", request.headers);
1519
1388
  } catch (_e) {
@@ -1522,7 +1391,7 @@ function registerSSRRoutes(app, options) {
1522
1391
  }
1523
1392
  if (method === "GET" && !isInternal) {
1524
1393
  try {
1525
- if (isWatchMode) {
1394
+ if (isWatchMode2) {
1526
1395
  await generateContentRegistry(cwd);
1527
1396
  }
1528
1397
  const bundleUrl = await getBundleUrl();
@@ -1531,7 +1400,7 @@ function registerSSRRoutes(app, options) {
1531
1400
  rootComponent,
1532
1401
  clientDir,
1533
1402
  cwd,
1534
- isWatchMode,
1403
+ isWatchMode: isWatchMode2,
1535
1404
  bundleUrl,
1536
1405
  head,
1537
1406
  lang,
@@ -1563,15 +1432,15 @@ function registerStaticRoutes(app, options) {
1563
1432
  shouldIgnore,
1564
1433
  bundleCache,
1565
1434
  fileCache,
1566
- isWatchMode
1435
+ isWatchMode: isWatchMode2
1567
1436
  } = options;
1568
1437
  app.get(`${prefix}/*`, async ({ params, headers }) => {
1569
1438
  const requestPath = params["*"];
1570
1439
  const hashedJsMatch = requestPath.match(/^(.+)\.([a-f0-9]{8})\.js$/);
1571
1440
  if (hashedJsMatch) {
1572
1441
  const [, filename, hash2] = hashedJsMatch;
1573
- const tsxPath = join(clientDir, `${filename}.tsx`);
1574
- const tsPath = join(clientDir, `${filename}.ts`);
1442
+ const tsxPath = join2(clientDir, `${filename}.tsx`);
1443
+ const tsPath = join2(clientDir, `${filename}.ts`);
1575
1444
  let filePath2 = null;
1576
1445
  if (await Bun.file(tsxPath).exists()) {
1577
1446
  filePath2 = tsxPath;
@@ -1601,8 +1470,8 @@ function registerStaticRoutes(app, options) {
1601
1470
  const sourceMapMatch = requestPath.match(/^(.+)\.([a-f0-9]{8})\.js\.map$/);
1602
1471
  if (sourceMapMatch) {
1603
1472
  const [, filename, hash2] = sourceMapMatch;
1604
- const tsxPath = join(clientDir, `${filename}.tsx`);
1605
- const tsPath = join(clientDir, `${filename}.ts`);
1473
+ const tsxPath = join2(clientDir, `${filename}.tsx`);
1474
+ const tsPath = join2(clientDir, `${filename}.ts`);
1606
1475
  let filePath2 = null;
1607
1476
  if (await Bun.file(tsxPath).exists()) {
1608
1477
  filePath2 = tsxPath;
@@ -1637,7 +1506,7 @@ function registerStaticRoutes(app, options) {
1637
1506
  const name = m[2];
1638
1507
  try {
1639
1508
  const cwd = process.cwd();
1640
- const regPath = join(cwd, ".reroute", "content.ts");
1509
+ const regPath = join2(cwd, ".reroute", "content.ts");
1641
1510
  const reg = await import((await import("node:url")).pathToFileURL(regPath).href + `?t=${Date.now()}`);
1642
1511
  const get = reg?.getContentEntry;
1643
1512
  const entry = typeof get === "function" ? get(collection, name) : undefined;
@@ -1650,7 +1519,7 @@ function registerStaticRoutes(app, options) {
1650
1519
  }
1651
1520
  } catch {}
1652
1521
  try {
1653
- const chunkDir = join(process.cwd(), ".reroute", "chunks", collection);
1522
+ const chunkDir = join2(process.cwd(), ".reroute", "chunks", collection);
1654
1523
  const files = await (await import("node:fs/promises")).readdir(chunkDir);
1655
1524
  const candidates = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
1656
1525
  if (candidates.length) {
@@ -1659,14 +1528,14 @@ function registerStaticRoutes(app, options) {
1659
1528
  const { stat: stat5 } = await import("node:fs/promises");
1660
1529
  for (const f of candidates) {
1661
1530
  try {
1662
- const s = await stat5(join(chunkDir, f));
1531
+ const s = await stat5(join2(chunkDir, f));
1663
1532
  if (s.mtimeMs >= latestM) {
1664
1533
  latestM = s.mtimeMs;
1665
1534
  latest = f;
1666
1535
  }
1667
1536
  } catch {}
1668
1537
  }
1669
- const loc = `/${join(".reroute", "chunks", collection, latest).replace(/\\+/g, "/")}`;
1538
+ const loc = `/${join2(".reroute", "chunks", collection, latest).replace(/\\+/g, "/")}`;
1670
1539
  return new Response(null, {
1671
1540
  status: 302,
1672
1541
  headers: { Location: loc }
@@ -1675,7 +1544,7 @@ function registerStaticRoutes(app, options) {
1675
1544
  } catch {}
1676
1545
  }
1677
1546
  } catch {}
1678
- const filePath2 = join(clientDir, requestPath);
1547
+ const filePath2 = join2(clientDir, requestPath);
1679
1548
  if (shouldIgnore(filePath2))
1680
1549
  throw new NotFoundError5;
1681
1550
  try {
@@ -1688,7 +1557,7 @@ function registerStaticRoutes(app, options) {
1688
1557
  return new Response(body, {
1689
1558
  headers: {
1690
1559
  "Content-Type": contentType,
1691
- "Cache-Control": isWatchMode ? "no-cache" : `${directive}, max-age=${maxAge}`,
1560
+ "Cache-Control": isWatchMode2 ? "no-cache" : `${directive}, max-age=${maxAge}`,
1692
1561
  ...extraHeaders,
1693
1562
  ...staticHeaders
1694
1563
  }
@@ -1700,12 +1569,12 @@ function registerStaticRoutes(app, options) {
1700
1569
  throw new NotFoundError5;
1701
1570
  }
1702
1571
  }
1703
- const filePath = join(clientDir, requestPath);
1572
+ const filePath = join2(clientDir, requestPath);
1704
1573
  try {
1705
1574
  let actualFilePath = filePath;
1706
1575
  let exists = await Bun.file(actualFilePath).exists();
1707
1576
  if (!exists && indexHTML) {
1708
- actualFilePath = join(filePath, "index.html");
1577
+ actualFilePath = join2(filePath, "index.html");
1709
1578
  exists = await Bun.file(actualFilePath).exists();
1710
1579
  }
1711
1580
  if (!exists)
@@ -1782,13 +1651,11 @@ var reroute = (options = {}) => async (app) => {
1782
1651
  }
1783
1652
  };
1784
1653
  const clientDir = assets.startsWith("/") ? assets : `${cwd.replace(/\/$/, "")}/${assets.replace(/^\.\//, "")}`;
1785
- const join3 = (...parts) => parts.join("/").replace(/\/+/g, "/");
1786
1654
  const shouldIgnore = !ignorePatterns.length ? () => false : (file) => ignorePatterns.find((pattern) => typeof pattern === "string" ? file.includes(pattern) : pattern.test(file));
1787
- const isWatchMode = process.execArgv[0] === "--watch";
1655
+ const isWatchMode2 = Array.isArray(process.execArgv) && process.execArgv.includes("--watch") || Array.isArray(process.argv) && process.argv.includes("--watch");
1788
1656
  const dataCacheControl = `${directive}, max-age=${maxAge}`;
1789
- if (isWatchMode) {
1657
+ if (isWatchMode2)
1790
1658
  console.log(`[reroute] Live reload enabled`);
1791
- }
1792
1659
  await generateContentRegistry(cwd);
1793
1660
  let cachedBundleUrlPromise = null;
1794
1661
  const ensureBundleUrl = () => {
@@ -1797,8 +1664,8 @@ var reroute = (options = {}) => async (app) => {
1797
1664
  }
1798
1665
  return cachedBundleUrlPromise;
1799
1666
  };
1800
- registerContentRoutes(app, clientDir, prefix, isWatchMode);
1801
- registerDevRoutes(app, liveReloadClients, isWatchMode, {
1667
+ registerContentRoutes(app, clientDir, prefix, isWatchMode2);
1668
+ registerDevRoutes(app, liveReloadClients, isWatchMode2, {
1802
1669
  clientDir,
1803
1670
  cwd,
1804
1671
  dataCacheControl
@@ -1817,62 +1684,27 @@ var reroute = (options = {}) => async (app) => {
1817
1684
  pathname,
1818
1685
  clientDir,
1819
1686
  cwd,
1820
- isWatchMode
1687
+ isWatchMode: isWatchMode2
1821
1688
  });
1822
1689
  return jsonWithCache({ data: data2 }, dataCacheControl, headers);
1823
1690
  } catch (_e) {
1824
1691
  return jsonError("failed", 500);
1825
1692
  }
1826
1693
  });
1827
- if (isWatchMode) {
1828
- try {
1829
- let debounce;
1830
- const schedule = () => {
1831
- clearTimeout(debounce);
1832
- debounce = setTimeout(async () => {
1833
- try {
1834
- bundleCache.clear();
1835
- cachedBundleUrlPromise = null;
1836
- await rebuildContentArtifacts(cwd, clientDir, true);
1837
- try {
1838
- await buildTailwind(cwd);
1839
- } catch {}
1840
- notifyReload();
1841
- console.log("[reroute] Rebuilt on change and notified clients");
1842
- } catch (e) {
1843
- console.error("[reroute] Dev rebuild failed:", e);
1844
- }
1845
- }, 120);
1846
- };
1847
- let tailwindProc = null;
1694
+ if (isWatchMode2) {
1695
+ app.post("/__reroute_reload", () => {
1848
1696
  try {
1849
- if (isTailwindAvailable(cwd) && hasTailwindInput(cwd)) {
1850
- tailwindProc = watchTailwind(cwd);
1851
- }
1852
- } catch {}
1853
- fsWatch(clientDir, { recursive: true }, (_event, filename) => {
1854
- try {
1855
- const name = String(filename || "");
1856
- if (!name)
1857
- return;
1858
- if (!/\.(ts|tsx|js|jsx|html|css|json)$/i.test(name))
1859
- return;
1860
- if (shouldIgnore(join3(clientDir, name)))
1861
- return;
1862
- schedule();
1863
- } catch {}
1864
- });
1865
- console.log(`[reroute] Watching ${clientDir} for changes`);
1866
- const stop = () => {
1867
- try {
1868
- tailwindProc?.stop?.();
1869
- } catch {}
1870
- };
1871
- process.on("SIGINT", stop);
1872
- process.on("exit", stop);
1873
- } catch (e) {
1874
- console.warn("[reroute] Failed to start dev file watcher:", e);
1875
- }
1697
+ notifyReload();
1698
+ return new Response(JSON.stringify({ ok: true }), {
1699
+ headers: { "content-type": "application/json" }
1700
+ });
1701
+ } catch {
1702
+ return new Response(JSON.stringify({ ok: false }), {
1703
+ status: 500,
1704
+ headers: { "content-type": "application/json" }
1705
+ });
1706
+ }
1707
+ });
1876
1708
  }
1877
1709
  registerArtifactsRoutes(app, cwd);
1878
1710
  if (rootComponent) {
@@ -1884,7 +1716,7 @@ var reroute = (options = {}) => async (app) => {
1884
1716
  rootComponent,
1885
1717
  clientDir,
1886
1718
  cwd,
1887
- isWatchMode,
1719
+ isWatchMode: isWatchMode2,
1888
1720
  getBundleUrl: ensureBundleUrl,
1889
1721
  head: ssrHead,
1890
1722
  lang: ssrLang,
@@ -1906,7 +1738,7 @@ var reroute = (options = {}) => async (app) => {
1906
1738
  shouldIgnore,
1907
1739
  bundleCache,
1908
1740
  fileCache,
1909
- isWatchMode
1741
+ isWatchMode: isWatchMode2
1910
1742
  });
1911
1743
  return app;
1912
1744
  };
@@ -1914,4 +1746,4 @@ export {
1914
1746
  reroute
1915
1747
  };
1916
1748
 
1917
- //# debugId=76C6E6C53BBB11F164756E2164756E21
1749
+ //# debugId=78F127C42E76400F64756E2164756E21