@akanjs/cli 3.1.0-rc.1 → 3.1.0-rc.3

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.
Files changed (74) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-kyprmy06.js → CodeAgent-ctk4fh2b.js} +2 -2
  3. package/{CodeTui-21mtze3j.js → CodeTui-mrxtrdzw.js} +1 -1
  4. package/TunnelShare-rj74jd6x.js +13 -0
  5. package/{agent.command-f3gsc1gd.js → agent.command-ncre6kwz.js} +5 -5
  6. package/akanCode.js +2 -2
  7. package/{application.command-5s780vnz.js → application.command-54mawreg.js} +52 -41
  8. package/{applicationBuildRunner-1yaqsrdq.js → applicationBuildRunner-8573zr2w.js} +16 -30
  9. package/buildBatch.proc.js +22 -13
  10. package/{cloud.command-yj6xb2a7.js → cloud.command-nyemv0m3.js} +57 -65
  11. package/cloud.script-ht6yb203.js +23 -0
  12. package/{code.command-3wkn4ja5.js → code.command-spsrzg63.js} +6 -6
  13. package/{context.command-9jjn3gcw.js → context.command-768zv7z4.js} +16 -13
  14. package/context.runner-tf1b53qq.js +24 -0
  15. package/{guideline.command-dtczrqpf.js → guideline.command-4ycwc51q.js} +2 -2
  16. package/guidelines/conventions/conventions.instruction.md +28 -15
  17. package/guidelines/cssRule/cssRule.instruction.md +12 -6
  18. package/guidelines/mcpRule/mcpRule.instruction.md +27 -11
  19. package/guidelines/runtimeRule/runtimeRule.instruction.md +24 -15
  20. package/guidelines/transportRule/transportRule.instruction.md +28 -5
  21. package/incrementalBuilder.proc.js +9 -6
  22. package/{index-2etcv0sc.js → index-00seamy5.js} +1 -1
  23. package/{index-jx4bzvwg.js → index-1a7nhq56.js} +92 -52
  24. package/{index-e0cvze1s.js → index-1nyxvz8j.js} +4 -4
  25. package/index-2z3kykvd.js +248 -0
  26. package/{index-rtct7d43.js → index-3675mvjw.js} +1 -1
  27. package/{index-56d2g8ms.js → index-3ddt3qjg.js} +1 -1
  28. package/{index-6jjtnhkw.js → index-3x7yeecy.js} +51 -9
  29. package/{index-ww9bhp67.js → index-4pf8g7ff.js} +1 -1
  30. package/index-8935h3n1.js +33 -0
  31. package/{index-v29746vb.js → index-8eqkxwsx.js} +3 -3
  32. package/{index-c2yrsxdh.js → index-91rt5bye.js} +96 -320
  33. package/{index-55mynnqs.js → index-bv210r6t.js} +459 -210
  34. package/{index-c76k723e.js → index-c4h5b5nq.js} +2 -2
  35. package/{index-qt22xstj.js → index-c9zjb3tw.js} +5 -3
  36. package/{index-c1x0be5j.js → index-dmsvd2rv.js} +2 -2
  37. package/index-ec080x99.js +1124 -0
  38. package/{index-ctanya41.js → index-fjqvd5mx.js} +4 -4
  39. package/{index-aprt7pkz.js → index-fvn6f5wx.js} +229 -1327
  40. package/{index-rc5rwyps.js → index-jj7yapwq.js} +71 -60
  41. package/index-kmamh5bv.js +241 -0
  42. package/{index-fm46xrf1.js → index-q5abh0jq.js} +3 -3
  43. package/{index-1w2qaee2.js → index-qf8g88j9.js} +361 -291
  44. package/{index-gnyf1fqy.js → index-qvghfv6v.js} +2 -2
  45. package/{index-ae5pwhgs.js → index-r5d6rq19.js} +10 -8
  46. package/{index-2mx692qq.js → index-vhfjzda3.js} +2 -2
  47. package/{index-8r4d7cmt.js → index-w9b71b6y.js} +4 -4
  48. package/{index-8ggztp8k.js → index-wanhh011.js} +42 -177
  49. package/{index-05g3jayg.js → index-wdze51wz.js} +1 -1
  50. package/index-wjqbc7sf.js +668 -0
  51. package/{index-rwq3ekqc.js → index-xf40a295.js} +7 -7
  52. package/{index-krq7btbt.js → index-xm5tmpv0.js} +3 -3
  53. package/index.js +22 -22
  54. package/{library.command-gaga5bmq.js → library.command-88ahgych.js} +3 -3
  55. package/{localRegistry.command-vsreyy42.js → localRegistry.command-ykea1m7b.js} +12 -9
  56. package/{module.command-7vpf6db4.js → module.command-zky4b7m9.js} +5 -5
  57. package/{package.command-twmvvf69.js → package.command-vh8pcedh.js} +3 -3
  58. package/package.json +2 -2
  59. package/{page.command-5asq7fdf.js → page.command-fyqeqxc3.js} +3 -3
  60. package/{pipeline.command-d0v38572.js → pipeline.command-r5t30py6.js} +220 -219
  61. package/{primitive.command-dyrs2fm8.js → primitive.command-a0516zfk.js} +6 -6
  62. package/{projectTypecheck-cvtkrzp2.js → projectTypecheck-7djd4z50.js} +1 -1
  63. package/{quality.command-6emsqpbg.js → quality.command-k7jcnfn0.js} +2 -2
  64. package/{repair.command-8t6aegv5.js → repair.command-85zg2an3.js} +5 -5
  65. package/{scalar.command-bnggy1x7.js → scalar.command-g5vmqwca.js} +4 -4
  66. package/{subspace.command-md2teygq.js → subspace.command-mp4evgsj.js} +421 -362
  67. package/{tunnel.command-jx3tdm2d.js → tunnel.command-kbnr99sj.js} +7 -4
  68. package/{workflow.command-jx0wag5r.js → workflow.command-9y9p1n8y.js} +10 -10
  69. package/{workspace.command-yxd7rr7g.js → workspace.command-jmec2kjg.js} +33 -30
  70. package/TunnelShare-q4jq08qg.js +0 -9
  71. package/cloud.script-h6pvcpa2.js +0 -20
  72. package/context.runner-atcrzz5b.js +0 -21
  73. package/index-6w0rbr9d.js +0 -68
  74. package/index-pgj2rt78.js +0 -404
@@ -3,13 +3,27 @@ import {
3
3
  SOURCE_EXTS,
4
4
  WatchRootResolver
5
5
  } from "./index-k9rrten6.js";
6
+ import {
7
+ bundleDefine,
8
+ CsrEntryFiles,
9
+ loaderFor,
10
+ BarrelAnalyzer,
11
+ createBarrelImportsPlugin,
12
+ createTsconfigPackageResolver,
13
+ rewriteBarrelImports,
14
+ toClientReferencePath,
15
+ scanUseClientExports,
16
+ CsrDevPaths,
17
+ PagesEntrySourceGenerator,
18
+ PagesBundleBuilder
19
+ } from "./index-ec080x99.js";
6
20
  import {
7
21
  FileSys2
8
22
  } from "./index-52w0fvh8.js";
9
23
  import {
10
24
  AsyncDefaultExportDetector,
11
25
  resolveSsrPageEntriesForApp
12
- } from "./index-55mynnqs.js";
26
+ } from "./index-bv210r6t.js";
13
27
 
14
28
  // pkgs/@akanjs/devkit/artifact/routeSeedIndex.ts
15
29
  import path from "path";
@@ -80,525 +94,12 @@ function serializeArtifactPath(artifactPath, artifactDir) {
80
94
 
81
95
  // pkgs/@akanjs/devkit/frontendBuild/clientEntryDiscovery.ts
82
96
  import fs from "fs";
83
- import path4 from "path";
84
-
85
- // pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
86
97
  import path2 from "path";
87
- import { Logger } from "akanjs/common";
88
-
89
- // pkgs/@akanjs/devkit/transforms/moduleSyntax.ts
90
- var loaderFor = (absPath) => {
91
- if (absPath.endsWith(".tsx"))
92
- return "tsx";
93
- if (absPath.endsWith(".jsx"))
94
- return "jsx";
95
- if (absPath.endsWith(".ts"))
96
- return "ts";
97
- return "js";
98
- };
99
- var parseNamedList = (listBody) => {
100
- const out = [];
101
- for (const raw of listBody.split(",")) {
102
- let rest = raw.trim();
103
- if (!rest)
104
- continue;
105
- let isType = false;
106
- if (rest.startsWith("type ")) {
107
- isType = true;
108
- rest = rest.slice(5).trim();
109
- }
110
- const asMatch = /^(\w+)\s+as\s+(\w+)$/.exec(rest);
111
- if (asMatch) {
112
- out.push({ imported: asMatch[1] ?? "", local: asMatch[2] ?? "", isType });
113
- continue;
114
- }
115
- if (/^\w+$/.test(rest))
116
- out.push({ imported: rest, local: rest, isType });
117
- }
118
- return out;
119
- };
120
-
121
- // pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
122
- var REEXPORT_RE = /(?:^|\n)\s*export\s+(?:type\s+)?(?:(\*)(?:\s+as\s+(\w+))?|\{\s*([^}]*?)\s*\})\s+from\s+(["'])([^"']+)\4;?/g;
123
- var LOCAL_NAMED_RE = /(?:^|\n)\s*export\s+\{\s*([^}]*?)\s*\}(?!\s*from)/g;
124
- var CANDIDATE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
125
-
126
- class BarrelAnalyzer {
127
- #logger = new Logger("BarrelAnalyzer");
128
- #opts;
129
- #cache = new Map;
130
- #tsTranspiler = new Bun.Transpiler({ loader: "ts" });
131
- #tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
132
- constructor(opts) {
133
- this.#opts = opts;
134
- }
135
- analyze(pkgName) {
136
- const cached = this.#cache.get(pkgName);
137
- if (cached)
138
- return cached;
139
- const promise = this.#analyzeSafe(pkgName);
140
- this.#cache.set(pkgName, promise);
141
- return promise;
142
- }
143
- async#analyzeSafe(pkgName) {
144
- try {
145
- const pkg = await this.#opts.resolvePackage(pkgName);
146
- if (!pkg)
147
- return null;
148
- const map = new Map;
149
- await this.#walk(pkg.entryFile, pkg, map, new Set);
150
- return map;
151
- } catch (err) {
152
- this.#logger.error(`analyze failed for ${pkgName}: ${err.message}`);
153
- return null;
154
- }
155
- }
156
- async#walk(absFile, pkg, map, visited) {
157
- if (visited.has(absFile))
158
- return;
159
- visited.add(absFile);
160
- const file = Bun.file(absFile);
161
- if (!await file.exists())
162
- return;
163
- const source = await file.text();
164
- const currentSubpath = this.#subpathFor(pkg, absFile);
165
- if (!currentSubpath)
166
- return;
167
- const authoritative = this.#scanExports(source, absFile);
168
- authoritative.delete("default");
169
- const attributed = new Set;
170
- const attribute = (listBody, subpath) => {
171
- for (const item of parseNamedList(listBody)) {
172
- if (item.isType || item.imported === "default" || !authoritative.has(item.local))
173
- continue;
174
- attributed.add(item.local);
175
- if (!map.has(item.local))
176
- map.set(item.local, { subpath, originalName: item.imported });
177
- }
178
- };
179
- const starSpecs = [];
180
- for (const m of source.matchAll(REEXPORT_RE)) {
181
- const star = m[1];
182
- const nsAs = m[2];
183
- const namedList = m[3];
184
- const spec = m[5] ?? "";
185
- if (!isRelative(spec))
186
- continue;
187
- if (star) {
188
- if (nsAs)
189
- authoritative.delete(nsAs);
190
- else
191
- starSpecs.push(spec);
192
- continue;
193
- }
194
- if (namedList !== undefined) {
195
- const targetAbs = await this.#resolveRel(absFile, spec);
196
- if (!targetAbs)
197
- continue;
198
- const targetSubpath = this.#subpathFor(pkg, targetAbs);
199
- if (targetSubpath)
200
- attribute(namedList, targetSubpath);
201
- }
202
- }
203
- LOCAL_NAMED_RE.lastIndex = 0;
204
- let n = LOCAL_NAMED_RE.exec(source);
205
- while (n !== null) {
206
- const body = n[1] ?? "";
207
- n = LOCAL_NAMED_RE.exec(source);
208
- attribute(body, currentSubpath);
209
- }
210
- for (const name of authoritative) {
211
- if (attributed.has(name))
212
- continue;
213
- if (map.has(name))
214
- continue;
215
- map.set(name, { subpath: currentSubpath, originalName: name });
216
- }
217
- for (const spec of starSpecs) {
218
- const targetAbs = await this.#resolveRel(absFile, spec);
219
- if (targetAbs)
220
- await this.#walk(targetAbs, pkg, map, visited);
221
- }
222
- }
223
- #scanExports(source, absFile) {
224
- try {
225
- const transpiler = [".tsx", ".jsx"].includes(path2.extname(absFile)) ? this.#tsxTranspiler : this.#tsTranspiler;
226
- const { exports } = transpiler.scan(source);
227
- return new Set(exports);
228
- } catch (err) {
229
- this.#logger.error(`scan failed: ${err.message}`);
230
- return new Set;
231
- }
232
- }
233
- #subpathFor(pkg, absFile) {
234
- const rel = path2.relative(pkg.pkgDir, absFile);
235
- if (!rel || rel.startsWith("..") || path2.isAbsolute(rel))
236
- return null;
237
- if (pkg.preserveFilePath)
238
- return `${pkg.pkgName}/${rel.split(path2.sep).join("/")}`;
239
- const ext = CANDIDATE_EXTS.find((candidate) => rel.endsWith(candidate));
240
- const parts = (ext ? rel.slice(0, -ext.length) : rel).split(path2.sep);
241
- if (parts[parts.length - 1] === "index")
242
- parts.pop();
243
- const tail = parts.join("/");
244
- return tail === "" ? pkg.pkgName : `${pkg.pkgName}/${tail}`;
245
- }
246
- async#resolveRel(fromFile, relSpec) {
247
- if (this.#opts.resolveRelative)
248
- return this.#opts.resolveRelative(fromFile, relSpec);
249
- return defaultResolveRelative(fromFile, relSpec);
250
- }
251
- }
252
- var isRelative = (spec) => {
253
- return spec.startsWith("./") || spec.startsWith("../") || spec === "." || spec === "..";
254
- };
255
- var defaultResolveRelative = async (fromFile, relSpec) => {
256
- const baseDir = path2.dirname(fromFile);
257
- const joined = path2.resolve(baseDir, relSpec);
258
- if (path2.extname(joined)) {
259
- if (await Bun.file(joined).exists())
260
- return joined;
261
- return null;
262
- }
263
- for (const ext of CANDIDATE_EXTS) {
264
- const cand = joined + ext;
265
- if (await Bun.file(cand).exists())
266
- return cand;
267
- }
268
- for (const ext of CANDIDATE_EXTS) {
269
- const cand = path2.join(joined, `index${ext}`);
270
- if (await Bun.file(cand).exists())
271
- return cand;
272
- }
273
- return null;
274
- };
275
-
276
- // pkgs/@akanjs/devkit/transforms/barrelImportsPlugin.ts
277
- import path3 from "path";
278
- import ts from "typescript";
279
- var createBarrelImportsPlugin = async (app, { skipPath = defaultSkipPath, pipeAfter } = {}) => {
280
- const akanConfig = await app.getConfig();
281
- const barrels = [...new Set(akanConfig.barrelImports)].filter(Boolean);
282
- const analyzer = new BarrelAnalyzer({
283
- resolvePackage: await createTsconfigPackageResolver(app)
284
- });
285
- return {
286
- name: "barrel-imports",
287
- setup(build) {
288
- build.onLoad({
289
- filter: /^(?:(?!.*[\\/]node_modules[\\/]).*|.*[\\/]node_modules[\\/]akanjs[\\/].*)\.(tsx|ts|jsx|js)(\?v=\d+)?$/
290
- }, async (args) => {
291
- const realPath = args.path.replace(/\?v=\d+$/, "");
292
- const loader = loaderFor(realPath);
293
- let source = await Bun.file(realPath).text();
294
- if (skipPath(realPath))
295
- return { contents: source, loader };
296
- if (!MACRO_ATTR_RE.test(source) && barrels.length > 0) {
297
- const rewritten = await rewriteBarrelImports(source, barrels, analyzer);
298
- if (rewritten !== null)
299
- source = rewritten;
300
- }
301
- if (pipeAfter) {
302
- const piped = await pipeAfter(source, { path: realPath });
303
- if (piped !== null)
304
- source = piped;
305
- }
306
- return { contents: source, loader };
307
- });
308
- }
309
- };
310
- };
311
- var createTsconfigPackageResolver = async (app) => {
312
- const tsconfig = await app.getTsConfig();
313
- const tsconfigPaths = tsconfig.compilerOptions.paths ?? {};
314
- const wildcardEntries = Object.entries(tsconfigPaths).filter(([k]) => k.endsWith("/*")).map(([k, v]) => ({ prefix: k.slice(0, -1), replacements: v })).sort((a, b) => b.prefix.length - a.prefix.length);
315
- return async (pkgName) => {
316
- const exact = tsconfigPaths[pkgName];
317
- if (exact && exact.length > 0) {
318
- const raw = exact[0];
319
- if (!raw)
320
- return null;
321
- const entryFile = path3.resolve(app.workspace.workspaceRoot, raw);
322
- if (!await Bun.file(entryFile).exists())
323
- return null;
324
- const parsed = path3.parse(entryFile);
325
- const lastSlash = pkgName.lastIndexOf("/");
326
- if (parsed.name !== "index" && lastSlash > 0 && pkgName.slice(lastSlash + 1) === parsed.name)
327
- return { pkgName: pkgName.slice(0, lastSlash), entryFile, pkgDir: parsed.dir };
328
- return { pkgName, entryFile, pkgDir: path3.dirname(entryFile) };
329
- }
330
- for (const { prefix, replacements } of wildcardEntries) {
331
- if (!pkgName.startsWith(prefix))
332
- continue;
333
- const suffix = pkgName.slice(prefix.length);
334
- for (const repl of replacements) {
335
- if (!repl)
336
- continue;
337
- const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
338
- const candidate = path3.resolve(app.workspace.workspaceRoot, replPath + suffix);
339
- for (const ext of CANDIDATE_EXTS2) {
340
- const file = `${candidate}${ext}`;
341
- if (await Bun.file(file).exists()) {
342
- const lastSlash = pkgName.lastIndexOf("/");
343
- const parentSpec = lastSlash > 0 ? pkgName.slice(0, lastSlash) : pkgName;
344
- return { pkgName: parentSpec, entryFile: file, pkgDir: path3.dirname(file) };
345
- }
346
- }
347
- for (const ext of CANDIDATE_EXTS2) {
348
- const file = path3.join(candidate, `index${ext}`);
349
- if (await Bun.file(file).exists())
350
- return { pkgName, entryFile: file, pkgDir: candidate };
351
- }
352
- }
353
- return null;
354
- }
355
- const exported = await resolveNodePackageExport(app.workspace.workspaceRoot, pkgName);
356
- if (exported)
357
- return exported;
358
- const pkgJsonPath = path3.join(app.workspace.workspaceRoot, "node_modules", pkgName, "package.json");
359
- if (!await Bun.file(pkgJsonPath).exists())
360
- return null;
361
- try {
362
- const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text());
363
- const rel = pkgJson.module ?? pkgJson.main ?? "index.js";
364
- const entryFile = path3.resolve(path3.dirname(pkgJsonPath), rel);
365
- if (!await Bun.file(entryFile).exists())
366
- return null;
367
- return { pkgName, entryFile, pkgDir: path3.dirname(pkgJsonPath) };
368
- } catch {
369
- return null;
370
- }
371
- };
372
- };
373
- var CANDIDATE_EXTS2 = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
98
+ var USE_CLIENT_RE = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
374
99
  var NODE_MODULES_RE = /[\\/]node_modules[\\/]/;
375
100
  var AKANJS_NODE_MODULE_RE = /[\\/]node_modules[\\/]akanjs[\\/]/;
376
- var defaultSkipPath = (absPath) => NODE_MODULES_RE.test(absPath) && !AKANJS_NODE_MODULE_RE.test(absPath);
377
- var resolveNodePackageExport = async (workspaceRoot, specifier) => {
378
- const packageName = getPackageName(specifier);
379
- if (!packageName)
380
- return null;
381
- const pkgJsonPath = path3.join(workspaceRoot, "node_modules", packageName, "package.json");
382
- if (!await Bun.file(pkgJsonPath).exists())
383
- return null;
384
- try {
385
- const pkgDir = path3.dirname(pkgJsonPath);
386
- const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text());
387
- const subpath = specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
388
- const exported = resolvePackageExport(pkgJson.exports, subpath);
389
- const rel = exported ?? (subpath === "." ? pkgJson.module ?? pkgJson.main ?? "index.js" : null);
390
- if (!rel?.startsWith("."))
391
- return null;
392
- const entryFile = await resolveFileCandidate(path3.resolve(pkgDir, rel));
393
- if (!entryFile)
394
- return null;
395
- return { pkgName: specifier, entryFile, pkgDir: path3.dirname(entryFile), preserveFilePath: true };
396
- } catch {
397
- return null;
398
- }
399
- };
400
- var resolveExportValue = (value) => {
401
- if (!value)
402
- return null;
403
- if (typeof value === "string")
404
- return value;
405
- if (Array.isArray(value)) {
406
- for (const item of value) {
407
- const resolved = resolveExportValue(item);
408
- if (resolved)
409
- return resolved;
410
- }
411
- return null;
412
- }
413
- for (const condition of ["source", "import", "default", "types"]) {
414
- const resolved = resolveExportValue(value[condition]);
415
- if (resolved)
416
- return resolved;
417
- }
418
- return null;
419
- };
420
- var resolvePackageExport = (exportsMap, subpath) => {
421
- if (!exportsMap)
422
- return null;
423
- const exact = resolveExportValue(exportsMap[subpath]);
424
- if (exact)
425
- return exact;
426
- for (const [key, value] of Object.entries(exportsMap)) {
427
- const starIdx = key.indexOf("*");
428
- if (starIdx === -1)
429
- continue;
430
- const prefix = key.slice(0, starIdx);
431
- const suffix = key.slice(starIdx + 1);
432
- if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
433
- continue;
434
- const wildcard = subpath.slice(prefix.length, subpath.length - suffix.length);
435
- const resolved = resolveExportValue(value);
436
- if (resolved)
437
- return resolved.replace("*", wildcard);
438
- }
439
- return null;
440
- };
441
- var getPackageName = (specifier) => {
442
- const parts = specifier.split("/");
443
- if (!parts[0])
444
- return null;
445
- if (specifier.startsWith("@"))
446
- return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : null;
447
- return parts[0];
448
- };
449
- var resolveFileCandidate = async (candidate) => {
450
- if (await Bun.file(candidate).exists())
451
- return candidate;
452
- if (path3.extname(candidate))
453
- return null;
454
- for (const ext of CANDIDATE_EXTS2) {
455
- const file = `${candidate}${ext}`;
456
- if (await Bun.file(file).exists())
457
- return file;
458
- }
459
- for (const ext of CANDIDATE_EXTS2) {
460
- const file = path3.join(candidate, `index${ext}`);
461
- if (await Bun.file(file).exists())
462
- return file;
463
- }
464
- return null;
465
- };
466
- var MACRO_ATTR_RE = /with\s*\{\s*type\s*:\s*["']macro["']\s*\}/;
467
- var rewriteBarrelImports = async (source, barrels, analyzer) => {
468
- if (!barrels.some((barrel) => source.includes(barrel)))
469
- return null;
470
- const statements = findImportStatements(source);
471
- if (statements.length === 0)
472
- return null;
473
- let changed = false;
474
- let out = source;
475
- for (let i = statements.length - 1;i >= 0; i--) {
476
- const stmt = statements[i];
477
- if (!stmt)
478
- continue;
479
- if (!barrels.includes(stmt.specifier))
480
- continue;
481
- const map = await analyzer.analyze(stmt.specifier);
482
- if (!map || map.size === 0)
483
- continue;
484
- const replacement = rewriteSingleStatement(stmt, map);
485
- if (replacement === null)
486
- continue;
487
- out = out.slice(0, stmt.start) + replacement + out.slice(stmt.end);
488
- changed = true;
489
- }
490
- return changed ? out : null;
491
- };
492
- var findImportStatements = (source) => {
493
- const statements = [];
494
- const sourceFile = ts.createSourceFile("barrel-imports.tsx", source, ts.ScriptTarget.Latest, false, ts.ScriptKind.TSX);
495
- for (const statement of sourceFile.statements) {
496
- if (!ts.isImportDeclaration(statement))
497
- continue;
498
- if (!ts.isStringLiteral(statement.moduleSpecifier))
499
- continue;
500
- const importClause = statement.importClause;
501
- if (!importClause)
502
- continue;
503
- statements.push({
504
- start: statement.getStart(sourceFile),
505
- end: statement.end,
506
- clause: source.slice(importClause.getStart(sourceFile), importClause.end).trim(),
507
- specifier: statement.moduleSpecifier.text
508
- });
509
- }
510
- return statements;
511
- };
512
- var parseImportClause = (clause) => {
513
- let rest = clause.trim();
514
- let typeOnly = false;
515
- if (rest.startsWith("type ")) {
516
- typeOnly = true;
517
- rest = rest.slice(5).trim();
518
- }
519
- const parsed = { typeOnly };
520
- const commaMatch = /^(\w+)\s*,\s*(.+)$/.exec(rest);
521
- if (commaMatch) {
522
- parsed.defaultImport = commaMatch[1];
523
- rest = commaMatch[2] ?? "";
524
- } else if (/^\w+$/.test(rest)) {
525
- parsed.defaultImport = rest;
526
- return parsed;
527
- }
528
- if (rest.startsWith("*")) {
529
- const ns = /^\*\s+as\s+(\w+)$/.exec(rest);
530
- if (!ns)
531
- return null;
532
- parsed.namespaceImport = ns[1];
533
- return parsed;
534
- }
535
- if (rest.startsWith("{")) {
536
- const close = rest.indexOf("}");
537
- if (close === -1)
538
- return null;
539
- parsed.named = parseNamedList(rest.slice(1, close));
540
- }
541
- return parsed;
542
- };
543
- var rewriteSingleStatement = (stmt, map) => {
544
- const clause = parseImportClause(stmt.clause);
545
- if (!clause)
546
- return null;
547
- if (clause.namespaceImport)
548
- return null;
549
- if (clause.typeOnly && !clause.defaultImport)
550
- return null;
551
- if (!clause.named?.length)
552
- return null;
553
- const remaining = [];
554
- const rewrites = new Map;
555
- for (const item of clause.named) {
556
- if (item.isType) {
557
- remaining.push(item);
558
- continue;
559
- }
560
- const target = map.get(item.imported);
561
- if (!target) {
562
- remaining.push(item);
563
- continue;
564
- }
565
- const list = rewrites.get(target.subpath) ?? [];
566
- list.push({ imported: target.originalName, local: item.local, isType: false });
567
- rewrites.set(target.subpath, list);
568
- }
569
- if (rewrites.size === 0)
570
- return null;
571
- const lines = [];
572
- if (shouldPreserveBarrelSideEffects(stmt.specifier))
573
- lines.push(`import "${stmt.specifier}";`);
574
- if (clause.defaultImport || remaining.length > 0) {
575
- const parts = [];
576
- if (clause.defaultImport)
577
- parts.push(clause.defaultImport);
578
- if (remaining.length > 0)
579
- parts.push(`{ ${remaining.map(serializeNamedItem).join(", ")} }`);
580
- lines.push(`import ${parts.join(", ")} from "${stmt.specifier}";`);
581
- }
582
- for (const [subpath, items] of rewrites) {
583
- lines.push(`import { ${items.map(serializeNamedItem).join(", ")} } from "${subpath}";`);
584
- }
585
- return lines.join(`
586
- `);
587
- };
588
- var shouldPreserveBarrelSideEffects = (specifier) => /^@(apps|libs)\/[^/]+\/client$/.test(specifier);
589
- var serializeNamedItem = (item) => {
590
- const prefix = item.isType ? "type " : "";
591
- if (item.imported === item.local)
592
- return `${prefix}${item.imported}`;
593
- return `${prefix}${item.imported} as ${item.local}`;
594
- };
595
-
596
- // pkgs/@akanjs/devkit/frontendBuild/clientEntryDiscovery.ts
597
- var USE_CLIENT_RE = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
598
- var NODE_MODULES_RE2 = /[\\/]node_modules[\\/]/;
599
- var AKANJS_NODE_MODULE_RE2 = /[\\/]node_modules[\\/]akanjs[\\/]/;
600
101
  var NON_SOURCE_EXT_RE = /\.(css|scss|sass|less|json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav)$/i;
601
- var shouldSkipNodeModule = (absPath) => NODE_MODULES_RE2.test(absPath) && !AKANJS_NODE_MODULE_RE2.test(absPath);
102
+ var shouldSkipNodeModule = (absPath) => NODE_MODULES_RE.test(absPath) && !AKANJS_NODE_MODULE_RE.test(absPath);
602
103
 
603
104
  class GraphClientEntryDiscovery {
604
105
  #akanConfig;
@@ -634,7 +135,7 @@ class GraphClientEntryDiscovery {
634
135
  return;
635
136
  let moved = false;
636
137
  for (const file of files) {
637
- const absPath = path4.resolve(file);
138
+ const absPath = path2.resolve(file);
638
139
  const exists = fs.existsSync(absPath);
639
140
  if (exists !== this.#readFiles.has(absPath))
640
141
  moved = true;
@@ -665,11 +166,11 @@ class GraphClientEntryDiscovery {
665
166
  return entry.promise;
666
167
  }
667
168
  async#fileExists(p) {
668
- const absPath = path4.resolve(p);
169
+ const absPath = path2.resolve(p);
669
170
  return await this.#lookup(this.#fileExistsCache, absPath, () => Bun.file(absPath).exists(), (exists) => exists);
670
171
  }
671
172
  #facts(file) {
672
- const absPath = path4.resolve(file);
173
+ const absPath = path2.resolve(file);
673
174
  let cached = this.#factsCache.get(absPath);
674
175
  if (!cached) {
675
176
  cached = (async () => {
@@ -702,7 +203,7 @@ class GraphClientEntryDiscovery {
702
203
  }
703
204
  }
704
205
  async#resolveFileCandidate(absPathNoExt) {
705
- const cacheKey = path4.resolve(absPathNoExt);
206
+ const cacheKey = path2.resolve(absPathNoExt);
706
207
  return await this.#lookup(this.#resolvedFileCache, cacheKey, async () => {
707
208
  if (await this.#fileExists(cacheKey))
708
209
  return cacheKey;
@@ -712,7 +213,7 @@ class GraphClientEntryDiscovery {
712
213
  return f;
713
214
  }
714
215
  for (const ext of SOURCE_EXTS) {
715
- const f = path4.join(cacheKey, `index${ext}`);
216
+ const f = path2.join(cacheKey, `index${ext}`);
716
217
  if (await this.#fileExists(f))
717
218
  return f;
718
219
  }
@@ -723,7 +224,7 @@ class GraphClientEntryDiscovery {
723
224
  const cacheKey = `${importerDir}\x00${spec}`;
724
225
  return await this.#lookup(this.#resolvedSpecifierCache, cacheKey, async () => {
725
226
  if (spec.startsWith(".") || spec.startsWith("/")) {
726
- const abs = spec.startsWith("/") ? spec : path4.resolve(importerDir, spec);
227
+ const abs = spec.startsWith("/") ? spec : path2.resolve(importerDir, spec);
727
228
  return await this.#resolveFileCandidate(abs);
728
229
  }
729
230
  const pkg = await this.#resolvePackage(spec);
@@ -732,7 +233,7 @@ class GraphClientEntryDiscovery {
732
233
  }
733
234
  async#discoverFromFile(file, walk) {
734
235
  const epoch = this.#epoch;
735
- const absPath = path4.resolve(file);
236
+ const absPath = path2.resolve(file);
736
237
  const cached = this.#reachableEntriesCache.get(absPath);
737
238
  if (cached)
738
239
  return new Set(cached);
@@ -764,7 +265,7 @@ class GraphClientEntryDiscovery {
764
265
  entries.add(absPath);
765
266
  return this.#finishDiscovery(absPath, walk, entries, epoch);
766
267
  }
767
- const importerDir = path4.dirname(absPath);
268
+ const importerDir = path2.dirname(absPath);
768
269
  for (const imp of facts.imports) {
769
270
  const spec = imp.path;
770
271
  if (!spec)
@@ -792,66 +293,12 @@ class GraphClientEntryDiscovery {
792
293
 
793
294
  // pkgs/@akanjs/devkit/frontendBuild/routeClientBuilder.ts
794
295
  import { mkdir } from "fs/promises";
795
- import path8 from "path";
296
+ import path4 from "path";
796
297
  import { SSR_DEV_CHUNK, SSR_DEV_ID_PREFIX } from "akanjs/server/hmr/csrDevManifest";
797
298
 
798
- // pkgs/@akanjs/devkit/transforms/rscUseClientTransform.ts
799
- import path5 from "path";
800
- import ts2 from "typescript";
801
- var USE_CLIENT_RE2 = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
802
- var IMPLICIT_ROOT_LAYOUT_RE = /[/\\]\.akan[/\\]generated[/\\](?:implicit-root-layout|root-layouts[/\\].*__root_layout)\.(tsx|ts|jsx|js)$/;
803
- var STAR_REEXPORT_HINT_RE = /\bexport\s*\*\s*from\b/;
804
- var hasUseClientDirective = (source) => USE_CLIENT_RE2.test(source);
805
- function toClientReferencePath(absPath, workspaceRoot) {
806
- return path5.relative(path5.resolve(workspaceRoot), path5.resolve(absPath)).split(path5.sep).join("/");
807
- }
808
- var starReexportSpecifiers = (source, filePath) => ts2.createSourceFile(filePath, source, ts2.ScriptTarget.Latest).statements.filter((statement) => ts2.isExportDeclaration(statement) && !statement.exportClause && !statement.isTypeOnly && !!statement.moduleSpecifier && ts2.isStringLiteral(statement.moduleSpecifier)).map((statement) => statement.moduleSpecifier.text);
809
- var scanUseClientExports = (source, filePath, workspaceRoot) => {
810
- const stars = USE_CLIENT_RE2.test(source) && STAR_REEXPORT_HINT_RE.test(source) ? starReexportSpecifiers(source, filePath) : [];
811
- if (stars.length) {
812
- const file = workspaceRoot ? toClientReferencePath(filePath, workspaceRoot) : filePath;
813
- const listed = stars.slice(0, 3).map((specifier) => `\`export * from ${JSON.stringify(specifier)}\``);
814
- const written = stars.length > 3 ? `${listed.join(", ")} (and ${stars.length - 3} more)` : listed.join(", ");
815
- throw new Error(`${file} is a "use client" module, so it cannot ${written}: the server sees only the names a client module ` + `declares, and a star re-export declares none. Re-export them by name \u2014 \`export { \u2026 } from ${JSON.stringify(stars[0])}\`.`);
816
- }
817
- return new Bun.Transpiler({ loader: loaderFor(filePath) }).scan(source).exports;
818
- };
819
- function transformUseClient(source, args) {
820
- if (!USE_CLIENT_RE2.test(source))
821
- return null;
822
- if (IMPLICIT_ROOT_LAYOUT_RE.test(args.path))
823
- return null;
824
- const exports = scanUseClientExports(source, args.path, args.workspaceRoot);
825
- if (exports.length === 0)
826
- return null;
827
- args.onClientModule?.(args.path, exports);
828
- const referencePath = args.workspaceRoot ? toClientReferencePath(args.path, args.workspaceRoot) : args.path;
829
- const filePathLit = JSON.stringify(referencePath);
830
- const lines = [`import { registerClientReference } from "react-server-dom-webpack/server.node";`];
831
- for (const name of exports) {
832
- const nameLit = JSON.stringify(name);
833
- const errMsg = JSON.stringify(`Attempted to call '${name}' from '${referencePath}' on the server, but it is a client-only export.`);
834
- const proxy = `() => { throw new Error(${errMsg}); }`;
835
- const binding = name === "default" ? `export default registerClientReference(${proxy}, ${filePathLit}, ${nameLit});` : `export const ${name} = registerClientReference(${proxy}, ${filePathLit}, ${nameLit});`;
836
- lines.push(binding);
837
- }
838
- return lines.join(`
839
- `);
840
- }
841
-
842
299
  // pkgs/@akanjs/devkit/frontendBuild/clientEntriesBundler.ts
843
300
  import fs2 from "fs";
844
- import path6 from "path";
845
-
846
- // pkgs/@akanjs/devkit/frontendBuild/bundleDefine.ts
847
- var bundleDefine = (app, command, renderEnv) => {
848
- const nodeEnv = command === "build" ? "production" : "development";
849
- return {
850
- "process.env.NODE_ENV": JSON.stringify(nodeEnv),
851
- "process.env.AKAN_PUBLIC_RENDER_ENV": JSON.stringify(renderEnv),
852
- ...Object.fromEntries(Object.entries(app.getPublicEnv()).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]))
853
- };
854
- };
301
+ import path3 from "path";
855
302
 
856
303
  // pkgs/@akanjs/devkit/frontendBuild/clientBuildTypes.ts
857
304
  var CLIENT_BUNDLE_NAMING = {
@@ -933,23 +380,23 @@ class ClientEntriesBundler {
933
380
  };
934
381
  }
935
382
  async#createOpaqueEntryAliases() {
936
- const aliasDir = path6.join(this.#app.cwdPath, ".akan", "generated", "client-entry-alias", this.#outputSubdir);
383
+ const aliasDir = path3.join(this.#app.cwdPath, ".akan", "generated", "client-entry-alias", this.#outputSubdir);
937
384
  fs2.mkdirSync(aliasDir, { recursive: true });
938
385
  const originalByAlias = new Map;
939
386
  const aliasedEntries = await Promise.all(this.#entries.map(async (entry) => {
940
- const absEntry = path6.resolve(entry);
387
+ const absEntry = path3.resolve(entry);
941
388
  const hash = Bun.hash(`${this.#app.name}
942
389
  ${this.#outputSubdir}
943
390
  ${absEntry}`).toString(36);
944
- const aliasPath = path6.join(aliasDir, `${hash}.tsx`);
391
+ const aliasPath = path3.join(aliasDir, `${hash}.tsx`);
945
392
  await Bun.write(aliasPath, this.#createOpaqueEntryAliasSource(absEntry, await this.#scanEntryExportNames(absEntry)));
946
- originalByAlias.set(path6.resolve(aliasPath), absEntry);
393
+ originalByAlias.set(path3.resolve(aliasPath), absEntry);
947
394
  return aliasPath;
948
395
  }));
949
396
  return { entries: aliasedEntries, originalByAlias, aliasDir };
950
397
  }
951
398
  #createOpaqueEntryAliasSource(absEntry, exportNames) {
952
- const entryLit = JSON.stringify(path6.resolve(absEntry));
399
+ const entryLit = JSON.stringify(path3.resolve(absEntry));
953
400
  if (exportNames.length === 0)
954
401
  return `export * from ${entryLit};
955
402
  `;
@@ -1018,16 +465,16 @@ ${absEntry}`).toString(36);
1018
465
  return rewritten;
1019
466
  }
1020
467
  #toServeUrl(absOutPath) {
1021
- const rel = path6.relative(this.#outdir, absOutPath).split(path6.sep).join("/");
468
+ const rel = path3.relative(this.#outdir, absOutPath).split(path3.sep).join("/");
1022
469
  return `${this.#servePrefix}/${rel}`;
1023
470
  }
1024
471
  #absFromOutdir(p) {
1025
- return path6.isAbsolute(p) ? p : path6.resolve(this.#outdir, p);
472
+ return path3.isAbsolute(p) ? p : path3.resolve(this.#outdir, p);
1026
473
  }
1027
474
  #absFromEntryPoint(p) {
1028
- if (path6.isAbsolute(p))
1029
- return path6.resolve(p);
1030
- const candidates = [path6.resolve(process.cwd(), p), path6.resolve(this.#app.cwdPath, p)];
475
+ if (path3.isAbsolute(p))
476
+ return path3.resolve(p);
477
+ const candidates = [path3.resolve(process.cwd(), p), path3.resolve(this.#app.cwdPath, p)];
1031
478
  return candidates.find((candidate) => fs2.existsSync(candidate)) ?? candidates[0];
1032
479
  }
1033
480
  #collectChunkUrls(absOutPath, visited = new Set) {
@@ -1103,118 +550,6 @@ ${absEntry}`).toString(36);
1103
550
  }
1104
551
  }
1105
552
 
1106
- // pkgs/@akanjs/devkit/frontendBuild/csrDevPaths.ts
1107
- import fs3 from "fs";
1108
- import path7 from "path";
1109
-
1110
- class CsrDevPaths {
1111
- static modulePrefix = "akan-module:";
1112
- static stubPrefix = "stub:";
1113
- static emptyStubPrefix = "stub:empty:";
1114
- static vendorPrefix = "vendor:";
1115
- root;
1116
- constructor(workspaceRoot) {
1117
- this.root = CsrDevPaths.realpath(workspaceRoot);
1118
- }
1119
- idOf(file) {
1120
- const real = CsrDevPaths.realpath(file);
1121
- const relative = path7.relative(this.root, real);
1122
- const id = relative.startsWith("..") || path7.isAbsolute(relative) ? real : relative;
1123
- return id.split(path7.sep).join("/");
1124
- }
1125
- fileOf(id) {
1126
- return path7.isAbsolute(id) ? id : path7.join(this.root, id);
1127
- }
1128
- static isStub(target) {
1129
- return target.startsWith(CsrDevPaths.stubPrefix);
1130
- }
1131
- static isVendorFile(file) {
1132
- return file.includes(`${path7.sep}node_modules${path7.sep}`);
1133
- }
1134
- static isScript(file) {
1135
- return /\.[cm]?[jt]sx?$/.test(file);
1136
- }
1137
- static mtimeOf(file) {
1138
- return fs3.statSync(file, { throwIfNoEntry: false })?.mtimeMs ?? -1;
1139
- }
1140
- static async hashOf(file) {
1141
- const source = Bun.file(file);
1142
- return await source.exists() ? Bun.hash(await source.arrayBuffer()).toString(36) : "";
1143
- }
1144
- static realpath(file) {
1145
- return fs3.existsSync(file) ? fs3.realpathSync.native(file) : path7.resolve(file);
1146
- }
1147
- static isNamed(file) {
1148
- try {
1149
- return fs3.realpathSync.native(file) === file;
1150
- } catch {
1151
- return false;
1152
- }
1153
- }
1154
- static #extensions = {
1155
- import: [".tsx", ".jsx", ".mts", ".ts", ".mjs", ".js", ".cts", ".cjs"],
1156
- require: [".tsx", ".ts", ".jsx", ".cts", ".cjs", ".js", ".mjs", ".mts"]
1157
- };
1158
- static resolveOnDisk(base, kind = "import") {
1159
- return CsrDevPaths.#asFile(base, kind) ?? CsrDevPaths.#asFolder(base, kind);
1160
- }
1161
- static resolveRelative(dir, specifier, kind = "import") {
1162
- const base = path7.resolve(dir, specifier);
1163
- const folder = /(^|[\\/])\.\.?$|[\\/]$/.test(specifier);
1164
- return folder ? CsrDevPaths.#asFolder(base, kind) : CsrDevPaths.resolveOnDisk(base, kind);
1165
- }
1166
- static #asFile(base, kind) {
1167
- const isFile = (candidate) => fs3.statSync(candidate, { throwIfNoEntry: false })?.isFile() ?? false;
1168
- return [base, ...CsrDevPaths.#extensions[kind].map((extension) => `${base}${extension}`)].find(isFile) ?? null;
1169
- }
1170
- static #asFolder(dir, kind) {
1171
- const entry = CsrDevPaths.#packageEntryOf(dir, kind);
1172
- const named = entry ? CsrDevPaths.#asFile(path7.join(dir, entry), kind) ?? CsrDevPaths.#indexOf(path7.join(dir, entry), kind) : null;
1173
- return named ?? CsrDevPaths.#indexOf(dir, kind);
1174
- }
1175
- static #indexOf(dir, kind) {
1176
- return CsrDevPaths.#asFile(path7.join(dir, "index"), kind);
1177
- }
1178
- static #packageEntryOf(dir, kind) {
1179
- try {
1180
- const pkg = JSON.parse(fs3.readFileSync(path7.join(dir, "package.json"), "utf8"));
1181
- const fields = kind === "require" ? [pkg.browser, pkg.main] : [pkg.browser, pkg.module, pkg.main];
1182
- const entry = fields.find((field) => typeof field === "string");
1183
- return typeof entry === "string" ? entry : null;
1184
- } catch {
1185
- return null;
1186
- }
1187
- }
1188
- static installedSince(specifier, from, since) {
1189
- const [first = "", second = ""] = specifier.split("/");
1190
- const name = first.startsWith("@") ? `${first}/${second}` : first;
1191
- if (!name || name.startsWith("."))
1192
- return false;
1193
- for (let dir = path7.resolve(from);; dir = path7.dirname(dir)) {
1194
- const pkgDir = path7.join(dir, "node_modules", name);
1195
- if (fs3.existsSync(path7.join(pkgDir, "package.json")))
1196
- return (fs3.statSync(pkgDir, { throwIfNoEntry: false })?.ctimeMs ?? 0) > since;
1197
- if (path7.dirname(dir) === dir)
1198
- return false;
1199
- }
1200
- }
1201
- static tryResolve(specifier, from) {
1202
- try {
1203
- return Bun.resolveSync(specifier, from);
1204
- } catch {
1205
- return null;
1206
- }
1207
- }
1208
- static lineCount(text) {
1209
- let count = 0;
1210
- for (let index = text.indexOf(`
1211
- `);index !== -1; index = text.indexOf(`
1212
- `, index + 1))
1213
- count += 1;
1214
- return count;
1215
- }
1216
- }
1217
-
1218
553
  // pkgs/@akanjs/devkit/frontendBuild/vendorSpecifiers.ts
1219
554
  var VENDOR_SPECIFIERS = [
1220
555
  "react",
@@ -1292,13 +627,13 @@ class RouteClientBuilder {
1292
627
  ssrModuleMap[row.id][row.name] = { id: ssrOutput, chunks: [ssrOutput, ssrOutput], name: row.name, async: true };
1293
628
  }
1294
629
  for (const entry of bootstrapEntries.buildEntries) {
1295
- const buildEntry = path8.resolve(entry);
1296
- const originalEntry = path8.resolve(bootstrapEntries.originalByBuildEntry.get(buildEntry) ?? buildEntry);
630
+ const buildEntry = path4.resolve(entry);
631
+ const originalEntry = path4.resolve(bootstrapEntries.originalByBuildEntry.get(buildEntry) ?? buildEntry);
1297
632
  if (!acceptedEntries.has(originalEntry))
1298
633
  continue;
1299
634
  const deps = new Set([originalEntry]);
1300
635
  for (const dep of referenceBundle.entryDepsByAbsPath.get(buildEntry) ?? [])
1301
- deps.add(path8.resolve(dep));
636
+ deps.add(path4.resolve(dep));
1302
637
  const sortedDeps = [...deps].sort();
1303
638
  clientDepsByEntry[originalEntry] = sortedDeps;
1304
639
  if (routeEntries.has(originalEntry))
@@ -1363,25 +698,25 @@ class RouteClientBuilder {
1363
698
  }).bundle();
1364
699
  }
1365
700
  async#createBootstrapEntries(entries) {
1366
- if (!await Bun.file(path8.join(this.#app.cwdPath, "lib", "st.ts")).exists()) {
701
+ if (!await Bun.file(path4.join(this.#app.cwdPath, "lib", "st.ts")).exists()) {
1367
702
  return { buildEntries: entries, originalByBuildEntry: new Map };
1368
703
  }
1369
- const outdir = path8.join(this.#app.cwdPath, ".akan", "generated", "client-entry-bootstrap");
704
+ const outdir = path4.join(this.#app.cwdPath, ".akan", "generated", "client-entry-bootstrap");
1370
705
  await mkdir(outdir, { recursive: true });
1371
706
  const originalByBuildEntry = new Map;
1372
707
  const buildEntries = await Promise.all(entries.map(async (entry) => {
1373
- const absEntry = path8.resolve(entry);
708
+ const absEntry = path4.resolve(entry);
1374
709
  const hash = Bun.hash(`${this.#app.name}
1375
710
  ${absEntry}`).toString(36);
1376
- const base = path8.basename(absEntry).replace(/[^A-Za-z0-9._-]/g, "_");
1377
- const wrapperEntry = path8.join(outdir, `${base}-${hash}.tsx`);
711
+ const base = path4.basename(absEntry).replace(/[^A-Za-z0-9._-]/g, "_");
712
+ const wrapperEntry = path4.join(outdir, `${base}-${hash}.tsx`);
1378
713
  const exportNames = await this.#scanExportNames(absEntry);
1379
714
  await Bun.write(wrapperEntry, RouteClientBuilder.createStoreBootstrapEntrySource({
1380
715
  appName: this.#app.name,
1381
716
  originalEntry: absEntry,
1382
717
  exportNames
1383
718
  }));
1384
- originalByBuildEntry.set(path8.resolve(wrapperEntry), absEntry);
719
+ originalByBuildEntry.set(path4.resolve(wrapperEntry), absEntry);
1385
720
  return wrapperEntry;
1386
721
  }));
1387
722
  return { buildEntries, originalByBuildEntry };
@@ -1455,11 +790,11 @@ ${declared.map(({ name }) => `export default ${name};`).join(`
1455
790
  try {
1456
791
  return Bun.resolveSync("akanjs/server", import.meta.dir);
1457
792
  } catch {
1458
- return path8.resolve(import.meta.dir, "../../../server/index.ts");
793
+ return path4.resolve(import.meta.dir, "../../../server/index.ts");
1459
794
  }
1460
795
  }
1461
796
  static createStoreBootstrapEntrySource(args) {
1462
- const originalEntry = JSON.stringify(path8.resolve(args.originalEntry));
797
+ const originalEntry = JSON.stringify(path4.resolve(args.originalEntry));
1463
798
  const namedExports = args.exportNames.filter((name) => name !== "default");
1464
799
  const lines = [
1465
800
  `import ${JSON.stringify(`@apps/${args.appName}/client`)};`,
@@ -1486,8 +821,8 @@ ${declared.map(({ name }) => `export default ${name};`).join(`
1486
821
 
1487
822
  // pkgs/@akanjs/devkit/frontendBuild/autoImportSync.ts
1488
823
  import { readdir, readFile, stat } from "fs/promises";
1489
- import path9 from "path";
1490
- import ts3 from "typescript";
824
+ import path5 from "path";
825
+ import ts from "typescript";
1491
826
  var TEST_FILE_RE = /\.(test|spec)\.(ts|tsx)$/;
1492
827
  var AKAN_BASE = {
1493
828
  names: ["Int", "Float", "ID", "Any", "Upload", "enumOf", "dayjs"],
@@ -1624,7 +959,7 @@ class AutoImportSync {
1624
959
  #workspaceRoot;
1625
960
  #domainCache = new Map;
1626
961
  constructor({ workspaceRoot }) {
1627
- this.#workspaceRoot = path9.resolve(workspaceRoot);
962
+ this.#workspaceRoot = path5.resolve(workspaceRoot);
1628
963
  }
1629
964
  async syncForBatch(files) {
1630
965
  const changedFiles = [];
@@ -1636,7 +971,7 @@ class AutoImportSync {
1636
971
  this.#domainCache.delete(pkgRoot);
1637
972
  }
1638
973
  for (const file of files) {
1639
- const abs = path9.resolve(file);
974
+ const abs = path5.resolve(file);
1640
975
  if (seen.has(abs))
1641
976
  continue;
1642
977
  seen.add(abs);
@@ -1654,13 +989,13 @@ class AutoImportSync {
1654
989
  return { changedFiles, errors };
1655
990
  }
1656
991
  #contextFor(abs) {
1657
- const rel = path9.relative(this.#workspaceRoot, abs);
1658
- if (rel.startsWith("..") || path9.isAbsolute(rel))
992
+ const rel = path5.relative(this.#workspaceRoot, abs);
993
+ if (rel.startsWith("..") || path5.isAbsolute(rel))
1659
994
  return null;
1660
- const base = path9.basename(abs);
995
+ const base = path5.basename(abs);
1661
996
  if (TEST_FILE_RE.test(base) || base === "index.ts" || base === "index.tsx" || base.endsWith(".d.ts"))
1662
997
  return null;
1663
- const parts = rel.split(path9.sep).filter(Boolean);
998
+ const parts = rel.split(path5.sep).filter(Boolean);
1664
999
  const [scope, project, facet] = parts;
1665
1000
  if (scope !== "apps" && scope !== "libs" || !project || !facet)
1666
1001
  return null;
@@ -1702,8 +1037,8 @@ class AutoImportSync {
1702
1037
  };
1703
1038
  }
1704
1039
  async#domainResolver(abs, ctx, kinds) {
1705
- const index = await this.#domainIndex(path9.join(this.#workspaceRoot, ctx.scope, ctx.project));
1706
- const fileDir = path9.dirname(abs);
1040
+ const index = await this.#domainIndex(path5.join(this.#workspaceRoot, ctx.scope, ctx.project));
1041
+ const fileDir = path5.dirname(abs);
1707
1042
  return (symbol) => {
1708
1043
  if (!PASCAL_CASE_RE.test(symbol) || DOMAIN_DENYLIST.has(symbol))
1709
1044
  return null;
@@ -1714,12 +1049,12 @@ class AutoImportSync {
1714
1049
  };
1715
1050
  }
1716
1051
  async#libBarrelResolver(abs, ctx) {
1717
- const fileDir = path9.dirname(abs);
1718
- const libDir = path9.join(this.#workspaceRoot, ctx.scope, ctx.project, "lib");
1052
+ const fileDir = path5.dirname(abs);
1053
+ const libDir = path5.join(this.#workspaceRoot, ctx.scope, ctx.project, "lib");
1719
1054
  const available = new Map;
1720
1055
  for (const [symbol, { barrel, kind }] of Object.entries(LIB_BARRELS)) {
1721
- if (await fileExists(path9.join(libDir, `${barrel}.ts`)))
1722
- available.set(symbol, { specifier: relativeSpecifier(fileDir, path9.join(libDir, barrel)), kind });
1056
+ if (await fileExists(path5.join(libDir, `${barrel}.ts`)))
1057
+ available.set(symbol, { specifier: relativeSpecifier(fileDir, path5.join(libDir, barrel)), kind });
1723
1058
  }
1724
1059
  return (symbol) => available.get(symbol) ?? null;
1725
1060
  }
@@ -1727,20 +1062,20 @@ class AutoImportSync {
1727
1062
  const cached = this.#domainCache.get(pkgRoot);
1728
1063
  if (cached)
1729
1064
  return cached;
1730
- const index = await buildDomainIndex(path9.join(pkgRoot, "lib"));
1065
+ const index = await buildDomainIndex(path5.join(pkgRoot, "lib"));
1731
1066
  this.#domainCache.set(pkgRoot, index);
1732
1067
  return index;
1733
1068
  }
1734
1069
  #domainPkgRootOf(file) {
1735
- const rel = path9.relative(this.#workspaceRoot, path9.resolve(file));
1736
- if (rel.startsWith("..") || path9.isAbsolute(rel))
1070
+ const rel = path5.relative(this.#workspaceRoot, path5.resolve(file));
1071
+ if (rel.startsWith("..") || path5.isAbsolute(rel))
1737
1072
  return null;
1738
- const [scope, project, facet] = rel.split(path9.sep).filter(Boolean);
1073
+ const [scope, project, facet] = rel.split(path5.sep).filter(Boolean);
1739
1074
  if (scope !== "apps" && scope !== "libs" || !project || facet !== "lib")
1740
1075
  return null;
1741
- if (!domainKindOf(path9.basename(file)))
1076
+ if (!domainKindOf(path5.basename(file)))
1742
1077
  return null;
1743
- return path9.join(this.#workspaceRoot, scope, project);
1078
+ return path5.join(this.#workspaceRoot, scope, project);
1744
1079
  }
1745
1080
  }
1746
1081
  var roleFor = (facet, base) => {
@@ -1781,7 +1116,7 @@ var targetFor = (symbol, ctx) => {
1781
1116
  return null;
1782
1117
  };
1783
1118
  var transformSource = (source, fileName, ctx, resolveExtra) => {
1784
- const sf = ts3.createSourceFile(fileName, source, ts3.ScriptTarget.Latest, true, scriptKindFor(fileName));
1119
+ const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, scriptKindFor(fileName));
1785
1120
  const bound = collectBoundNames(sf);
1786
1121
  const used = collectUsedReferences(sf);
1787
1122
  const bareGlobals = collectBareGlobalReferences(sf);
@@ -1803,7 +1138,7 @@ var transformSource = (source, fileName, ctx, resolveExtra) => {
1803
1138
  }
1804
1139
  if (namedBySpecifier.size === 0 && namespaceImports.length === 0)
1805
1140
  return null;
1806
- const importDecls = sf.statements.filter(ts3.isImportDeclaration);
1141
+ const importDecls = sf.statements.filter(ts.isImportDeclaration);
1807
1142
  const anchor = importDecls.at(-1) ?? null;
1808
1143
  const namedImportsBySpecifier = collectExistingNamedImports(importDecls);
1809
1144
  const edits = [];
@@ -1859,61 +1194,61 @@ ${newStatements.join(`
1859
1194
  var collectBoundNames = (sf) => {
1860
1195
  const names = new Set;
1861
1196
  const visit = (node) => {
1862
- if (ts3.isImportClause(node)) {
1197
+ if (ts.isImportClause(node)) {
1863
1198
  if (node.name)
1864
1199
  names.add(node.name.text);
1865
1200
  const bindings = node.namedBindings;
1866
- if (bindings && ts3.isNamespaceImport(bindings))
1201
+ if (bindings && ts.isNamespaceImport(bindings))
1867
1202
  names.add(bindings.name.text);
1868
- if (bindings && ts3.isNamedImports(bindings))
1203
+ if (bindings && ts.isNamedImports(bindings))
1869
1204
  for (const el of bindings.elements)
1870
1205
  names.add(el.name.text);
1871
1206
  }
1872
- if ((ts3.isVariableDeclaration(node) || ts3.isFunctionDeclaration(node) || ts3.isClassDeclaration(node) || ts3.isParameter(node) || ts3.isBindingElement(node) || ts3.isEnumDeclaration(node) || ts3.isTypeAliasDeclaration(node) || ts3.isInterfaceDeclaration(node)) && node.name && ts3.isIdentifier(node.name))
1207
+ if ((ts.isVariableDeclaration(node) || ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isParameter(node) || ts.isBindingElement(node) || ts.isEnumDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) && node.name && ts.isIdentifier(node.name))
1873
1208
  names.add(node.name.text);
1874
- ts3.forEachChild(node, visit);
1209
+ ts.forEachChild(node, visit);
1875
1210
  };
1876
- ts3.forEachChild(sf, visit);
1211
+ ts.forEachChild(sf, visit);
1877
1212
  return names;
1878
1213
  };
1879
1214
  var collectUsedReferences = (sf) => {
1880
1215
  const used = new Set;
1881
1216
  const visit = (node) => {
1882
- if (ts3.isIdentifier(node) && isReferencePosition(node))
1217
+ if (ts.isIdentifier(node) && isReferencePosition(node))
1883
1218
  used.add(node.text);
1884
- ts3.forEachChild(node, visit);
1219
+ ts.forEachChild(node, visit);
1885
1220
  };
1886
- ts3.forEachChild(sf, visit);
1221
+ ts.forEachChild(sf, visit);
1887
1222
  return used;
1888
1223
  };
1889
1224
  var collectBareGlobalReferences = (sf) => {
1890
1225
  const bare = new Set;
1891
1226
  const visit = (node) => {
1892
- if (ts3.isIdentifier(node) && GLOBAL_NAMES.has(node.text) && isReferencePosition(node)) {
1227
+ if (ts.isIdentifier(node) && GLOBAL_NAMES.has(node.text) && isReferencePosition(node)) {
1893
1228
  const parent = node.parent;
1894
- if (!(parent && ts3.isPropertyAccessExpression(parent) && parent.expression === node))
1229
+ if (!(parent && ts.isPropertyAccessExpression(parent) && parent.expression === node))
1895
1230
  bare.add(node.text);
1896
1231
  }
1897
- ts3.forEachChild(node, visit);
1232
+ ts.forEachChild(node, visit);
1898
1233
  };
1899
- ts3.forEachChild(sf, visit);
1234
+ ts.forEachChild(sf, visit);
1900
1235
  return bare;
1901
1236
  };
1902
1237
  var isReferencePosition = (node) => {
1903
1238
  const parent = node.parent;
1904
1239
  if (!parent)
1905
1240
  return true;
1906
- if (ts3.isPropertyAccessExpression(parent) && parent.name === node)
1241
+ if (ts.isPropertyAccessExpression(parent) && parent.name === node)
1907
1242
  return false;
1908
- if (ts3.isQualifiedName(parent) && parent.right === node)
1243
+ if (ts.isQualifiedName(parent) && parent.right === node)
1909
1244
  return false;
1910
- if (ts3.isPropertyAssignment(parent) && parent.name === node)
1245
+ if (ts.isPropertyAssignment(parent) && parent.name === node)
1911
1246
  return false;
1912
- if (ts3.isPropertySignature(parent) && parent.name === node)
1247
+ if (ts.isPropertySignature(parent) && parent.name === node)
1913
1248
  return false;
1914
- if (ts3.isBindingElement(parent) && parent.propertyName === node)
1249
+ if (ts.isBindingElement(parent) && parent.propertyName === node)
1915
1250
  return false;
1916
- if (ts3.isImportSpecifier(parent) || ts3.isExportSpecifier(parent))
1251
+ if (ts.isImportSpecifier(parent) || ts.isExportSpecifier(parent))
1917
1252
  return false;
1918
1253
  return true;
1919
1254
  };
@@ -1922,9 +1257,9 @@ var collectExistingNamedImports = (importDecls) => {
1922
1257
  for (const decl of importDecls) {
1923
1258
  const clause = decl.importClause;
1924
1259
  const bindings = clause?.namedBindings;
1925
- if (!clause || !bindings || !ts3.isNamedImports(bindings))
1260
+ if (!clause || !bindings || !ts.isNamedImports(bindings))
1926
1261
  continue;
1927
- if (!ts3.isStringLiteral(decl.moduleSpecifier))
1262
+ if (!ts.isStringLiteral(decl.moduleSpecifier))
1928
1263
  continue;
1929
1264
  const specifier = decl.moduleSpecifier.text;
1930
1265
  if (map.has(specifier))
@@ -1946,14 +1281,14 @@ var formatNamedImport = (specifier, names) => {
1946
1281
  var directivePrologueEnd = (sf) => {
1947
1282
  let end = -1;
1948
1283
  for (const stmt of sf.statements) {
1949
- if (ts3.isExpressionStatement(stmt) && ts3.isStringLiteral(stmt.expression))
1284
+ if (ts.isExpressionStatement(stmt) && ts.isStringLiteral(stmt.expression))
1950
1285
  end = stmt.getEnd();
1951
1286
  else
1952
1287
  break;
1953
1288
  }
1954
1289
  return end;
1955
1290
  };
1956
- var scriptKindFor = (fileName) => fileName.endsWith(".tsx") ? ts3.ScriptKind.TSX : ts3.ScriptKind.TS;
1291
+ var scriptKindFor = (fileName) => fileName.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
1957
1292
  var compareNames = (a, b) => {
1958
1293
  const [la, lb] = [a.toLowerCase(), b.toLowerCase()];
1959
1294
  if (la !== lb)
@@ -1974,7 +1309,7 @@ var domainKindOf = (base) => {
1974
1309
  var buildDomainIndex = async (libDir) => {
1975
1310
  const index = new Map;
1976
1311
  for (const file of await collectDomainFiles(libDir)) {
1977
- const kind = domainKindOf(path9.basename(file));
1312
+ const kind = domainKindOf(path5.basename(file));
1978
1313
  if (!kind)
1979
1314
  continue;
1980
1315
  const src = await readFile(file, "utf8").catch(() => null);
@@ -1994,7 +1329,7 @@ var collectDomainFiles = async (dir) => {
1994
1329
  for (const entry of entries) {
1995
1330
  if (entry.name.startsWith(".") || entry.name === "node_modules")
1996
1331
  continue;
1997
- const full = path9.join(dir, entry.name);
1332
+ const full = path5.join(dir, entry.name);
1998
1333
  if (entry.isDirectory())
1999
1334
  files.push(...await collectDomainFiles(full));
2000
1335
  else if (domainKindOf(entry.name) && !TEST_FILE_RE.test(entry.name))
@@ -2003,18 +1338,18 @@ var collectDomainFiles = async (dir) => {
2003
1338
  return files;
2004
1339
  };
2005
1340
  var exportedPascalNames = (source, fileName) => {
2006
- const sf = ts3.createSourceFile(fileName, source, ts3.ScriptTarget.Latest, true);
2007
- const isExported = (node) => ts3.canHaveModifiers(node) && (ts3.getModifiers(node) ?? []).some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
1341
+ const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true);
1342
+ const isExported = (node) => ts.canHaveModifiers(node) && (ts.getModifiers(node) ?? []).some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
2008
1343
  const names = [];
2009
1344
  for (const stmt of sf.statements) {
2010
- if ((ts3.isClassDeclaration(stmt) || ts3.isFunctionDeclaration(stmt) || ts3.isEnumDeclaration(stmt)) && stmt.name) {
1345
+ if ((ts.isClassDeclaration(stmt) || ts.isFunctionDeclaration(stmt) || ts.isEnumDeclaration(stmt)) && stmt.name) {
2011
1346
  if (isExported(stmt))
2012
1347
  names.push(stmt.name.text);
2013
- } else if (ts3.isVariableStatement(stmt) && isExported(stmt)) {
1348
+ } else if (ts.isVariableStatement(stmt) && isExported(stmt)) {
2014
1349
  for (const decl of stmt.declarationList.declarations)
2015
- if (ts3.isIdentifier(decl.name))
1350
+ if (ts.isIdentifier(decl.name))
2016
1351
  names.push(decl.name.text);
2017
- } else if (ts3.isExportDeclaration(stmt) && stmt.exportClause && ts3.isNamedExports(stmt.exportClause)) {
1352
+ } else if (ts.isExportDeclaration(stmt) && stmt.exportClause && ts.isNamedExports(stmt.exportClause)) {
2018
1353
  for (const el of stmt.exportClause.elements)
2019
1354
  names.push(el.name.text);
2020
1355
  }
@@ -2022,430 +1357,18 @@ var exportedPascalNames = (source, fileName) => {
2022
1357
  return names.filter((name) => PASCAL_CASE_RE.test(name));
2023
1358
  };
2024
1359
  var relativeSpecifier = (fromDir, toFile) => {
2025
- const rel = path9.relative(fromDir, toFile).replace(/\.tsx?$/, "").split(path9.sep).join("/");
1360
+ const rel = path5.relative(fromDir, toFile).replace(/\.tsx?$/, "").split(path5.sep).join("/");
2026
1361
  return rel.startsWith(".") ? rel : `./${rel}`;
2027
1362
  };
2028
1363
 
2029
- // pkgs/@akanjs/devkit/frontendBuild/serverGraphFile.ts
2030
- import fs4 from "fs";
2031
- import path10 from "path";
2032
- class ServerGraphFile {
2033
- static fileName = "server-graph.json";
2034
- static #cache = null;
2035
- static async read(artifactDir) {
2036
- const file = path10.join(artifactDir, ServerGraphFile.fileName);
2037
- const stat = fs4.statSync(file, { throwIfNoEntry: false });
2038
- if (!stat)
2039
- return null;
2040
- const stamp = `${stat.ino}:${stat.size}:${stat.mtimeMs}`;
2041
- const cached = ServerGraphFile.#cache;
2042
- if (cached?.file === file && cached.stamp === stamp)
2043
- return cached.graph;
2044
- const graph = await Bun.file(file).json().catch(() => null);
2045
- if (graph)
2046
- ServerGraphFile.#cache = { file, stamp, graph };
2047
- return graph;
2048
- }
2049
- static async write(artifactDir, graph) {
2050
- const file = path10.join(artifactDir, ServerGraphFile.fileName);
2051
- const temp = `${file}.${process.pid}.tmp`;
2052
- await Bun.write(temp, JSON.stringify(graph));
2053
- await FileSys2.replace(temp, file);
2054
- }
2055
- static async carry(artifactDir, files) {
2056
- const graph = await ServerGraphFile.read(artifactDir);
2057
- if (!graph || files.length === 0)
2058
- return;
2059
- const carried = [...new Set([...graph.carried ?? [], ...files.map((file) => CsrDevPaths.realpath(file))])];
2060
- await ServerGraphFile.write(artifactDir, { ...graph, carried });
2061
- }
2062
- static async touches(graph, files, exportsNow, next) {
2063
- if (!graph)
2064
- return true;
2065
- const inputs = new Set(graph.inputs);
2066
- const joined = new Set((next?.inputs ?? []).filter((input) => !inputs.has(input)));
2067
- for (const rawFile of files) {
2068
- const file = CsrDevPaths.realpath(rawFile);
2069
- if (joined.has(file))
2070
- return true;
2071
- if (!inputs.has(file))
2072
- continue;
2073
- const before = graph.clientExports[file];
2074
- if (!before)
2075
- return true;
2076
- const now = await exportsNow(file);
2077
- if (!now || ServerGraphFile.#names(now) !== ServerGraphFile.#names(before))
2078
- return true;
2079
- }
2080
- return false;
2081
- }
2082
- static async clientExportsOf(file) {
2083
- const source = await Bun.file(file).text().catch(() => null);
2084
- if (source === null || !hasUseClientDirective(source))
2085
- return null;
2086
- try {
2087
- return scanUseClientExports(source, file);
2088
- } catch {
2089
- return null;
2090
- }
2091
- }
2092
- static #names(exports) {
2093
- return [...exports].sort().join(",");
2094
- }
2095
- }
2096
-
2097
- // pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
2098
- import fs5 from "fs";
2099
- import path13 from "path";
2100
-
2101
- // pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
2102
- import path11 from "path";
2103
- var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
2104
- var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "@akanjs/cli", "@akanjs/devkit"]);
2105
- var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
2106
- var OPTIONAL_BACKEND_EXTERNAL_EXACT = new Set(["bullmq", "ioredis", "postgres", "protobufjs"]);
2107
- var RUNTIME_EXTERNAL_EXACT = new Set([
2108
- "react",
2109
- "react-dom",
2110
- "react/jsx-runtime",
2111
- "react/jsx-dev-runtime",
2112
- "react-server-dom-webpack",
2113
- "react-server-dom-webpack/server.node",
2114
- "react-server-dom-webpack/client.node",
2115
- "react-server-dom-webpack/client.browser"
2116
- ]);
2117
- var RUNTIME_EXTERNAL_PREFIX = ["react-dom/", "react-server-dom-webpack/"];
2118
- var CANDIDATE_EXTS3 = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".cjs"];
2119
- async function createExternalizeFrameworkPlugin(options) {
2120
- const tsconfig = await options.app.getTsConfig();
2121
- const includePrefixes = options.include ?? DEFAULT_INCLUDE;
2122
- const extraExact = new Set(options.extra ?? []);
2123
- const workspaceRoot = options.app.workspace.workspaceRoot;
2124
- const tsconfigPaths = tsconfig.compilerOptions.paths ?? {};
2125
- const rootEntries = Object.entries(tsconfigPaths).filter(([k]) => !k.endsWith("/*")).map(([k, v]) => ({ pkg: k, entryFile: v[0] ?? null })).filter((e) => e.entryFile !== null);
2126
- const wildcardEntries = Object.entries(tsconfigPaths).filter(([k]) => k.endsWith("/*")).map(([k, v]) => ({ prefix: k.slice(0, -1), replacements: v })).sort((a, b) => b.prefix.length - a.prefix.length);
2127
- async function resolveWorkspaceSubpath(spec) {
2128
- if (!workspaceRoot)
2129
- return null;
2130
- for (const { prefix, replacements } of wildcardEntries) {
2131
- if (!spec.startsWith(prefix))
2132
- continue;
2133
- const suffix = spec.slice(prefix.length);
2134
- for (const repl of replacements) {
2135
- const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
2136
- if (!replPath)
2137
- continue;
2138
- const candidate = path11.resolve(workspaceRoot, replPath + suffix);
2139
- const hit = await firstExisting(candidate);
2140
- if (hit)
2141
- return hit;
2142
- }
2143
- }
2144
- for (const { pkg, entryFile } of rootEntries) {
2145
- if (!spec.startsWith(`${pkg}/`))
2146
- continue;
2147
- const suffix = spec.slice(pkg.length + 1);
2148
- const pkgDir = path11.dirname(path11.resolve(workspaceRoot, entryFile));
2149
- const candidate = path11.join(pkgDir, suffix);
2150
- const hit = await firstExisting(candidate);
2151
- if (hit)
2152
- return hit;
2153
- }
2154
- return null;
2155
- }
2156
- return {
2157
- name: "akan-externalize-framework",
2158
- setup(build) {
2159
- build.onResolve({ filter: /.*/ }, async (args) => {
2160
- const spec = args.path;
2161
- if (spec === "." || spec === ".." || spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/"))
2162
- return;
2163
- if (extraExact.has(spec) || DEFAULT_EXCLUDE_EXACT.has(spec))
2164
- return { path: spec, external: true };
2165
- for (const prefix of DEFAULT_EXCLUDE_PREFIX) {
2166
- if (spec.startsWith(prefix))
2167
- return { path: spec, external: true };
2168
- }
2169
- if (OPTIONAL_BACKEND_EXTERNAL_EXACT.has(spec))
2170
- return { path: spec, external: true };
2171
- if (RUNTIME_EXTERNAL_EXACT.has(spec))
2172
- return { path: spec, external: true };
2173
- for (const prefix of RUNTIME_EXTERNAL_PREFIX) {
2174
- if (spec.startsWith(prefix))
2175
- return { path: spec, external: true };
2176
- }
2177
- if (!includePrefixes.some((prefix) => spec.startsWith(prefix)))
2178
- return;
2179
- const resolved = await resolveWorkspaceSubpath(spec);
2180
- return resolved ? { path: resolved } : undefined;
2181
- });
2182
- }
2183
- };
2184
- }
2185
- async function firstExisting(basePath) {
2186
- if (await Bun.file(basePath).exists())
2187
- return basePath;
2188
- for (const ext of CANDIDATE_EXTS3) {
2189
- const candidate = `${basePath}${ext}`;
2190
- if (await Bun.file(candidate).exists())
2191
- return candidate;
2192
- }
2193
- for (const ext of CANDIDATE_EXTS3) {
2194
- const candidate = path11.join(basePath, `index${ext}`);
2195
- if (await Bun.file(candidate).exists())
2196
- return candidate;
2197
- }
2198
- return null;
2199
- }
2200
-
2201
- // pkgs/@akanjs/devkit/transforms/useClientBundlePlugin.ts
2202
- function createUseClientBundlePlugin(options = {}) {
2203
- return {
2204
- name: "akan-use-client-bundle",
2205
- setup(build) {
2206
- build.onLoad({ filter: /\.(tsx|ts|jsx|js)$/ }, async (args) => {
2207
- if (args.path.includes("/node_modules/"))
2208
- return;
2209
- let source;
2210
- try {
2211
- source = await Bun.file(args.path).text();
2212
- } catch {
2213
- return;
2214
- }
2215
- const stubbed = transformUseClient(source, {
2216
- path: args.path,
2217
- workspaceRoot: options.workspaceRoot,
2218
- onClientModule: options.onClientModule
2219
- });
2220
- if (stubbed === null)
2221
- return;
2222
- return { contents: stubbed, loader: loaderFor(args.path) };
2223
- });
2224
- }
2225
- };
2226
- }
2227
-
2228
- // pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
2229
- import path12 from "path";
2230
- class PagesEntrySourceGenerator {
2231
- #pageEntries;
2232
- #asyncDefaults = new Map;
2233
- #detect;
2234
- constructor(pageEntries, { isAsyncDefault } = {}) {
2235
- this.#pageEntries = pageEntries;
2236
- this.#detect = isAsyncDefault ?? ((moduleAbsPath) => AsyncDefaultExportDetector.detect(moduleAbsPath));
2237
- }
2238
- static generate(pageEntries) {
2239
- return new PagesEntrySourceGenerator(pageEntries).generate();
2240
- }
2241
- generate() {
2242
- const lines = this.#pageEntries.map(({ key, moduleAbsPath }) => {
2243
- const specifier = PagesEntrySourceGenerator.#toImportSpecifier(moduleAbsPath);
2244
- return ` ${JSON.stringify(key)}: () => import(${JSON.stringify(specifier)}),`;
2245
- });
2246
- return `export const pages = {
2247
- ${lines.join(`
2248
- `)}
2249
- };
2250
- `;
2251
- }
2252
- static async generateStatic(pageEntries, { fromDir } = {}) {
2253
- return await new PagesEntrySourceGenerator(pageEntries).generateStatic({ fromDir });
2254
- }
2255
- async generateStatic({ fromDir } = {}) {
2256
- const imports = this.#pageEntries.map(({ moduleAbsPath }, index) => {
2257
- const specifier = fromDir ? PagesEntrySourceGenerator.#toRelativeSpecifier(fromDir, moduleAbsPath) : PagesEntrySourceGenerator.#toImportSpecifier(moduleAbsPath);
2258
- return `import * as page${index} from ${JSON.stringify(specifier)};`;
2259
- });
2260
- const entries = await Promise.all(this.#pageEntries.map(async ({ key, moduleAbsPath }, index) => {
2261
- const isAsyncDefault = await this.#isAsyncDefault(moduleAbsPath);
2262
- return ` ${JSON.stringify(key)}: { loader: async () => page${index}, isAsyncDefault: ${isAsyncDefault} },`;
2263
- }));
2264
- return `${imports.join(`
2265
- `)}
2266
- export const pages = {
2267
- ${entries.join(`
2268
- `)}
2269
- };
2270
- `;
2271
- }
2272
- async generateHotReplace({
2273
- fromDir,
2274
- ownerId,
2275
- moduleIds
2276
- }) {
2277
- const entries = await Promise.all(this.#pageEntries.map(async ({ key, moduleAbsPath }) => {
2278
- const specifier = PagesEntrySourceGenerator.#toRelativeSpecifier(fromDir, moduleAbsPath);
2279
- const isAsyncDefault = await this.#isAsyncDefault(moduleAbsPath);
2280
- return ` ${JSON.stringify(key)}: { loader: async () => require(${JSON.stringify(specifier)}), isAsyncDefault: ${isAsyncDefault} },`;
2281
- }));
2282
- return `__akan.accept(${JSON.stringify(ownerId)}, ${JSON.stringify(moduleIds)}, async () => {
2283
- const replaced = await akanWebkit.replacePages({
2284
- ${entries.join(`
2285
- `)}
2286
- });
2287
- if (!replaced) throw new Error("the route table no longer matches the pages it was built from");
2288
- });
2289
- `;
2290
- }
2291
- #isAsyncDefault(moduleAbsPath) {
2292
- const known = this.#asyncDefaults.get(moduleAbsPath);
2293
- if (known)
2294
- return known;
2295
- const detected = this.#detect(moduleAbsPath);
2296
- this.#asyncDefaults.set(moduleAbsPath, detected);
2297
- return detected;
2298
- }
2299
- static #toImportSpecifier(moduleAbsPath) {
2300
- return path12.resolve(moduleAbsPath).split(path12.sep).join("/");
2301
- }
2302
- static #toRelativeSpecifier(fromDir, moduleAbsPath) {
2303
- const relative = path12.relative(fromDir, path12.resolve(moduleAbsPath)).split(path12.sep).join("/");
2304
- return relative.startsWith(".") ? relative : `./${relative}`;
2305
- }
2306
- }
2307
-
2308
- // pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
2309
- var VIRTUAL_PAGES_ENTRY = "akan-pages-entry";
2310
-
2311
- class PagesBundleBuilder {
2312
- #app;
2313
- #command;
2314
- #pageEntries;
2315
- #started = Date.now();
2316
- #serverEnv;
2317
- constructor(app, command = "start", pageEntries, serverEnv) {
2318
- this.#app = app;
2319
- this.#command = command;
2320
- this.#pageEntries = pageEntries;
2321
- this.#serverEnv = serverEnv;
2322
- }
2323
- async build() {
2324
- const akanConfig = await this.#app.getConfig();
2325
- const resolvedEntries = this.#pageEntries ?? await resolveSsrPageEntriesForApp(this.#app, await this.#app.getPageKeys());
2326
- const entrySource = PagesEntrySourceGenerator.generate(resolvedEntries);
2327
- const workspaceRoot = this.#app.workspace.workspaceRoot;
2328
- const dev = this.#command === "start";
2329
- const clientExports = {};
2330
- const onClientModule = dev ? (file, exports) => {
2331
- clientExports[CsrDevPaths.realpath(file)] = exports;
2332
- } : undefined;
2333
- const result = await Bun.build({
2334
- entrypoints: [VIRTUAL_PAGES_ENTRY],
2335
- outdir: `${this.#artifactDir}/server`,
2336
- target: "bun",
2337
- format: "esm",
2338
- splitting: this.#splitting,
2339
- minify: this.#command === "build",
2340
- naming: {
2341
- entry: "pages-[hash].[ext]",
2342
- chunk: "chunks/[name]-[hash].[ext]",
2343
- asset: "assets/[name]-[hash].[ext]"
2344
- },
2345
- define: bundleDefine(this.#app, this.#command, "ssr"),
2346
- metafile: dev,
2347
- plugins: [
2348
- ...this.#serverEnv ? [this.#serverEnv] : [],
2349
- PagesBundleBuilder.createPagesEntryPlugin(entrySource),
2350
- PagesBundleBuilder.createCssStubPlugin(),
2351
- PagesBundleBuilder.createServerUseClientFetchPlugin(),
2352
- await createExternalizeFrameworkPlugin({ app: this.#app, extra: akanConfig.externalLibs }),
2353
- akanConfig.barrelImports.length > 0 ? await createBarrelImportsPlugin(this.#app, {
2354
- pipeAfter: (source, args) => transformUseClient(source, {
2355
- path: args.path,
2356
- workspaceRoot,
2357
- onClientModule
2358
- })
2359
- }) : createUseClientBundlePlugin({ workspaceRoot, onClientModule })
2360
- ]
2361
- });
2362
- if (!result.success)
2363
- throw new AggregateError(result.logs, "[PagesBundleBuilder] Bun.build failed");
2364
- const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
2365
- if (!entryArtifact)
2366
- throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
2367
- const bundlePath = path13.resolve(entryArtifact.path);
2368
- const buildId = Date.now();
2369
- if (dev && result.metafile)
2370
- await ServerGraphFile.write(this.#artifactDir, this.#serverGraph(result.metafile, clientExports));
2371
- const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
2372
- const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
2373
- this.#app.verbose(`[PagesBundleBuilder] ${path13.basename(bundlePath)} emitted in ${Date.now() - this.#started}ms splitting=${this.#splitting} entry=${entryArtifact.size} bytes outputs=${result.outputs.length} chunks=${chunkCount} total=${outputBytes} bytes`);
2374
- return {
2375
- bundlePath,
2376
- buildId,
2377
- splitting: this.#splitting,
2378
- entryBytes: entryArtifact.size,
2379
- outputBytes,
2380
- outputCount: result.outputs.length,
2381
- chunkCount
2382
- };
2383
- }
2384
- #serverGraph(metafile, clientExports) {
2385
- const inputs = Object.keys(metafile.inputs).filter((input) => !input.includes("node_modules")).map((input) => path13.resolve(input)).filter((input) => fs5.existsSync(input)).map((input) => CsrDevPaths.realpath(input));
2386
- return { inputs, clientExports };
2387
- }
2388
- get #artifactDir() {
2389
- return `${this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath}/.akan/artifact`;
2390
- }
2391
- get #splitting() {
2392
- return process.env.AKAN_SERVER_PAGES_SPLITTING === "1";
2393
- }
2394
- static createPagesEntryPlugin(source) {
2395
- return {
2396
- name: "akan-pages-entry",
2397
- setup(build) {
2398
- build.onResolve({ filter: /^akan-pages-entry$/ }, () => ({
2399
- path: VIRTUAL_PAGES_ENTRY,
2400
- namespace: "akan-virtual"
2401
- }));
2402
- build.onLoad({ filter: /^akan-pages-entry$/, namespace: "akan-virtual" }, () => ({
2403
- contents: source,
2404
- loader: "tsx"
2405
- }));
2406
- }
2407
- };
2408
- }
2409
- static createCssStubPlugin() {
2410
- return {
2411
- name: "akan-css-stub",
2412
- setup(build) {
2413
- build.onLoad({ filter: /\.css$/ }, () => ({
2414
- contents: "",
2415
- loader: "js"
2416
- }));
2417
- }
2418
- };
2419
- }
2420
- static createServerUseClientFetchPlugin() {
2421
- return {
2422
- name: "akan-server-use-client-fetch",
2423
- setup(build) {
2424
- build.onLoad({ filter: /[/\\]lib[/\\]useClient\.(ts|tsx|js|jsx)$/ }, async (args) => {
2425
- const source = await Bun.file(args.path).text();
2426
- const transformed = PagesBundleBuilder.transformServerUseClientFetchSource(source);
2427
- if (transformed === source)
2428
- return;
2429
- return { contents: transformed, loader: loaderFor(args.path) };
2430
- });
2431
- }
2432
- };
2433
- }
2434
- static transformServerUseClientFetchSource(source) {
2435
- if (!source.includes(`with { type: "macro" }`) || !source.includes("FetchClient.build"))
2436
- return source;
2437
- return source.replace(/import\s+\{\s*getSerializedSignal\s*\}\s+from\s+["']\.\/sig["']\s+with\s+\{\s*type\s*:\s*["']macro["']\s*\};/, `import { fetch as serverFetch } from "./sig";`).replace(/const\s+fetchProto\s*=\s*FetchClient\.build<[^;]+;/, "const fetchProto = FetchClient.build<typeof signal>(cnst, serverFetch.serializedSignal, { Err: pageProto.Err, base: serverFetch });");
2438
- }
2439
- }
2440
-
2441
1364
  // pkgs/@akanjs/devkit/frontendBuild/csrDevPatcher.ts
2442
- import fs7 from "fs";
2443
- import path15 from "path";
1365
+ import fs4 from "fs";
1366
+ import path7 from "path";
2444
1367
  import { appGenerationOf, CSR_DEV_MANIFEST_FILE } from "akanjs/server/hmr/csrDevManifest";
2445
1368
 
2446
1369
  // pkgs/@akanjs/devkit/frontendBuild/csrDevResolver.ts
2447
- import fs6 from "fs";
2448
- import path14 from "path";
1370
+ import fs3 from "fs";
1371
+ import path6 from "path";
2449
1372
  class CsrDevResolver {
2450
1373
  static inline = "inline";
2451
1374
  #paths;
@@ -2527,7 +1450,7 @@ class CsrDevResolver {
2527
1450
  }
2528
1451
  #record(inputs, only) {
2529
1452
  for (const [input, { imports }] of Object.entries(inputs)) {
2530
- const importer = CsrDevPaths.realpath(path14.resolve(input));
1453
+ const importer = CsrDevPaths.realpath(path6.resolve(input));
2531
1454
  if (only && !only.has(importer))
2532
1455
  continue;
2533
1456
  if (imports.every((record) => record.original))
@@ -2540,8 +1463,8 @@ class CsrDevResolver {
2540
1463
  this.#remember(importer, record.original, `${CsrDevPaths.stubPrefix}${record.original}`);
2541
1464
  continue;
2542
1465
  }
2543
- const target = path14.resolve(record.path);
2544
- if (!fs6.existsSync(target))
1466
+ const target = path6.resolve(record.path);
1467
+ if (!fs3.existsSync(target))
2545
1468
  continue;
2546
1469
  this.#remember(importer, record.original, CsrDevPaths.realpath(target));
2547
1470
  this.#runtimeResolved.get(importer)?.delete(record.original);
@@ -2568,13 +1491,13 @@ class CsrDevResolver {
2568
1491
  #stillAnswers(importer, specifier, known, kind) {
2569
1492
  if (CsrDevPaths.isStub(known))
2570
1493
  return true;
2571
- if (!fs6.existsSync(known))
1494
+ if (!fs3.existsSync(known))
2572
1495
  return false;
2573
1496
  if (!specifier.startsWith(".") || CsrDevPaths.isVendorFile(importer))
2574
1497
  return true;
2575
- if (this.#hasBrowserMap(path14.dirname(importer)))
1498
+ if (this.#hasBrowserMap(path6.dirname(importer)))
2576
1499
  return true;
2577
- const onDisk = CsrDevPaths.resolveRelative(path14.dirname(importer), specifier, kind);
1500
+ const onDisk = CsrDevPaths.resolveRelative(path6.dirname(importer), specifier, kind);
2578
1501
  return onDisk !== null && CsrDevPaths.realpath(onDisk) === known;
2579
1502
  }
2580
1503
  isRegistryModule(file) {
@@ -2589,12 +1512,12 @@ class CsrDevResolver {
2589
1512
  });
2590
1513
  }
2591
1514
  #disabledInBrowser(importer, specifier, kind) {
2592
- const map = this.#browserMapOf(path14.dirname(importer));
1515
+ const map = this.#browserMapOf(path6.dirname(importer));
2593
1516
  if (!map || map.offFiles.size === 0 && map.offNames.size === 0)
2594
1517
  return null;
2595
- if (!specifier.startsWith(".") && !path14.isAbsolute(specifier))
1518
+ if (!specifier.startsWith(".") && !path6.isAbsolute(specifier))
2596
1519
  return map.offNames.has(specifier) ? `${CsrDevPaths.emptyStubPrefix}${specifier}` : null;
2597
- const target = CsrDevPaths.resolveRelative(path14.dirname(importer), specifier, kind);
1520
+ const target = CsrDevPaths.resolveRelative(path6.dirname(importer), specifier, kind);
2598
1521
  return target && map.offFiles.has(CsrDevPaths.realpath(target)) ? `${CsrDevPaths.emptyStubPrefix}${this.#paths.idOf(target)}` : null;
2599
1522
  }
2600
1523
  #hasBrowserMap(dir) {
@@ -2604,12 +1527,12 @@ class CsrDevResolver {
2604
1527
  const cached = this.#browserMaps.get(dir);
2605
1528
  if (cached !== undefined)
2606
1529
  return cached;
2607
- const pkgFile = path14.join(dir, "package.json");
2608
- const parent = path14.dirname(dir);
1530
+ const pkgFile = path6.join(dir, "package.json");
1531
+ const parent = path6.dirname(dir);
2609
1532
  let map = null;
2610
- if (fs6.existsSync(pkgFile)) {
1533
+ if (fs3.existsSync(pkgFile)) {
2611
1534
  try {
2612
- const browser = JSON.parse(fs6.readFileSync(pkgFile, "utf8")).browser;
1535
+ const browser = JSON.parse(fs3.readFileSync(pkgFile, "utf8")).browser;
2613
1536
  if (typeof browser === "object" && browser !== null) {
2614
1537
  const off = Object.entries(browser).filter(([, target]) => target === false).map(([key]) => key);
2615
1538
  const files = off.filter((key) => key.startsWith(".")).map((key) => CsrDevPaths.resolveRelative(dir, key)).filter((file) => !!file);
@@ -2634,16 +1557,16 @@ class CsrDevResolver {
2634
1557
  serialize() {
2635
1558
  return Object.fromEntries([...this.#resolution].map(([importer, bySpecifier]) => [
2636
1559
  this.#paths.idOf(importer),
2637
- Object.fromEntries([...bySpecifier].filter(([, target]) => CsrDevPaths.isStub(target) || fs6.existsSync(target)).map(([specifier, target]) => [specifier, CsrDevPaths.isStub(target) ? target : this.#paths.idOf(target)]))
1560
+ Object.fromEntries([...bySpecifier].filter(([, target]) => CsrDevPaths.isStub(target) || fs3.existsSync(target)).map(([specifier, target]) => [specifier, CsrDevPaths.isStub(target) ? target : this.#paths.idOf(target)]))
2638
1561
  ]));
2639
1562
  }
2640
1563
  #resolveUnknown(importer, specifier, kind) {
2641
1564
  if (specifier.startsWith("node:"))
2642
1565
  return `${CsrDevPaths.stubPrefix}${specifier}`;
2643
- const relative = specifier.startsWith(".") || path14.isAbsolute(specifier);
1566
+ const relative = specifier.startsWith(".") || path6.isAbsolute(specifier);
2644
1567
  const cannotResolve = () => new Error(`[csr-dev] cannot resolve "${specifier}" from ${this.#paths.idOf(importer)}`);
2645
1568
  if (relative) {
2646
- const onDisk = CsrDevPaths.resolveRelative(path14.dirname(importer), specifier, kind) ?? CsrDevResolver.#onDisk(CsrDevPaths.tryResolve(specifier, path14.dirname(importer)));
1569
+ const onDisk = CsrDevPaths.resolveRelative(path6.dirname(importer), specifier, kind) ?? CsrDevResolver.#onDisk(CsrDevPaths.tryResolve(specifier, path6.dirname(importer)));
2647
1570
  if (!onDisk)
2648
1571
  throw cannotResolve();
2649
1572
  return CsrDevPaths.realpath(onDisk);
@@ -2651,9 +1574,9 @@ class CsrDevResolver {
2651
1574
  const sibling = this.#resolvedBySibling(importer, specifier);
2652
1575
  if (sibling)
2653
1576
  return sibling;
2654
- const resolved = CsrDevPaths.tryResolve(specifier, path14.dirname(importer));
2655
- const moved = resolved !== null && path14.isAbsolute(resolved) && !fs6.existsSync(resolved);
2656
- const installed = resolved === null && CsrDevPaths.installedSince(specifier, path14.dirname(importer), this.#startedAt);
1577
+ const resolved = CsrDevPaths.tryResolve(specifier, path6.dirname(importer));
1578
+ const moved = resolved !== null && path6.isAbsolute(resolved) && !fs3.existsSync(resolved);
1579
+ const installed = resolved === null && CsrDevPaths.installedSince(specifier, path6.dirname(importer), this.#startedAt);
2657
1580
  if (!this.#prepassDone || moved) {
2658
1581
  if (resolved === null && !installed && !CsrDevPaths.isVendorFile(importer))
2659
1582
  throw cannotResolve();
@@ -2664,14 +1587,14 @@ class CsrDevResolver {
2664
1587
  return null;
2665
1588
  throw cannotResolve();
2666
1589
  }
2667
- if (!path14.isAbsolute(resolved))
1590
+ if (!path6.isAbsolute(resolved))
2668
1591
  return `${CsrDevPaths.stubPrefix}${specifier}`;
2669
1592
  this.#fallbacks.add(specifier);
2670
1593
  this.#runtimeResolved.set(importer, (this.#runtimeResolved.get(importer) ?? new Set).add(specifier));
2671
1594
  return CsrDevPaths.realpath(resolved);
2672
1595
  }
2673
1596
  static #onDisk(resolved) {
2674
- return resolved && path14.isAbsolute(resolved) && fs6.existsSync(resolved) ? resolved : null;
1597
+ return resolved && path6.isAbsolute(resolved) && fs3.existsSync(resolved) ? resolved : null;
2675
1598
  }
2676
1599
  #resolvedBySibling(importer, specifier) {
2677
1600
  const scope = CsrDevResolver.#packageScopeOf(importer);
@@ -2679,7 +1602,7 @@ class CsrDevResolver {
2679
1602
  const target = bySpecifier.get(specifier);
2680
1603
  if (!target || other === importer || this.#runtimeResolved.get(other)?.has(specifier))
2681
1604
  continue;
2682
- if (!CsrDevPaths.isStub(target) && !fs6.existsSync(target))
1605
+ if (!CsrDevPaths.isStub(target) && !fs3.existsSync(target))
2683
1606
  continue;
2684
1607
  if (CsrDevResolver.#packageScopeOf(other) === scope)
2685
1608
  return target;
@@ -2691,7 +1614,7 @@ class CsrDevResolver {
2691
1614
  this.#resolution.set(importer, byImporter.set(specifier, target));
2692
1615
  }
2693
1616
  #isInlineSpecifier(specifier) {
2694
- if (specifier.startsWith(".") || path14.isAbsolute(specifier) || specifier.startsWith("node:"))
1617
+ if (specifier.startsWith(".") || path6.isAbsolute(specifier) || specifier.startsWith("node:"))
2695
1618
  return false;
2696
1619
  return this.#context.optimizeImports.some((pattern) => {
2697
1620
  const base = CsrDevResolver.#patternBase(pattern);
@@ -2702,20 +1625,20 @@ class CsrDevResolver {
2702
1625
  return pattern.endsWith("/*") ? pattern.slice(0, -2) : pattern;
2703
1626
  }
2704
1627
  static #packageNameOf(file) {
2705
- const marker = `${path14.sep}node_modules${path14.sep}`;
1628
+ const marker = `${path6.sep}node_modules${path6.sep}`;
2706
1629
  const index = file.lastIndexOf(marker);
2707
1630
  if (index < 0)
2708
1631
  return null;
2709
- const [scope, name] = file.slice(index + marker.length).split(path14.sep);
1632
+ const [scope, name] = file.slice(index + marker.length).split(path6.sep);
2710
1633
  return (scope?.startsWith("@") ? `${scope}/${name}` : scope) || null;
2711
1634
  }
2712
1635
  static #packageScopeOf(file) {
2713
- const marker = `${path14.sep}node_modules${path14.sep}`;
1636
+ const marker = `${path6.sep}node_modules${path6.sep}`;
2714
1637
  const index = file.lastIndexOf(marker);
2715
1638
  if (index < 0)
2716
1639
  return "";
2717
- const [scope, name] = file.slice(index + marker.length).split(path14.sep);
2718
- return file.slice(0, index + marker.length) + (scope?.startsWith("@") ? `${scope}${path14.sep}${name}` : scope);
1640
+ const [scope, name] = file.slice(index + marker.length).split(path6.sep);
1641
+ return file.slice(0, index + marker.length) + (scope?.startsWith("@") ? `${scope}${path6.sep}${name}` : scope);
2719
1642
  }
2720
1643
  }
2721
1644
 
@@ -2753,11 +1676,11 @@ class CsrDevPatcher {
2753
1676
  return this.#handBack("the dev bundle config changed", generation, context);
2754
1677
  const metadataFile = changedFiles.find((file) => this.#bundler.isMetadataFile(file));
2755
1678
  if (metadataFile)
2756
- return this.#handBack(`${path15.basename(metadataFile)} changed`, generation, context);
1679
+ return this.#handBack(`${path7.basename(metadataFile)} changed`, generation, context);
2757
1680
  if (!resident && state.graph.metadata !== await this.#bundler.metadataFingerprint())
2758
1681
  return this.#handBack("signal or dictionary metadata changed since the registry was built", generation, context);
2759
1682
  this.#state = this.#resident ? state : null;
2760
- const healable = appGenerationOf(state.manifest) < state.manifest.generation && this.#withoutFactory(state, (file) => fs7.existsSync(file)).length === 0;
1683
+ const healable = appGenerationOf(state.manifest) < state.manifest.generation && this.#withoutFactory(state, (file) => fs4.existsSync(file)).length === 0;
2761
1684
  if (healable)
2762
1685
  state.manifest = await this.#bundler.writer.healApp(state.graph, state.manifest, await this.#code(state));
2763
1686
  return await this.#patch(context, state, changedFiles, generation, {
@@ -2779,7 +1702,7 @@ class CsrDevPatcher {
2779
1702
  changed.add(id);
2780
1703
  for (const file of entries.changed)
2781
1704
  changed.add(paths.idOf(file));
2782
- const rootFiles = [...Object.values(entries.files), ...roots.filter((file) => fs7.existsSync(file))];
1705
+ const rootFiles = [...Object.values(entries.files), ...roots.filter((file) => fs4.existsSync(file))];
2783
1706
  for (const file of rootFiles) {
2784
1707
  const id = paths.idOf(file);
2785
1708
  if (!graph.modules[id] && !(onlyRoots && await this.#parked(graph, id)))
@@ -2857,7 +1780,7 @@ class CsrDevPatcher {
2857
1780
  }
2858
1781
  const changedIds = compiled.filter((module) => !module.vendor).map((module) => module.id);
2859
1782
  const constantId = changedIds.find((id) => id.endsWith(".constant.ts"));
2860
- const reason = vendorJoined ? "an npm module joined the graph" : routesMoved ? "the route table changed" : constantId ? `${path15.basename(constantId)} changed` : undefined;
1783
+ const reason = vendorJoined ? "an npm module joined the graph" : routesMoved ? "the route table changed" : constantId ? `${path7.basename(constantId)} changed` : undefined;
2861
1784
  if (compiled.length === 0 && !reason) {
2862
1785
  await writer.writeJson("graph.json", graph);
2863
1786
  await writer.forgetModules(forgotten);
@@ -2971,9 +1894,9 @@ class CsrDevPatcher {
2971
1894
  const messages = error instanceof AggregateError ? error.errors : [];
2972
1895
  const named = messages.flatMap((message) => {
2973
1896
  const text = String(message.message ?? "");
2974
- const bases = [process.cwd(), ...failing.map((file) => path15.dirname(file))];
1897
+ const bases = [process.cwd(), ...failing.map((file) => path7.dirname(file))];
2975
1898
  return [...text.matchAll(/"([^"\n]+)"/g)].flatMap(([, quoted = ""]) => {
2976
- const found = bases.map((base) => path15.resolve(base, quoted)).find((file) => CsrDevPaths.isScript(file) && fs7.existsSync(file));
1899
+ const found = bases.map((base) => path7.resolve(base, quoted)).find((file) => CsrDevPaths.isScript(file) && fs4.existsSync(file));
2977
1900
  return found ? [CsrDevPaths.realpath(found)] : [];
2978
1901
  });
2979
1902
  });
@@ -2981,7 +1904,7 @@ class CsrDevPatcher {
2981
1904
  }
2982
1905
  static #failingFiles(error) {
2983
1906
  const messages = error instanceof AggregateError ? error.errors : [];
2984
- return messages.map((message) => message.position?.file).filter((file) => typeof file === "string" && path15.isAbsolute(file)).map((file) => CsrDevPaths.realpath(file));
1907
+ return messages.map((message) => message.position?.file).filter((file) => typeof file === "string" && path7.isAbsolute(file)).map((file) => CsrDevPaths.realpath(file));
2985
1908
  }
2986
1909
  async#carriedRoots(graph, changed, present) {
2987
1910
  const { paths } = this.#bundler;
@@ -3024,8 +1947,8 @@ class CsrDevPatcher {
3024
1947
  return Object.entries(graph.modules).filter(([id, module]) => !module.vendor && !hasFactory(id) && present(paths.fileOf(id))).map(([id]) => id);
3025
1948
  }
3026
1949
  static #presence(changedFiles) {
3027
- const caseMoved = changedFiles.some((file) => fs7.existsSync(file) && !CsrDevPaths.isNamed(file));
3028
- return caseMoved ? (file) => CsrDevPaths.isNamed(file) : (file) => fs7.existsSync(file);
1950
+ const caseMoved = changedFiles.some((file) => fs4.existsSync(file) && !CsrDevPaths.isNamed(file));
1951
+ return caseMoved ? (file) => CsrDevPaths.isNamed(file) : (file) => fs4.existsSync(file);
3029
1952
  }
3030
1953
  #handBack(reason, generation, context, { first = false } = {}) {
3031
1954
  this.#state = null;
@@ -3080,17 +2003,17 @@ class CsrDevPatcher {
3080
2003
  }
3081
2004
  #shadowedImporters(graph, changedFiles) {
3082
2005
  const { paths } = this.#bundler;
3083
- const bases = new Set(changedFiles.map((file) => CsrDevPaths.realpath(file)).filter((file) => !graph.modules[paths.idOf(file)] && CsrDevPaths.isScript(file) && fs7.existsSync(file)).flatMap((file) => {
3084
- const stem = file.slice(0, file.length - path15.extname(file).length);
3085
- return path15.basename(stem) === "index" ? [stem, path15.dirname(stem)] : [stem];
2006
+ const bases = new Set(changedFiles.map((file) => CsrDevPaths.realpath(file)).filter((file) => !graph.modules[paths.idOf(file)] && CsrDevPaths.isScript(file) && fs4.existsSync(file)).flatMap((file) => {
2007
+ const stem = file.slice(0, file.length - path7.extname(file).length);
2008
+ return path7.basename(stem) === "index" ? [stem, path7.dirname(stem)] : [stem];
3086
2009
  }));
3087
2010
  if (bases.size === 0)
3088
2011
  return [];
3089
2012
  return Object.entries(graph.resolution).filter(([importer, bySpecifier]) => {
3090
2013
  if (!graph.modules[importer] || graph.modules[importer]?.vendor)
3091
2014
  return false;
3092
- const dir = path15.dirname(paths.fileOf(importer));
3093
- return Object.keys(bySpecifier).some((specifier) => specifier.startsWith(".") && bases.has(path15.resolve(dir, specifier)));
2015
+ const dir = path7.dirname(paths.fileOf(importer));
2016
+ return Object.keys(bySpecifier).some((specifier) => specifier.startsWith(".") && bases.has(path7.resolve(dir, specifier)));
3094
2017
  }).map(([importer]) => importer);
3095
2018
  }
3096
2019
  #forgetDeletedModules({ graph, code }, present) {
@@ -3106,39 +2029,18 @@ class CsrDevPatcher {
3106
2029
 
3107
2030
  // pkgs/@akanjs/devkit/frontendBuild/csrDevBundler.ts
3108
2031
  import { mkdir as mkdir3 } from "fs/promises";
3109
- import path21 from "path";
2032
+ import path12 from "path";
3110
2033
  import { CSR_DEV_DIRNAME, CSR_DEV_ROUTE_PREFIX } from "akanjs/server/hmr/csrDevManifest";
3111
2034
 
3112
- // pkgs/@akanjs/devkit/frontendBuild/csrEntryFiles.ts
3113
- import path16 from "path";
3114
-
3115
- class CsrEntryFiles {
3116
- static entryFilename(basePath) {
3117
- return `${basePath || "index"}.csr.tsx`;
3118
- }
3119
- static pageEntriesForBasePath(pageEntries, basePath, basePaths) {
3120
- return pageEntries.filter((entry) => {
3121
- const entryBasePath = CsrEntryFiles.basePathOfPageKey(entry.key, basePaths);
3122
- return entryBasePath === null || entryBasePath === basePath;
3123
- });
3124
- }
3125
- static basePathOfPageKey(pageKey, basePaths) {
3126
- const normalized = pageKey.split(path16.sep).join("/").replace(/^\.\//, "");
3127
- const segments = normalized.split("/");
3128
- const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
3129
- return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
3130
- }
3131
- }
3132
-
3133
2035
  // pkgs/@akanjs/devkit/frontendBuild/devRegistryBundler.ts
3134
- import fs10 from "fs";
3135
- import path20 from "path";
2036
+ import fs7 from "fs";
2037
+ import path11 from "path";
3136
2038
  import { isAkanRuntimeMetadataFile } from "akanjs/server/hmr/runtimeMetadataFile";
3137
2039
 
3138
2040
  // pkgs/@akanjs/devkit/frontendBuild/csrDevArtifactWriter.ts
3139
- import fs8 from "fs";
2041
+ import fs5 from "fs";
3140
2042
  import { mkdir as mkdir2, readdir as readdir2, rm } from "fs/promises";
3141
- import path17 from "path";
2043
+ import path8 from "path";
3142
2044
  import {
3143
2045
  appGenerationOf as appGenerationOf2,
3144
2046
  CSR_DEV_APP_FILE,
@@ -3159,19 +2061,19 @@ class CsrDevArtifactWriter {
3159
2061
  this.#library = library;
3160
2062
  }
3161
2063
  async markBuilding() {
3162
- await Bun.write(path17.join(this.#outDir, CsrDevArtifactWriter.#buildingMarker), String(process.pid));
2064
+ await Bun.write(path8.join(this.#outDir, CsrDevArtifactWriter.#buildingMarker), String(process.pid));
3163
2065
  }
3164
2066
  async clearBuilding() {
3165
- await CsrDevArtifactWriter.#remove(path17.join(this.#outDir, CsrDevArtifactWriter.#buildingMarker));
2067
+ await CsrDevArtifactWriter.#remove(path8.join(this.#outDir, CsrDevArtifactWriter.#buildingMarker));
3166
2068
  }
3167
2069
  async isBuilding() {
3168
- return await Bun.file(path17.join(this.#outDir, CsrDevArtifactWriter.#buildingMarker)).exists();
2070
+ return await Bun.file(path8.join(this.#outDir, CsrDevArtifactWriter.#buildingMarker)).exists();
3169
2071
  }
3170
2072
  async forgetPatch(generation) {
3171
- await Promise.all([`patch-${generation}.js`, `patch-${generation}.js.layout.json`].map((name) => CsrDevArtifactWriter.#remove(path17.join(this.#outDir, name))));
2073
+ await Promise.all([`patch-${generation}.js`, `patch-${generation}.js.layout.json`].map((name) => CsrDevArtifactWriter.#remove(path8.join(this.#outDir, name))));
3172
2074
  }
3173
2075
  async readJson(name) {
3174
- const file = Bun.file(path17.join(this.#outDir, name));
2076
+ const file = Bun.file(path8.join(this.#outDir, name));
3175
2077
  if (!await file.exists())
3176
2078
  return null;
3177
2079
  return await file.json().catch(() => null);
@@ -3180,7 +2082,7 @@ class CsrDevArtifactWriter {
3180
2082
  await this.#writeAtomic(name, JSON.stringify(value));
3181
2083
  }
3182
2084
  async writeModules(compiled) {
3183
- await mkdir2(path17.join(this.#outDir, "modules"), { recursive: true });
2085
+ await mkdir2(path8.join(this.#outDir, "modules"), { recursive: true });
3184
2086
  const helpers = new Map(compiled.flatMap((module) => module.helpers ? [[module.helpers.hash, module.helpers]] : []));
3185
2087
  await Promise.all([
3186
2088
  ...compiled.flatMap((module) => [
@@ -3200,7 +2102,7 @@ class CsrDevArtifactWriter {
3200
2102
  return { modules: new Map(modules), helpers: new Map(helpers) };
3201
2103
  }
3202
2104
  hasModule(id) {
3203
- return fs8.existsSync(this.#modulePath(id, ".js"));
2105
+ return fs5.existsSync(this.#modulePath(id, ".js"));
3204
2106
  }
3205
2107
  async forgetModules(ids) {
3206
2108
  await Promise.all(ids.flatMap((id) => [
@@ -3277,8 +2179,8 @@ class CsrDevArtifactWriter {
3277
2179
  const patch = /^patch-(\d+)\.js(?:\.layout\.json)?$/.exec(name);
3278
2180
  return patch ? Number(patch[1]) <= generation - CSR_DEV_KEPT_PATCHES : false;
3279
2181
  });
3280
- const vendors = names.filter((name) => /^vendor-[\w-]+\.js$/.test(name) && name !== vendorFile).map((name) => ({ name, mtimeMs: CsrDevPaths.mtimeOf(path17.join(this.#outDir, name)) })).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(CsrDevArtifactWriter.#keptVendors - 1).map(({ name }) => name);
3281
- await Promise.all([...stale, ...vendors].map((name) => CsrDevArtifactWriter.#remove(path17.join(this.#outDir, name))));
2182
+ const vendors = names.filter((name) => /^vendor-[\w-]+\.js$/.test(name) && name !== vendorFile).map((name) => ({ name, mtimeMs: CsrDevPaths.mtimeOf(path8.join(this.#outDir, name)) })).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(CsrDevArtifactWriter.#keptVendors - 1).map(({ name }) => name);
2183
+ await Promise.all([...stale, ...vendors].map((name) => CsrDevArtifactWriter.#remove(path8.join(this.#outDir, name))));
3282
2184
  }
3283
2185
  async pruneAfterFullBuild(graph, vendorFile, { generation, assets }) {
3284
2186
  const kept = new Set(Object.keys(graph.modules).flatMap((id) => [this.#modulePath(id, ".js"), this.#modulePath(id, ".js.map")]));
@@ -3286,16 +2188,16 @@ class CsrDevArtifactWriter {
3286
2188
  if (module.helpers)
3287
2189
  kept.add(this.#helpersPath(module.helpers));
3288
2190
  for (const asset of assets)
3289
- kept.add(path17.resolve(asset));
3290
- const listed = async (dir) => (await readdir2(path17.join(this.#outDir, dir)).catch(() => [])).map((name) => path17.join(this.#outDir, dir, name));
2191
+ kept.add(path8.resolve(asset));
2192
+ const listed = async (dir) => (await readdir2(path8.join(this.#outDir, dir)).catch(() => [])).map((name) => path8.join(this.#outDir, dir, name));
3291
2193
  const stale = [
3292
2194
  ...(await listed("modules")).filter((file) => !kept.has(file)),
3293
2195
  ...(await listed("assets")).filter((file) => !kept.has(file)),
3294
2196
  ...(await listed(".")).filter((file) => {
3295
- const name = path17.basename(file);
2197
+ const name = path8.basename(file);
3296
2198
  return /^patch-\d+\.js(?:\.layout\.json)?$/.test(name) || name.endsWith(".tmp");
3297
2199
  }),
3298
- path17.join(this.#outDir, CSR_DEV_PATCHING_MARKER)
2200
+ path8.join(this.#outDir, CSR_DEV_PATCHING_MARKER)
3299
2201
  ];
3300
2202
  await Promise.all(stale.map((file) => CsrDevArtifactWriter.#remove(file)));
3301
2203
  await this.prune(vendorFile, generation);
@@ -3325,7 +2227,7 @@ class CsrDevArtifactWriter {
3325
2227
  await this.#writeAtomic(name, code);
3326
2228
  }
3327
2229
  async#writeAtomic(name, content) {
3328
- const target = path17.join(this.#outDir, name);
2230
+ const target = path8.join(this.#outDir, name);
3329
2231
  const temp = `${target}.${process.pid}.tmp`;
3330
2232
  await Bun.write(temp, content);
3331
2233
  await FileSys2.replace(temp, target);
@@ -3341,15 +2243,15 @@ class CsrDevArtifactWriter {
3341
2243
  await Bun.sleep(ms);
3342
2244
  }
3343
2245
  #modulePath(id, extension) {
3344
- return path17.join(this.#outDir, csrDevModuleFile(id, extension));
2246
+ return path8.join(this.#outDir, csrDevModuleFile(id, extension));
3345
2247
  }
3346
2248
  #helpersPath(hash) {
3347
- return path17.join(this.#outDir, "modules", `helpers-${hash}.js`);
2249
+ return path8.join(this.#outDir, "modules", `helpers-${hash}.js`);
3348
2250
  }
3349
2251
  }
3350
2252
 
3351
2253
  // pkgs/@akanjs/devkit/frontendBuild/csrDevModuleCompiler.ts
3352
- import path18 from "path";
2254
+ import path9 from "path";
3353
2255
 
3354
2256
  // pkgs/@akanjs/devkit/frontendBuild/csrDevFactoryCheck.ts
3355
2257
  class CsrDevFactoryCheck {
@@ -3499,7 +2401,7 @@ class CsrDevModuleCompiler {
3499
2401
  const tangled = [];
3500
2402
  for (const artifact of result.outputs) {
3501
2403
  if (artifact.kind === "asset") {
3502
- const assetPath = path18.join(this.#outDir, artifact.path);
2404
+ const assetPath = path9.join(this.#outDir, artifact.path);
3503
2405
  await Bun.write(assetPath, artifact);
3504
2406
  this.#assets.add(assetPath);
3505
2407
  continue;
@@ -3509,8 +2411,8 @@ class CsrDevModuleCompiler {
3509
2411
  const meta = outputs[artifact.path];
3510
2412
  if (!meta?.entryPoint)
3511
2413
  throw new Error(`[csr-dev] no entry point recorded for ${artifact.path}`);
3512
- const file = CsrDevPaths.realpath(path18.resolve(meta.entryPoint));
3513
- const inputs = Object.keys(meta.inputs).map((input) => CsrDevPaths.realpath(path18.resolve(input)));
2414
+ const file = CsrDevPaths.realpath(path9.resolve(meta.entryPoint));
2415
+ const inputs = Object.keys(meta.inputs).map((input) => CsrDevPaths.realpath(path9.resolve(input)));
3514
2416
  if (inputs.some((input) => input !== file && this.#resolver.isRegistryModule(input))) {
3515
2417
  tangled.push(file);
3516
2418
  continue;
@@ -3543,7 +2445,7 @@ class CsrDevModuleCompiler {
3543
2445
  const reasons = new Map;
3544
2446
  for (const message of error.errors) {
3545
2447
  const file = message.position?.file;
3546
- if (typeof file !== "string" || !path18.isAbsolute(file))
2448
+ if (typeof file !== "string" || !path9.isAbsolute(file))
3547
2449
  continue;
3548
2450
  const real = CsrDevPaths.realpath(file);
3549
2451
  const at = message.position?.line ? `:${message.position.line}` : "";
@@ -3642,7 +2544,7 @@ class CsrDevModuleCompiler {
3642
2544
  }
3643
2545
  #rebaseSourceMap(text) {
3644
2546
  const map = JSON.parse(text);
3645
- const files = map.sources.map((source) => path18.resolve(source));
2547
+ const files = map.sources.map((source) => path9.resolve(source));
3646
2548
  map.sources = files.map((file) => `/${this.#paths.idOf(file)}`);
3647
2549
  map.sourcesContent = files.map((file, index) => CsrDevPaths.isVendorFile(file) ? null : map.sourcesContent?.[index] ?? null);
3648
2550
  return JSON.stringify(map);
@@ -3706,8 +2608,8 @@ ${preamble}return { ${names.join(", ")} };
3706
2608
  }
3707
2609
 
3708
2610
  // pkgs/@akanjs/devkit/frontendBuild/registryMetadataFingerprint.ts
3709
- import fs9 from "fs";
3710
- import path19 from "path";
2611
+ import fs6 from "fs";
2612
+ import path10 from "path";
3711
2613
 
3712
2614
  class RegistryMetadataFingerprint {
3713
2615
  static #sources = new Bun.Glob("**/*.{signal,dictionary}.ts");
@@ -3715,16 +2617,16 @@ class RegistryMetadataFingerprint {
3715
2617
  static async of(roots, isMetadataFile) {
3716
2618
  const stamps = [];
3717
2619
  for (const root of new Set(roots)) {
3718
- const libDir = path19.join(root, "lib");
3719
- if (!fs9.existsSync(libDir))
2620
+ const libDir = path10.join(root, "lib");
2621
+ if (!fs6.existsSync(libDir))
3720
2622
  continue;
3721
- const files = RegistryMetadataFingerprint.#libFiles.map((name) => path19.join(libDir, name));
2623
+ const files = RegistryMetadataFingerprint.#libFiles.map((name) => path10.join(libDir, name));
3722
2624
  for await (const relative of RegistryMetadataFingerprint.#sources.scan({ cwd: libDir, onlyFiles: true }))
3723
- files.push(path19.join(libDir, relative));
2625
+ files.push(path10.join(libDir, relative));
3724
2626
  for (const file of files) {
3725
2627
  if (!isMetadataFile(file))
3726
2628
  continue;
3727
- const stat = fs9.statSync(file, { throwIfNoEntry: false });
2629
+ const stat = fs6.statSync(file, { throwIfNoEntry: false });
3728
2630
  if (stat)
3729
2631
  stamps.push(`${file}:${stat.mtimeMs}:${stat.size}`);
3730
2632
  }
@@ -3746,8 +2648,8 @@ class DevRegistryBundler {
3746
2648
  this.app = app;
3747
2649
  this.routePrefix = routePrefix;
3748
2650
  this.paths = new CsrDevPaths(app.workspace.workspaceRoot);
3749
- this.outDir = path20.join(app.cwdPath, ".akan/artifact", dirName);
3750
- this.entryDir = path20.join(app.cwdPath, ".akan/generated", dirName);
2651
+ this.outDir = path11.join(app.cwdPath, ".akan/artifact", dirName);
2652
+ this.entryDir = path11.join(app.cwdPath, ".akan/generated", dirName);
3751
2653
  this.writer = new CsrDevArtifactWriter(this.outDir, { routePrefix, library });
3752
2654
  }
3753
2655
  async update(changedFiles = [], options = {}) {
@@ -3785,10 +2687,10 @@ class DevRegistryBundler {
3785
2687
  return isAkanRuntimeMetadataFile(file);
3786
2688
  }
3787
2689
  async metadataFingerprint() {
3788
- const libsContainer = path20.resolve(this.app.workspace.workspaceRoot, "libs");
2690
+ const libsContainer = path11.resolve(this.app.workspace.workspaceRoot, "libs");
3789
2691
  const roots = await new WatchRootResolver(this.app).resolve();
3790
- const libRoots = roots.includes(libsContainer) ? fs10.readdirSync(libsContainer).map((name) => path20.join(libsContainer, name)) : roots.filter((root) => path20.dirname(root) === libsContainer);
3791
- return await RegistryMetadataFingerprint.of([path20.resolve(this.app.cwdPath), ...libRoots], (file) => this.isMetadataFile(file));
2692
+ const libRoots = roots.includes(libsContainer) ? fs7.readdirSync(libsContainer).map((name) => path11.join(libsContainer, name)) : roots.filter((root) => path11.dirname(root) === libsContainer);
2693
+ return await RegistryMetadataFingerprint.of([path11.resolve(this.app.cwdPath), ...libRoots], (file) => this.isMetadataFile(file));
3792
2694
  }
3793
2695
  async fullBuild(context, generation, reason) {
3794
2696
  const metadata = await this.metadataFingerprint();
@@ -3881,7 +2783,7 @@ class CsrDevBundler extends DevRegistryBundler {
3881
2783
  const files = {};
3882
2784
  const changed = [];
3883
2785
  for (const basePath of context.htmlBasePaths) {
3884
- const file = path21.join(this.entryDir, CsrEntryFiles.entryFilename(basePath));
2786
+ const file = path12.join(this.entryDir, CsrEntryFiles.entryFilename(basePath));
3885
2787
  const entryPages = CsrEntryFiles.pageEntriesForBasePath(context.pageEntries, basePath, context.basePaths);
3886
2788
  const generator = new PagesEntrySourceGenerator(entryPages, {
3887
2789
  isAsyncDefault: (moduleAbsPath) => this.#isAsyncDefault(moduleAbsPath)
@@ -3920,7 +2822,7 @@ ${hot}`;
3920
2822
  }
3921
2823
  #resolveRefreshRuntime() {
3922
2824
  const akanWebkit = CsrDevPaths.tryResolve("akanjs/webkit", this.app.cwdPath);
3923
- const bases = [this.app.cwdPath, this.paths.root, ...akanWebkit ? [path21.dirname(path21.dirname(akanWebkit))] : []];
2825
+ const bases = [this.app.cwdPath, this.paths.root, ...akanWebkit ? [path12.dirname(path12.dirname(akanWebkit))] : []];
3924
2826
  for (const base of bases) {
3925
2827
  const resolved = CsrDevPaths.tryResolve("react-refresh/runtime", base);
3926
2828
  if (resolved)
@@ -3931,7 +2833,7 @@ ${hot}`;
3931
2833
  }
3932
2834
 
3933
2835
  // pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
3934
- import path22 from "path";
2836
+ import path13 from "path";
3935
2837
  var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
3936
2838
  var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
3937
2839
  var CLIENT_SUFFIXES = [".Template.tsx", ".Unit.tsx", ".Util.tsx", ".View.tsx", ".Zone.tsx", ".store.ts"];
@@ -3942,11 +2844,11 @@ var RUNTIME_METADATA_BASENAMES = new Set(["dict.ts", "sig.ts", "useClient.ts", "
3942
2844
  class DevChangePlanner {
3943
2845
  #workspaceRoot;
3944
2846
  constructor({ workspaceRoot }) {
3945
- this.#workspaceRoot = path22.resolve(workspaceRoot);
2847
+ this.#workspaceRoot = path13.resolve(workspaceRoot);
3946
2848
  }
3947
2849
  plan({ generation, files, kinds, generatedFiles = [] }) {
3948
2850
  const fileList = uniqueResolved([...files, ...generatedFiles]);
3949
- const generatedSet = new Set(generatedFiles.map((file) => path22.resolve(file)));
2851
+ const generatedSet = new Set(generatedFiles.map((file) => path13.resolve(file)));
3950
2852
  const kindSet = new Set(kinds);
3951
2853
  const roles = new Set;
3952
2854
  const actions = new Set;
@@ -3963,13 +2865,13 @@ class DevChangePlanner {
3963
2865
  }
3964
2866
  for (const file of fileList) {
3965
2867
  const reasons = new Set;
3966
- const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(path22.resolve(file)), reasons });
2868
+ const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(path13.resolve(file)), reasons });
3967
2869
  for (const role of fileRoles)
3968
2870
  roles.add(role);
3969
2871
  if (reasons.has("runtime-metadata"))
3970
2872
  actions.add("restart-builder");
3971
2873
  if (reasons.size > 0)
3972
- reasonByFile[path22.resolve(file)] = [...reasons].sort();
2874
+ reasonByFile[path13.resolve(file)] = [...reasons].sort();
3973
2875
  }
3974
2876
  if (roles.has("barrel"))
3975
2877
  actions.add("sync-generated");
@@ -3990,12 +2892,12 @@ class DevChangePlanner {
3990
2892
  }
3991
2893
  #rolesForFile(file, { isGenerated, reasons }) {
3992
2894
  const roles = new Set;
3993
- const abs = path22.resolve(file);
3994
- const base = path22.basename(abs);
3995
- const ext = path22.extname(abs).toLowerCase();
2895
+ const abs = path13.resolve(file);
2896
+ const base = path13.basename(abs);
2897
+ const ext = path13.extname(abs).toLowerCase();
3996
2898
  const isSource = SOURCE_EXTS.has(ext);
3997
- const rel = path22.relative(this.#workspaceRoot, abs);
3998
- const parts = rel.split(path22.sep).filter(Boolean);
2899
+ const rel = path13.relative(this.#workspaceRoot, abs);
2900
+ const parts = rel.split(path13.sep).filter(Boolean);
3999
2901
  if (CONFIG_BASENAMES.has(base)) {
4000
2902
  roles.add("config");
4001
2903
  reasons.add("config-file");
@@ -4066,17 +2968,17 @@ class DevChangePlanner {
4066
2968
  return true;
4067
2969
  }
4068
2970
  #isWorkspaceSource(rel) {
4069
- if (!rel || rel.startsWith("..") || path22.isAbsolute(rel))
2971
+ if (!rel || rel.startsWith("..") || path13.isAbsolute(rel))
4070
2972
  return false;
4071
- const [scope] = rel.split(path22.sep);
2973
+ const [scope] = rel.split(path13.sep);
4072
2974
  return scope === "apps" || scope === "libs" || scope === "pkgs";
4073
2975
  }
4074
2976
  }
4075
- var uniqueResolved = (files) => [...new Set(files.map((file) => path22.resolve(file)))].sort();
2977
+ var uniqueResolved = (files) => [...new Set(files.map((file) => path13.resolve(file)))].sort();
4076
2978
 
4077
2979
  // pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
4078
2980
  import { mkdir as mkdir4, readdir as readdir3, readFile as readFile2, rm as rm2, stat as stat2 } from "fs/promises";
4079
- import path23 from "path";
2981
+ import path14 from "path";
4080
2982
  import { capitalize } from "akanjs/common";
4081
2983
  var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
4082
2984
  var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
@@ -4090,7 +2992,7 @@ var SCALAR_UI_TYPES = ["Template", "Unit"];
4090
2992
  class DevGeneratedIndexSync {
4091
2993
  #workspaceRoot;
4092
2994
  constructor({ workspaceRoot }) {
4093
- this.#workspaceRoot = path23.resolve(workspaceRoot);
2995
+ this.#workspaceRoot = path14.resolve(workspaceRoot);
4094
2996
  }
4095
2997
  async syncForBatch(files) {
4096
2998
  const indexPaths = new Set;
@@ -4119,11 +3021,11 @@ class DevGeneratedIndexSync {
4119
3021
  return { changedFiles, errors };
4120
3022
  }
4121
3023
  #facetIndexFor(file) {
4122
- const abs = path23.resolve(file);
4123
- const rel = path23.relative(this.#workspaceRoot, abs);
4124
- if (rel.startsWith("..") || path23.isAbsolute(rel))
3024
+ const abs = path14.resolve(file);
3025
+ const rel = path14.relative(this.#workspaceRoot, abs);
3026
+ if (rel.startsWith("..") || path14.isAbsolute(rel))
4125
3027
  return null;
4126
- const parts = rel.split(path23.sep).filter(Boolean);
3028
+ const parts = rel.split(path14.sep).filter(Boolean);
4127
3029
  if (parts.length < 4)
4128
3030
  return null;
4129
3031
  const [scope, project, facet, child] = parts;
@@ -4131,32 +3033,32 @@ class DevGeneratedIndexSync {
4131
3033
  return null;
4132
3034
  if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
4133
3035
  return null;
4134
- return path23.join(this.#workspaceRoot, scope, project, facet, "index.ts");
3036
+ return path14.join(this.#workspaceRoot, scope, project, facet, "index.ts");
4135
3037
  }
4136
3038
  async#moduleIndexForDirectoryEvent(file) {
4137
- const abs = path23.resolve(file);
4138
- const rel = path23.relative(this.#workspaceRoot, abs);
4139
- if (rel.startsWith("..") || path23.isAbsolute(rel))
3039
+ const abs = path14.resolve(file);
3040
+ const rel = path14.relative(this.#workspaceRoot, abs);
3041
+ if (rel.startsWith("..") || path14.isAbsolute(rel))
4140
3042
  return null;
4141
- const parts = rel.split(path23.sep).filter(Boolean);
3043
+ const parts = rel.split(path14.sep).filter(Boolean);
4142
3044
  if (parts.length !== 4 && parts.length !== 5)
4143
3045
  return null;
4144
3046
  const [scope, project, libSegment, moduleSegment, scalarSegment] = parts;
4145
3047
  if (scope !== "apps" && scope !== "libs" || !project || libSegment !== "lib")
4146
3048
  return null;
4147
3049
  const isExistingDirectory = await stat2(abs).then((s) => s.isDirectory()).catch(() => false);
4148
- const looksLikeDeletedDirectory = !path23.extname(abs);
3050
+ const looksLikeDeletedDirectory = !path14.extname(abs);
4149
3051
  if (!isExistingDirectory && !looksLikeDeletedDirectory)
4150
3052
  return null;
4151
3053
  if (moduleSegment === "__scalar" && scalarSegment) {
4152
- return path23.join(this.#workspaceRoot, scope, project, "lib", "__scalar", scalarSegment, "index.ts");
3054
+ return path14.join(this.#workspaceRoot, scope, project, "lib", "__scalar", scalarSegment, "index.ts");
4153
3055
  }
4154
3056
  if (!moduleSegment || moduleSegment === "__scalar")
4155
3057
  return null;
4156
- return path23.join(this.#workspaceRoot, scope, project, "lib", moduleSegment, "index.ts");
3058
+ return path14.join(this.#workspaceRoot, scope, project, "lib", moduleSegment, "index.ts");
4157
3059
  }
4158
3060
  async#syncIndex(indexPath) {
4159
- const dir = path23.dirname(indexPath);
3061
+ const dir = path14.dirname(indexPath);
4160
3062
  const content = await this.#contentForIndex(indexPath);
4161
3063
  if (content === null) {
4162
3064
  if (!await exists(indexPath))
@@ -4172,14 +3074,14 @@ class DevGeneratedIndexSync {
4172
3074
  return true;
4173
3075
  }
4174
3076
  async#contentForIndex(indexPath) {
4175
- const parts = path23.relative(this.#workspaceRoot, indexPath).split(path23.sep).filter(Boolean);
3077
+ const parts = path14.relative(this.#workspaceRoot, indexPath).split(path14.sep).filter(Boolean);
4176
3078
  const facet = parts.at(-2);
4177
3079
  if (facet && BARREL_FACETS2.has(facet))
4178
- return this.#facetContent(path23.dirname(indexPath));
4179
- return this.#moduleContent(path23.dirname(indexPath));
3080
+ return this.#facetContent(path14.dirname(indexPath));
3081
+ return this.#moduleContent(path14.dirname(indexPath));
4180
3082
  }
4181
3083
  async#facetContent(dir) {
4182
- const nameCasePattern = path23.basename(dir) === "ui" ? FACET_PASCAL_CASE_RE : FACET_CAMEL_CASE_RE;
3084
+ const nameCasePattern = path14.basename(dir) === "ui" ? FACET_PASCAL_CASE_RE : FACET_CAMEL_CASE_RE;
4183
3085
  const entries = await readdir3(dir, { withFileTypes: true }).catch(() => null);
4184
3086
  if (!entries)
4185
3087
  return null;
@@ -4204,8 +3106,8 @@ class DevGeneratedIndexSync {
4204
3106
  `;
4205
3107
  }
4206
3108
  async#moduleContent(dir) {
4207
- const rel = path23.relative(this.#workspaceRoot, dir);
4208
- const parts = rel.split(path23.sep).filter(Boolean);
3109
+ const rel = path14.relative(this.#workspaceRoot, dir);
3110
+ const parts = rel.split(path14.sep).filter(Boolean);
4209
3111
  const moduleSegment = parts.at(-1);
4210
3112
  if (!moduleSegment)
4211
3113
  return null;
@@ -4217,7 +3119,7 @@ class DevGeneratedIndexSync {
4217
3119
  const allowedTypes = isScalar ? SCALAR_UI_TYPES : moduleSegment.startsWith("_") ? SERVICE_UI_TYPES : MODULE_UI_TYPES;
4218
3120
  const fileTypes = [];
4219
3121
  for (const type of allowedTypes) {
4220
- if (await exists(path23.join(dir, `${modelName}.${type}.tsx`)))
3122
+ if (await exists(path14.join(dir, `${modelName}.${type}.tsx`)))
4221
3123
  fileTypes.push(type);
4222
3124
  }
4223
3125
  if (fileTypes.length === 0)
@@ -4252,7 +3154,7 @@ var formatError2 = (err) => err instanceof Error ? err.message : String(err);
4252
3154
 
4253
3155
  // pkgs/@akanjs/devkit/frontendBuild/ssrDevBundler.ts
4254
3156
  import { mkdir as mkdir5 } from "fs/promises";
4255
- import path24 from "path";
3157
+ import path15 from "path";
4256
3158
  import { SSR_DEV_DIRNAME, SSR_DEV_ROUTE_PREFIX } from "akanjs/server/hmr/csrDevManifest";
4257
3159
  class SsrDevBundler extends DevRegistryBundler {
4258
3160
  static #formatVersion = 2;
@@ -4281,12 +3183,12 @@ class SsrDevBundler extends DevRegistryBundler {
4281
3183
  };
4282
3184
  }
4283
3185
  isMetadataFile(file) {
4284
- return super.isMetadataFile(file) && !file.endsWith(".dictionary.ts") && path24.basename(file) !== "dict.ts";
3186
+ return super.isMetadataFile(file) && !file.endsWith(".dictionary.ts") && path15.basename(file) !== "dict.ts";
4285
3187
  }
4286
3188
  async writeEntries() {
4287
3189
  await mkdir5(this.entryDir, { recursive: true });
4288
- const file = path24.join(this.entryDir, "bootstrap.ts");
4289
- const hasStore = await Bun.file(path24.join(this.app.cwdPath, "lib", "st.ts")).exists();
3190
+ const file = path15.join(this.entryDir, "bootstrap.ts");
3191
+ const hasStore = await Bun.file(path15.join(this.app.cwdPath, "lib", "st.ts")).exists();
4290
3192
  const source = hasStore ? `import ${JSON.stringify(`@apps/${this.app.name}/client`)};
4291
3193
  ` : `export {};
4292
3194
  `;
@@ -4312,4 +3214,4 @@ class SsrDevBundler extends DevRegistryBundler {
4312
3214
  }
4313
3215
  }
4314
3216
 
4315
- export { computeRouteSeedIndex, saveRouteSeedIndex, BarrelAnalyzer, createTsconfigPackageResolver, rewriteBarrelImports, GraphClientEntryDiscovery, bundleDefine, ClientEntriesBundler, VENDOR_SPECIFIERS, RouteClientBuilder, AutoImportSync, CsrEntryFiles, PagesEntrySourceGenerator, ServerGraphFile, PagesBundleBuilder, CsrDevPatcher, CsrDevBundler, DevChangePlanner, DevGeneratedIndexSync, SsrDevBundler };
3217
+ export { computeRouteSeedIndex, saveRouteSeedIndex, GraphClientEntryDiscovery, ClientEntriesBundler, VENDOR_SPECIFIERS, RouteClientBuilder, AutoImportSync, CsrDevPatcher, CsrDevBundler, DevChangePlanner, DevGeneratedIndexSync, SsrDevBundler };