@float.js/core 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,11 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined") return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
8
+ });
3
9
  var __esm = (fn, res) => function __init() {
4
10
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
11
  };
@@ -729,7 +735,7 @@ function generateAPIResponse(state) {
729
735
  function createDevDashboard(options = {}) {
730
736
  const {
731
737
  enabled = process.env.NODE_ENV !== "production",
732
- path: path8 = "/__float",
738
+ path: path9 = "/__float",
733
739
  auth
734
740
  } = options;
735
741
  if (!enabled) {
@@ -737,7 +743,7 @@ function createDevDashboard(options = {}) {
737
743
  }
738
744
  return (req, res, next) => {
739
745
  const url = req.url || "";
740
- if (!url.startsWith(path8)) {
746
+ if (!url.startsWith(path9)) {
741
747
  return next();
742
748
  }
743
749
  if (auth) {
@@ -756,7 +762,7 @@ function createDevDashboard(options = {}) {
756
762
  return;
757
763
  }
758
764
  }
759
- const subPath = url.slice(path8.length);
765
+ const subPath = url.slice(path9.length);
760
766
  if (subPath === "" || subPath === "/") {
761
767
  res.setHeader("Content-Type", "text/html");
762
768
  res.end(generateDashboardHTML(dashboardState));
@@ -870,8 +876,8 @@ init_esm_shims();
870
876
  // src/server/dev-server.ts
871
877
  init_esm_shims();
872
878
  import http from "http";
873
- import fs4 from "fs";
874
- import path6 from "path";
879
+ import fs5 from "fs";
880
+ import path7 from "path";
875
881
  import pc2 from "picocolors";
876
882
  import chokidar from "chokidar";
877
883
  import { WebSocketServer, WebSocket } from "ws";
@@ -934,6 +940,26 @@ function findLayouts(routePath, allLayouts) {
934
940
  }
935
941
  return layouts;
936
942
  }
943
+ function findLoading(routePath, allLoading) {
944
+ const segments = routePath.split("/").filter(Boolean);
945
+ for (let i = segments.length; i >= 0; i--) {
946
+ const currentPath = i === 0 ? "/" : "/" + segments.slice(0, i).join("/");
947
+ if (allLoading.has(currentPath)) {
948
+ return allLoading.get(currentPath);
949
+ }
950
+ }
951
+ return void 0;
952
+ }
953
+ function findError(routePath, allErrors) {
954
+ const segments = routePath.split("/").filter(Boolean);
955
+ for (let i = segments.length; i >= 0; i--) {
956
+ const currentPath = i === 0 ? "/" : "/" + segments.slice(0, i).join("/");
957
+ if (allErrors.has(currentPath)) {
958
+ return allErrors.get(currentPath);
959
+ }
960
+ }
961
+ return void 0;
962
+ }
937
963
  async function scanRoutes(rootDir, options = {}) {
938
964
  const opts = { ...DEFAULT_OPTIONS, ...options };
939
965
  const appDir = path2.join(rootDir, opts.appDir);
@@ -945,12 +971,20 @@ async function scanRoutes(rootDir, options = {}) {
945
971
  ignore: ["**/node_modules/**", "**/_*/**"]
946
972
  });
947
973
  const layoutMap = /* @__PURE__ */ new Map();
974
+ const loadingMap = /* @__PURE__ */ new Map();
975
+ const errorMap = /* @__PURE__ */ new Map();
948
976
  for (const file of files) {
949
977
  const type = getRouteType(file);
978
+ const { urlPath } = filePathToUrlPath(file, "");
950
979
  if (type === "layout") {
951
- const { urlPath } = filePathToUrlPath(file, "");
952
980
  const layoutPath = urlPath === "/" ? "/" : urlPath.replace(/\/layout$/, "") || "/";
953
981
  layoutMap.set(layoutPath, path2.join(appDir, file));
982
+ } else if (type === "loading") {
983
+ const loadingPath = urlPath === "/" ? "/" : urlPath.replace(/\/loading$/, "") || "/";
984
+ loadingMap.set(loadingPath, path2.join(appDir, file));
985
+ } else if (type === "error") {
986
+ const errorPath = urlPath === "/" ? "/" : urlPath.replace(/\/error$/, "") || "/";
987
+ errorMap.set(errorPath, path2.join(appDir, file));
954
988
  }
955
989
  }
956
990
  const routes = [];
@@ -968,7 +1002,9 @@ async function scanRoutes(rootDir, options = {}) {
968
1002
  params,
969
1003
  isCatchAll,
970
1004
  isOptionalCatchAll,
971
- layouts: type === "page" ? findLayouts(urlPath, layoutMap) : []
1005
+ layouts: type === "page" ? findLayouts(urlPath, layoutMap) : [],
1006
+ loading: type === "page" ? findLoading(urlPath, loadingMap) : void 0,
1007
+ error: type === "page" ? findError(urlPath, errorMap) : void 0
972
1008
  };
973
1009
  routes.push(route);
974
1010
  }
@@ -1026,23 +1062,222 @@ import { Writable } from "stream";
1026
1062
  // src/build/transform.ts
1027
1063
  init_esm_shims();
1028
1064
  import * as esbuild from "esbuild";
1065
+ import fs2 from "fs";
1066
+ import path4 from "path";
1067
+ import { pathToFileURL } from "url";
1068
+
1069
+ // src/build/persistent-cache.ts
1070
+ init_esm_shims();
1029
1071
  import fs from "fs";
1030
1072
  import path3 from "path";
1031
- import { pathToFileURL } from "url";
1073
+ import crypto from "crypto";
1074
+ var PersistentCache = class {
1075
+ cacheDir;
1076
+ manifestPath;
1077
+ manifest;
1078
+ constructor(rootDir = process.cwd()) {
1079
+ this.cacheDir = path3.join(rootDir, ".float", "cache");
1080
+ this.manifestPath = path3.join(this.cacheDir, "manifest.json");
1081
+ fs.mkdirSync(this.cacheDir, { recursive: true });
1082
+ this.manifest = this.loadManifest();
1083
+ }
1084
+ loadManifest() {
1085
+ if (fs.existsSync(this.manifestPath)) {
1086
+ try {
1087
+ const data = fs.readFileSync(this.manifestPath, "utf-8");
1088
+ return JSON.parse(data);
1089
+ } catch {
1090
+ }
1091
+ }
1092
+ return {
1093
+ version: "1.0",
1094
+ entries: {}
1095
+ };
1096
+ }
1097
+ saveManifest() {
1098
+ fs.writeFileSync(
1099
+ this.manifestPath,
1100
+ JSON.stringify(this.manifest, null, 2)
1101
+ );
1102
+ }
1103
+ /**
1104
+ * Generate hash for content
1105
+ */
1106
+ hash(content) {
1107
+ return crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
1108
+ }
1109
+ /**
1110
+ * Get cache key path
1111
+ */
1112
+ getKeyPath(key) {
1113
+ const safeKey = key.replace(/[^a-z0-9_-]/gi, "_");
1114
+ return path3.join(this.cacheDir, `${safeKey}.cache`);
1115
+ }
1116
+ /**
1117
+ * Check if cache entry is valid
1118
+ */
1119
+ has(key, contentHash) {
1120
+ const entry = this.manifest.entries[key];
1121
+ if (!entry) return false;
1122
+ const cachePath = this.getKeyPath(key);
1123
+ if (!fs.existsSync(cachePath)) {
1124
+ delete this.manifest.entries[key];
1125
+ this.saveManifest();
1126
+ return false;
1127
+ }
1128
+ if (contentHash && entry.hash !== contentHash) {
1129
+ return false;
1130
+ }
1131
+ return true;
1132
+ }
1133
+ /**
1134
+ * Get cached value
1135
+ */
1136
+ get(key) {
1137
+ if (!this.has(key)) return null;
1138
+ try {
1139
+ const cachePath = this.getKeyPath(key);
1140
+ const data = fs.readFileSync(cachePath, "utf-8");
1141
+ const entry = JSON.parse(data);
1142
+ return entry.value;
1143
+ } catch {
1144
+ return null;
1145
+ }
1146
+ }
1147
+ /**
1148
+ * Set cache value
1149
+ */
1150
+ set(key, value, content) {
1151
+ const entry = {
1152
+ key,
1153
+ value,
1154
+ timestamp: Date.now(),
1155
+ hash: content ? this.hash(content) : this.hash(JSON.stringify(value))
1156
+ };
1157
+ const cachePath = this.getKeyPath(key);
1158
+ const data = JSON.stringify(entry);
1159
+ fs.writeFileSync(cachePath, data);
1160
+ this.manifest.entries[key] = {
1161
+ hash: entry.hash,
1162
+ timestamp: entry.timestamp,
1163
+ size: Buffer.byteLength(data)
1164
+ };
1165
+ this.saveManifest();
1166
+ }
1167
+ /**
1168
+ * Delete cache entry
1169
+ */
1170
+ delete(key) {
1171
+ const cachePath = this.getKeyPath(key);
1172
+ if (fs.existsSync(cachePath)) {
1173
+ fs.unlinkSync(cachePath);
1174
+ }
1175
+ if (this.manifest.entries[key]) {
1176
+ delete this.manifest.entries[key];
1177
+ this.saveManifest();
1178
+ return true;
1179
+ }
1180
+ return false;
1181
+ }
1182
+ /**
1183
+ * Clear all cache
1184
+ */
1185
+ clear() {
1186
+ if (fs.existsSync(this.cacheDir)) {
1187
+ fs.rmSync(this.cacheDir, { recursive: true });
1188
+ fs.mkdirSync(this.cacheDir, { recursive: true });
1189
+ }
1190
+ this.manifest = {
1191
+ version: "1.0",
1192
+ entries: {}
1193
+ };
1194
+ this.saveManifest();
1195
+ }
1196
+ /**
1197
+ * Get cache statistics
1198
+ */
1199
+ stats() {
1200
+ const entries = Object.values(this.manifest.entries);
1201
+ const size = entries.reduce((acc, e) => acc + e.size, 0);
1202
+ const timestamps = entries.map((e) => e.timestamp);
1203
+ return {
1204
+ entries: entries.length,
1205
+ size,
1206
+ oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : null,
1207
+ newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : null
1208
+ };
1209
+ }
1210
+ /**
1211
+ * Clean old entries (older than maxAge milliseconds)
1212
+ */
1213
+ prune(maxAge = 7 * 24 * 60 * 60 * 1e3) {
1214
+ const now = Date.now();
1215
+ let cleaned = 0;
1216
+ for (const [key, entry] of Object.entries(this.manifest.entries)) {
1217
+ if (now - entry.timestamp > maxAge) {
1218
+ this.delete(key);
1219
+ cleaned++;
1220
+ }
1221
+ }
1222
+ return cleaned;
1223
+ }
1224
+ };
1225
+ var globalCache = null;
1226
+ function getCache(rootDir) {
1227
+ if (!globalCache) {
1228
+ globalCache = new PersistentCache(rootDir);
1229
+ }
1230
+ return globalCache;
1231
+ }
1232
+
1233
+ // src/build/transform.ts
1032
1234
  var moduleCache = /* @__PURE__ */ new Map();
1033
- async function transformFile(filePath) {
1034
- const absolutePath = path3.isAbsolute(filePath) ? filePath : path3.resolve(filePath);
1035
- if (!fs.existsSync(absolutePath)) {
1235
+ async function transformFile(filePath, useCache = true) {
1236
+ const absolutePath = path4.isAbsolute(filePath) ? filePath : path4.resolve(filePath);
1237
+ if (!fs2.existsSync(absolutePath)) {
1036
1238
  throw new Error(`File not found: ${absolutePath}`);
1037
1239
  }
1038
- const stats = fs.statSync(absolutePath);
1240
+ const stats = fs2.statSync(absolutePath);
1039
1241
  const mtime = stats.mtimeMs;
1040
1242
  const cached = moduleCache.get(absolutePath);
1041
1243
  if (cached && cached.mtime === mtime) {
1042
1244
  return cached.module;
1043
1245
  }
1044
- const source = fs.readFileSync(absolutePath, "utf-8");
1045
- const ext = path3.extname(absolutePath);
1246
+ if (useCache) {
1247
+ const cache = getCache();
1248
+ const source2 = fs2.readFileSync(absolutePath, "utf-8");
1249
+ const sourceHash = __require("crypto").createHash("sha256").update(source2).digest("hex").slice(0, 16);
1250
+ const cacheKey = `transform_${absolutePath}_${sourceHash}`;
1251
+ if (cache.has(cacheKey)) {
1252
+ const cachedCode = cache.get(cacheKey);
1253
+ if (cachedCode) {
1254
+ const tempDir2 = path4.join(process.cwd(), ".float", ".cache");
1255
+ fs2.mkdirSync(tempDir2, { recursive: true });
1256
+ const tempFile2 = path4.join(tempDir2, `${path4.basename(absolutePath, path4.extname(absolutePath))}_${Date.now()}.mjs`);
1257
+ fs2.writeFileSync(tempFile2, cachedCode);
1258
+ try {
1259
+ const module = await import(pathToFileURL(tempFile2).href);
1260
+ moduleCache.set(absolutePath, { module, mtime });
1261
+ setImmediate(() => {
1262
+ try {
1263
+ fs2.unlinkSync(tempFile2);
1264
+ } catch {
1265
+ }
1266
+ });
1267
+ return module;
1268
+ } catch (error) {
1269
+ setImmediate(() => {
1270
+ try {
1271
+ fs2.unlinkSync(tempFile2);
1272
+ } catch {
1273
+ }
1274
+ });
1275
+ }
1276
+ }
1277
+ }
1278
+ }
1279
+ const source = fs2.readFileSync(absolutePath, "utf-8");
1280
+ const ext = path4.extname(absolutePath);
1046
1281
  const loader = getLoader(ext);
1047
1282
  const result = await esbuild.transform(source, {
1048
1283
  loader,
@@ -1052,25 +1287,31 @@ async function transformFile(filePath) {
1052
1287
  sourcemap: "inline",
1053
1288
  sourcefile: absolutePath
1054
1289
  });
1055
- const tempDir = path3.join(process.cwd(), ".float", ".cache");
1056
- fs.mkdirSync(tempDir, { recursive: true });
1057
- const tempFile = path3.join(tempDir, `${path3.basename(absolutePath, ext)}_${Date.now()}.mjs`);
1290
+ const tempDir = path4.join(process.cwd(), ".float", ".cache");
1291
+ fs2.mkdirSync(tempDir, { recursive: true });
1292
+ const tempFile = path4.join(tempDir, `${path4.basename(absolutePath, ext)}_${Date.now()}.mjs`);
1058
1293
  let code = result.code;
1059
- code = rewriteImports(code, path3.dirname(absolutePath));
1060
- fs.writeFileSync(tempFile, code);
1294
+ code = rewriteImports(code, path4.dirname(absolutePath));
1295
+ fs2.writeFileSync(tempFile, code);
1061
1296
  try {
1062
1297
  const module = await import(pathToFileURL(tempFile).href);
1063
1298
  moduleCache.set(absolutePath, { module, mtime });
1299
+ if (useCache) {
1300
+ const cache = getCache();
1301
+ const sourceHash = __require("crypto").createHash("sha256").update(source).digest("hex").slice(0, 16);
1302
+ const cacheKey = `transform_${absolutePath}_${sourceHash}`;
1303
+ cache.set(cacheKey, code, source);
1304
+ }
1064
1305
  setImmediate(() => {
1065
1306
  try {
1066
- fs.unlinkSync(tempFile);
1307
+ fs2.unlinkSync(tempFile);
1067
1308
  } catch {
1068
1309
  }
1069
1310
  });
1070
1311
  return module;
1071
1312
  } catch (error) {
1072
1313
  try {
1073
- fs.unlinkSync(tempFile);
1314
+ fs2.unlinkSync(tempFile);
1074
1315
  } catch {
1075
1316
  }
1076
1317
  throw error;
@@ -1099,18 +1340,18 @@ function getLoader(ext) {
1099
1340
  function rewriteImports(code, baseDir) {
1100
1341
  const importRegex = /from\s+['"](\.[^'"]+)['"]/g;
1101
1342
  return code.replace(importRegex, (match, importPath) => {
1102
- let resolvedPath = path3.resolve(baseDir, importPath);
1343
+ let resolvedPath = path4.resolve(baseDir, importPath);
1103
1344
  const extensions = [".tsx", ".ts", ".jsx", ".js", ".mjs", ""];
1104
1345
  let found = false;
1105
1346
  for (const ext of extensions) {
1106
1347
  const tryPath = resolvedPath + ext;
1107
- if (fs.existsSync(tryPath)) {
1348
+ if (fs2.existsSync(tryPath)) {
1108
1349
  resolvedPath = tryPath;
1109
1350
  found = true;
1110
1351
  break;
1111
1352
  }
1112
- const indexPath = path3.join(resolvedPath, `index${ext}`);
1113
- if (fs.existsSync(indexPath)) {
1353
+ const indexPath = path4.join(resolvedPath, `index${ext}`);
1354
+ if (fs2.existsSync(indexPath)) {
1114
1355
  resolvedPath = indexPath;
1115
1356
  found = true;
1116
1357
  break;
@@ -2496,13 +2737,13 @@ function generateExamplesPage() {
2496
2737
 
2497
2738
  // src/build/css-processor.ts
2498
2739
  init_esm_shims();
2499
- import fs3 from "fs";
2500
- import path5 from "path";
2740
+ import fs4 from "fs";
2741
+ import path6 from "path";
2501
2742
 
2502
2743
  // src/build/tailwind-setup.ts
2503
2744
  init_esm_shims();
2504
- import fs2 from "fs";
2505
- import path4 from "path";
2745
+ import fs3 from "fs";
2746
+ import path5 from "path";
2506
2747
  import pc from "picocolors";
2507
2748
  function checkTailwindSetup(rootDir) {
2508
2749
  const possibleConfigs = [
@@ -2513,14 +2754,14 @@ function checkTailwindSetup(rootDir) {
2513
2754
  ];
2514
2755
  let configPath = null;
2515
2756
  for (const config of possibleConfigs) {
2516
- const fullPath = path4.join(rootDir, config);
2517
- if (fs2.existsSync(fullPath)) {
2757
+ const fullPath = path5.join(rootDir, config);
2758
+ if (fs3.existsSync(fullPath)) {
2518
2759
  configPath = fullPath;
2519
2760
  break;
2520
2761
  }
2521
2762
  }
2522
- const globalsPath = path4.join(rootDir, "app", "globals.css");
2523
- const hasGlobals = fs2.existsSync(globalsPath);
2763
+ const globalsPath = path5.join(rootDir, "app", "globals.css");
2764
+ const hasGlobals = fs3.existsSync(globalsPath);
2524
2765
  return {
2525
2766
  hasTailwind: !!configPath,
2526
2767
  configPath,
@@ -2550,14 +2791,14 @@ export default {
2550
2791
  plugins: [],
2551
2792
  }
2552
2793
  `;
2553
- const configPath = path4.join(rootDir, "tailwind.config.js");
2554
- fs2.writeFileSync(configPath, tailwindConfig);
2794
+ const configPath = path5.join(rootDir, "tailwind.config.js");
2795
+ fs3.writeFileSync(configPath, tailwindConfig);
2555
2796
  if (!silent) {
2556
2797
  console.log(pc.green(" \u2713 Created tailwind.config.js"));
2557
2798
  }
2558
2799
  }
2559
- const postcssPath = path4.join(rootDir, "postcss.config.js");
2560
- if (!fs2.existsSync(postcssPath) || force) {
2800
+ const postcssPath = path5.join(rootDir, "postcss.config.js");
2801
+ if (!fs3.existsSync(postcssPath) || force) {
2561
2802
  const postcssConfig = `export default {
2562
2803
  plugins: {
2563
2804
  tailwindcss: {},
@@ -2565,28 +2806,28 @@ export default {
2565
2806
  },
2566
2807
  }
2567
2808
  `;
2568
- fs2.writeFileSync(postcssPath, postcssConfig);
2809
+ fs3.writeFileSync(postcssPath, postcssConfig);
2569
2810
  if (!silent) {
2570
2811
  console.log(pc.green(" \u2713 Created postcss.config.js"));
2571
2812
  }
2572
2813
  }
2573
- const appDir = path4.join(rootDir, "app");
2574
- if (!fs2.existsSync(appDir)) {
2575
- fs2.mkdirSync(appDir, { recursive: true });
2814
+ const appDir = path5.join(rootDir, "app");
2815
+ if (!fs3.existsSync(appDir)) {
2816
+ fs3.mkdirSync(appDir, { recursive: true });
2576
2817
  }
2577
- const globalsPath = path4.join(appDir, "globals.css");
2578
- if (!fs2.existsSync(globalsPath) || force) {
2818
+ const globalsPath = path5.join(appDir, "globals.css");
2819
+ if (!fs3.existsSync(globalsPath) || force) {
2579
2820
  const globalsCss = `@tailwind base;
2580
2821
  @tailwind components;
2581
2822
  @tailwind utilities;
2582
2823
  `;
2583
- fs2.writeFileSync(globalsPath, globalsCss);
2824
+ fs3.writeFileSync(globalsPath, globalsCss);
2584
2825
  if (!silent) {
2585
2826
  console.log(pc.green(" \u2713 Created app/globals.css"));
2586
2827
  }
2587
2828
  }
2588
- const layoutPath = path4.join(appDir, "layout.tsx");
2589
- if (!fs2.existsSync(layoutPath)) {
2829
+ const layoutPath = path5.join(appDir, "layout.tsx");
2830
+ if (!fs3.existsSync(layoutPath)) {
2590
2831
  const layoutContent = `import './globals.css'
2591
2832
 
2592
2833
  export default function RootLayout({
@@ -2601,7 +2842,7 @@ export default function RootLayout({
2601
2842
  )
2602
2843
  }
2603
2844
  `;
2604
- fs2.writeFileSync(layoutPath, layoutContent);
2845
+ fs3.writeFileSync(layoutPath, layoutContent);
2605
2846
  if (!silent) {
2606
2847
  console.log(pc.green(" \u2713 Created app/layout.tsx"));
2607
2848
  }
@@ -2611,8 +2852,8 @@ export default function RootLayout({
2611
2852
  }
2612
2853
  }
2613
2854
  function checkTailwindDeps(rootDir) {
2614
- const packageJsonPath = path4.join(rootDir, "package.json");
2615
- if (!fs2.existsSync(packageJsonPath)) {
2855
+ const packageJsonPath = path5.join(rootDir, "package.json");
2856
+ if (!fs3.existsSync(packageJsonPath)) {
2616
2857
  return {
2617
2858
  hasPackageJson: false,
2618
2859
  hasTailwind: false,
@@ -2620,7 +2861,7 @@ function checkTailwindDeps(rootDir) {
2620
2861
  hasAutoprefixer: false
2621
2862
  };
2622
2863
  }
2623
- const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
2864
+ const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
2624
2865
  const allDeps = {
2625
2866
  ...packageJson.dependencies,
2626
2867
  ...packageJson.devDependencies
@@ -2644,9 +2885,9 @@ function getTailwindInstallCommand(rootDir) {
2644
2885
  if (missing.length === 0) {
2645
2886
  return null;
2646
2887
  }
2647
- const hasYarnLock = fs2.existsSync(path4.join(rootDir, "yarn.lock"));
2648
- const hasPnpmLock = fs2.existsSync(path4.join(rootDir, "pnpm-lock.yaml"));
2649
- const hasBunLock = fs2.existsSync(path4.join(rootDir, "bun.lockb"));
2888
+ const hasYarnLock = fs3.existsSync(path5.join(rootDir, "yarn.lock"));
2889
+ const hasPnpmLock = fs3.existsSync(path5.join(rootDir, "pnpm-lock.yaml"));
2890
+ const hasBunLock = fs3.existsSync(path5.join(rootDir, "bun.lockb"));
2650
2891
  let pm = "npm install -D";
2651
2892
  if (hasBunLock) pm = "bun add -d";
2652
2893
  else if (hasPnpmLock) pm = "pnpm add -D";
@@ -2656,7 +2897,7 @@ function getTailwindInstallCommand(rootDir) {
2656
2897
 
2657
2898
  // src/build/css-processor.ts
2658
2899
  async function processCSS(filePath, rootDir = process.cwd()) {
2659
- const content = fs3.readFileSync(filePath, "utf-8");
2900
+ const content = fs4.readFileSync(filePath, "utf-8");
2660
2901
  const tailwindConfig = checkTailwindSetup(rootDir);
2661
2902
  if (!tailwindConfig.hasTailwind) {
2662
2903
  return { code: content };
@@ -2665,9 +2906,9 @@ async function processCSS(filePath, rootDir = process.cwd()) {
2665
2906
  const postcss = await import("postcss").then((m) => m.default);
2666
2907
  const tailwindcss = await import("tailwindcss").then((m) => m.default);
2667
2908
  const autoprefixer = await import("autoprefixer").then((m) => m.default);
2668
- const configPath = tailwindConfig.configPath || path5.join(rootDir, "tailwind.config.js");
2909
+ const configPath = tailwindConfig.configPath || path6.join(rootDir, "tailwind.config.js");
2669
2910
  let tailwindConfigModule = {};
2670
- if (fs3.existsSync(configPath)) {
2911
+ if (fs4.existsSync(configPath)) {
2671
2912
  const configUrl = new URL(`file://${configPath}`);
2672
2913
  tailwindConfigModule = await import(configUrl.href).then((m) => m.default || m);
2673
2914
  }
@@ -2693,7 +2934,7 @@ function needsCSSProcessing(filePath, rootDir) {
2693
2934
  if (!config.hasTailwind) {
2694
2935
  return false;
2695
2936
  }
2696
- const content = fs3.readFileSync(filePath, "utf-8");
2937
+ const content = fs4.readFileSync(filePath, "utf-8");
2697
2938
  return content.includes("@tailwind") || content.includes("@apply");
2698
2939
  }
2699
2940
 
@@ -2701,7 +2942,7 @@ function needsCSSProcessing(filePath, rootDir) {
2701
2942
  async function createDevServer(options) {
2702
2943
  const { port, host, open } = options;
2703
2944
  const rootDir = process.cwd();
2704
- const publicDir = path6.join(rootDir, "public");
2945
+ const publicDir = path7.join(rootDir, "public");
2705
2946
  let routes = [];
2706
2947
  let server = null;
2707
2948
  let wss = null;
@@ -2785,17 +3026,17 @@ ${FLOAT_ERROR_OVERLAY}
2785
3026
  const pathname = url.pathname;
2786
3027
  console.log(pc2.dim(` ${req.method} ${pathname}`));
2787
3028
  try {
2788
- const publicFilePath = path6.join(publicDir, pathname);
2789
- if (fs4.existsSync(publicFilePath) && fs4.statSync(publicFilePath).isFile()) {
2790
- const content = fs4.readFileSync(publicFilePath);
3029
+ const publicFilePath = path7.join(publicDir, pathname);
3030
+ if (fs5.existsSync(publicFilePath) && fs5.statSync(publicFilePath).isFile()) {
3031
+ const content = fs5.readFileSync(publicFilePath);
2791
3032
  const contentType = mime.lookup(publicFilePath) || "application/octet-stream";
2792
3033
  res.writeHead(200, { "Content-Type": contentType });
2793
3034
  res.end(content);
2794
3035
  return;
2795
3036
  }
2796
3037
  if (pathname.endsWith(".css")) {
2797
- const cssPath = path6.join(rootDir, "app", pathname.replace(/^\//, ""));
2798
- if (fs4.existsSync(cssPath)) {
3038
+ const cssPath = path7.join(rootDir, "app", pathname.replace(/^\//, ""));
3039
+ if (fs5.existsSync(cssPath)) {
2799
3040
  try {
2800
3041
  const needsProcessing = needsCSSProcessing(cssPath, rootDir);
2801
3042
  if (needsProcessing) {
@@ -2806,7 +3047,7 @@ ${FLOAT_ERROR_OVERLAY}
2806
3047
  });
2807
3048
  res.end(result.code);
2808
3049
  } else {
2809
- const content = fs4.readFileSync(cssPath, "utf-8");
3050
+ const content = fs5.readFileSync(cssPath, "utf-8");
2810
3051
  res.writeHead(200, {
2811
3052
  "Content-Type": "text/css",
2812
3053
  "Cache-Control": "no-cache"
@@ -2816,7 +3057,7 @@ ${FLOAT_ERROR_OVERLAY}
2816
3057
  return;
2817
3058
  } catch (error) {
2818
3059
  console.error(pc2.red("CSS processing error:"), error);
2819
- const content = fs4.readFileSync(cssPath, "utf-8");
3060
+ const content = fs5.readFileSync(cssPath, "utf-8");
2820
3061
  res.writeHead(200, { "Content-Type": "text/css" });
2821
3062
  res.end(content);
2822
3063
  return;
@@ -2931,9 +3172,9 @@ ${FLOAT_ERROR_OVERLAY}
2931
3172
  });
2932
3173
  const watcher = chokidar.watch(
2933
3174
  [
2934
- path6.join(rootDir, "app/**/*.{ts,tsx,js,jsx}"),
2935
- path6.join(rootDir, "components/**/*.{ts,tsx,js,jsx}"),
2936
- path6.join(rootDir, "lib/**/*.{ts,tsx,js,jsx}")
3175
+ path7.join(rootDir, "app/**/*.{ts,tsx,js,jsx}"),
3176
+ path7.join(rootDir, "components/**/*.{ts,tsx,js,jsx}"),
3177
+ path7.join(rootDir, "lib/**/*.{ts,tsx,js,jsx}")
2937
3178
  ],
2938
3179
  {
2939
3180
  ignored: /node_modules/,
@@ -2942,7 +3183,7 @@ ${FLOAT_ERROR_OVERLAY}
2942
3183
  );
2943
3184
  watcher.on("change", async (filePath) => {
2944
3185
  console.log(pc2.yellow(`
2945
- \u26A1 File changed: ${path6.relative(rootDir, filePath)}`));
3186
+ \u26A1 File changed: ${path7.relative(rootDir, filePath)}`));
2946
3187
  if (filePath.includes("/app/")) {
2947
3188
  await refreshRoutes();
2948
3189
  }
@@ -2951,7 +3192,7 @@ ${FLOAT_ERROR_OVERLAY}
2951
3192
  watcher.on("add", async (filePath) => {
2952
3193
  if (filePath.includes("/app/")) {
2953
3194
  console.log(pc2.green(`
2954
- \u2795 File added: ${path6.relative(rootDir, filePath)}`));
3195
+ \u2795 File added: ${path7.relative(rootDir, filePath)}`));
2955
3196
  await refreshRoutes();
2956
3197
  notifyClients("reload");
2957
3198
  }
@@ -2959,7 +3200,7 @@ ${FLOAT_ERROR_OVERLAY}
2959
3200
  watcher.on("unlink", async (filePath) => {
2960
3201
  if (filePath.includes("/app/")) {
2961
3202
  console.log(pc2.red(`
2962
- \u2796 File removed: ${path6.relative(rootDir, filePath)}`));
3203
+ \u2796 File removed: ${path7.relative(rootDir, filePath)}`));
2963
3204
  await refreshRoutes();
2964
3205
  notifyClients("reload");
2965
3206
  }
@@ -3094,8 +3335,8 @@ function escapeHtml2(text) {
3094
3335
  // src/server/prod-server.ts
3095
3336
  init_esm_shims();
3096
3337
  import http2 from "http";
3097
- import fs5 from "fs";
3098
- import path7 from "path";
3338
+ import fs6 from "fs";
3339
+ import path8 from "path";
3099
3340
  import pc3 from "picocolors";
3100
3341
  import mime2 from "mime-types";
3101
3342
  var cachedRoutes = [];
@@ -3103,24 +3344,24 @@ var pageCache = /* @__PURE__ */ new Map();
3103
3344
  async function startProductionServer(options) {
3104
3345
  const { port, host } = options;
3105
3346
  const rootDir = process.cwd();
3106
- const distDir = path7.join(rootDir, ".float");
3107
- const publicDir = path7.join(rootDir, "public");
3108
- const manifestPath = path7.join(distDir, "routes-manifest.json");
3109
- if (fs5.existsSync(manifestPath)) {
3110
- const manifest = JSON.parse(fs5.readFileSync(manifestPath, "utf-8"));
3347
+ const distDir = path8.join(rootDir, ".float");
3348
+ const publicDir = path8.join(rootDir, "public");
3349
+ const manifestPath = path8.join(distDir, "routes-manifest.json");
3350
+ if (fs6.existsSync(manifestPath)) {
3351
+ const manifest = JSON.parse(fs6.readFileSync(manifestPath, "utf-8"));
3111
3352
  cachedRoutes = manifest.routes;
3112
3353
  console.log(pc3.dim(` \u{1F4E6} Loaded ${cachedRoutes.length} routes from manifest`));
3113
3354
  } else {
3114
3355
  console.error(pc3.red(" \u274C No build manifest found. Run `float build` first."));
3115
3356
  process.exit(1);
3116
3357
  }
3117
- const pagesDir = path7.join(distDir, "pages");
3118
- if (fs5.existsSync(pagesDir)) {
3119
- const prerenderedFiles = fs5.readdirSync(pagesDir, { recursive: true });
3358
+ const pagesDir = path8.join(distDir, "pages");
3359
+ if (fs6.existsSync(pagesDir)) {
3360
+ const prerenderedFiles = fs6.readdirSync(pagesDir, { recursive: true });
3120
3361
  for (const file of prerenderedFiles) {
3121
3362
  if (file.endsWith(".html")) {
3122
3363
  const routePath = "/" + file.replace(/\.html$/, "").replace(/index$/, "");
3123
- const content = fs5.readFileSync(path7.join(pagesDir, file), "utf-8");
3364
+ const content = fs6.readFileSync(path8.join(pagesDir, file), "utf-8");
3124
3365
  pageCache.set(routePath, content);
3125
3366
  }
3126
3367
  }
@@ -3130,9 +3371,9 @@ async function startProductionServer(options) {
3130
3371
  const url = new URL(req.url || "/", `http://${host}:${port}`);
3131
3372
  const pathname = url.pathname;
3132
3373
  try {
3133
- const staticPath = path7.join(distDir, "static", pathname);
3134
- if (fs5.existsSync(staticPath) && fs5.statSync(staticPath).isFile()) {
3135
- const content = fs5.readFileSync(staticPath);
3374
+ const staticPath = path8.join(distDir, "static", pathname);
3375
+ if (fs6.existsSync(staticPath) && fs6.statSync(staticPath).isFile()) {
3376
+ const content = fs6.readFileSync(staticPath);
3136
3377
  const contentType = mime2.lookup(staticPath) || "application/octet-stream";
3137
3378
  res.writeHead(200, {
3138
3379
  "Content-Type": contentType,
@@ -3141,9 +3382,9 @@ async function startProductionServer(options) {
3141
3382
  res.end(content);
3142
3383
  return;
3143
3384
  }
3144
- const publicFilePath = path7.join(publicDir, pathname);
3145
- if (fs5.existsSync(publicFilePath) && fs5.statSync(publicFilePath).isFile()) {
3146
- const content = fs5.readFileSync(publicFilePath);
3385
+ const publicFilePath = path8.join(publicDir, pathname);
3386
+ if (fs6.existsSync(publicFilePath) && fs6.statSync(publicFilePath).isFile()) {
3387
+ const content = fs6.readFileSync(publicFilePath);
3147
3388
  const contentType = mime2.lookup(publicFilePath) || "application/octet-stream";
3148
3389
  res.writeHead(200, { "Content-Type": contentType });
3149
3390
  res.end(content);