@float.js/core 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
4
10
  var __esm = (fn, res) => function __init() {
5
11
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
12
  };
@@ -9,11 +15,11 @@ var __export = (target, all) => {
9
15
  __defProp(target, name, { get: all[name], enumerable: true });
10
16
  };
11
17
 
12
- // ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
18
+ // ../../node_modules/.pnpm/tsup@8.5.1_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
13
19
  import path from "path";
14
20
  import { fileURLToPath } from "url";
15
21
  var init_esm_shims = __esm({
16
- "../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js"() {
22
+ "../../node_modules/.pnpm/tsup@8.5.1_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js"() {
17
23
  "use strict";
18
24
  }
19
25
  });
@@ -730,7 +736,7 @@ function generateAPIResponse(state) {
730
736
  function createDevDashboard(options = {}) {
731
737
  const {
732
738
  enabled = process.env.NODE_ENV !== "production",
733
- path: path9 = "/__float",
739
+ path: path10 = "/__float",
734
740
  auth
735
741
  } = options;
736
742
  if (!enabled) {
@@ -738,7 +744,7 @@ function createDevDashboard(options = {}) {
738
744
  }
739
745
  return (req, res, next) => {
740
746
  const url = req.url || "";
741
- if (!url.startsWith(path9)) {
747
+ if (!url.startsWith(path10)) {
742
748
  return next();
743
749
  }
744
750
  if (auth) {
@@ -757,7 +763,7 @@ function createDevDashboard(options = {}) {
757
763
  return;
758
764
  }
759
765
  }
760
- const subPath = url.slice(path9.length);
766
+ const subPath = url.slice(path10.length);
761
767
  if (subPath === "" || subPath === "/") {
762
768
  res.setHeader("Content-Type", "text/html");
763
769
  res.end(generateDashboardHTML(dashboardState));
@@ -873,8 +879,8 @@ import pc5 from "picocolors";
873
879
  // src/server/dev-server.ts
874
880
  init_esm_shims();
875
881
  import http from "http";
876
- import fs4 from "fs";
877
- import path6 from "path";
882
+ import fs5 from "fs";
883
+ import path7 from "path";
878
884
  import pc2 from "picocolors";
879
885
  import chokidar from "chokidar";
880
886
  import { WebSocketServer, WebSocket } from "ws";
@@ -937,6 +943,26 @@ function findLayouts(routePath, allLayouts) {
937
943
  }
938
944
  return layouts;
939
945
  }
946
+ function findLoading(routePath, allLoading) {
947
+ const segments = routePath.split("/").filter(Boolean);
948
+ for (let i = segments.length; i >= 0; i--) {
949
+ const currentPath = i === 0 ? "/" : "/" + segments.slice(0, i).join("/");
950
+ if (allLoading.has(currentPath)) {
951
+ return allLoading.get(currentPath);
952
+ }
953
+ }
954
+ return void 0;
955
+ }
956
+ function findError(routePath, allErrors) {
957
+ const segments = routePath.split("/").filter(Boolean);
958
+ for (let i = segments.length; i >= 0; i--) {
959
+ const currentPath = i === 0 ? "/" : "/" + segments.slice(0, i).join("/");
960
+ if (allErrors.has(currentPath)) {
961
+ return allErrors.get(currentPath);
962
+ }
963
+ }
964
+ return void 0;
965
+ }
940
966
  async function scanRoutes(rootDir, options = {}) {
941
967
  const opts = { ...DEFAULT_OPTIONS, ...options };
942
968
  const appDir = path2.join(rootDir, opts.appDir);
@@ -948,12 +974,20 @@ async function scanRoutes(rootDir, options = {}) {
948
974
  ignore: ["**/node_modules/**", "**/_*/**"]
949
975
  });
950
976
  const layoutMap = /* @__PURE__ */ new Map();
977
+ const loadingMap = /* @__PURE__ */ new Map();
978
+ const errorMap = /* @__PURE__ */ new Map();
951
979
  for (const file of files) {
952
980
  const type = getRouteType(file);
981
+ const { urlPath } = filePathToUrlPath(file, "");
953
982
  if (type === "layout") {
954
- const { urlPath } = filePathToUrlPath(file, "");
955
983
  const layoutPath = urlPath === "/" ? "/" : urlPath.replace(/\/layout$/, "") || "/";
956
984
  layoutMap.set(layoutPath, path2.join(appDir, file));
985
+ } else if (type === "loading") {
986
+ const loadingPath = urlPath === "/" ? "/" : urlPath.replace(/\/loading$/, "") || "/";
987
+ loadingMap.set(loadingPath, path2.join(appDir, file));
988
+ } else if (type === "error") {
989
+ const errorPath = urlPath === "/" ? "/" : urlPath.replace(/\/error$/, "") || "/";
990
+ errorMap.set(errorPath, path2.join(appDir, file));
957
991
  }
958
992
  }
959
993
  const routes = [];
@@ -971,7 +1005,9 @@ async function scanRoutes(rootDir, options = {}) {
971
1005
  params,
972
1006
  isCatchAll,
973
1007
  isOptionalCatchAll,
974
- layouts: type === "page" ? findLayouts(urlPath, layoutMap) : []
1008
+ layouts: type === "page" ? findLayouts(urlPath, layoutMap) : [],
1009
+ loading: type === "page" ? findLoading(urlPath, loadingMap) : void 0,
1010
+ error: type === "page" ? findError(urlPath, errorMap) : void 0
975
1011
  };
976
1012
  routes.push(route);
977
1013
  }
@@ -1029,23 +1065,222 @@ import { Writable } from "stream";
1029
1065
  // src/build/transform.ts
1030
1066
  init_esm_shims();
1031
1067
  import * as esbuild from "esbuild";
1068
+ import fs2 from "fs";
1069
+ import path4 from "path";
1070
+ import { pathToFileURL } from "url";
1071
+
1072
+ // src/build/persistent-cache.ts
1073
+ init_esm_shims();
1032
1074
  import fs from "fs";
1033
1075
  import path3 from "path";
1034
- import { pathToFileURL } from "url";
1076
+ import crypto from "crypto";
1077
+ var PersistentCache = class {
1078
+ cacheDir;
1079
+ manifestPath;
1080
+ manifest;
1081
+ constructor(rootDir = process.cwd()) {
1082
+ this.cacheDir = path3.join(rootDir, ".float", "cache");
1083
+ this.manifestPath = path3.join(this.cacheDir, "manifest.json");
1084
+ fs.mkdirSync(this.cacheDir, { recursive: true });
1085
+ this.manifest = this.loadManifest();
1086
+ }
1087
+ loadManifest() {
1088
+ if (fs.existsSync(this.manifestPath)) {
1089
+ try {
1090
+ const data = fs.readFileSync(this.manifestPath, "utf-8");
1091
+ return JSON.parse(data);
1092
+ } catch {
1093
+ }
1094
+ }
1095
+ return {
1096
+ version: "1.0",
1097
+ entries: {}
1098
+ };
1099
+ }
1100
+ saveManifest() {
1101
+ fs.writeFileSync(
1102
+ this.manifestPath,
1103
+ JSON.stringify(this.manifest, null, 2)
1104
+ );
1105
+ }
1106
+ /**
1107
+ * Generate hash for content
1108
+ */
1109
+ hash(content) {
1110
+ return crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
1111
+ }
1112
+ /**
1113
+ * Get cache key path
1114
+ */
1115
+ getKeyPath(key) {
1116
+ const safeKey = key.replace(/[^a-z0-9_-]/gi, "_");
1117
+ return path3.join(this.cacheDir, `${safeKey}.cache`);
1118
+ }
1119
+ /**
1120
+ * Check if cache entry is valid
1121
+ */
1122
+ has(key, contentHash) {
1123
+ const entry = this.manifest.entries[key];
1124
+ if (!entry) return false;
1125
+ const cachePath = this.getKeyPath(key);
1126
+ if (!fs.existsSync(cachePath)) {
1127
+ delete this.manifest.entries[key];
1128
+ this.saveManifest();
1129
+ return false;
1130
+ }
1131
+ if (contentHash && entry.hash !== contentHash) {
1132
+ return false;
1133
+ }
1134
+ return true;
1135
+ }
1136
+ /**
1137
+ * Get cached value
1138
+ */
1139
+ get(key) {
1140
+ if (!this.has(key)) return null;
1141
+ try {
1142
+ const cachePath = this.getKeyPath(key);
1143
+ const data = fs.readFileSync(cachePath, "utf-8");
1144
+ const entry = JSON.parse(data);
1145
+ return entry.value;
1146
+ } catch {
1147
+ return null;
1148
+ }
1149
+ }
1150
+ /**
1151
+ * Set cache value
1152
+ */
1153
+ set(key, value, content) {
1154
+ const entry = {
1155
+ key,
1156
+ value,
1157
+ timestamp: Date.now(),
1158
+ hash: content ? this.hash(content) : this.hash(JSON.stringify(value))
1159
+ };
1160
+ const cachePath = this.getKeyPath(key);
1161
+ const data = JSON.stringify(entry);
1162
+ fs.writeFileSync(cachePath, data);
1163
+ this.manifest.entries[key] = {
1164
+ hash: entry.hash,
1165
+ timestamp: entry.timestamp,
1166
+ size: Buffer.byteLength(data)
1167
+ };
1168
+ this.saveManifest();
1169
+ }
1170
+ /**
1171
+ * Delete cache entry
1172
+ */
1173
+ delete(key) {
1174
+ const cachePath = this.getKeyPath(key);
1175
+ if (fs.existsSync(cachePath)) {
1176
+ fs.unlinkSync(cachePath);
1177
+ }
1178
+ if (this.manifest.entries[key]) {
1179
+ delete this.manifest.entries[key];
1180
+ this.saveManifest();
1181
+ return true;
1182
+ }
1183
+ return false;
1184
+ }
1185
+ /**
1186
+ * Clear all cache
1187
+ */
1188
+ clear() {
1189
+ if (fs.existsSync(this.cacheDir)) {
1190
+ fs.rmSync(this.cacheDir, { recursive: true });
1191
+ fs.mkdirSync(this.cacheDir, { recursive: true });
1192
+ }
1193
+ this.manifest = {
1194
+ version: "1.0",
1195
+ entries: {}
1196
+ };
1197
+ this.saveManifest();
1198
+ }
1199
+ /**
1200
+ * Get cache statistics
1201
+ */
1202
+ stats() {
1203
+ const entries = Object.values(this.manifest.entries);
1204
+ const size = entries.reduce((acc, e) => acc + e.size, 0);
1205
+ const timestamps = entries.map((e) => e.timestamp);
1206
+ return {
1207
+ entries: entries.length,
1208
+ size,
1209
+ oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : null,
1210
+ newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : null
1211
+ };
1212
+ }
1213
+ /**
1214
+ * Clean old entries (older than maxAge milliseconds)
1215
+ */
1216
+ prune(maxAge = 7 * 24 * 60 * 60 * 1e3) {
1217
+ const now = Date.now();
1218
+ let cleaned = 0;
1219
+ for (const [key, entry] of Object.entries(this.manifest.entries)) {
1220
+ if (now - entry.timestamp > maxAge) {
1221
+ this.delete(key);
1222
+ cleaned++;
1223
+ }
1224
+ }
1225
+ return cleaned;
1226
+ }
1227
+ };
1228
+ var globalCache = null;
1229
+ function getCache(rootDir) {
1230
+ if (!globalCache) {
1231
+ globalCache = new PersistentCache(rootDir);
1232
+ }
1233
+ return globalCache;
1234
+ }
1235
+
1236
+ // src/build/transform.ts
1035
1237
  var moduleCache = /* @__PURE__ */ new Map();
1036
- async function transformFile(filePath) {
1037
- const absolutePath = path3.isAbsolute(filePath) ? filePath : path3.resolve(filePath);
1038
- if (!fs.existsSync(absolutePath)) {
1238
+ async function transformFile(filePath, useCache = true) {
1239
+ const absolutePath = path4.isAbsolute(filePath) ? filePath : path4.resolve(filePath);
1240
+ if (!fs2.existsSync(absolutePath)) {
1039
1241
  throw new Error(`File not found: ${absolutePath}`);
1040
1242
  }
1041
- const stats = fs.statSync(absolutePath);
1243
+ const stats = fs2.statSync(absolutePath);
1042
1244
  const mtime = stats.mtimeMs;
1043
1245
  const cached = moduleCache.get(absolutePath);
1044
1246
  if (cached && cached.mtime === mtime) {
1045
1247
  return cached.module;
1046
1248
  }
1047
- const source = fs.readFileSync(absolutePath, "utf-8");
1048
- const ext = path3.extname(absolutePath);
1249
+ if (useCache) {
1250
+ const cache = getCache();
1251
+ const source2 = fs2.readFileSync(absolutePath, "utf-8");
1252
+ const sourceHash = __require("crypto").createHash("sha256").update(source2).digest("hex").slice(0, 16);
1253
+ const cacheKey = `transform_${absolutePath}_${sourceHash}`;
1254
+ if (cache.has(cacheKey)) {
1255
+ const cachedCode = cache.get(cacheKey);
1256
+ if (cachedCode) {
1257
+ const tempDir2 = path4.join(process.cwd(), ".float", ".cache");
1258
+ fs2.mkdirSync(tempDir2, { recursive: true });
1259
+ const tempFile2 = path4.join(tempDir2, `${path4.basename(absolutePath, path4.extname(absolutePath))}_${Date.now()}.mjs`);
1260
+ fs2.writeFileSync(tempFile2, cachedCode);
1261
+ try {
1262
+ const module = await import(pathToFileURL(tempFile2).href);
1263
+ moduleCache.set(absolutePath, { module, mtime });
1264
+ setImmediate(() => {
1265
+ try {
1266
+ fs2.unlinkSync(tempFile2);
1267
+ } catch {
1268
+ }
1269
+ });
1270
+ return module;
1271
+ } catch (error) {
1272
+ setImmediate(() => {
1273
+ try {
1274
+ fs2.unlinkSync(tempFile2);
1275
+ } catch {
1276
+ }
1277
+ });
1278
+ }
1279
+ }
1280
+ }
1281
+ }
1282
+ const source = fs2.readFileSync(absolutePath, "utf-8");
1283
+ const ext = path4.extname(absolutePath);
1049
1284
  const loader = getLoader(ext);
1050
1285
  const result = await esbuild.transform(source, {
1051
1286
  loader,
@@ -1055,25 +1290,31 @@ async function transformFile(filePath) {
1055
1290
  sourcemap: "inline",
1056
1291
  sourcefile: absolutePath
1057
1292
  });
1058
- const tempDir = path3.join(process.cwd(), ".float", ".cache");
1059
- fs.mkdirSync(tempDir, { recursive: true });
1060
- const tempFile = path3.join(tempDir, `${path3.basename(absolutePath, ext)}_${Date.now()}.mjs`);
1293
+ const tempDir = path4.join(process.cwd(), ".float", ".cache");
1294
+ fs2.mkdirSync(tempDir, { recursive: true });
1295
+ const tempFile = path4.join(tempDir, `${path4.basename(absolutePath, ext)}_${Date.now()}.mjs`);
1061
1296
  let code = result.code;
1062
- code = rewriteImports(code, path3.dirname(absolutePath));
1063
- fs.writeFileSync(tempFile, code);
1297
+ code = rewriteImports(code, path4.dirname(absolutePath));
1298
+ fs2.writeFileSync(tempFile, code);
1064
1299
  try {
1065
1300
  const module = await import(pathToFileURL(tempFile).href);
1066
1301
  moduleCache.set(absolutePath, { module, mtime });
1302
+ if (useCache) {
1303
+ const cache = getCache();
1304
+ const sourceHash = __require("crypto").createHash("sha256").update(source).digest("hex").slice(0, 16);
1305
+ const cacheKey = `transform_${absolutePath}_${sourceHash}`;
1306
+ cache.set(cacheKey, code, source);
1307
+ }
1067
1308
  setImmediate(() => {
1068
1309
  try {
1069
- fs.unlinkSync(tempFile);
1310
+ fs2.unlinkSync(tempFile);
1070
1311
  } catch {
1071
1312
  }
1072
1313
  });
1073
1314
  return module;
1074
1315
  } catch (error) {
1075
1316
  try {
1076
- fs.unlinkSync(tempFile);
1317
+ fs2.unlinkSync(tempFile);
1077
1318
  } catch {
1078
1319
  }
1079
1320
  throw error;
@@ -1102,18 +1343,18 @@ function getLoader(ext) {
1102
1343
  function rewriteImports(code, baseDir) {
1103
1344
  const importRegex = /from\s+['"](\.[^'"]+)['"]/g;
1104
1345
  return code.replace(importRegex, (match, importPath) => {
1105
- let resolvedPath = path3.resolve(baseDir, importPath);
1346
+ let resolvedPath = path4.resolve(baseDir, importPath);
1106
1347
  const extensions = [".tsx", ".ts", ".jsx", ".js", ".mjs", ""];
1107
1348
  let found = false;
1108
1349
  for (const ext of extensions) {
1109
1350
  const tryPath = resolvedPath + ext;
1110
- if (fs.existsSync(tryPath)) {
1351
+ if (fs2.existsSync(tryPath)) {
1111
1352
  resolvedPath = tryPath;
1112
1353
  found = true;
1113
1354
  break;
1114
1355
  }
1115
- const indexPath = path3.join(resolvedPath, `index${ext}`);
1116
- if (fs.existsSync(indexPath)) {
1356
+ const indexPath = path4.join(resolvedPath, `index${ext}`);
1357
+ if (fs2.existsSync(indexPath)) {
1117
1358
  resolvedPath = indexPath;
1118
1359
  found = true;
1119
1360
  break;
@@ -2466,13 +2707,13 @@ function generateExamplesPage() {
2466
2707
 
2467
2708
  // src/build/css-processor.ts
2468
2709
  init_esm_shims();
2469
- import fs3 from "fs";
2470
- import path5 from "path";
2710
+ import fs4 from "fs";
2711
+ import path6 from "path";
2471
2712
 
2472
2713
  // src/build/tailwind-setup.ts
2473
2714
  init_esm_shims();
2474
- import fs2 from "fs";
2475
- import path4 from "path";
2715
+ import fs3 from "fs";
2716
+ import path5 from "path";
2476
2717
  import pc from "picocolors";
2477
2718
  function checkTailwindSetup(rootDir) {
2478
2719
  const possibleConfigs = [
@@ -2483,14 +2724,14 @@ function checkTailwindSetup(rootDir) {
2483
2724
  ];
2484
2725
  let configPath = null;
2485
2726
  for (const config of possibleConfigs) {
2486
- const fullPath = path4.join(rootDir, config);
2487
- if (fs2.existsSync(fullPath)) {
2727
+ const fullPath = path5.join(rootDir, config);
2728
+ if (fs3.existsSync(fullPath)) {
2488
2729
  configPath = fullPath;
2489
2730
  break;
2490
2731
  }
2491
2732
  }
2492
- const globalsPath = path4.join(rootDir, "app", "globals.css");
2493
- const hasGlobals = fs2.existsSync(globalsPath);
2733
+ const globalsPath = path5.join(rootDir, "app", "globals.css");
2734
+ const hasGlobals = fs3.existsSync(globalsPath);
2494
2735
  return {
2495
2736
  hasTailwind: !!configPath,
2496
2737
  configPath,
@@ -2520,14 +2761,14 @@ export default {
2520
2761
  plugins: [],
2521
2762
  }
2522
2763
  `;
2523
- const configPath = path4.join(rootDir, "tailwind.config.js");
2524
- fs2.writeFileSync(configPath, tailwindConfig);
2764
+ const configPath = path5.join(rootDir, "tailwind.config.js");
2765
+ fs3.writeFileSync(configPath, tailwindConfig);
2525
2766
  if (!silent) {
2526
2767
  console.log(pc.green(" \u2713 Created tailwind.config.js"));
2527
2768
  }
2528
2769
  }
2529
- const postcssPath = path4.join(rootDir, "postcss.config.js");
2530
- if (!fs2.existsSync(postcssPath) || force) {
2770
+ const postcssPath = path5.join(rootDir, "postcss.config.js");
2771
+ if (!fs3.existsSync(postcssPath) || force) {
2531
2772
  const postcssConfig = `export default {
2532
2773
  plugins: {
2533
2774
  tailwindcss: {},
@@ -2535,28 +2776,28 @@ export default {
2535
2776
  },
2536
2777
  }
2537
2778
  `;
2538
- fs2.writeFileSync(postcssPath, postcssConfig);
2779
+ fs3.writeFileSync(postcssPath, postcssConfig);
2539
2780
  if (!silent) {
2540
2781
  console.log(pc.green(" \u2713 Created postcss.config.js"));
2541
2782
  }
2542
2783
  }
2543
- const appDir = path4.join(rootDir, "app");
2544
- if (!fs2.existsSync(appDir)) {
2545
- fs2.mkdirSync(appDir, { recursive: true });
2784
+ const appDir = path5.join(rootDir, "app");
2785
+ if (!fs3.existsSync(appDir)) {
2786
+ fs3.mkdirSync(appDir, { recursive: true });
2546
2787
  }
2547
- const globalsPath = path4.join(appDir, "globals.css");
2548
- if (!fs2.existsSync(globalsPath) || force) {
2788
+ const globalsPath = path5.join(appDir, "globals.css");
2789
+ if (!fs3.existsSync(globalsPath) || force) {
2549
2790
  const globalsCss = `@tailwind base;
2550
2791
  @tailwind components;
2551
2792
  @tailwind utilities;
2552
2793
  `;
2553
- fs2.writeFileSync(globalsPath, globalsCss);
2794
+ fs3.writeFileSync(globalsPath, globalsCss);
2554
2795
  if (!silent) {
2555
2796
  console.log(pc.green(" \u2713 Created app/globals.css"));
2556
2797
  }
2557
2798
  }
2558
- const layoutPath = path4.join(appDir, "layout.tsx");
2559
- if (!fs2.existsSync(layoutPath)) {
2799
+ const layoutPath = path5.join(appDir, "layout.tsx");
2800
+ if (!fs3.existsSync(layoutPath)) {
2560
2801
  const layoutContent = `import './globals.css'
2561
2802
 
2562
2803
  export default function RootLayout({
@@ -2571,7 +2812,7 @@ export default function RootLayout({
2571
2812
  )
2572
2813
  }
2573
2814
  `;
2574
- fs2.writeFileSync(layoutPath, layoutContent);
2815
+ fs3.writeFileSync(layoutPath, layoutContent);
2575
2816
  if (!silent) {
2576
2817
  console.log(pc.green(" \u2713 Created app/layout.tsx"));
2577
2818
  }
@@ -2581,8 +2822,8 @@ export default function RootLayout({
2581
2822
  }
2582
2823
  }
2583
2824
  function checkTailwindDeps(rootDir) {
2584
- const packageJsonPath = path4.join(rootDir, "package.json");
2585
- if (!fs2.existsSync(packageJsonPath)) {
2825
+ const packageJsonPath = path5.join(rootDir, "package.json");
2826
+ if (!fs3.existsSync(packageJsonPath)) {
2586
2827
  return {
2587
2828
  hasPackageJson: false,
2588
2829
  hasTailwind: false,
@@ -2590,7 +2831,7 @@ function checkTailwindDeps(rootDir) {
2590
2831
  hasAutoprefixer: false
2591
2832
  };
2592
2833
  }
2593
- const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
2834
+ const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
2594
2835
  const allDeps = {
2595
2836
  ...packageJson.dependencies,
2596
2837
  ...packageJson.devDependencies
@@ -2614,9 +2855,9 @@ function getTailwindInstallCommand(rootDir) {
2614
2855
  if (missing.length === 0) {
2615
2856
  return null;
2616
2857
  }
2617
- const hasYarnLock = fs2.existsSync(path4.join(rootDir, "yarn.lock"));
2618
- const hasPnpmLock = fs2.existsSync(path4.join(rootDir, "pnpm-lock.yaml"));
2619
- const hasBunLock = fs2.existsSync(path4.join(rootDir, "bun.lockb"));
2858
+ const hasYarnLock = fs3.existsSync(path5.join(rootDir, "yarn.lock"));
2859
+ const hasPnpmLock = fs3.existsSync(path5.join(rootDir, "pnpm-lock.yaml"));
2860
+ const hasBunLock = fs3.existsSync(path5.join(rootDir, "bun.lockb"));
2620
2861
  let pm = "npm install -D";
2621
2862
  if (hasBunLock) pm = "bun add -d";
2622
2863
  else if (hasPnpmLock) pm = "pnpm add -D";
@@ -2626,7 +2867,7 @@ function getTailwindInstallCommand(rootDir) {
2626
2867
 
2627
2868
  // src/build/css-processor.ts
2628
2869
  async function processCSS(filePath, rootDir = process.cwd()) {
2629
- const content = fs3.readFileSync(filePath, "utf-8");
2870
+ const content = fs4.readFileSync(filePath, "utf-8");
2630
2871
  const tailwindConfig = checkTailwindSetup(rootDir);
2631
2872
  if (!tailwindConfig.hasTailwind) {
2632
2873
  return { code: content };
@@ -2635,9 +2876,9 @@ async function processCSS(filePath, rootDir = process.cwd()) {
2635
2876
  const postcss = await import("postcss").then((m) => m.default);
2636
2877
  const tailwindcss = await import("tailwindcss").then((m) => m.default);
2637
2878
  const autoprefixer = await import("autoprefixer").then((m) => m.default);
2638
- const configPath = tailwindConfig.configPath || path5.join(rootDir, "tailwind.config.js");
2879
+ const configPath = tailwindConfig.configPath || path6.join(rootDir, "tailwind.config.js");
2639
2880
  let tailwindConfigModule = {};
2640
- if (fs3.existsSync(configPath)) {
2881
+ if (fs4.existsSync(configPath)) {
2641
2882
  const configUrl = new URL(`file://${configPath}`);
2642
2883
  tailwindConfigModule = await import(configUrl.href).then((m) => m.default || m);
2643
2884
  }
@@ -2663,7 +2904,7 @@ function needsCSSProcessing(filePath, rootDir) {
2663
2904
  if (!config.hasTailwind) {
2664
2905
  return false;
2665
2906
  }
2666
- const content = fs3.readFileSync(filePath, "utf-8");
2907
+ const content = fs4.readFileSync(filePath, "utf-8");
2667
2908
  return content.includes("@tailwind") || content.includes("@apply");
2668
2909
  }
2669
2910
 
@@ -2671,7 +2912,7 @@ function needsCSSProcessing(filePath, rootDir) {
2671
2912
  async function createDevServer(options) {
2672
2913
  const { port, host, open } = options;
2673
2914
  const rootDir = process.cwd();
2674
- const publicDir = path6.join(rootDir, "public");
2915
+ const publicDir = path7.join(rootDir, "public");
2675
2916
  let routes = [];
2676
2917
  let server = null;
2677
2918
  let wss = null;
@@ -2755,17 +2996,17 @@ ${FLOAT_ERROR_OVERLAY}
2755
2996
  const pathname = url.pathname;
2756
2997
  console.log(pc2.dim(` ${req.method} ${pathname}`));
2757
2998
  try {
2758
- const publicFilePath = path6.join(publicDir, pathname);
2759
- if (fs4.existsSync(publicFilePath) && fs4.statSync(publicFilePath).isFile()) {
2760
- const content = fs4.readFileSync(publicFilePath);
2999
+ const publicFilePath = path7.join(publicDir, pathname);
3000
+ if (fs5.existsSync(publicFilePath) && fs5.statSync(publicFilePath).isFile()) {
3001
+ const content = fs5.readFileSync(publicFilePath);
2761
3002
  const contentType = mime.lookup(publicFilePath) || "application/octet-stream";
2762
3003
  res.writeHead(200, { "Content-Type": contentType });
2763
3004
  res.end(content);
2764
3005
  return;
2765
3006
  }
2766
3007
  if (pathname.endsWith(".css")) {
2767
- const cssPath = path6.join(rootDir, "app", pathname.replace(/^\//, ""));
2768
- if (fs4.existsSync(cssPath)) {
3008
+ const cssPath = path7.join(rootDir, "app", pathname.replace(/^\//, ""));
3009
+ if (fs5.existsSync(cssPath)) {
2769
3010
  try {
2770
3011
  const needsProcessing = needsCSSProcessing(cssPath, rootDir);
2771
3012
  if (needsProcessing) {
@@ -2776,7 +3017,7 @@ ${FLOAT_ERROR_OVERLAY}
2776
3017
  });
2777
3018
  res.end(result.code);
2778
3019
  } else {
2779
- const content = fs4.readFileSync(cssPath, "utf-8");
3020
+ const content = fs5.readFileSync(cssPath, "utf-8");
2780
3021
  res.writeHead(200, {
2781
3022
  "Content-Type": "text/css",
2782
3023
  "Cache-Control": "no-cache"
@@ -2786,7 +3027,7 @@ ${FLOAT_ERROR_OVERLAY}
2786
3027
  return;
2787
3028
  } catch (error) {
2788
3029
  console.error(pc2.red("CSS processing error:"), error);
2789
- const content = fs4.readFileSync(cssPath, "utf-8");
3030
+ const content = fs5.readFileSync(cssPath, "utf-8");
2790
3031
  res.writeHead(200, { "Content-Type": "text/css" });
2791
3032
  res.end(content);
2792
3033
  return;
@@ -2901,9 +3142,9 @@ ${FLOAT_ERROR_OVERLAY}
2901
3142
  });
2902
3143
  const watcher = chokidar.watch(
2903
3144
  [
2904
- path6.join(rootDir, "app/**/*.{ts,tsx,js,jsx}"),
2905
- path6.join(rootDir, "components/**/*.{ts,tsx,js,jsx}"),
2906
- path6.join(rootDir, "lib/**/*.{ts,tsx,js,jsx}")
3145
+ path7.join(rootDir, "app/**/*.{ts,tsx,js,jsx}"),
3146
+ path7.join(rootDir, "components/**/*.{ts,tsx,js,jsx}"),
3147
+ path7.join(rootDir, "lib/**/*.{ts,tsx,js,jsx}")
2907
3148
  ],
2908
3149
  {
2909
3150
  ignored: /node_modules/,
@@ -2912,7 +3153,7 @@ ${FLOAT_ERROR_OVERLAY}
2912
3153
  );
2913
3154
  watcher.on("change", async (filePath) => {
2914
3155
  console.log(pc2.yellow(`
2915
- \u26A1 File changed: ${path6.relative(rootDir, filePath)}`));
3156
+ \u26A1 File changed: ${path7.relative(rootDir, filePath)}`));
2916
3157
  if (filePath.includes("/app/")) {
2917
3158
  await refreshRoutes();
2918
3159
  }
@@ -2921,7 +3162,7 @@ ${FLOAT_ERROR_OVERLAY}
2921
3162
  watcher.on("add", async (filePath) => {
2922
3163
  if (filePath.includes("/app/")) {
2923
3164
  console.log(pc2.green(`
2924
- \u2795 File added: ${path6.relative(rootDir, filePath)}`));
3165
+ \u2795 File added: ${path7.relative(rootDir, filePath)}`));
2925
3166
  await refreshRoutes();
2926
3167
  notifyClients("reload");
2927
3168
  }
@@ -2929,7 +3170,7 @@ ${FLOAT_ERROR_OVERLAY}
2929
3170
  watcher.on("unlink", async (filePath) => {
2930
3171
  if (filePath.includes("/app/")) {
2931
3172
  console.log(pc2.red(`
2932
- \u2796 File removed: ${path6.relative(rootDir, filePath)}`));
3173
+ \u2796 File removed: ${path7.relative(rootDir, filePath)}`));
2933
3174
  await refreshRoutes();
2934
3175
  notifyClients("reload");
2935
3176
  }
@@ -3064,8 +3305,8 @@ function escapeHtml2(text) {
3064
3305
  // src/build/index.ts
3065
3306
  init_esm_shims();
3066
3307
  import * as esbuild2 from "esbuild";
3067
- import fs5 from "fs";
3068
- import path7 from "path";
3308
+ import fs6 from "fs";
3309
+ import path8 from "path";
3069
3310
  import pc3 from "picocolors";
3070
3311
  var DEFAULT_BUILD_OPTIONS = {
3071
3312
  analyze: false,
@@ -3076,14 +3317,14 @@ async function build2(options = {}) {
3076
3317
  const opts = { ...DEFAULT_BUILD_OPTIONS, ...options };
3077
3318
  const startTime = Date.now();
3078
3319
  const rootDir = process.cwd();
3079
- const outputDir = path7.join(rootDir, ".float");
3080
- if (fs5.existsSync(outputDir)) {
3081
- fs5.rmSync(outputDir, { recursive: true });
3082
- }
3083
- fs5.mkdirSync(outputDir, { recursive: true });
3084
- fs5.mkdirSync(path7.join(outputDir, "pages"), { recursive: true });
3085
- fs5.mkdirSync(path7.join(outputDir, "static"), { recursive: true });
3086
- fs5.mkdirSync(path7.join(outputDir, "server"), { recursive: true });
3320
+ const outputDir = path8.join(rootDir, ".float");
3321
+ if (fs6.existsSync(outputDir)) {
3322
+ fs6.rmSync(outputDir, { recursive: true });
3323
+ }
3324
+ fs6.mkdirSync(outputDir, { recursive: true });
3325
+ fs6.mkdirSync(path8.join(outputDir, "pages"), { recursive: true });
3326
+ fs6.mkdirSync(path8.join(outputDir, "static"), { recursive: true });
3327
+ fs6.mkdirSync(path8.join(outputDir, "server"), { recursive: true });
3087
3328
  console.log(pc3.dim(" Scanning routes..."));
3088
3329
  const routes = await scanRoutes(rootDir);
3089
3330
  const pageRoutes = routes.filter((r) => r.type === "page" && !r.params.length);
@@ -3096,7 +3337,7 @@ async function build2(options = {}) {
3096
3337
  await esbuild2.build({
3097
3338
  entryPoints: clientEntryPoints,
3098
3339
  bundle: true,
3099
- outdir: path7.join(outputDir, "static", "_float"),
3340
+ outdir: path8.join(outputDir, "static", "_float"),
3100
3341
  format: "esm",
3101
3342
  splitting: true,
3102
3343
  minify: opts.minify,
@@ -3124,7 +3365,7 @@ async function build2(options = {}) {
3124
3365
  await esbuild2.build({
3125
3366
  entryPoints: serverEntryPoints,
3126
3367
  bundle: true,
3127
- outdir: path7.join(outputDir, "server"),
3368
+ outdir: path8.join(outputDir, "server"),
3128
3369
  format: "esm",
3129
3370
  platform: "node",
3130
3371
  target: ["node18"],
@@ -3146,9 +3387,9 @@ async function build2(options = {}) {
3146
3387
  for (const route of pageRoutes) {
3147
3388
  try {
3148
3389
  const html = await renderPage(route, {}, { isDev: false });
3149
- const outputPath = route.path === "/" ? path7.join(outputDir, "pages", "index.html") : path7.join(outputDir, "pages", route.path, "index.html");
3150
- fs5.mkdirSync(path7.dirname(outputPath), { recursive: true });
3151
- fs5.writeFileSync(outputPath, html);
3390
+ const outputPath = route.path === "/" ? path8.join(outputDir, "pages", "index.html") : path8.join(outputDir, "pages", route.path, "index.html");
3391
+ fs6.mkdirSync(path8.dirname(outputPath), { recursive: true });
3392
+ fs6.writeFileSync(outputPath, html);
3152
3393
  prerenderedPages.push(route.path);
3153
3394
  console.log(pc3.dim(` \u2713 ${route.path}`));
3154
3395
  } catch (error) {
@@ -3160,7 +3401,7 @@ async function build2(options = {}) {
3160
3401
  await esbuild2.build({
3161
3402
  entryPoints: [route.absolutePath],
3162
3403
  bundle: true,
3163
- outfile: path7.join(outputDir, "server", "api", `${route.path.replace(/\//g, "_")}.js`),
3404
+ outfile: path8.join(outputDir, "server", "api", `${route.path.replace(/\//g, "_")}.js`),
3164
3405
  format: "esm",
3165
3406
  platform: "neutral",
3166
3407
  // Edge compatible
@@ -3168,10 +3409,10 @@ async function build2(options = {}) {
3168
3409
  minify: true
3169
3410
  });
3170
3411
  }
3171
- const publicDir = path7.join(rootDir, "public");
3172
- if (fs5.existsSync(publicDir)) {
3412
+ const publicDir = path8.join(rootDir, "public");
3413
+ if (fs6.existsSync(publicDir)) {
3173
3414
  console.log(pc3.dim(" Copying public assets..."));
3174
- copyDir(publicDir, path7.join(outputDir, "static"));
3415
+ copyDir(publicDir, path8.join(outputDir, "static"));
3175
3416
  }
3176
3417
  const manifest = {
3177
3418
  version: 1,
@@ -3180,19 +3421,19 @@ async function build2(options = {}) {
3180
3421
  path: r.path,
3181
3422
  type: r.type,
3182
3423
  filePath: r.filePath,
3183
- absolutePath: path7.relative(rootDir, r.absolutePath),
3424
+ absolutePath: path8.relative(rootDir, r.absolutePath),
3184
3425
  params: r.params,
3185
3426
  isCatchAll: r.isCatchAll,
3186
3427
  isOptionalCatchAll: r.isOptionalCatchAll,
3187
- layouts: r.layouts.map((l) => path7.relative(rootDir, l)),
3428
+ layouts: r.layouts.map((l) => path8.relative(rootDir, l)),
3188
3429
  prerendered: prerenderedPages.includes(r.path)
3189
3430
  })),
3190
3431
  staticPages: prerenderedPages,
3191
3432
  dynamicRoutes: dynamicRoutes.map((r) => r.path),
3192
3433
  apiRoutes: apiRoutes.map((r) => r.path)
3193
3434
  };
3194
- fs5.writeFileSync(
3195
- path7.join(outputDir, "routes-manifest.json"),
3435
+ fs6.writeFileSync(
3436
+ path8.join(outputDir, "routes-manifest.json"),
3196
3437
  JSON.stringify(manifest, null, 2)
3197
3438
  );
3198
3439
  const duration = Date.now() - startTime;
@@ -3202,8 +3443,8 @@ async function build2(options = {}) {
3202
3443
  routes: routes.length,
3203
3444
  pages: prerenderedPages.length
3204
3445
  };
3205
- fs5.writeFileSync(
3206
- path7.join(outputDir, "build-info.json"),
3446
+ fs6.writeFileSync(
3447
+ path8.join(outputDir, "build-info.json"),
3207
3448
  JSON.stringify(buildInfo, null, 2)
3208
3449
  );
3209
3450
  console.log("");
@@ -3221,15 +3462,15 @@ async function build2(options = {}) {
3221
3462
  };
3222
3463
  }
3223
3464
  function copyDir(src, dest) {
3224
- fs5.mkdirSync(dest, { recursive: true });
3225
- const entries = fs5.readdirSync(src, { withFileTypes: true });
3465
+ fs6.mkdirSync(dest, { recursive: true });
3466
+ const entries = fs6.readdirSync(src, { withFileTypes: true });
3226
3467
  for (const entry of entries) {
3227
- const srcPath = path7.join(src, entry.name);
3228
- const destPath = path7.join(dest, entry.name);
3468
+ const srcPath = path8.join(src, entry.name);
3469
+ const destPath = path8.join(dest, entry.name);
3229
3470
  if (entry.isDirectory()) {
3230
3471
  copyDir(srcPath, destPath);
3231
3472
  } else {
3232
- fs5.copyFileSync(srcPath, destPath);
3473
+ fs6.copyFileSync(srcPath, destPath);
3233
3474
  }
3234
3475
  }
3235
3476
  }
@@ -3237,8 +3478,8 @@ function copyDir(src, dest) {
3237
3478
  // src/server/prod-server.ts
3238
3479
  init_esm_shims();
3239
3480
  import http2 from "http";
3240
- import fs6 from "fs";
3241
- import path8 from "path";
3481
+ import fs7 from "fs";
3482
+ import path9 from "path";
3242
3483
  import pc4 from "picocolors";
3243
3484
  import mime2 from "mime-types";
3244
3485
  var cachedRoutes = [];
@@ -3246,24 +3487,24 @@ var pageCache = /* @__PURE__ */ new Map();
3246
3487
  async function startProductionServer(options) {
3247
3488
  const { port, host } = options;
3248
3489
  const rootDir = process.cwd();
3249
- const distDir = path8.join(rootDir, ".float");
3250
- const publicDir = path8.join(rootDir, "public");
3251
- const manifestPath = path8.join(distDir, "routes-manifest.json");
3252
- if (fs6.existsSync(manifestPath)) {
3253
- const manifest = JSON.parse(fs6.readFileSync(manifestPath, "utf-8"));
3490
+ const distDir = path9.join(rootDir, ".float");
3491
+ const publicDir = path9.join(rootDir, "public");
3492
+ const manifestPath = path9.join(distDir, "routes-manifest.json");
3493
+ if (fs7.existsSync(manifestPath)) {
3494
+ const manifest = JSON.parse(fs7.readFileSync(manifestPath, "utf-8"));
3254
3495
  cachedRoutes = manifest.routes;
3255
3496
  console.log(pc4.dim(` \u{1F4E6} Loaded ${cachedRoutes.length} routes from manifest`));
3256
3497
  } else {
3257
3498
  console.error(pc4.red(" \u274C No build manifest found. Run `float build` first."));
3258
3499
  process.exit(1);
3259
3500
  }
3260
- const pagesDir = path8.join(distDir, "pages");
3261
- if (fs6.existsSync(pagesDir)) {
3262
- const prerenderedFiles = fs6.readdirSync(pagesDir, { recursive: true });
3501
+ const pagesDir = path9.join(distDir, "pages");
3502
+ if (fs7.existsSync(pagesDir)) {
3503
+ const prerenderedFiles = fs7.readdirSync(pagesDir, { recursive: true });
3263
3504
  for (const file of prerenderedFiles) {
3264
3505
  if (file.endsWith(".html")) {
3265
3506
  const routePath = "/" + file.replace(/\.html$/, "").replace(/index$/, "");
3266
- const content = fs6.readFileSync(path8.join(pagesDir, file), "utf-8");
3507
+ const content = fs7.readFileSync(path9.join(pagesDir, file), "utf-8");
3267
3508
  pageCache.set(routePath, content);
3268
3509
  }
3269
3510
  }
@@ -3273,9 +3514,9 @@ async function startProductionServer(options) {
3273
3514
  const url = new URL(req.url || "/", `http://${host}:${port}`);
3274
3515
  const pathname = url.pathname;
3275
3516
  try {
3276
- const staticPath = path8.join(distDir, "static", pathname);
3277
- if (fs6.existsSync(staticPath) && fs6.statSync(staticPath).isFile()) {
3278
- const content = fs6.readFileSync(staticPath);
3517
+ const staticPath = path9.join(distDir, "static", pathname);
3518
+ if (fs7.existsSync(staticPath) && fs7.statSync(staticPath).isFile()) {
3519
+ const content = fs7.readFileSync(staticPath);
3279
3520
  const contentType = mime2.lookup(staticPath) || "application/octet-stream";
3280
3521
  res.writeHead(200, {
3281
3522
  "Content-Type": contentType,
@@ -3284,9 +3525,9 @@ async function startProductionServer(options) {
3284
3525
  res.end(content);
3285
3526
  return;
3286
3527
  }
3287
- const publicFilePath = path8.join(publicDir, pathname);
3288
- if (fs6.existsSync(publicFilePath) && fs6.statSync(publicFilePath).isFile()) {
3289
- const content = fs6.readFileSync(publicFilePath);
3528
+ const publicFilePath = path9.join(publicDir, pathname);
3529
+ if (fs7.existsSync(publicFilePath) && fs7.statSync(publicFilePath).isFile()) {
3530
+ const content = fs7.readFileSync(publicFilePath);
3290
3531
  const contentType = mime2.lookup(publicFilePath) || "application/octet-stream";
3291
3532
  res.writeHead(200, { "Content-Type": contentType });
3292
3533
  res.end(content);