@akanjs/cli 3.0.0-beta.19 → 3.0.0-beta.20

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 (95) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-6cm97kay.js → CodeAgent-awv258wb.js} +2 -2
  3. package/{CodeTui-za4jsm41.js → CodeTui-1nqh35ez.js} +20 -22
  4. package/TunnelShare-scf4e4pd.js +9 -0
  5. package/{agent.command-e0wpbbyg.js → agent.command-1s9ag7sb.js} +8 -9
  6. package/akanCode.js +4 -4
  7. package/{application.command-8wyxqc8q.js → application.command-49hwy6va.js} +25 -56
  8. package/{applicationBuildRunner-n9gzaxd0.js → applicationBuildRunner-ybyp97pv.js} +33 -59
  9. package/{applicationReleasePackager-vpggfqgq.js → applicationReleasePackager-esnrphw8.js} +40 -60
  10. package/buildBatch.proc.js +19 -24
  11. package/{capacitorApp-q3z0qht0.js → capacitorApp-1synz4en.js} +3 -4
  12. package/{cloud.command-4zwa5dsx.js → cloud.command-d7rqtzt9.js} +16 -26
  13. package/cloud.script-bkbpcr96.js +19 -0
  14. package/{code.command-468c9d7s.js → code.command-nn48xzej.js} +22 -37
  15. package/context.command-s3mcmvpa.js +48 -0
  16. package/context.runner-k99nb5pk.js +21 -0
  17. package/{dependencyScanner-0z2h2tks.js → dependencyScanner-ye2e6pdz.js} +2 -2
  18. package/{devTui-ffjsarqa.js → devTui-q7k7bakd.js} +5 -9
  19. package/fileSys-5ngz93ga.js +9 -0
  20. package/{guideline.command-vhw13pqr.js → guideline.command-sct4qnt5.js} +4 -5
  21. package/guidelines/conventions/conventions.instruction.md +5 -1
  22. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  23. package/incrementalBuilder.proc.js +30 -48
  24. package/{index-s5rhm04y.js → index-0bq14vr1.js} +1 -1
  25. package/{index-10dkrrww.js → index-13ffe9wp.js} +4 -4
  26. package/{index-srmay5jw.js → index-22d57v4c.js} +84 -67
  27. package/{index-53176s7j.js → index-31yr441d.js} +10 -17
  28. package/index-3hx1z96c.js +87 -0
  29. package/{index-4m929vvn.js → index-3sq321ak.js} +10 -18
  30. package/{index-bhtmj233.js → index-3t7g9e4r.js} +41 -78
  31. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  32. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  33. package/{index-7ep8qtvp.js → index-5pc1qrbv.js} +5 -8
  34. package/{index-esk82rvk.js → index-8mna0947.js} +34 -71
  35. package/{index-sq2dzkzm.js → index-8sf7wmdr.js} +6 -6
  36. package/{index-crmeqnmf.js → index-9d9bgcx4.js} +283 -722
  37. package/{index-bwf965h6.js → index-ahemdr5n.js} +6 -6
  38. package/{index-ab0c38ea.js → index-as7xmyz8.js} +20 -20
  39. package/{index-bc88j1ry.js → index-axzjaqve.js} +94 -142
  40. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  41. package/{index-667w0yah.js → index-c6eggbee.js} +2 -5
  42. package/{index-a1w6934z.js → index-ddxvdd1p.js} +169 -305
  43. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  44. package/{index-22xtgmhn.js → index-dzf3r49a.js} +1 -1
  45. package/{index-89hy31kf.js → index-fgq75haa.js} +172 -287
  46. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  47. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  48. package/{index-vqx8bdxz.js → index-mxav6j3c.js} +78 -231
  49. package/{index-2446k7b4.js → index-myhc3c1j.js} +512 -588
  50. package/{index-3jrp517k.js → index-nv5976x3.js} +45 -128
  51. package/{index-zqgj2rt2.js → index-przybvy5.js} +69 -147
  52. package/{index-n3cv0tm4.js → index-smme4r47.js} +1 -1
  53. package/{index-qdgzsnhg.js → index-w2zdcw3k.js} +110 -231
  54. package/{index-14zrtgfa.js → index-wa5jbxj1.js} +6 -39
  55. package/{index-bftkz6cp.js → index-ww4z397j.js} +198 -555
  56. package/{index-kwaq3n9n.js → index-xqjwd384.js} +4 -7
  57. package/{index-txr7dj2g.js → index-xqpzbab5.js} +106 -240
  58. package/{index-e4v6vhxq.js → index-xsjh6nzh.js} +178 -165
  59. package/{index-18zybgkc.js → index-ygn77a5w.js} +47 -99
  60. package/{index-9d6nvkz2.js → index-ztp3e73t.js} +79 -35
  61. package/index.js +23 -24
  62. package/{library.command-cqr175dy.js → library.command-1gx04jgn.js} +4 -5
  63. package/{localRegistry.command-49z55qqz.js → localRegistry.command-zndxj1q6.js} +21 -42
  64. package/{module.command-9p8mm3b0.js → module.command-3waddk95.js} +6 -7
  65. package/{package.command-wxyz909t.js → package.command-zrc7br1y.js} +5 -6
  66. package/package.json +2 -2
  67. package/{page.command-gsrsfqqs.js → page.command-vpjgardh.js} +4 -5
  68. package/{primitive.command-ns1mptje.js → primitive.command-sz84tk4t.js} +9 -20
  69. package/{prompter-1f8d9pcc.js → prompter-ptaa3nk0.js} +2 -2
  70. package/{quality.command-e76k2q9k.js → quality.command-g869hafs.js} +129 -363
  71. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  72. package/{repair.command-pkrsm3cw.js → repair.command-chsnjvvv.js} +11 -35
  73. package/{scalar.command-0cpt3fc8.js → scalar.command-2v21newx.js} +5 -6
  74. package/skills/akan-code/SKILL.md +12 -4
  75. package/{subspace.command-fktpwp0g.js → subspace.command-ckcbwfp1.js} +39 -58
  76. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +3 -3
  77. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +3 -3
  78. package/templates/client.ts +7 -30
  79. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  80. package/templates/lib/__lib/lib.document.ts +0 -2
  81. package/templates/lib/sig.ts +8 -30
  82. package/templates/server.ts +0 -2
  83. package/{tunnel.command-d5jy9gk8.js → tunnel.command-kd2yr4fx.js} +5 -6
  84. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  85. package/typecheck.proc.js +1 -1
  86. package/workflow.command-44252cqv.js +79 -0
  87. package/{workspace.command-gv84eh1p.js → workspace.command-fqcztt5p.js} +72 -107
  88. package/TunnelShare-2j6s511d.js +0 -9
  89. package/cloud.script-fwx3vb34.js +0 -20
  90. package/context.command-dsnw0jby.js +0 -80
  91. package/context.runner-rs4rj15d.js +0 -22
  92. package/devTuiView-1q1mdgrv.js +0 -9
  93. package/getDirname-dr3jz1xg.js +0 -7
  94. package/index-6wwzs1bc.js +0 -7
  95. package/workflow.command-6tkcysmx.js +0 -105
@@ -2,26 +2,34 @@
2
2
  import {
3
3
  AsyncDefaultExportDetector,
4
4
  resolveSsrPageEntriesForApp
5
- } from "./index-crmeqnmf.js";
5
+ } from "./index-9d9bgcx4.js";
6
6
  import {
7
+ SOURCE_EXTS
8
+ } from "./index-khpfpcsd.js";
9
+ import {
10
+ loaderFor,
7
11
  BarrelAnalyzer,
8
12
  createBarrelImportsPlugin,
9
13
  createTsconfigPackageResolver,
10
14
  rewriteBarrelImports,
11
15
  GraphClientEntryDiscovery,
12
16
  transformUseClient,
17
+ bundleDefine,
13
18
  ClientEntriesBundler,
14
19
  VENDOR_SPECIFIERS,
15
20
  RouteClientBuilder
16
- } from "./index-89hy31kf.js";
21
+ } from "./index-fgq75haa.js";
17
22
  var __require = import.meta.require;
18
23
 
19
24
  // pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
20
- import path3 from "path";
25
+ import path2 from "path";
21
26
 
22
27
  // pkgs/@akanjs/devkit/artifact/routeSeedIndex.ts
23
28
  import path from "path";
24
29
  import { assertUniqueRoutePatterns, compareRouteSpecificity, parseRouteModuleKey } from "akanjs/common";
30
+ import {
31
+ ROUTE_SEED_INDEX_JSON
32
+ } from "akanjs/server/artifact/routeSeedIndexStore";
25
33
  function computeRouteSeedIndex(pageEntries) {
26
34
  const layoutsByPrefix = new Map;
27
35
  const pagesBySegments = [];
@@ -29,9 +37,7 @@ function computeRouteSeedIndex(pageEntries) {
29
37
  const parsed = parseRouteModuleKey(key);
30
38
  const files = [path.resolve(moduleAbsPath), ...(seedAbsPaths ?? []).map((seed) => path.resolve(seed))];
31
39
  if (parsed.kind === "layout" || parsed.kind === "overrides") {
32
- const prefix = parsed.routeSegments.join("/");
33
- const prev = layoutsByPrefix.get(prefix) ?? [];
34
- layoutsByPrefix.set(prefix, [...prev, ...files]);
40
+ layoutsByPrefix.getOrInsert(parsed.routeSegments.join("/"), []).push(...files);
35
41
  } else if (parsed.kind === "page") {
36
42
  pagesBySegments.push({
37
43
  key,
@@ -43,8 +49,7 @@ function computeRouteSeedIndex(pageEntries) {
43
49
  }
44
50
  }
45
51
  assertUniqueRoutePatterns(pagesBySegments);
46
- const rootLayouts = layoutsByPrefix.get("") ?? [];
47
- const globalLayoutFiles = rootLayouts;
52
+ const globalLayoutFiles = layoutsByPrefix.get("") ?? [];
48
53
  const seedEntries = [];
49
54
  for (const { pattern, segments, files, includeOwnLayout } of pagesBySegments) {
50
55
  const layouts = [];
@@ -62,14 +67,10 @@ function computeRouteSeedIndex(pageEntries) {
62
67
  seedEntries.sort((a, b) => compareRouteSpecificity(a.pattern, b.pattern));
63
68
  return { entries: seedEntries, globalLayoutFiles };
64
69
  }
65
- var ROUTE_SEED_INDEX_JSON = "route-seed-index.json";
66
70
  function serializeRouteSeedIndexForArtifact(index, artifactDir, options = {}) {
67
71
  const normalizedArtifactDir = path.resolve(artifactDir);
68
- if (options.production) {
69
- return {
70
- entries: index.entries.map((entry) => ({ routeId: entry.routeId }))
71
- };
72
- }
72
+ if (options.production)
73
+ return { entries: index.entries.map((entry) => ({ routeId: entry.routeId })) };
73
74
  return {
74
75
  entries: index.entries.map((entry) => ({
75
76
  ...entry,
@@ -91,7 +92,7 @@ function serializeArtifactPath(artifactPath, artifactDir) {
91
92
  }
92
93
 
93
94
  // pkgs/@akanjs/devkit/frontendBuild/routesManifestArtifactSerializer.ts
94
- import path2 from "path";
95
+ import { RoutesManifestStore } from "akanjs/server/artifact/routesManifestStore";
95
96
 
96
97
  class RoutesManifestArtifactSerializer {
97
98
  #manifest;
@@ -99,42 +100,17 @@ class RoutesManifestArtifactSerializer {
99
100
  #production;
100
101
  constructor(manifest, artifactDir, options = {}) {
101
102
  this.#manifest = manifest;
102
- this.#artifactDir = path2.resolve(artifactDir);
103
+ this.#artifactDir = artifactDir;
103
104
  this.#production = options.production ?? false;
104
105
  }
105
106
  static serialize(manifest, artifactDir, options = {}) {
106
107
  return new RoutesManifestArtifactSerializer(manifest, artifactDir, options).serialize();
107
108
  }
108
109
  serialize() {
109
- const serialized = {
110
- ...this.#manifest,
111
- knownEntries: this.#manifest.knownEntries.map((entry) => this.#serializeArtifactPath(entry))
112
- };
110
+ const serialized = RoutesManifestStore.serialize(this.#manifest, this.#artifactDir);
113
111
  if (this.#production)
114
112
  delete serialized.knownEntries;
115
- return {
116
- ...serialized,
117
- clientManifest: Object.fromEntries(Object.entries(this.#manifest.clientManifest).map(([key, row]) => [this.#serializeArtifactPath(key), row])),
118
- ssrManifest: {
119
- ...this.#manifest.ssrManifest,
120
- moduleMap: Object.fromEntries(Object.entries(this.#manifest.ssrManifest.moduleMap).map(([entryUrl, byName]) => [
121
- entryUrl,
122
- Object.fromEntries(Object.entries(byName).map(([name, entry]) => [
123
- name,
124
- {
125
- ...entry,
126
- id: this.#serializeArtifactPath(entry.id),
127
- chunks: entry.chunks.map((chunk) => this.#serializeArtifactPath(chunk))
128
- }
129
- ]))
130
- ]))
131
- }
132
- };
133
- }
134
- #serializeArtifactPath(artifactPath) {
135
- if (!path2.isAbsolute(artifactPath))
136
- return artifactPath;
137
- return path2.relative(this.#artifactDir, artifactPath).split(path2.sep).join("/");
113
+ return serialized;
138
114
  }
139
115
  }
140
116
 
@@ -164,27 +140,22 @@ class AllRoutesBuilder {
164
140
  const seedIndex = computeRouteSeedIndex(pageEntries);
165
141
  this.#app.verbose(`[build-all] discovered ${seedIndex.entries.length} routes`);
166
142
  this.#discovery = await GraphClientEntryDiscovery.create(this.#app);
167
- const allEntries = [];
168
- const seen = new Set;
143
+ const allEntries = new Set;
169
144
  for (const entry of seedIndex.entries) {
170
145
  const seeds = Array.from(new Set([...seedIndex.globalLayoutFiles, ...entry.seeds]));
171
- for (const discovered of await this.#discovery.discover(seeds)) {
172
- if (seen.has(discovered))
173
- continue;
174
- seen.add(discovered);
175
- allEntries.push(discovered);
176
- }
146
+ for (const discovered of await this.#discovery.discover(seeds))
147
+ allEntries.add(discovered);
177
148
  this.#routeIds.push(entry.routeId);
178
149
  }
179
- this.#app.verbose(`[build-all] ${allEntries.length} client entries across ${this.#routeIds.length} routes`);
180
- const delta = await this.#buildEntries(allEntries);
150
+ this.#app.verbose(`[build-all] ${allEntries.size} client entries across ${this.#routeIds.length} routes`);
151
+ const delta = await this.#buildEntries([...allEntries]);
181
152
  this.#mergeDelta(delta);
182
153
  this.#merged.knownEntries = Array.from(this.#knownSet);
183
154
  const manifest = {
184
155
  routeIds: this.#routeIds,
185
156
  ...this.#merged
186
157
  };
187
- const manifestPath = path3.join(path3.resolve(this.#artifactDir), "routes-manifest.json");
158
+ const manifestPath = path2.join(path2.resolve(this.#artifactDir), "routes-manifest.json");
188
159
  await Bun.write(manifestPath, `${JSON.stringify(RoutesManifestArtifactSerializer.serialize(manifest, this.#artifactDir, {
189
160
  production: this.#command === "build"
190
161
  }), null, 2)}
@@ -216,18 +187,15 @@ class AllRoutesBuilder {
216
187
  return delta;
217
188
  }
218
189
  #mergeDelta(delta) {
219
- for (const [key, row] of Object.entries(delta.manifestDelta))
220
- this.#merged.clientManifest[key] = row;
221
- for (const [url, byName] of Object.entries(delta.ssrManifestDelta.moduleMap)) {
222
- this.#merged.ssrManifest.moduleMap[url] = byName;
223
- }
190
+ Object.assign(this.#merged.clientManifest, delta.manifestDelta);
191
+ Object.assign(this.#merged.ssrManifest.moduleMap, delta.ssrManifestDelta.moduleMap);
224
192
  for (const abs of delta.newEntries)
225
193
  this.#knownSet.add(abs);
226
194
  }
227
195
  }
228
196
 
229
197
  // pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
230
- import path5 from "path";
198
+ import path4 from "path";
231
199
  import { Logger } from "akanjs/common";
232
200
  import { compile } from "tailwindcss";
233
201
 
@@ -298,7 +266,7 @@ class CssCandidateCache {
298
266
  }
299
267
 
300
268
  // pkgs/@akanjs/devkit/frontendBuild/cssImportResolver.ts
301
- import path4 from "path";
269
+ import path3 from "path";
302
270
  var CSS_IMPORT_EXTS = ["", ".css", "/styles.css", "/index.css"];
303
271
 
304
272
  class CssImportResolver {
@@ -317,8 +285,8 @@ class CssImportResolver {
317
285
  async resolve(id, fromBase) {
318
286
  for (const resolve of [
319
287
  () => this.#resolveWithTsconfig(id),
320
- () => this.#resolveWithBun(id, fromBase),
321
- () => this.#resolveWithRequire(id, fromBase),
288
+ () => this.#resolveCssWith(fromBase, (base) => Bun.resolveSync(id, base)),
289
+ () => this.#resolveCssWith(fromBase, (base) => __require.resolve(id, { paths: [base] })),
322
290
  () => this.#resolvePackageStyle(id, fromBase)
323
291
  ]) {
324
292
  const resolved = await resolve();
@@ -327,20 +295,10 @@ class CssImportResolver {
327
295
  }
328
296
  return null;
329
297
  }
330
- #resolveWithBun(id, fromBase) {
331
- for (const base of this.#resolutionBases(fromBase)) {
332
- try {
333
- const resolved = Bun.resolveSync(id, base);
334
- if (CssImportResolver.isCssFile(resolved))
335
- return resolved;
336
- } catch {}
337
- }
338
- return null;
339
- }
340
- #resolveWithRequire(id, fromBase) {
298
+ #resolveCssWith(fromBase, resolveFrom) {
341
299
  for (const base of this.#resolutionBases(fromBase)) {
342
300
  try {
343
- const resolved = __require.resolve(id, { paths: [base] });
301
+ const resolved = resolveFrom(base);
344
302
  if (CssImportResolver.isCssFile(resolved))
345
303
  return resolved;
346
304
  } catch {}
@@ -351,7 +309,7 @@ class CssImportResolver {
351
309
  const exact = this.#paths[id];
352
310
  if (exact) {
353
311
  for (const repl of exact) {
354
- const resolved = await this.#firstExisting(path4.resolve(this.#workspaceRoot, repl));
312
+ const resolved = await this.#firstExisting(path3.resolve(this.#workspaceRoot, repl));
355
313
  if (resolved)
356
314
  return resolved;
357
315
  }
@@ -362,7 +320,7 @@ class CssImportResolver {
362
320
  const suffix = id.slice(prefix.length);
363
321
  for (const repl of replacements) {
364
322
  const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
365
- const resolved = await this.#firstExisting(path4.resolve(this.#workspaceRoot, replPath + suffix));
323
+ const resolved = await this.#firstExisting(path3.resolve(this.#workspaceRoot, replPath + suffix));
366
324
  if (resolved)
367
325
  return resolved;
368
326
  }
@@ -392,34 +350,34 @@ class CssImportResolver {
392
350
  try {
393
351
  if (!await Bun.file(pkgPath).exists())
394
352
  return null;
395
- const pkgDir = path4.dirname(pkgPath);
353
+ const pkgDir = path3.dirname(pkgPath);
396
354
  const pkg = await Bun.file(pkgPath).json();
397
355
  const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
398
356
  const exportValue = pkg.exports?.[subpath];
399
357
  const exportedEntry = typeof exportValue === "string" ? exportValue : exportValue?.style || exportValue?.import || exportValue?.default;
400
358
  if (exportedEntry)
401
- return await this.#firstExisting(path4.resolve(pkgDir, exportedEntry));
359
+ return await this.#firstExisting(path3.resolve(pkgDir, exportedEntry));
402
360
  if (subpath !== ".")
403
- return await this.#firstExisting(path4.resolve(pkgDir, subpath));
404
- return await this.#firstExisting(path4.resolve(pkgDir, pkg.exports?.["."]?.style || pkg.style || "index.css"));
361
+ return await this.#firstExisting(path3.resolve(pkgDir, subpath));
362
+ return await this.#firstExisting(path3.resolve(pkgDir, pkg.exports?.["."]?.style || pkg.style || "index.css"));
405
363
  } catch {
406
364
  return null;
407
365
  }
408
366
  }
409
367
  #resolutionBases(fromBase) {
410
- return [fromBase, this.#workspaceRoot, path4.dirname(Bun.main), path4.resolve(path4.dirname(Bun.main), "../..")];
368
+ return [fromBase, this.#workspaceRoot, path3.dirname(Bun.main), path3.resolve(path3.dirname(Bun.main), "../..")];
411
369
  }
412
370
  #packageJsonCandidates(pkgName) {
413
371
  return [
414
- path4.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
415
- path4.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
416
- path4.join(path4.dirname(Bun.main), "node_modules", pkgName, "package.json"),
417
- path4.join(path4.dirname(Bun.main), "../../", pkgName, "package.json")
372
+ path3.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
373
+ path3.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
374
+ path3.join(path3.dirname(Bun.main), "node_modules", pkgName, "package.json"),
375
+ path3.join(path3.dirname(Bun.main), "../../", pkgName, "package.json")
418
376
  ];
419
377
  }
420
378
  async#firstExisting(basePath) {
421
379
  for (const suffix of CSS_IMPORT_EXTS) {
422
- const candidate = path4.normalize(`${basePath}${suffix}`);
380
+ const candidate = path3.normalize(`${basePath}${suffix}`);
423
381
  if (await Bun.file(candidate).exists())
424
382
  return candidate;
425
383
  }
@@ -432,12 +390,11 @@ class CssImportResolver {
432
390
  return parts[0] ?? null;
433
391
  }
434
392
  static isCssFile(filePath) {
435
- return path4.extname(filePath) === ".css";
393
+ return path3.extname(filePath) === ".css";
436
394
  }
437
395
  }
438
396
 
439
397
  // pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
440
- var SOURCE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
441
398
  var NON_SOURCE_EXT_RE = /\.(json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav)$/i;
442
399
  var NODE_MODULES_RE = /[\\/]node_modules[\\/]/;
443
400
  var AKANJS_NODE_MODULE_RE = /[\\/]node_modules[\\/]akanjs[\\/]/;
@@ -451,7 +408,7 @@ class CssCompiler {
451
408
  this.#app = app;
452
409
  }
453
410
  get #candidateCachePath() {
454
- return path5.join(this.#app.cwdPath, ".akan/cache/cssCandidates.json");
411
+ return path4.join(this.#app.cwdPath, ".akan/cache/cssCandidates.json");
455
412
  }
456
413
  #cssText = null;
457
414
  #cssTextByBasePath = null;
@@ -481,7 +438,7 @@ class CssCompiler {
481
438
  return filePath;
482
439
  }
483
440
  for (const ext of SOURCE_EXTS) {
484
- const filePath = path5.join(absPathNoExt, `index${ext}`);
441
+ const filePath = path4.join(absPathNoExt, `index${ext}`);
485
442
  if (await this.#fileExists(filePath))
486
443
  return filePath;
487
444
  }
@@ -511,42 +468,33 @@ class CssCompiler {
511
468
  const pageKeys = await this.#app.getPageKeys({ refresh });
512
469
  const basePaths = [...akanConfig.basePaths];
513
470
  const rootPageKeys = pageKeys.filter((pageKey) => getPageKeyBasePath(pageKey, basePaths) === null);
471
+ const compileBasePath = async (basePath, basePathPageKeys, label = basePath) => {
472
+ if (basePathPageKeys.length === 0)
473
+ return [basePath, ""];
474
+ const started = Date.now();
475
+ const { cssPaths, sourcePaths } = await this.discoverCssAndSources({ refresh, pageKeys: basePathPageKeys });
476
+ const { css, imported } = await this.#compileWithImports(cssPaths, sourcePaths);
477
+ this.importedStylesheetsByBasePath[basePath] = imported;
478
+ this.#logger.verbose(`css base=${label} paths=${cssPaths.length} sources=${sourcePaths.length} in ${Date.now() - started}ms`);
479
+ return [basePath, css];
480
+ };
514
481
  const cssEntries = await Promise.all([
515
- (async () => {
516
- if (rootPageKeys.length === 0)
517
- return ["", ""];
518
- const started = Date.now();
519
- const { cssPaths, sourcePaths } = await this.discoverCssAndSources({ refresh, pageKeys: rootPageKeys });
520
- const { css, imported } = await this.#compileWithImports(cssPaths, sourcePaths);
521
- this.importedStylesheetsByBasePath[""] = imported;
522
- this.#logger.verbose(`css base=root paths=${cssPaths.length} sources=${sourcePaths.length} in ${Date.now() - started}ms`);
523
- return ["", css];
524
- })(),
525
- ...basePaths.map(async (basePath) => {
526
- const basePathPageKeys = pageKeys.filter((pageKey) => getPageKeyBasePath(pageKey, basePaths) === basePath);
527
- if (basePathPageKeys.length === 0)
528
- return [basePath, ""];
529
- const started = Date.now();
530
- const { cssPaths, sourcePaths } = await this.discoverCssAndSources({ refresh, pageKeys: basePathPageKeys });
531
- const { css, imported } = await this.#compileWithImports(cssPaths, sourcePaths);
532
- this.importedStylesheetsByBasePath[basePath] = imported;
533
- this.#logger.verbose(`css base=${basePath} paths=${cssPaths.length} sources=${sourcePaths.length} in ${Date.now() - started}ms`);
534
- return [basePath, css];
535
- })
482
+ compileBasePath("", rootPageKeys, "root"),
483
+ ...basePaths.map((basePath) => compileBasePath(basePath, pageKeys.filter((pageKey) => getPageKeyBasePath(pageKey, basePaths) === basePath)))
536
484
  ]);
537
485
  this.#cssTextByBasePath = Object.fromEntries(cssEntries);
538
486
  await this.#warnUnreachableStylesheets();
539
487
  return this.#cssTextByBasePath;
540
488
  }
541
489
  async#warnUnreachableStylesheets() {
542
- const pageDir = path5.join(this.#app.cwdPath, "page");
490
+ const pageDir = path4.join(this.#app.cwdPath, "page");
543
491
  const glob = new Bun.Glob("**/*.css");
544
492
  for await (const cssPath of glob.scan({ cwd: pageDir, absolute: true })) {
545
- if (cssPath.includes(`${path5.sep}(libs)${path5.sep}`))
493
+ if (cssPath.includes(`${path4.sep}(libs)${path4.sep}`))
546
494
  continue;
547
495
  if (this.#discoveredCssPaths.has(cssPath))
548
496
  continue;
549
- this.#logger.warn(`css ${path5.relative(this.#app.cwdPath, cssPath)} is imported by no route and never compiled`);
497
+ this.#logger.warn(`css ${path4.relative(this.#app.cwdPath, cssPath)} is imported by no route and never compiled`);
550
498
  }
551
499
  }
552
500
  async discoverCss({ refresh } = {}) {
@@ -558,7 +506,7 @@ class CssCompiler {
558
506
  pageKeys
559
507
  } = {}) {
560
508
  pageKeys ??= await this.#app.getPageKeys({ refresh });
561
- const seeds = pageKeys.map((key) => path5.resolve(this.#app.cwdPath, "page", key));
509
+ const seeds = pageKeys.map((key) => path4.resolve(this.#app.cwdPath, "page", key));
562
510
  const cssFiles = new Set;
563
511
  const sourceFiles = new Set;
564
512
  const queue = [...seeds];
@@ -590,7 +538,7 @@ class CssCompiler {
590
538
  } catch {
591
539
  continue;
592
540
  }
593
- const importerDir = path5.dirname(filePath);
541
+ const importerDir = path4.dirname(filePath);
594
542
  for (const imp of imports) {
595
543
  const spec = imp.path;
596
544
  if (!spec)
@@ -615,18 +563,18 @@ class CssCompiler {
615
563
  return { cssPaths, sourcePaths: [...sourceFiles] };
616
564
  }
617
565
  async#libTokenStylesheets(sourceFiles) {
618
- const libsRoot = path5.join(this.#app.workspace.workspaceRoot, "libs");
566
+ const libsRoot = path4.join(this.#app.workspace.workspaceRoot, "libs");
619
567
  const libNames = new Set;
620
568
  for (const filePath of sourceFiles) {
621
- const relPath = path5.relative(libsRoot, filePath);
622
- if (relPath.startsWith("..") || path5.isAbsolute(relPath))
569
+ const relPath = path4.relative(libsRoot, filePath);
570
+ if (relPath.startsWith("..") || path4.isAbsolute(relPath))
623
571
  continue;
624
- const [libName] = relPath.split(path5.sep);
572
+ const [libName] = relPath.split(path4.sep);
625
573
  if (libName)
626
574
  libNames.add(libName);
627
575
  }
628
576
  const tokenPaths = await Promise.all([...libNames].sort().map(async (libName) => {
629
- const tokensPath = path5.join(libsRoot, libName, "ui/tokens.css");
577
+ const tokensPath = path4.join(libsRoot, libName, "ui/tokens.css");
630
578
  return await this.#fileExists(tokensPath) ? tokensPath : null;
631
579
  }));
632
580
  return tokenPaths.filter((tokensPath) => !!tokensPath);
@@ -641,7 +589,7 @@ class CssCompiler {
641
589
  const compileStarted = Date.now();
642
590
  const compilers = await Promise.all(cssPaths.map(async (cssPath) => {
643
591
  const css = await Bun.file(cssPath).text();
644
- const base = path5.dirname(cssPath);
592
+ const base = path4.dirname(cssPath);
645
593
  const imported = new Map;
646
594
  const compiler = await compile(css, {
647
595
  base,
@@ -652,8 +600,6 @@ class CssCompiler {
652
600
  }));
653
601
  const sourceDirs = new Set;
654
602
  for (const entry of compilers) {
655
- if (!entry)
656
- continue;
657
603
  for (const s of entry.compiler.sources)
658
604
  sourceDirs.add(s.base);
659
605
  }
@@ -663,8 +609,6 @@ class CssCompiler {
663
609
  const parts = [];
664
610
  const imported = [];
665
611
  for (const entry of compilers) {
666
- if (!entry)
667
- continue;
668
612
  const part = entry.compiler.build(candidates);
669
613
  parts.push(part);
670
614
  for (const [cssPath, content] of entry.imported) {
@@ -685,31 +629,25 @@ class CssCompiler {
685
629
  const content = await Bun.file(p).text();
686
630
  imported?.set(p, content);
687
631
  this.#logger.verbose(`css import "${id}" from ${fromBase} -> ${p} (${content.length} bytes)`);
688
- return { path: p, base: path5.dirname(p), content };
632
+ return { path: p, base: path4.dirname(p), content };
689
633
  }
690
634
  async#resolveCssImport(id, fromBase) {
691
635
  if (id.startsWith(".") || id.startsWith("/")) {
692
- const filePath = path5.resolve(fromBase, id);
636
+ const filePath = path4.resolve(fromBase, id);
693
637
  if (await this.#fileExists(filePath))
694
638
  return filePath;
695
639
  throw new Error(`[css] failed to resolve stylesheet import "${id}" from ${fromBase} (no file at ${filePath})`);
696
640
  }
697
- const resolver = await this.#getCssImportResolver();
698
- const resolved = await resolver.resolve(id, fromBase);
641
+ this.#cssImportResolver ??= await CssImportResolver.create(this.#app);
642
+ const resolved = await this.#cssImportResolver.resolve(id, fromBase);
699
643
  if (resolved)
700
644
  return resolved;
701
645
  throw new Error(`[css] failed to resolve stylesheet import "${id}" from ${fromBase}`);
702
646
  }
703
- async#getCssImportResolver() {
704
- if (this.#cssImportResolver)
705
- return this.#cssImportResolver;
706
- this.#cssImportResolver = await CssImportResolver.create(this.#app);
707
- return this.#cssImportResolver;
708
- }
709
647
  async#loadModule(id, fromBase) {
710
648
  const p = __require.resolve(id, { paths: [fromBase] });
711
649
  const mod = await import(p);
712
- return { path: p, base: path5.dirname(p), module: mod.default ?? mod };
650
+ return { path: p, base: path4.dirname(p), module: mod.default ?? mod };
713
651
  }
714
652
  #resolveSourceImport(id, fromBase, resolvePackage) {
715
653
  const cacheKey = `${fromBase}\x00${id}`;
@@ -722,7 +660,7 @@ class CssCompiler {
722
660
  }
723
661
  async#resolveSourceImportUncached(id, fromBase, resolvePackage) {
724
662
  if (id.startsWith(".") || id.startsWith("/")) {
725
- const abs = id.startsWith("/") ? id : path5.resolve(fromBase, id);
663
+ const abs = id.startsWith("/") ? id : path4.resolve(fromBase, id);
726
664
  return this.#resolveSourceFileCandidate(abs);
727
665
  }
728
666
  const pkg = await resolvePackage(id);
@@ -773,7 +711,7 @@ function resolveSourceWithRequire(id, fromBase) {
773
711
  }
774
712
  }
775
713
  function isSourceFile(filePath) {
776
- return SOURCE_EXTS.includes(path5.extname(filePath));
714
+ return SOURCE_EXTS.has(path4.extname(filePath));
777
715
  }
778
716
  function isIgnoredNodeModuleSource(filePath) {
779
717
  return NODE_MODULES_RE.test(filePath) && !AKANJS_NODE_MODULE_RE.test(filePath);
@@ -783,17 +721,17 @@ function declaredCustomProperties(css) {
783
721
  return [...new Set([...withoutThemeBlocks.matchAll(/(?:^|[\s;{])(--[\w-]+)\s*:/g)].map(([, name]) => name))].filter((name) => !!name);
784
722
  }
785
723
  function getPageKeyBasePath(pageKey, basePaths) {
786
- const normalized = pageKey.split(path5.sep).join("/").replace(/^\.\//, "");
724
+ const normalized = pageKey.split(path4.sep).join("/").replace(/^\.\//, "");
787
725
  const segments = normalized.split("/");
788
726
  const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
789
727
  return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
790
728
  }
791
729
 
792
730
  // pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
793
- import path8 from "path";
731
+ import path7 from "path";
794
732
 
795
733
  // pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
796
- import path6 from "path";
734
+ import path5 from "path";
797
735
  var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
798
736
  var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "@akanjs/cli", "@akanjs/devkit"]);
799
737
  var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
@@ -835,20 +773,18 @@ async function createExternalizeFrameworkPlugin(options) {
835
773
  const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
836
774
  if (!replPath)
837
775
  continue;
838
- const candidate = path6.resolve(workspaceRoot, replPath + suffix);
776
+ const candidate = path5.resolve(workspaceRoot, replPath + suffix);
839
777
  const hit = await firstExisting(candidate);
840
778
  if (hit)
841
779
  return hit;
842
780
  }
843
781
  }
844
782
  for (const { pkg, entryFile } of rootEntries) {
845
- if (spec !== pkg && !spec.startsWith(`${pkg}/`))
846
- continue;
847
- if (spec === pkg)
783
+ if (!spec.startsWith(`${pkg}/`))
848
784
  continue;
849
785
  const suffix = spec.slice(pkg.length + 1);
850
- const pkgDir = path6.dirname(path6.resolve(workspaceRoot, entryFile));
851
- const candidate = path6.join(pkgDir, suffix);
786
+ const pkgDir = path5.dirname(path5.resolve(workspaceRoot, entryFile));
787
+ const candidate = path5.join(pkgDir, suffix);
852
788
  const hit = await firstExisting(candidate);
853
789
  if (hit)
854
790
  return hit;
@@ -876,15 +812,10 @@ async function createExternalizeFrameworkPlugin(options) {
876
812
  if (spec.startsWith(prefix))
877
813
  return { path: spec, external: true };
878
814
  }
879
- for (const prefix of includePrefixes) {
880
- if (!spec.startsWith(prefix))
881
- continue;
882
- const resolved = await resolveWorkspaceSubpath(spec);
883
- if (resolved)
884
- return { path: resolved };
815
+ if (!includePrefixes.some((prefix) => spec.startsWith(prefix)))
885
816
  return;
886
- }
887
- return;
817
+ const resolved = await resolveWorkspaceSubpath(spec);
818
+ return resolved ? { path: resolved } : undefined;
888
819
  });
889
820
  }
890
821
  };
@@ -898,7 +829,7 @@ async function firstExisting(basePath) {
898
829
  return candidate;
899
830
  }
900
831
  for (const ext of CANDIDATE_EXTS) {
901
- const candidate = path6.join(basePath, `index${ext}`);
832
+ const candidate = path5.join(basePath, `index${ext}`);
902
833
  if (await Bun.file(candidate).exists())
903
834
  return candidate;
904
835
  }
@@ -930,18 +861,9 @@ function createUseClientBundlePlugin(options = {}) {
930
861
  }
931
862
  };
932
863
  }
933
- function loaderFor(absPath) {
934
- if (absPath.endsWith(".tsx"))
935
- return "tsx";
936
- if (absPath.endsWith(".jsx"))
937
- return "jsx";
938
- if (absPath.endsWith(".ts"))
939
- return "ts";
940
- return "js";
941
- }
942
864
 
943
865
  // pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
944
- import path7 from "path";
866
+ import path6 from "path";
945
867
  class PagesEntrySourceGenerator {
946
868
  #pageEntries;
947
869
  constructor(pageEntries) {
@@ -982,7 +904,7 @@ ${entries.join(`
982
904
  `;
983
905
  }
984
906
  static #toImportSpecifier(moduleAbsPath) {
985
- return path7.resolve(moduleAbsPath).split(path7.sep).join("/");
907
+ return path6.resolve(moduleAbsPath).split(path6.sep).join("/");
986
908
  }
987
909
  }
988
910
 
@@ -1016,7 +938,7 @@ class PagesBundleBuilder {
1016
938
  chunk: "chunks/[name]-[hash].[ext]",
1017
939
  asset: "assets/[name]-[hash].[ext]"
1018
940
  },
1019
- define: this.#define(),
941
+ define: bundleDefine(this.#app, this.#command, "ssr"),
1020
942
  plugins: [
1021
943
  PagesBundleBuilder.createPagesEntryPlugin(entrySource),
1022
944
  PagesBundleBuilder.createCssStubPlugin(),
@@ -1035,11 +957,11 @@ class PagesBundleBuilder {
1035
957
  const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
1036
958
  if (!entryArtifact)
1037
959
  throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
1038
- const bundlePath = path8.resolve(entryArtifact.path);
960
+ const bundlePath = path7.resolve(entryArtifact.path);
1039
961
  const buildId = Date.now();
1040
962
  const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
1041
963
  const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
1042
- this.#app.verbose(`[PagesBundleBuilder] ${path8.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`);
964
+ this.#app.verbose(`[PagesBundleBuilder] ${path7.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`);
1043
965
  return {
1044
966
  bundlePath,
1045
967
  buildId,
@@ -1056,14 +978,6 @@ class PagesBundleBuilder {
1056
978
  get #splitting() {
1057
979
  return process.env.AKAN_SERVER_PAGES_SPLITTING === "1";
1058
980
  }
1059
- #define() {
1060
- const nodeEnv = this.#command === "build" ? "production" : "development";
1061
- return {
1062
- "process.env.NODE_ENV": JSON.stringify(nodeEnv),
1063
- "process.env.AKAN_PUBLIC_RENDER_ENV": JSON.stringify("ssr"),
1064
- ...Object.fromEntries(Object.entries(this.#app.getPublicEnv()).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]))
1065
- };
1066
- }
1067
981
  static createPagesEntryPlugin(source) {
1068
982
  return {
1069
983
  name: "akan-pages-entry",
@@ -1099,7 +1013,7 @@ class PagesBundleBuilder {
1099
1013
  const transformed = PagesBundleBuilder.transformServerUseClientFetchSource(source);
1100
1014
  if (transformed === source)
1101
1015
  return;
1102
- return { contents: transformed, loader: loaderFor2(args.path) };
1016
+ return { contents: transformed, loader: loaderFor(args.path) };
1103
1017
  });
1104
1018
  }
1105
1019
  };
@@ -1110,19 +1024,10 @@ class PagesBundleBuilder {
1110
1024
  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 });");
1111
1025
  }
1112
1026
  }
1113
- function loaderFor2(absPath) {
1114
- if (absPath.endsWith(".tsx"))
1115
- return "tsx";
1116
- if (absPath.endsWith(".jsx"))
1117
- return "jsx";
1118
- if (absPath.endsWith(".ts"))
1119
- return "ts";
1120
- return "js";
1121
- }
1122
1027
 
1123
1028
  // pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
1124
1029
  import { mkdir, rm, unlink } from "fs/promises";
1125
- import path9 from "path";
1030
+ import path8 from "path";
1126
1031
  class CsrArtifactBuilder {
1127
1032
  #app;
1128
1033
  #command;
@@ -1158,7 +1063,7 @@ class CsrArtifactBuilder {
1158
1063
  splitting: false,
1159
1064
  minify: true,
1160
1065
  env: "AKAN_PUBLIC_*",
1161
- define: this.#define(),
1066
+ define: bundleDefine(this.#app, this.#command, "csr"),
1162
1067
  optimizeImports: akanConfig.optimizeImports,
1163
1068
  plugins: [PagesBundleBuilder.createCssStubPlugin()]
1164
1069
  });
@@ -1185,28 +1090,20 @@ ${logs}` : ""}`);
1185
1090
  return `${basePath || "index"}.csr.tsx`;
1186
1091
  }
1187
1092
  static basePathOfHtml(htmlPath) {
1188
- const name = path9.basename(htmlPath, ".html");
1093
+ const name = path8.basename(htmlPath, ".html");
1189
1094
  return name === "index" ? "" : name;
1190
1095
  }
1191
1096
  get #outputDir() {
1192
- return path9.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
1097
+ return path8.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
1193
1098
  }
1194
1099
  get #generatedDir() {
1195
- return path9.join(this.#app.cwdPath, ".akan/generated/csr");
1100
+ return path8.join(this.#app.cwdPath, ".akan/generated/csr");
1196
1101
  }
1197
1102
  get #artifactDir() {
1198
- return path9.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
1103
+ return path8.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
1199
1104
  }
1200
1105
  #generatedPath(filename) {
1201
- return path9.join(this.#generatedDir, filename);
1202
- }
1203
- #define() {
1204
- const nodeEnv = this.#command === "build" ? "production" : "development";
1205
- return {
1206
- "process.env.NODE_ENV": JSON.stringify(nodeEnv),
1207
- "process.env.AKAN_PUBLIC_RENDER_ENV": JSON.stringify("csr"),
1208
- ...Object.fromEntries(Object.entries(this.#app.getPublicEnv()).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]))
1209
- };
1106
+ return path8.join(this.#generatedDir, filename);
1210
1107
  }
1211
1108
  async#createEntryFile(basePath, pageEntries) {
1212
1109
  return [
@@ -1237,7 +1134,7 @@ void bootCsr(pages);
1237
1134
  ];
1238
1135
  }
1239
1136
  async#loadCssAssets() {
1240
- const artifactFile = Bun.file(path9.join(this.#artifactDir, "base-artifact.json"));
1137
+ const artifactFile = Bun.file(path8.join(this.#artifactDir, "base-artifact.json"));
1241
1138
  if (!await artifactFile.exists())
1242
1139
  return {};
1243
1140
  const artifact = await artifactFile.json();
@@ -1245,14 +1142,14 @@ void bootCsr(pages);
1245
1142
  }
1246
1143
  async#inlineCsrArtifacts(cssAssets) {
1247
1144
  const jsFiles = new Set;
1248
- for (const htmlPath of await this.#htmlOutputPaths()) {
1145
+ for (const htmlPath of await this.#listOutputFiles((filePath) => filePath.endsWith(".html"))) {
1249
1146
  const htmlFile = Bun.file(htmlPath);
1250
1147
  if (!await htmlFile.exists())
1251
1148
  continue;
1252
1149
  const basePath = CsrArtifactBuilder.basePathOfHtml(htmlPath);
1253
1150
  const cssAsset = cssAssets[basePath];
1254
1151
  if (!cssAsset) {
1255
- this.#app.logger.warn(`[csr-build] base-artifact.json has no compiled stylesheet for ${basePath || "root"}; ${path9.basename(htmlPath)} ships without CSS`);
1152
+ this.#app.logger.warn(`[csr-build] base-artifact.json has no compiled stylesheet for ${basePath || "root"}; ${path8.basename(htmlPath)} ships without CSS`);
1256
1153
  }
1257
1154
  const inlined = await this.#inlineHtmlAssets(await htmlFile.text(), htmlPath, cssAsset);
1258
1155
  for (const filePath of inlined.jsFiles)
@@ -1273,7 +1170,7 @@ ${remainingAssets.join(`
1273
1170
  async#inlineHtmlAssets(html, htmlPath, cssAsset) {
1274
1171
  let next = html;
1275
1172
  if (cssAsset) {
1276
- const css = await Bun.file(path9.join(this.#artifactDir, cssAsset.cssRelPath)).text();
1173
+ const css = await Bun.file(path8.join(this.#artifactDir, cssAsset.cssRelPath)).text();
1277
1174
  next = CsrArtifactBuilder.injectBeforeHeadEnd(next, CsrArtifactBuilder.createInlineStyle(css));
1278
1175
  }
1279
1176
  const jsFiles = [];
@@ -1284,9 +1181,6 @@ ${remainingAssets.join(`
1284
1181
  });
1285
1182
  return { html: next, jsFiles };
1286
1183
  }
1287
- async#htmlOutputPaths() {
1288
- return await this.#listOutputFiles((filePath) => filePath.endsWith(".html"));
1289
- }
1290
1184
  async#listOutputFiles(predicate) {
1291
1185
  const glob = new Bun.Glob("**/*");
1292
1186
  const files = [];
@@ -1346,13 +1240,13 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
1346
1240
  throw new Error(`[csr-build] cannot inline external script: ${src}`);
1347
1241
  }
1348
1242
  const normalized = src.startsWith("/") ? src.slice(1) : src;
1349
- return path9.resolve(path9.dirname(htmlPath), normalized);
1243
+ return path8.resolve(path8.dirname(htmlPath), normalized);
1350
1244
  }
1351
1245
  }
1352
1246
 
1353
1247
  // pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
1354
1248
  import { mkdir as mkdir2, stat as stat2 } from "fs/promises";
1355
- import path10 from "path";
1249
+ import path9 from "path";
1356
1250
  import ts from "typescript";
1357
1251
  var FONT_URL_PREFIX = "/_akan/fonts";
1358
1252
  var DEFAULT_FONT_SUBSETS = ["latin"];
@@ -1369,7 +1263,7 @@ class FontOptimizer {
1369
1263
  constructor(app, command = "start") {
1370
1264
  this.#app = app;
1371
1265
  this.#command = command;
1372
- this.#artifactRoot = path10.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
1266
+ this.#artifactRoot = path9.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
1373
1267
  }
1374
1268
  async optimize() {
1375
1269
  const fonts = await this.discoverFonts();
@@ -1394,7 +1288,7 @@ class FontOptimizer {
1394
1288
  return result;
1395
1289
  }
1396
1290
  get #cachePath() {
1397
- return path10.join(this.#artifactRoot, "fontCache.json");
1291
+ return path9.join(this.#artifactRoot, "fontCache.json");
1398
1292
  }
1399
1293
  async#buildCacheKey(fonts) {
1400
1294
  const sources = [];
@@ -1409,7 +1303,7 @@ class FontOptimizer {
1409
1303
  sources.push({ optimizedSrc: face.optimizedSrc, ...stamp });
1410
1304
  }
1411
1305
  for (const filePath of font.subsetFiles ?? []) {
1412
- const abs = path10.isAbsolute(filePath) ? filePath : path10.join(this.#app.cwdPath, filePath);
1306
+ const abs = path9.isAbsolute(filePath) ? filePath : path9.join(this.#app.cwdPath, filePath);
1413
1307
  const stamp = await this.#fileStamp(abs);
1414
1308
  if (!stamp)
1415
1309
  return null;
@@ -1435,7 +1329,7 @@ class FontOptimizer {
1435
1329
  const cache = await Bun.file(this.#cachePath).json().catch(() => null);
1436
1330
  if (cache?.version !== FontOptimizer.#cacheVersion || cache.key !== key)
1437
1331
  return null;
1438
- const files = cache.files.map((relativePath) => path10.join(this.#artifactRoot, relativePath));
1332
+ const files = cache.files.map((relativePath) => path9.join(this.#artifactRoot, relativePath));
1439
1333
  for (const filePath of files) {
1440
1334
  if (!await Bun.file(filePath).exists())
1441
1335
  return null;
@@ -1447,7 +1341,7 @@ class FontOptimizer {
1447
1341
  version: FontOptimizer.#cacheVersion,
1448
1342
  key,
1449
1343
  css: result.css,
1450
- files: result.files.map((filePath) => path10.relative(this.#artifactRoot, filePath))
1344
+ files: result.files.map((filePath) => path9.relative(this.#artifactRoot, filePath))
1451
1345
  };
1452
1346
  await Bun.write(this.#cachePath, JSON.stringify(cache));
1453
1347
  }
@@ -1455,7 +1349,7 @@ class FontOptimizer {
1455
1349
  const pageKeys = await this.#app.getPageKeys();
1456
1350
  const fonts = [];
1457
1351
  await Promise.all(pageKeys.map(async (key) => {
1458
- const filePath = path10.resolve(this.#app.cwdPath, "page", key);
1352
+ const filePath = path9.resolve(this.#app.cwdPath, "page", key);
1459
1353
  const file = Bun.file(filePath);
1460
1354
  if (!await file.exists())
1461
1355
  return;
@@ -1464,7 +1358,7 @@ class FontOptimizer {
1464
1358
  return;
1465
1359
  fonts.push(...this.#extractFontsExport(source, filePath));
1466
1360
  }));
1467
- return this.#dedupeFonts(fonts);
1361
+ return [...new Map(fonts.map((font) => [JSON.stringify(font), font])).values()];
1468
1362
  }
1469
1363
  async#optimizeFont(font) {
1470
1364
  const faceCss = [];
@@ -1474,8 +1368,8 @@ class FontOptimizer {
1474
1368
  this.#app.logger.warn(`[font] source not found: ${face.src}`);
1475
1369
  continue;
1476
1370
  }
1477
- const outputPath = path10.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
1478
- await mkdir2(path10.dirname(outputPath), { recursive: true });
1371
+ const outputPath = path9.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
1372
+ await mkdir2(path9.dirname(outputPath), { recursive: true });
1479
1373
  const sourceBuffer = Buffer.from(await Bun.file(sourcePath).arrayBuffer());
1480
1374
  const outputBuffer = await this.#buildFontBuffer(font, sourceBuffer, sourcePath);
1481
1375
  await Bun.write(outputPath, outputBuffer);
@@ -1497,8 +1391,8 @@ class FontOptimizer {
1497
1391
  const entries = Array.isArray(value) ? value : [];
1498
1392
  const fonts = entries.filter((entry) => this.#isReadableFont(entry));
1499
1393
  if (fonts.length !== entries.length || !Array.isArray(value))
1500
- this.#app.logger.warn(`[font] ${path10.relative(this.#app.cwdPath, filePath)} declares fonts the build cannot read without evaluating the module \u2014 write the list inline, or nothing is subset for it and every /_akan/fonts request 404s`);
1501
- return fonts.map((font) => this.#withFontDefaults(font));
1394
+ this.#app.logger.warn(`[font] ${path9.relative(this.#app.cwdPath, filePath)} declares fonts the build cannot read without evaluating the module \u2014 write the list inline, or nothing is subset for it and every /_akan/fonts request 404s`);
1395
+ return fonts.map((font) => ({ ...font, subsets: font.subsets ?? [...DEFAULT_FONT_SUBSETS] }));
1502
1396
  }
1503
1397
  #isReadableFont(value) {
1504
1398
  if (!value || typeof value !== "object")
@@ -1587,15 +1481,6 @@ class FontOptimizer {
1587
1481
  return name.text;
1588
1482
  return null;
1589
1483
  }
1590
- #dedupeFonts(fonts) {
1591
- const map = new Map;
1592
- for (const font of fonts)
1593
- map.set(JSON.stringify(font), font);
1594
- return [...map.values()];
1595
- }
1596
- #withFontDefaults(font) {
1597
- return { ...font, subsets: font.subsets ?? [...DEFAULT_FONT_SUBSETS] };
1598
- }
1599
1484
  #getFontSubsets(font) {
1600
1485
  return font.subsets ?? DEFAULT_FONT_SUBSETS;
1601
1486
  }
@@ -1608,11 +1493,8 @@ class FontOptimizer {
1608
1493
  #isFontOptimizationEnabled(font) {
1609
1494
  return font.optimize !== false;
1610
1495
  }
1611
- #getFontStyles(font) {
1612
- return font.styles?.length ? font.styles : ["normal"];
1613
- }
1614
1496
  #getFontFaces(font) {
1615
- const enabledStyles = new Set(this.#getFontStyles(font));
1497
+ const enabledStyles = new Set(font.styles?.length ? font.styles : ["normal"]);
1616
1498
  return font.paths.map((fontPath) => {
1617
1499
  const style = fontPath.style ?? "normal";
1618
1500
  return {
@@ -1667,8 +1549,8 @@ class FontOptimizer {
1667
1549
  return null;
1668
1550
  const rel = src.replace(/^\//, "");
1669
1551
  const candidates = [
1670
- this.#command === "build" ? path10.join(this.#app.dist.cwdPath, "public", rel) : null,
1671
- path10.join(this.#app.cwdPath, "public", rel),
1552
+ this.#command === "build" ? path9.join(this.#app.dist.cwdPath, "public", rel) : null,
1553
+ path9.join(this.#app.cwdPath, "public", rel),
1672
1554
  this.#resolveWorkspacePublicPath(rel)
1673
1555
  ].filter(Boolean);
1674
1556
  for (const candidate of candidates) {
@@ -1685,15 +1567,12 @@ class FontOptimizer {
1685
1567
  }
1686
1568
  async#convertToWoff2(buffer, sourcePath) {
1687
1569
  const { createFont } = await import("fonteditor-core");
1688
- await this.#initWoff2();
1689
- const font = createFont(buffer, { type: this.#getFontType(sourcePath, buffer) });
1690
- return font.write({ type: "woff2", toBuffer: true });
1691
- }
1692
- async#initWoff2() {
1693
1570
  this.#woff2Ready ??= import("fonteditor-core").then(({ woff2 }) => woff2.init()).then(() => {
1694
1571
  return;
1695
1572
  });
1696
- return this.#woff2Ready;
1573
+ await this.#woff2Ready;
1574
+ const font = createFont(buffer, { type: this.#getFontType(sourcePath, buffer) });
1575
+ return font.write({ type: "woff2", toBuffer: true });
1697
1576
  }
1698
1577
  #getFontType(sourcePath, buffer) {
1699
1578
  const signature = buffer.toString("ascii", 0, 4);
@@ -1703,7 +1582,7 @@ class FontOptimizer {
1703
1582
  return "woff2";
1704
1583
  if (signature === "OTTO")
1705
1584
  return "otf";
1706
- const ext = path10.extname(sourcePath).slice(1).toLowerCase();
1585
+ const ext = path9.extname(sourcePath).slice(1).toLowerCase();
1707
1586
  if (ext === "otf" || ext === "woff" || ext === "woff2")
1708
1587
  return ext;
1709
1588
  return "ttf";
@@ -1712,7 +1591,7 @@ class FontOptimizer {
1712
1591
  const [root, dep, ...rest] = rel.split("/");
1713
1592
  if (root !== "libs" || !dep || rest.length === 0)
1714
1593
  return null;
1715
- return path10.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
1594
+ return path9.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
1716
1595
  }
1717
1596
  async#getSubsetText(font) {
1718
1597
  const parts = new Set;
@@ -1722,7 +1601,7 @@ class FontOptimizer {
1722
1601
  if (font.subsetText)
1723
1602
  parts.add(font.subsetText);
1724
1603
  for (const filePath of font.subsetFiles ?? []) {
1725
- const abs = path10.isAbsolute(filePath) ? filePath : path10.join(this.#app.cwdPath, filePath);
1604
+ const abs = path9.isAbsolute(filePath) ? filePath : path9.join(this.#app.cwdPath, filePath);
1726
1605
  const file = Bun.file(abs);
1727
1606
  if (await file.exists())
1728
1607
  parts.add(await file.text());
@@ -1731,9 +1610,9 @@ class FontOptimizer {
1731
1610
  }
1732
1611
  async#getSubsetPresetText(subset) {
1733
1612
  if (subset === "latin")
1734
- return this.#rangeText(32, 126);
1613
+ return FontOptimizer.#rangeText(32, 126);
1735
1614
  if (subset === "latin-ext")
1736
- return `${this.#rangeText(32, 126)}${this.#rangeText(160, 591)}`;
1615
+ return `${FontOptimizer.#rangeText(32, 126)}${FontOptimizer.#rangeText(160, 591)}`;
1737
1616
  if (subset === "ks-x-1001")
1738
1617
  return FontOptimizer.#getKsX1001Text();
1739
1618
  if (subset === "auto")
@@ -1742,7 +1621,7 @@ class FontOptimizer {
1742
1621
  }
1743
1622
  async#collectAutoSubsetText() {
1744
1623
  const libPageRoots = (await this.#app.getPageRoots()).filter((root) => root.keyPrefix).map((root) => root.dir);
1745
- const roots = [...["page", "ui", "lib"].map((dir) => path10.join(this.#app.cwdPath, dir)), ...libPageRoots];
1624
+ const roots = [...["page", "ui", "lib"].map((dir) => path9.join(this.#app.cwdPath, dir)), ...libPageRoots];
1746
1625
  const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
1747
1626
  const parts = [];
1748
1627
  for (const root of [...new Set(roots)].sort()) {
@@ -1757,12 +1636,6 @@ class FontOptimizer {
1757
1636
  }
1758
1637
  return parts.join("");
1759
1638
  }
1760
- #rangeText(start, end) {
1761
- let text = "";
1762
- for (let code = start;code <= end; code++)
1763
- text += String.fromCodePoint(code);
1764
- return text;
1765
- }
1766
1639
  static #getKsX1001Text() {
1767
1640
  if (FontOptimizer.#ksX1001Text)
1768
1641
  return FontOptimizer.#ksX1001Text;
@@ -1778,11 +1651,11 @@ class FontOptimizer {
1778
1651
  }
1779
1652
  FontOptimizer.#ksX1001Text = [...chars].join("");
1780
1653
  } catch {
1781
- FontOptimizer.#ksX1001Text = FontOptimizer.#rangeTextStatic(44032, 55203);
1654
+ FontOptimizer.#ksX1001Text = FontOptimizer.#rangeText(44032, 55203);
1782
1655
  }
1783
1656
  return FontOptimizer.#ksX1001Text;
1784
1657
  }
1785
- static #rangeTextStatic(start, end) {
1658
+ static #rangeText(start, end) {
1786
1659
  let text = "";
1787
1660
  for (let code = start;code <= end; code++)
1788
1661
  text += String.fromCodePoint(code);
@@ -1862,7 +1735,7 @@ ${declarations.map(([prop, value]) => ` ${prop}: ${value};`).join(`
1862
1735
 
1863
1736
  // pkgs/@akanjs/devkit/frontendBuild/fontPruner.ts
1864
1737
  import { rm as rm2, rmdir, stat as stat3 } from "fs/promises";
1865
- import path11 from "path";
1738
+ import path10 from "path";
1866
1739
  import { isFontOptimizationEnabled } from "akanjs/client";
1867
1740
  var FONT_GLOB = "**/*.{woff2,woff,ttf,otf,ttc,eot}";
1868
1741
  var REFERRER_GLOB = "**/*.{css,js,mjs,cjs,json,html,htm,svg,xml,webmanifest}";
@@ -1875,8 +1748,8 @@ class FontPruner {
1875
1748
  constructor(app, { keepFonts = [] } = {}) {
1876
1749
  this.#app = app;
1877
1750
  this.#keepGlobs = keepFonts;
1878
- this.#publicRoot = path11.join(app.dist.cwdPath, "public");
1879
- this.#artifactRoot = path11.join(app.dist.cwdPath, ".akan/artifact");
1751
+ this.#publicRoot = path10.join(app.dist.cwdPath, "public");
1752
+ this.#artifactRoot = path10.join(app.dist.cwdPath, ".akan/artifact");
1880
1753
  }
1881
1754
  async prune() {
1882
1755
  const empty = { removed: [], kept: [], freedBytes: 0 };
@@ -1891,7 +1764,7 @@ class FontPruner {
1891
1764
  for (const font of fonts) {
1892
1765
  const target = isFontOptimizationEnabled(font) ? optimizedSrcs : unoptimizedSrcs;
1893
1766
  for (const fontPath of font.paths)
1894
- target.add(path11.posix.basename(fontPath.src));
1767
+ target.add(path10.posix.basename(fontPath.src));
1895
1768
  }
1896
1769
  const result = { removed: [], kept: [], freedBytes: 0 };
1897
1770
  const undecided = [];
@@ -1929,10 +1802,10 @@ class FontPruner {
1929
1802
  async#collectCandidates() {
1930
1803
  const candidates = [];
1931
1804
  for await (const rel of new Bun.Glob(FONT_GLOB).scan({ cwd: this.#publicRoot, dot: false })) {
1932
- const entry = await stat3(path11.join(this.#publicRoot, rel)).catch(() => null);
1805
+ const entry = await stat3(path10.join(this.#publicRoot, rel)).catch(() => null);
1933
1806
  if (!entry?.isFile())
1934
1807
  continue;
1935
- candidates.push({ rel: rel.split(path11.sep).join("/"), basename: path11.basename(rel), bytes: entry.size });
1808
+ candidates.push({ rel: rel.split(path10.sep).join("/"), basename: path10.basename(rel), bytes: entry.size });
1936
1809
  }
1937
1810
  return candidates;
1938
1811
  }
@@ -1942,11 +1815,11 @@ class FontPruner {
1942
1815
  const bundled = candidates.filter((candidate) => !optimizedSrcs.has(candidate.basename));
1943
1816
  const roots = [
1944
1817
  { dir: this.#publicRoot, label: "public", needles: authoritative },
1945
- { dir: path11.join(this.#artifactRoot, "styles"), label: ".akan/artifact/styles", needles: authoritative },
1946
- { dir: path11.join(this.#artifactRoot, "client"), label: ".akan/artifact/client", needles: bundled },
1947
- { dir: path11.join(this.#artifactRoot, "client-ssr"), label: ".akan/artifact/client-ssr", needles: bundled },
1948
- { dir: path11.join(this.#artifactRoot, "server"), label: ".akan/artifact/server", needles: bundled },
1949
- { dir: path11.join(this.#app.dist.cwdPath, "csr"), label: "csr", needles: bundled }
1818
+ { dir: path10.join(this.#artifactRoot, "styles"), label: ".akan/artifact/styles", needles: authoritative },
1819
+ { dir: path10.join(this.#artifactRoot, "client"), label: ".akan/artifact/client", needles: bundled },
1820
+ { dir: path10.join(this.#artifactRoot, "client-ssr"), label: ".akan/artifact/client-ssr", needles: bundled },
1821
+ { dir: path10.join(this.#artifactRoot, "server"), label: ".akan/artifact/server", needles: bundled },
1822
+ { dir: path10.join(this.#app.dist.cwdPath, "csr"), label: "csr", needles: bundled }
1950
1823
  ];
1951
1824
  for (const root of roots) {
1952
1825
  const pending = root.needles.filter((candidate) => !referrers.has(candidate.rel));
@@ -1965,20 +1838,20 @@ class FontPruner {
1965
1838
  const remaining = needles.filter((needle) => !referrers.has(needle.rel));
1966
1839
  if (!remaining.length)
1967
1840
  return;
1968
- const text = await Bun.file(path11.join(root.dir, rel)).text().catch(() => "");
1841
+ const text = await Bun.file(path10.join(root.dir, rel)).text().catch(() => "");
1969
1842
  if (!text)
1970
1843
  continue;
1971
1844
  for (const needle of remaining) {
1972
1845
  if (needle.forms.some((form) => text.includes(form)))
1973
- referrers.set(needle.rel, `${root.label}/${rel.split(path11.sep).join("/")}`);
1846
+ referrers.set(needle.rel, `${root.label}/${rel.split(path10.sep).join("/")}`);
1974
1847
  }
1975
1848
  }
1976
1849
  }
1977
1850
  async#remove(files) {
1978
- await Promise.all(files.map((file) => rm2(path11.join(this.#publicRoot, file), { force: true })));
1979
- const dirs = [...new Set(files.map((file) => path11.posix.dirname(file)))].filter((dir) => dir !== "." && dir !== "/").sort((a, b) => b.length - a.length);
1851
+ await Promise.all(files.map((file) => rm2(path10.join(this.#publicRoot, file), { force: true })));
1852
+ const dirs = [...new Set(files.map((file) => path10.posix.dirname(file)))].filter((dir) => dir !== "." && dir !== "/").sort((a, b) => b.length - a.length);
1980
1853
  for (const dir of dirs)
1981
- await rmdir(path11.join(this.#publicRoot, dir)).catch(() => {
1854
+ await rmdir(path10.join(this.#publicRoot, dir)).catch(() => {
1982
1855
  return;
1983
1856
  });
1984
1857
  }
@@ -2026,17 +1899,18 @@ class FontPruner {
2026
1899
 
2027
1900
  // pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
2028
1901
  import fs from "fs";
2029
- import path12 from "path";
1902
+ import path11 from "path";
2030
1903
  import zlib from "zlib";
2031
1904
  var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
2032
1905
  var MIN_COMPRESS_BYTES = 1024;
2033
1906
  var BROTLI_QUALITY_BY_EXT = { ".css": 11 };
2034
1907
  var DEFAULT_BROTLI_QUALITY = 9;
2035
1908
  var GZIP_LEVEL = 9;
1909
+ var { formatBytes } = FontPruner;
2036
1910
  async function precompressArtifacts(app) {
2037
1911
  const roots = [
2038
- path12.join(app.dist.cwdPath, ".akan/artifact/client"),
2039
- path12.join(app.dist.cwdPath, ".akan/artifact/styles")
1912
+ path11.join(app.dist.cwdPath, ".akan/artifact/client"),
1913
+ path11.join(app.dist.cwdPath, ".akan/artifact/styles")
2040
1914
  ];
2041
1915
  const result = { files: 0, inputBytes: 0, outputBytes: 0, brotliBytes: 0 };
2042
1916
  await Promise.all(roots.map((root) => precompressRoot(root, result)));
@@ -2053,9 +1927,9 @@ async function precompressRoot(root, result) {
2053
1927
  if (!await shouldPrecompress(filePath))
2054
1928
  continue;
2055
1929
  const bytes = await Bun.file(filePath).bytes();
2056
- const buffer = toArrayBuffer(bytes);
1930
+ const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
2057
1931
  const gz = Bun.gzipSync(buffer, { level: GZIP_LEVEL });
2058
- const br = brotliCompress(buffer, path12.extname(filePath).toLowerCase());
1932
+ const br = brotliCompress(buffer, path11.extname(filePath).toLowerCase());
2059
1933
  await Promise.all([Bun.write(`${filePath}.gz`, gz), Bun.write(`${filePath}.br`, br)]);
2060
1934
  result.files += 1;
2061
1935
  result.inputBytes += bytes.byteLength;
@@ -2075,26 +1949,16 @@ function brotliCompress(buffer, ext) {
2075
1949
  async function shouldPrecompress(filePath) {
2076
1950
  if (filePath.endsWith(".gz") || filePath.endsWith(".br"))
2077
1951
  return false;
2078
- if (!COMPRESSIBLE_EXTS.has(path12.extname(filePath).toLowerCase()))
1952
+ if (!COMPRESSIBLE_EXTS.has(path11.extname(filePath).toLowerCase()))
2079
1953
  return false;
2080
1954
  const file = Bun.file(filePath);
2081
1955
  if (!await file.exists())
2082
1956
  return false;
2083
1957
  return file.size >= MIN_COMPRESS_BYTES;
2084
1958
  }
2085
- function toArrayBuffer(bytes) {
2086
- return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
2087
- }
2088
- function formatBytes(bytes) {
2089
- if (bytes < 1024)
2090
- return `${bytes}B`;
2091
- if (bytes < 1024 * 1024)
2092
- return `${(bytes / 1024).toFixed(1)}KB`;
2093
- return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
2094
- }
2095
1959
 
2096
1960
  // pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
2097
- import path13 from "path";
1961
+ import path12 from "path";
2098
1962
  import { optimize } from "@tailwindcss/node";
2099
1963
  function prepareCssAsset(command, basePath, cssText) {
2100
1964
  return optimize(cssText, { file: `${basePath || "root"}.css`, minify: command === "build" }).code;
@@ -2110,7 +1974,7 @@ class SsrBaseArtifactBuilder {
2110
1974
  this.#app = app;
2111
1975
  this.#command = command;
2112
1976
  this.#artifactDir = `${command === "build" ? app.dist.cwdPath : app.cwdPath}/.akan/artifact`;
2113
- this.#absArtifactDir = path13.resolve(this.#artifactDir);
1977
+ this.#absArtifactDir = path12.resolve(this.#artifactDir);
2114
1978
  }
2115
1979
  async build() {
2116
1980
  const akanConfig = await this.#app.getConfig();
@@ -2132,7 +1996,7 @@ class SsrBaseArtifactBuilder {
2132
1996
  rscRuntimeSsrManifest,
2133
1997
  vendorMap,
2134
1998
  cssAssets,
2135
- pagesBundlePath: this.#command === "build" ? path13.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
1999
+ pagesBundlePath: this.#command === "build" ? path12.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
2136
2000
  pagesBundleBuildId: pagesBundle.buildId,
2137
2001
  domains: [...akanConfig.domains],
2138
2002
  subRoutes: Object.fromEntries(Array.from(akanConfig.subRoutes.entries()).map(([basePath, domains]) => [basePath, [...domains]])),
@@ -2149,18 +2013,18 @@ class SsrBaseArtifactBuilder {
2149
2013
  androidSha256CertFingerprints: target.deepLinks?.android?.sha256CertFingerprints
2150
2014
  }))
2151
2015
  };
2152
- await Bun.write(path13.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
2016
+ await Bun.write(path12.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
2153
2017
  `);
2154
2018
  this.#app.verbose(`[base-artifact] complete in ${Date.now() - this.#started}ms`);
2155
2019
  return { artifact, seedIndex, cssCompiler, optimizedFonts };
2156
2020
  }
2157
2021
  async#buildRuntimeClientEntries() {
2158
2022
  const akanServerPath = await this.#resolveAkanServerPath();
2159
- const rscClientEntry = path13.resolve(akanServerPath, "rscClient.tsx");
2160
- const rscSegmentOutletEntry = path13.resolve(akanServerPath, "rscSegmentOutlet.tsx");
2023
+ const rscClientEntry = path12.resolve(akanServerPath, "rscClient.tsx");
2024
+ const rscSegmentOutletEntry = path12.resolve(akanServerPath, "rscSegmentOutlet.tsx");
2161
2025
  const vendorEntries = VENDOR_SPECIFIERS.map((specifier) => ({
2162
2026
  specifier,
2163
- absPath: path13.resolve(akanServerPath, "vendor", `${specifier.replaceAll("/", "-").replaceAll(".", "-")}.ts`)
2027
+ absPath: path12.resolve(akanServerPath, "vendor", `${specifier.replaceAll("/", "-").replaceAll(".", "-")}.ts`)
2164
2028
  }));
2165
2029
  const entries = [rscClientEntry, rscSegmentOutletEntry, ...vendorEntries.map((v) => v.absPath)];
2166
2030
  const clientBundle = await new ClientEntriesBundler({ app: this.#app, entries, command: this.#command }).bundle();
@@ -2197,15 +2061,15 @@ class SsrBaseArtifactBuilder {
2197
2061
  async#resolveAkanServerPath() {
2198
2062
  const candidates = [];
2199
2063
  try {
2200
- candidates.push(path13.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
2064
+ candidates.push(path12.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
2201
2065
  } catch {}
2202
- candidates.push(path13.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path13.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
2066
+ candidates.push(path12.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path12.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
2203
2067
  try {
2204
- candidates.push(path13.dirname(Bun.resolveSync("akanjs/server", path13.dirname(Bun.main))));
2068
+ candidates.push(path12.dirname(Bun.resolveSync("akanjs/server", path12.dirname(Bun.main))));
2205
2069
  } catch {}
2206
- candidates.push(path13.join(path13.dirname(Bun.main), "node_modules/akanjs/server"), path13.join(path13.dirname(Bun.main), "../../akanjs/server"), path13.resolve(import.meta.dir, "../../server"), path13.resolve(import.meta.dir, "../server"));
2070
+ candidates.push(path12.join(path12.dirname(Bun.main), "node_modules/akanjs/server"), path12.join(path12.dirname(Bun.main), "../../akanjs/server"), path12.resolve(import.meta.dir, "../../server"), path12.resolve(import.meta.dir, "../server"));
2207
2071
  for (const candidate of candidates) {
2208
- if (await Bun.file(path13.join(candidate, "rscClient.tsx")).exists())
2072
+ if (await Bun.file(path12.join(candidate, "rscClient.tsx")).exists())
2209
2073
  return candidate;
2210
2074
  }
2211
2075
  throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
@@ -2234,7 +2098,7 @@ ${preparedCssText}`).toString(36);
2234
2098
  `styles/${cssAssetName}-${cssHash}.css`,
2235
2099
  `/_akan/styles/${cssAssetName}-${cssHash}.css`
2236
2100
  ];
2237
- await Bun.write(path13.join(this.#absArtifactDir, cssRelPath), preparedCssText);
2101
+ await Bun.write(path12.join(this.#absArtifactDir, cssRelPath), preparedCssText);
2238
2102
  SsrBaseArtifactBuilder.#warnDroppedImports(this.#app, cssRelPath, preparedCssText, imported);
2239
2103
  this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath} -> ${cssRelPath}`);
2240
2104
  return [basePath, { cssUrl, cssRelPath }];