@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/server/index.js
CHANGED
|
@@ -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
|
};
|
|
@@ -8,11 +14,11 @@ var __export = (target, all) => {
|
|
|
8
14
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
15
|
};
|
|
10
16
|
|
|
11
|
-
// ../../node_modules/.pnpm/tsup@8.5.
|
|
17
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
|
|
12
18
|
import path from "path";
|
|
13
19
|
import { fileURLToPath } from "url";
|
|
14
20
|
var init_esm_shims = __esm({
|
|
15
|
-
"../../node_modules/.pnpm/tsup@8.5.
|
|
21
|
+
"../../node_modules/.pnpm/tsup@8.5.1_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js"() {
|
|
16
22
|
"use strict";
|
|
17
23
|
}
|
|
18
24
|
});
|
|
@@ -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:
|
|
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(
|
|
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(
|
|
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
|
|
874
|
-
import
|
|
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
|
|
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 =
|
|
1035
|
-
if (!
|
|
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 =
|
|
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
|
-
|
|
1045
|
-
|
|
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 =
|
|
1056
|
-
|
|
1057
|
-
const tempFile =
|
|
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,
|
|
1060
|
-
|
|
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
|
-
|
|
1307
|
+
fs2.unlinkSync(tempFile);
|
|
1067
1308
|
} catch {
|
|
1068
1309
|
}
|
|
1069
1310
|
});
|
|
1070
1311
|
return module;
|
|
1071
1312
|
} catch (error) {
|
|
1072
1313
|
try {
|
|
1073
|
-
|
|
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 =
|
|
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 (
|
|
1348
|
+
if (fs2.existsSync(tryPath)) {
|
|
1108
1349
|
resolvedPath = tryPath;
|
|
1109
1350
|
found = true;
|
|
1110
1351
|
break;
|
|
1111
1352
|
}
|
|
1112
|
-
const indexPath =
|
|
1113
|
-
if (
|
|
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
|
|
2500
|
-
import
|
|
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
|
|
2505
|
-
import
|
|
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 =
|
|
2517
|
-
if (
|
|
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 =
|
|
2523
|
-
const hasGlobals =
|
|
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 =
|
|
2554
|
-
|
|
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 =
|
|
2560
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
2574
|
-
if (!
|
|
2575
|
-
|
|
2814
|
+
const appDir = path5.join(rootDir, "app");
|
|
2815
|
+
if (!fs3.existsSync(appDir)) {
|
|
2816
|
+
fs3.mkdirSync(appDir, { recursive: true });
|
|
2576
2817
|
}
|
|
2577
|
-
const globalsPath =
|
|
2578
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
2589
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
2615
|
-
if (!
|
|
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(
|
|
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 =
|
|
2648
|
-
const hasPnpmLock =
|
|
2649
|
-
const hasBunLock =
|
|
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 =
|
|
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 ||
|
|
2909
|
+
const configPath = tailwindConfig.configPath || path6.join(rootDir, "tailwind.config.js");
|
|
2669
2910
|
let tailwindConfigModule = {};
|
|
2670
|
-
if (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
2789
|
-
if (
|
|
2790
|
-
const content =
|
|
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 =
|
|
2798
|
-
if (
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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
|
|
3098
|
-
import
|
|
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 =
|
|
3107
|
-
const publicDir =
|
|
3108
|
-
const manifestPath =
|
|
3109
|
-
if (
|
|
3110
|
-
const manifest = JSON.parse(
|
|
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 =
|
|
3118
|
-
if (
|
|
3119
|
-
const prerenderedFiles =
|
|
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 =
|
|
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 =
|
|
3134
|
-
if (
|
|
3135
|
-
const content =
|
|
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 =
|
|
3145
|
-
if (
|
|
3146
|
-
const content =
|
|
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);
|