@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/README.md +38 -0
- package/dist/cli/index.js +361 -120
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +389 -148
- package/dist/index.js.map +1 -1
- package/dist/router/index.d.ts +4 -0
- package/dist/router/index.js +32 -2
- package/dist/router/index.js.map +1 -1
- package/dist/server/index.js +331 -90
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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.
|
|
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:
|
|
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(
|
|
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(
|
|
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
|
|
877
|
-
import
|
|
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
|
|
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 =
|
|
1038
|
-
if (!
|
|
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 =
|
|
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
|
-
|
|
1048
|
-
|
|
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 =
|
|
1059
|
-
|
|
1060
|
-
const tempFile =
|
|
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,
|
|
1063
|
-
|
|
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
|
-
|
|
1310
|
+
fs2.unlinkSync(tempFile);
|
|
1070
1311
|
} catch {
|
|
1071
1312
|
}
|
|
1072
1313
|
});
|
|
1073
1314
|
return module;
|
|
1074
1315
|
} catch (error) {
|
|
1075
1316
|
try {
|
|
1076
|
-
|
|
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 =
|
|
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 (
|
|
1351
|
+
if (fs2.existsSync(tryPath)) {
|
|
1111
1352
|
resolvedPath = tryPath;
|
|
1112
1353
|
found = true;
|
|
1113
1354
|
break;
|
|
1114
1355
|
}
|
|
1115
|
-
const indexPath =
|
|
1116
|
-
if (
|
|
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
|
|
2470
|
-
import
|
|
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
|
|
2475
|
-
import
|
|
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 =
|
|
2487
|
-
if (
|
|
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 =
|
|
2493
|
-
const hasGlobals =
|
|
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 =
|
|
2524
|
-
|
|
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 =
|
|
2530
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
2544
|
-
if (!
|
|
2545
|
-
|
|
2784
|
+
const appDir = path5.join(rootDir, "app");
|
|
2785
|
+
if (!fs3.existsSync(appDir)) {
|
|
2786
|
+
fs3.mkdirSync(appDir, { recursive: true });
|
|
2546
2787
|
}
|
|
2547
|
-
const globalsPath =
|
|
2548
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
2559
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
2585
|
-
if (!
|
|
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(
|
|
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 =
|
|
2618
|
-
const hasPnpmLock =
|
|
2619
|
-
const hasBunLock =
|
|
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 =
|
|
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 ||
|
|
2879
|
+
const configPath = tailwindConfig.configPath || path6.join(rootDir, "tailwind.config.js");
|
|
2639
2880
|
let tailwindConfigModule = {};
|
|
2640
|
-
if (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
2759
|
-
if (
|
|
2760
|
-
const content =
|
|
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 =
|
|
2768
|
-
if (
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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
|
|
3068
|
-
import
|
|
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 =
|
|
3080
|
-
if (
|
|
3081
|
-
|
|
3082
|
-
}
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
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:
|
|
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:
|
|
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 === "/" ?
|
|
3150
|
-
|
|
3151
|
-
|
|
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:
|
|
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 =
|
|
3172
|
-
if (
|
|
3412
|
+
const publicDir = path8.join(rootDir, "public");
|
|
3413
|
+
if (fs6.existsSync(publicDir)) {
|
|
3173
3414
|
console.log(pc3.dim(" Copying public assets..."));
|
|
3174
|
-
copyDir(publicDir,
|
|
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:
|
|
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) =>
|
|
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
|
-
|
|
3195
|
-
|
|
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
|
-
|
|
3206
|
-
|
|
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
|
-
|
|
3225
|
-
const entries =
|
|
3465
|
+
fs6.mkdirSync(dest, { recursive: true });
|
|
3466
|
+
const entries = fs6.readdirSync(src, { withFileTypes: true });
|
|
3226
3467
|
for (const entry of entries) {
|
|
3227
|
-
const srcPath =
|
|
3228
|
-
const destPath =
|
|
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
|
-
|
|
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
|
|
3241
|
-
import
|
|
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 =
|
|
3250
|
-
const publicDir =
|
|
3251
|
-
const manifestPath =
|
|
3252
|
-
if (
|
|
3253
|
-
const manifest = JSON.parse(
|
|
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 =
|
|
3261
|
-
if (
|
|
3262
|
-
const prerenderedFiles =
|
|
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 =
|
|
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 =
|
|
3277
|
-
if (
|
|
3278
|
-
const content =
|
|
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 =
|
|
3288
|
-
if (
|
|
3289
|
-
const content =
|
|
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);
|