olovaplugin 1.0.6 → 1.0.8
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,6 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// olova-plugins.ts
|
|
31
|
+
var olova_plugins_exports = {};
|
|
32
|
+
__export(olova_plugins_exports, {
|
|
33
|
+
autoGeneratePlugin: () => autoGeneratePlugin,
|
|
34
|
+
cleanUrlPlugin: () => cleanUrlPlugin,
|
|
35
|
+
colors: () => colors3,
|
|
36
|
+
configPlugin: () => configPlugin,
|
|
37
|
+
createTimer: () => createTimer,
|
|
38
|
+
formatBytes: () => formatBytes2,
|
|
39
|
+
formatTime: () => formatTime2,
|
|
40
|
+
frameworkPlugin: () => frameworkPlugin,
|
|
41
|
+
generateBuildId: () => generateBuildId,
|
|
42
|
+
generateCriticalCSS: () => generateCriticalCSS,
|
|
43
|
+
generateJsonLd: () => generateJsonLd,
|
|
44
|
+
generateOlovaHydration: () => generateOlovaHydration,
|
|
45
|
+
generatePerformanceMeta: () => generatePerformanceMeta,
|
|
46
|
+
generateResourceHints: () => generateResourceHints,
|
|
47
|
+
generateServiceWorkerContent: () => generateServiceWorkerContent,
|
|
48
|
+
generateServiceWorkerScript: () => generateServiceWorkerScript,
|
|
49
|
+
logger: () => logger2,
|
|
50
|
+
minifyHtml: () => minifyHtml,
|
|
51
|
+
olovaPlugins: () => olovaPlugins,
|
|
52
|
+
parseFlightData: () => parseFlightData,
|
|
53
|
+
proactiveErrorPlugin: () => proactiveErrorPlugin,
|
|
54
|
+
routerPlugin: () => routerPlugin,
|
|
55
|
+
ssgPlugin: () => ssgPlugin,
|
|
56
|
+
symbols: () => symbols2,
|
|
57
|
+
virtualHtmlPlugin: () => virtualHtmlPlugin
|
|
58
|
+
});
|
|
59
|
+
module.exports = __toCommonJS(olova_plugins_exports);
|
|
60
|
+
|
|
1
61
|
// router/config.ts
|
|
2
|
-
|
|
3
|
-
|
|
62
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
63
|
+
var import_path = __toESM(require("path"), 1);
|
|
4
64
|
var colors = {
|
|
5
65
|
reset: "\x1B[0m",
|
|
6
66
|
bold: "\x1B[1m",
|
|
@@ -10,12 +70,12 @@ var colors = {
|
|
|
10
70
|
white: "\x1B[37m"
|
|
11
71
|
};
|
|
12
72
|
function configPlugin() {
|
|
13
|
-
const olovaDir =
|
|
73
|
+
const olovaDir = import_path.default.resolve(".olova");
|
|
14
74
|
return {
|
|
15
75
|
name: "olova-config",
|
|
16
76
|
config(_config, { command }) {
|
|
17
|
-
if (!
|
|
18
|
-
|
|
77
|
+
if (!import_fs.default.existsSync(olovaDir)) {
|
|
78
|
+
import_fs.default.mkdirSync(olovaDir, { recursive: true });
|
|
19
79
|
}
|
|
20
80
|
if (process.env.IS_SSG_BUILD) {
|
|
21
81
|
return {
|
|
@@ -88,12 +148,13 @@ function configPlugin() {
|
|
|
88
148
|
}
|
|
89
149
|
|
|
90
150
|
// router/router.ts
|
|
91
|
-
|
|
92
|
-
|
|
151
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
152
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
93
153
|
function routerPlugin() {
|
|
94
154
|
const virtualModuleId = "olova/routes";
|
|
95
155
|
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
96
156
|
let server = null;
|
|
157
|
+
let root = process.cwd();
|
|
97
158
|
const invalidateRoutes = () => {
|
|
98
159
|
if (server) {
|
|
99
160
|
const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId);
|
|
@@ -108,31 +169,34 @@ function routerPlugin() {
|
|
|
108
169
|
};
|
|
109
170
|
return {
|
|
110
171
|
name: "olova-router",
|
|
172
|
+
configResolved(config) {
|
|
173
|
+
root = config.root;
|
|
174
|
+
},
|
|
111
175
|
// Configure dev server to watch for file changes
|
|
112
176
|
configureServer(devServer) {
|
|
113
177
|
server = devServer;
|
|
114
|
-
const srcDir =
|
|
178
|
+
const srcDir = import_path2.default.resolve(root, "src");
|
|
115
179
|
const watcher = devServer.watcher;
|
|
116
180
|
watcher.on("add", (filePath) => {
|
|
117
181
|
if (filePath.startsWith(srcDir) && /\.(tsx|jsx|html|md)$/.test(filePath)) {
|
|
118
|
-
console.log("\x1B[36m[olova]\x1B[0m New route detected:",
|
|
182
|
+
console.log("\x1B[36m[olova]\x1B[0m New route detected:", import_path2.default.relative(srcDir, filePath));
|
|
119
183
|
invalidateRoutes();
|
|
120
184
|
}
|
|
121
185
|
});
|
|
122
186
|
watcher.on("unlink", (filePath) => {
|
|
123
187
|
if (filePath.startsWith(srcDir) && /\.(tsx|jsx|html|md)$/.test(filePath)) {
|
|
124
|
-
console.log("\x1B[36m[olova]\x1B[0m Route removed:",
|
|
188
|
+
console.log("\x1B[36m[olova]\x1B[0m Route removed:", import_path2.default.relative(srcDir, filePath));
|
|
125
189
|
invalidateRoutes();
|
|
126
190
|
}
|
|
127
191
|
});
|
|
128
192
|
watcher.on("addDir", (dirPath) => {
|
|
129
193
|
if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {
|
|
130
|
-
console.log("\x1B[36m[olova]\x1B[0m New route folder detected:",
|
|
194
|
+
console.log("\x1B[36m[olova]\x1B[0m New route folder detected:", import_path2.default.relative(srcDir, dirPath));
|
|
131
195
|
}
|
|
132
196
|
});
|
|
133
197
|
watcher.on("unlinkDir", (dirPath) => {
|
|
134
198
|
if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {
|
|
135
|
-
console.log("\x1B[36m[olova]\x1B[0m Route folder removed:",
|
|
199
|
+
console.log("\x1B[36m[olova]\x1B[0m Route folder removed:", import_path2.default.relative(srcDir, dirPath));
|
|
136
200
|
invalidateRoutes();
|
|
137
201
|
}
|
|
138
202
|
});
|
|
@@ -144,7 +208,7 @@ function routerPlugin() {
|
|
|
144
208
|
},
|
|
145
209
|
// Mark the virtual module as having side effects for proper HMR
|
|
146
210
|
handleHotUpdate({ file, server: devServer }) {
|
|
147
|
-
const srcDir =
|
|
211
|
+
const srcDir = import_path2.default.resolve(root, "src");
|
|
148
212
|
if (file.startsWith(srcDir) && /\.(tsx|jsx)$/.test(file)) {
|
|
149
213
|
const mod = devServer.moduleGraph.getModuleById(resolvedVirtualModuleId);
|
|
150
214
|
if (mod) {
|
|
@@ -154,13 +218,13 @@ function routerPlugin() {
|
|
|
154
218
|
},
|
|
155
219
|
load(id) {
|
|
156
220
|
if (id === resolvedVirtualModuleId) {
|
|
157
|
-
const srcDir =
|
|
221
|
+
const srcDir = import_path2.default.resolve(root, "src");
|
|
158
222
|
const getRoutes = (dir, baseRoute = "", baseImportPath = "") => {
|
|
159
|
-
const entries =
|
|
223
|
+
const entries = import_fs2.default.readdirSync(dir, { withFileTypes: true });
|
|
160
224
|
let routes = [];
|
|
161
225
|
for (const entry of entries) {
|
|
162
226
|
const entryName = entry.name;
|
|
163
|
-
const fullPath =
|
|
227
|
+
const fullPath = import_path2.default.join(dir, entryName);
|
|
164
228
|
if (entry.isDirectory()) {
|
|
165
229
|
const isRouteGroup = /^\(.+\)$/.test(entryName);
|
|
166
230
|
if (isRouteGroup) {
|
|
@@ -179,7 +243,7 @@ function routerPlugin() {
|
|
|
179
243
|
));
|
|
180
244
|
}
|
|
181
245
|
} else {
|
|
182
|
-
const ext =
|
|
246
|
+
const ext = import_path2.default.extname(entryName);
|
|
183
247
|
const supportedExts = [".tsx", ".jsx", ".html", ".md"];
|
|
184
248
|
if (supportedExts.includes(ext)) {
|
|
185
249
|
const nameNoExt = entryName.replace(/\.(tsx|jsx|html|md)$/, "");
|
|
@@ -195,7 +259,7 @@ function routerPlugin() {
|
|
|
195
259
|
} else if (ext === ".md") {
|
|
196
260
|
routes.push(` "${normalizedRoutePath}": () => import("${importPath}?raw").then(m => ({ default: m.default, __isMd: true, __isStatic: true })),`);
|
|
197
261
|
} else {
|
|
198
|
-
const fileContent =
|
|
262
|
+
const fileContent = import_fs2.default.readFileSync(fullPath, "utf-8");
|
|
199
263
|
const firstLine = fileContent.trim().split("\n")[0].trim();
|
|
200
264
|
const hasStaticDirective = firstLine === '"static"' || firstLine === "'static'";
|
|
201
265
|
if (hasStaticDirective) {
|
|
@@ -210,7 +274,7 @@ function routerPlugin() {
|
|
|
210
274
|
return routes;
|
|
211
275
|
};
|
|
212
276
|
let routeLines = [];
|
|
213
|
-
if (
|
|
277
|
+
if (import_fs2.default.existsSync(srcDir)) {
|
|
214
278
|
routeLines = getRoutes(srcDir);
|
|
215
279
|
}
|
|
216
280
|
return `export const routes = {
|
|
@@ -222,7 +286,7 @@ ${routeLines.join("\n")}
|
|
|
222
286
|
}
|
|
223
287
|
|
|
224
288
|
// router/framework.ts
|
|
225
|
-
|
|
289
|
+
var import_vite = require("vite");
|
|
226
290
|
function frameworkPlugin() {
|
|
227
291
|
const virtualClientEntry = "olova/client";
|
|
228
292
|
const resolvedVirtualClientEntry = "\0" + virtualClientEntry;
|
|
@@ -350,7 +414,7 @@ loadRoute(path).then((result) => {
|
|
|
350
414
|
createRoot(document).render(app);
|
|
351
415
|
}
|
|
352
416
|
});`;
|
|
353
|
-
const result = await transformWithEsbuild(code, "olova-client.tsx", {
|
|
417
|
+
const result = await (0, import_vite.transformWithEsbuild)(code, "olova-client.tsx", {
|
|
354
418
|
loader: "tsx",
|
|
355
419
|
jsx: "automatic"
|
|
356
420
|
});
|
|
@@ -467,7 +531,7 @@ export function renderShellWithMetadata(metadata) {
|
|
|
467
531
|
|
|
468
532
|
// Re-export loadRoute so it can be used during SSG to extract metadata from any route
|
|
469
533
|
export { loadRoute };`;
|
|
470
|
-
const result = await transformWithEsbuild(code, "olova-server.tsx", {
|
|
534
|
+
const result = await (0, import_vite.transformWithEsbuild)(code, "olova-server.tsx", {
|
|
471
535
|
loader: "tsx",
|
|
472
536
|
jsx: "automatic"
|
|
473
537
|
});
|
|
@@ -478,8 +542,8 @@ export { loadRoute };`;
|
|
|
478
542
|
}
|
|
479
543
|
|
|
480
544
|
// router/virtual-html.ts
|
|
481
|
-
|
|
482
|
-
|
|
545
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
546
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
483
547
|
|
|
484
548
|
// router/hydration.ts
|
|
485
549
|
function generateOlovaHydration(data, buildId) {
|
|
@@ -692,30 +756,30 @@ function virtualHtmlPlugin() {
|
|
|
692
756
|
// Serve HTML for all routes in dev mode with SSR (like Next.js)
|
|
693
757
|
configureServer(server) {
|
|
694
758
|
const isStaticRoute = (routePath) => {
|
|
695
|
-
const srcDir =
|
|
759
|
+
const srcDir = import_path3.default.resolve("src");
|
|
696
760
|
let filePath = routePath === "/" ? "index" : routePath.slice(1);
|
|
697
761
|
const staticPaths = [
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
762
|
+
import_path3.default.join(srcDir, filePath, "index.html"),
|
|
763
|
+
import_path3.default.join(srcDir, filePath, "index.md"),
|
|
764
|
+
import_path3.default.join(srcDir, filePath + ".html"),
|
|
765
|
+
import_path3.default.join(srcDir, filePath + ".md")
|
|
702
766
|
];
|
|
703
767
|
for (const p of staticPaths) {
|
|
704
|
-
if (
|
|
768
|
+
if (import_fs3.default.existsSync(p)) {
|
|
705
769
|
return true;
|
|
706
770
|
}
|
|
707
771
|
}
|
|
708
772
|
const possiblePaths = [
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
773
|
+
import_path3.default.join(srcDir, filePath, "index.tsx"),
|
|
774
|
+
import_path3.default.join(srcDir, filePath, "index.jsx"),
|
|
775
|
+
import_path3.default.join(srcDir, filePath + ".tsx"),
|
|
776
|
+
import_path3.default.join(srcDir, filePath + ".jsx"),
|
|
777
|
+
import_path3.default.join(srcDir, "App.tsx"),
|
|
778
|
+
import_path3.default.join(srcDir, "App.jsx")
|
|
715
779
|
];
|
|
716
780
|
for (const p of possiblePaths) {
|
|
717
|
-
if (
|
|
718
|
-
const content =
|
|
781
|
+
if (import_fs3.default.existsSync(p)) {
|
|
782
|
+
const content = import_fs3.default.readFileSync(p, "utf-8");
|
|
719
783
|
const firstLine = content.trim().split("\n")[0].trim();
|
|
720
784
|
return firstLine === '"static"' || firstLine === "'static'";
|
|
721
785
|
}
|
|
@@ -809,10 +873,10 @@ function virtualHtmlPlugin() {
|
|
|
809
873
|
}
|
|
810
874
|
|
|
811
875
|
// router/ssg.ts
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
876
|
+
var import_vite2 = require("vite");
|
|
877
|
+
var import_fs4 = __toESM(require("fs"), 1);
|
|
878
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
879
|
+
var import_url = require("url");
|
|
816
880
|
|
|
817
881
|
// router/utils.ts
|
|
818
882
|
function minifyHtml(html) {
|
|
@@ -981,7 +1045,7 @@ function ssgPlugin() {
|
|
|
981
1045
|
logger.header("Generating static pages...");
|
|
982
1046
|
const serverBuildStart = performance.now();
|
|
983
1047
|
try {
|
|
984
|
-
await build({
|
|
1048
|
+
await (0, import_vite2.build)({
|
|
985
1049
|
configFile: "./vite.config.ts",
|
|
986
1050
|
build: {
|
|
987
1051
|
ssr: true,
|
|
@@ -1006,10 +1070,10 @@ function ssgPlugin() {
|
|
|
1006
1070
|
const scanStart = performance.now();
|
|
1007
1071
|
const allRoutes = [];
|
|
1008
1072
|
const scan = (dir, base = "") => {
|
|
1009
|
-
if (!
|
|
1010
|
-
const entries =
|
|
1073
|
+
if (!import_fs4.default.existsSync(dir)) return;
|
|
1074
|
+
const entries = import_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
1011
1075
|
for (const entry of entries) {
|
|
1012
|
-
const fullPath =
|
|
1076
|
+
const fullPath = import_path4.default.join(dir, entry.name);
|
|
1013
1077
|
if (entry.isDirectory()) {
|
|
1014
1078
|
const isRouteGroup = /^\(.+\)$/.test(entry.name);
|
|
1015
1079
|
if (isRouteGroup) {
|
|
@@ -1018,7 +1082,7 @@ function ssgPlugin() {
|
|
|
1018
1082
|
scan(fullPath, `${base}/${entry.name}`);
|
|
1019
1083
|
}
|
|
1020
1084
|
} else {
|
|
1021
|
-
const ext =
|
|
1085
|
+
const ext = import_path4.default.extname(entry.name);
|
|
1022
1086
|
const supportedExts = [".tsx", ".jsx", ".html", ".md"];
|
|
1023
1087
|
if (supportedExts.includes(ext)) {
|
|
1024
1088
|
const nameNoExt = entry.name.replace(/\.(tsx|jsx|html|md)$/, "");
|
|
@@ -1031,7 +1095,7 @@ function ssgPlugin() {
|
|
|
1031
1095
|
if (ext === ".html" || ext === ".md") {
|
|
1032
1096
|
allRoutes.push({ route, isStatic: true, filePath: fullPath });
|
|
1033
1097
|
} else {
|
|
1034
|
-
const fileContent =
|
|
1098
|
+
const fileContent = import_fs4.default.readFileSync(fullPath, "utf-8");
|
|
1035
1099
|
const firstLine = fileContent.trim().split("\n")[0].trim();
|
|
1036
1100
|
const isStatic = firstLine === '"static"' || firstLine === "'static'";
|
|
1037
1101
|
allRoutes.push({ route, isStatic, filePath: fullPath });
|
|
@@ -1040,36 +1104,36 @@ function ssgPlugin() {
|
|
|
1040
1104
|
}
|
|
1041
1105
|
}
|
|
1042
1106
|
};
|
|
1043
|
-
scan(
|
|
1107
|
+
scan(import_path4.default.resolve("src"));
|
|
1044
1108
|
logger.step(`Found ${allRoutes.length} routes`, performance.now() - scanStart);
|
|
1045
|
-
const serverDir =
|
|
1046
|
-
let serverFile =
|
|
1109
|
+
const serverDir = import_path4.default.resolve(".olova/server");
|
|
1110
|
+
let serverFile = import_fs4.default.readdirSync(serverDir).find(
|
|
1047
1111
|
(f) => (f === "server.js" || f.includes("server-entry")) && f.endsWith(".js")
|
|
1048
1112
|
);
|
|
1049
1113
|
if (!serverFile) {
|
|
1050
1114
|
logger.error("Could not find server build artifact");
|
|
1051
1115
|
return;
|
|
1052
1116
|
}
|
|
1053
|
-
const serverEntryPath =
|
|
1054
|
-
const { render, renderShell, renderShellWithMetadata, loadRoute } = await import(pathToFileURL(serverEntryPath).href);
|
|
1117
|
+
const serverEntryPath = import_path4.default.join(serverDir, serverFile);
|
|
1118
|
+
const { render, renderShell, renderShellWithMetadata, loadRoute } = await import((0, import_url.pathToFileURL)(serverEntryPath).href);
|
|
1055
1119
|
const assetsStart = performance.now();
|
|
1056
|
-
const distDir =
|
|
1057
|
-
const clientHtmlPath =
|
|
1120
|
+
const distDir = import_path4.default.resolve(".olova/dist");
|
|
1121
|
+
const clientHtmlPath = import_path4.default.join(distDir, "olova.html");
|
|
1058
1122
|
let shellHtml = renderShell();
|
|
1059
1123
|
if (!shellHtml.startsWith("<!DOCTYPE html>")) {
|
|
1060
1124
|
shellHtml = `<!DOCTYPE html>
|
|
1061
1125
|
${shellHtml}`;
|
|
1062
1126
|
}
|
|
1063
1127
|
let template = "";
|
|
1064
|
-
if (
|
|
1065
|
-
template =
|
|
1128
|
+
if (import_fs4.default.existsSync(clientHtmlPath)) {
|
|
1129
|
+
template = import_fs4.default.readFileSync(clientHtmlPath, "utf-8");
|
|
1066
1130
|
}
|
|
1067
1131
|
const scripts = template.match(/<script[\s\S]*?>[\s\S]*?<\/script>/gi) || [];
|
|
1068
1132
|
const links = template.match(/<link[\s\S]*?>/gi) || [];
|
|
1069
|
-
const chunksDir =
|
|
1133
|
+
const chunksDir = import_path4.default.join(distDir, "pro_olova_static", "chunks");
|
|
1070
1134
|
let preloadLinks = [];
|
|
1071
|
-
if (
|
|
1072
|
-
const chunks =
|
|
1135
|
+
if (import_fs4.default.existsSync(chunksDir)) {
|
|
1136
|
+
const chunks = import_fs4.default.readdirSync(chunksDir).filter((f) => f.endsWith(".js"));
|
|
1073
1137
|
preloadLinks = chunks.map(
|
|
1074
1138
|
(chunk) => `<link rel="modulepreload" crossorigin href="/pro_olova_static/chunks/${chunk}" />`
|
|
1075
1139
|
);
|
|
@@ -1079,8 +1143,8 @@ ${shellHtml}`;
|
|
|
1079
1143
|
preloadLinks.unshift(`<link rel="modulepreload" crossorigin href="${mainScriptMatch[1]}" />`);
|
|
1080
1144
|
}
|
|
1081
1145
|
const chunkList = [];
|
|
1082
|
-
if (
|
|
1083
|
-
const chunks =
|
|
1146
|
+
if (import_fs4.default.existsSync(chunksDir)) {
|
|
1147
|
+
const chunks = import_fs4.default.readdirSync(chunksDir).filter((f) => f.endsWith(".js"));
|
|
1084
1148
|
chunks.forEach((chunk) => chunkList.push(`/pro_olova_static/chunks/${chunk}`));
|
|
1085
1149
|
}
|
|
1086
1150
|
const resourceHints = generateResourceHints();
|
|
@@ -1095,7 +1159,7 @@ ${shellHtml}`;
|
|
|
1095
1159
|
...links.map((l) => l.match(/href="([^"]+)"/)?.[1]).filter(Boolean)
|
|
1096
1160
|
];
|
|
1097
1161
|
const swContent = generateServiceWorkerContent(buildId, allAssetsForSW);
|
|
1098
|
-
|
|
1162
|
+
import_fs4.default.writeFileSync(import_path4.default.join(distDir, "sw.js"), swContent);
|
|
1099
1163
|
const assets = [performanceHead, ...links, ...preloadLinks, ...scripts, swScript].join("\n");
|
|
1100
1164
|
logger.step(`Assets optimized (${preloadLinks.length} preloads, SW ready)`, performance.now() - assetsStart);
|
|
1101
1165
|
console.log("");
|
|
@@ -1177,17 +1241,17 @@ ${finalHtml}`;
|
|
|
1177
1241
|
}
|
|
1178
1242
|
finalHtml = minifyHtml(finalHtml);
|
|
1179
1243
|
}
|
|
1180
|
-
const outPath =
|
|
1181
|
-
|
|
1182
|
-
|
|
1244
|
+
const outPath = import_path4.default.join(distDir, route === "/" ? "index.html" : `${route}/index.html`);
|
|
1245
|
+
import_fs4.default.mkdirSync(import_path4.default.dirname(outPath), { recursive: true });
|
|
1246
|
+
import_fs4.default.writeFileSync(outPath, finalHtml);
|
|
1183
1247
|
const routeTime = performance.now() - routeStart;
|
|
1184
1248
|
const routeSize = Buffer.byteLength(finalHtml, "utf8");
|
|
1185
1249
|
routeResults.push({ route, type: isStatic ? "static" : "ssr", size: routeSize, time: routeTime });
|
|
1186
1250
|
logger.route(route, isStatic ? "static" : "ssr", routeSize, routeTime);
|
|
1187
1251
|
}
|
|
1188
|
-
const fallbackPath =
|
|
1189
|
-
if (
|
|
1190
|
-
|
|
1252
|
+
const fallbackPath = import_path4.default.join(distDir, "404.html");
|
|
1253
|
+
if (import_fs4.default.existsSync(clientHtmlPath)) {
|
|
1254
|
+
import_fs4.default.copyFileSync(clientHtmlPath, fallbackPath);
|
|
1191
1255
|
}
|
|
1192
1256
|
const totalTime = performance.now() - totalStartTime;
|
|
1193
1257
|
logger.buildComplete(allRoutes.length, staticCount, totalTime);
|
|
@@ -1198,28 +1262,28 @@ ${finalHtml}`;
|
|
|
1198
1262
|
}
|
|
1199
1263
|
|
|
1200
1264
|
// router/clean-url.ts
|
|
1201
|
-
|
|
1202
|
-
|
|
1265
|
+
var import_fs5 = __toESM(require("fs"), 1);
|
|
1266
|
+
var import_path5 = __toESM(require("path"), 1);
|
|
1203
1267
|
function cleanUrlPlugin() {
|
|
1204
1268
|
return {
|
|
1205
1269
|
name: "olova-clean-url",
|
|
1206
1270
|
configurePreviewServer(server) {
|
|
1207
1271
|
server.middlewares.use((req, res, next) => {
|
|
1208
1272
|
const urlPath = (req.url || "/").split("?")[0];
|
|
1209
|
-
const distDir =
|
|
1273
|
+
const distDir = import_path5.default.resolve(".olova/dist");
|
|
1210
1274
|
if (urlPath === "/") {
|
|
1211
|
-
const indexPath2 =
|
|
1212
|
-
if (
|
|
1213
|
-
const content =
|
|
1275
|
+
const indexPath2 = import_path5.default.join(distDir, "index.html");
|
|
1276
|
+
if (import_fs5.default.existsSync(indexPath2)) {
|
|
1277
|
+
const content = import_fs5.default.readFileSync(indexPath2, "utf-8");
|
|
1214
1278
|
res.setHeader("Content-Type", "text/html");
|
|
1215
1279
|
res.end(content);
|
|
1216
1280
|
return;
|
|
1217
1281
|
}
|
|
1218
1282
|
}
|
|
1219
1283
|
if (urlPath.includes(".")) return next();
|
|
1220
|
-
const indexPath =
|
|
1221
|
-
if (
|
|
1222
|
-
const content =
|
|
1284
|
+
const indexPath = import_path5.default.join(distDir, urlPath, "index.html");
|
|
1285
|
+
if (import_fs5.default.existsSync(indexPath)) {
|
|
1286
|
+
const content = import_fs5.default.readFileSync(indexPath, "utf-8");
|
|
1223
1287
|
res.setHeader("Content-Type", "text/html");
|
|
1224
1288
|
res.end(content);
|
|
1225
1289
|
return;
|
|
@@ -1231,8 +1295,8 @@ function cleanUrlPlugin() {
|
|
|
1231
1295
|
}
|
|
1232
1296
|
|
|
1233
1297
|
// router/auto-generate.ts
|
|
1234
|
-
|
|
1235
|
-
|
|
1298
|
+
var import_fs6 = __toESM(require("fs"), 1);
|
|
1299
|
+
var import_path6 = __toESM(require("path"), 1);
|
|
1236
1300
|
function toPascalCase(str) {
|
|
1237
1301
|
const cleanStr = str.replace(/^\$/, "");
|
|
1238
1302
|
return cleanStr.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
|
|
@@ -1269,34 +1333,34 @@ function autoGeneratePlugin() {
|
|
|
1269
1333
|
return {
|
|
1270
1334
|
name: "olova-auto-generate",
|
|
1271
1335
|
configResolved(config) {
|
|
1272
|
-
srcDir =
|
|
1336
|
+
srcDir = import_path6.default.resolve(config.root, "src");
|
|
1273
1337
|
},
|
|
1274
1338
|
configureServer(server) {
|
|
1275
1339
|
console.log(
|
|
1276
1340
|
"\x1B[36m[olova] Auto-generate plugin active - watching for new route files\x1B[0m"
|
|
1277
1341
|
);
|
|
1278
1342
|
server.watcher.on("add", (filePath) => {
|
|
1279
|
-
const normalizedPath =
|
|
1280
|
-
const normalizedSrcDir =
|
|
1281
|
-
const ext =
|
|
1343
|
+
const normalizedPath = import_path6.default.normalize(filePath);
|
|
1344
|
+
const normalizedSrcDir = import_path6.default.normalize(srcDir);
|
|
1345
|
+
const ext = import_path6.default.extname(normalizedPath);
|
|
1282
1346
|
if (ext !== ".tsx" && ext !== ".jsx") {
|
|
1283
1347
|
return;
|
|
1284
1348
|
}
|
|
1285
1349
|
if (!normalizedPath.startsWith(normalizedSrcDir)) {
|
|
1286
1350
|
return;
|
|
1287
1351
|
}
|
|
1288
|
-
const fileName =
|
|
1352
|
+
const fileName = import_path6.default.basename(normalizedPath, ext);
|
|
1289
1353
|
if (fileName !== "index") {
|
|
1290
1354
|
return;
|
|
1291
1355
|
}
|
|
1292
|
-
const folderPath =
|
|
1293
|
-
const folderName =
|
|
1356
|
+
const folderPath = import_path6.default.dirname(normalizedPath);
|
|
1357
|
+
const folderName = import_path6.default.basename(folderPath);
|
|
1294
1358
|
if (folderName === "src" || folderName.startsWith("(")) {
|
|
1295
1359
|
return;
|
|
1296
1360
|
}
|
|
1297
1361
|
try {
|
|
1298
|
-
|
|
1299
|
-
const content =
|
|
1362
|
+
import_fs6.default.statSync(normalizedPath);
|
|
1363
|
+
const content = import_fs6.default.readFileSync(normalizedPath, "utf-8");
|
|
1300
1364
|
if (content.trim().length > 10) {
|
|
1301
1365
|
return;
|
|
1302
1366
|
}
|
|
@@ -1306,7 +1370,7 @@ function autoGeneratePlugin() {
|
|
|
1306
1370
|
const isDynamic = folderName.startsWith("$");
|
|
1307
1371
|
const boilerplate = generateBoilerplate(folderName, isDynamic);
|
|
1308
1372
|
try {
|
|
1309
|
-
|
|
1373
|
+
import_fs6.default.writeFileSync(normalizedPath, boilerplate, "utf-8");
|
|
1310
1374
|
console.log(
|
|
1311
1375
|
`\x1B[32m\u2713 [olova] Auto-generated: ${folderName}/index${ext}\x1B[0m`
|
|
1312
1376
|
);
|
|
@@ -1322,20 +1386,20 @@ function autoGeneratePlugin() {
|
|
|
1322
1386
|
}
|
|
1323
1387
|
|
|
1324
1388
|
// router/error-overlay.ts
|
|
1325
|
-
|
|
1389
|
+
var import_path7 = __toESM(require("path"), 1);
|
|
1326
1390
|
function proactiveErrorPlugin() {
|
|
1327
1391
|
return {
|
|
1328
1392
|
name: "olova-proactive-error",
|
|
1329
1393
|
enforce: "post",
|
|
1330
1394
|
configureServer(devServer) {
|
|
1331
|
-
const srcDir =
|
|
1395
|
+
const srcDir = import_path7.default.resolve(process.cwd(), "src");
|
|
1332
1396
|
const validateFile = async (filePath) => {
|
|
1333
1397
|
if (!filePath.startsWith(srcDir)) return;
|
|
1334
1398
|
if (!/\.(tsx?|jsx?)$/.test(filePath)) return;
|
|
1335
|
-
const relativePath =
|
|
1399
|
+
const relativePath = import_path7.default.relative(srcDir, filePath);
|
|
1336
1400
|
console.log("\x1B[36m[olova]\x1B[0m Checking:", relativePath);
|
|
1337
1401
|
try {
|
|
1338
|
-
const url = "/" +
|
|
1402
|
+
const url = "/" + import_path7.default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
1339
1403
|
await devServer.transformRequest(url);
|
|
1340
1404
|
console.log("\x1B[32m[olova]\x1B[0m \u2713", relativePath, "OK");
|
|
1341
1405
|
} catch (err) {
|
|
@@ -1511,14 +1575,15 @@ function olovaPlugins() {
|
|
|
1511
1575
|
// Checks all files on save for instant error detection
|
|
1512
1576
|
];
|
|
1513
1577
|
}
|
|
1514
|
-
export
|
|
1578
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1579
|
+
0 && (module.exports = {
|
|
1515
1580
|
autoGeneratePlugin,
|
|
1516
1581
|
cleanUrlPlugin,
|
|
1517
|
-
|
|
1582
|
+
colors,
|
|
1518
1583
|
configPlugin,
|
|
1519
1584
|
createTimer,
|
|
1520
|
-
|
|
1521
|
-
|
|
1585
|
+
formatBytes,
|
|
1586
|
+
formatTime,
|
|
1522
1587
|
frameworkPlugin,
|
|
1523
1588
|
generateBuildId,
|
|
1524
1589
|
generateCriticalCSS,
|
|
@@ -1528,13 +1593,13 @@ export {
|
|
|
1528
1593
|
generateResourceHints,
|
|
1529
1594
|
generateServiceWorkerContent,
|
|
1530
1595
|
generateServiceWorkerScript,
|
|
1531
|
-
|
|
1596
|
+
logger,
|
|
1532
1597
|
minifyHtml,
|
|
1533
1598
|
olovaPlugins,
|
|
1534
1599
|
parseFlightData,
|
|
1535
1600
|
proactiveErrorPlugin,
|
|
1536
1601
|
routerPlugin,
|
|
1537
1602
|
ssgPlugin,
|
|
1538
|
-
|
|
1603
|
+
symbols,
|
|
1539
1604
|
virtualHtmlPlugin
|
|
1540
|
-
};
|
|
1605
|
+
});
|
package/dist/olova-plugins.js
CHANGED
|
@@ -1,66 +1,6 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// olova-plugins.ts
|
|
31
|
-
var olova_plugins_exports = {};
|
|
32
|
-
__export(olova_plugins_exports, {
|
|
33
|
-
autoGeneratePlugin: () => autoGeneratePlugin,
|
|
34
|
-
cleanUrlPlugin: () => cleanUrlPlugin,
|
|
35
|
-
colors: () => colors3,
|
|
36
|
-
configPlugin: () => configPlugin,
|
|
37
|
-
createTimer: () => createTimer,
|
|
38
|
-
formatBytes: () => formatBytes2,
|
|
39
|
-
formatTime: () => formatTime2,
|
|
40
|
-
frameworkPlugin: () => frameworkPlugin,
|
|
41
|
-
generateBuildId: () => generateBuildId,
|
|
42
|
-
generateCriticalCSS: () => generateCriticalCSS,
|
|
43
|
-
generateJsonLd: () => generateJsonLd,
|
|
44
|
-
generateOlovaHydration: () => generateOlovaHydration,
|
|
45
|
-
generatePerformanceMeta: () => generatePerformanceMeta,
|
|
46
|
-
generateResourceHints: () => generateResourceHints,
|
|
47
|
-
generateServiceWorkerContent: () => generateServiceWorkerContent,
|
|
48
|
-
generateServiceWorkerScript: () => generateServiceWorkerScript,
|
|
49
|
-
logger: () => logger2,
|
|
50
|
-
minifyHtml: () => minifyHtml,
|
|
51
|
-
olovaPlugins: () => olovaPlugins,
|
|
52
|
-
parseFlightData: () => parseFlightData,
|
|
53
|
-
proactiveErrorPlugin: () => proactiveErrorPlugin,
|
|
54
|
-
routerPlugin: () => routerPlugin,
|
|
55
|
-
ssgPlugin: () => ssgPlugin,
|
|
56
|
-
symbols: () => symbols2,
|
|
57
|
-
virtualHtmlPlugin: () => virtualHtmlPlugin
|
|
58
|
-
});
|
|
59
|
-
module.exports = __toCommonJS(olova_plugins_exports);
|
|
60
|
-
|
|
61
1
|
// router/config.ts
|
|
62
|
-
|
|
63
|
-
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
64
4
|
var colors = {
|
|
65
5
|
reset: "\x1B[0m",
|
|
66
6
|
bold: "\x1B[1m",
|
|
@@ -70,12 +10,12 @@ var colors = {
|
|
|
70
10
|
white: "\x1B[37m"
|
|
71
11
|
};
|
|
72
12
|
function configPlugin() {
|
|
73
|
-
const olovaDir =
|
|
13
|
+
const olovaDir = path.resolve(".olova");
|
|
74
14
|
return {
|
|
75
15
|
name: "olova-config",
|
|
76
16
|
config(_config, { command }) {
|
|
77
|
-
if (!
|
|
78
|
-
|
|
17
|
+
if (!fs.existsSync(olovaDir)) {
|
|
18
|
+
fs.mkdirSync(olovaDir, { recursive: true });
|
|
79
19
|
}
|
|
80
20
|
if (process.env.IS_SSG_BUILD) {
|
|
81
21
|
return {
|
|
@@ -148,12 +88,13 @@ function configPlugin() {
|
|
|
148
88
|
}
|
|
149
89
|
|
|
150
90
|
// router/router.ts
|
|
151
|
-
|
|
152
|
-
|
|
91
|
+
import fs2 from "fs";
|
|
92
|
+
import path2 from "path";
|
|
153
93
|
function routerPlugin() {
|
|
154
94
|
const virtualModuleId = "olova/routes";
|
|
155
95
|
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
156
96
|
let server = null;
|
|
97
|
+
let root = process.cwd();
|
|
157
98
|
const invalidateRoutes = () => {
|
|
158
99
|
if (server) {
|
|
159
100
|
const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId);
|
|
@@ -168,31 +109,34 @@ function routerPlugin() {
|
|
|
168
109
|
};
|
|
169
110
|
return {
|
|
170
111
|
name: "olova-router",
|
|
112
|
+
configResolved(config) {
|
|
113
|
+
root = config.root;
|
|
114
|
+
},
|
|
171
115
|
// Configure dev server to watch for file changes
|
|
172
116
|
configureServer(devServer) {
|
|
173
117
|
server = devServer;
|
|
174
|
-
const srcDir =
|
|
118
|
+
const srcDir = path2.resolve(root, "src");
|
|
175
119
|
const watcher = devServer.watcher;
|
|
176
120
|
watcher.on("add", (filePath) => {
|
|
177
121
|
if (filePath.startsWith(srcDir) && /\.(tsx|jsx|html|md)$/.test(filePath)) {
|
|
178
|
-
console.log("\x1B[36m[olova]\x1B[0m New route detected:",
|
|
122
|
+
console.log("\x1B[36m[olova]\x1B[0m New route detected:", path2.relative(srcDir, filePath));
|
|
179
123
|
invalidateRoutes();
|
|
180
124
|
}
|
|
181
125
|
});
|
|
182
126
|
watcher.on("unlink", (filePath) => {
|
|
183
127
|
if (filePath.startsWith(srcDir) && /\.(tsx|jsx|html|md)$/.test(filePath)) {
|
|
184
|
-
console.log("\x1B[36m[olova]\x1B[0m Route removed:",
|
|
128
|
+
console.log("\x1B[36m[olova]\x1B[0m Route removed:", path2.relative(srcDir, filePath));
|
|
185
129
|
invalidateRoutes();
|
|
186
130
|
}
|
|
187
131
|
});
|
|
188
132
|
watcher.on("addDir", (dirPath) => {
|
|
189
133
|
if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {
|
|
190
|
-
console.log("\x1B[36m[olova]\x1B[0m New route folder detected:",
|
|
134
|
+
console.log("\x1B[36m[olova]\x1B[0m New route folder detected:", path2.relative(srcDir, dirPath));
|
|
191
135
|
}
|
|
192
136
|
});
|
|
193
137
|
watcher.on("unlinkDir", (dirPath) => {
|
|
194
138
|
if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {
|
|
195
|
-
console.log("\x1B[36m[olova]\x1B[0m Route folder removed:",
|
|
139
|
+
console.log("\x1B[36m[olova]\x1B[0m Route folder removed:", path2.relative(srcDir, dirPath));
|
|
196
140
|
invalidateRoutes();
|
|
197
141
|
}
|
|
198
142
|
});
|
|
@@ -204,7 +148,7 @@ function routerPlugin() {
|
|
|
204
148
|
},
|
|
205
149
|
// Mark the virtual module as having side effects for proper HMR
|
|
206
150
|
handleHotUpdate({ file, server: devServer }) {
|
|
207
|
-
const srcDir =
|
|
151
|
+
const srcDir = path2.resolve(root, "src");
|
|
208
152
|
if (file.startsWith(srcDir) && /\.(tsx|jsx)$/.test(file)) {
|
|
209
153
|
const mod = devServer.moduleGraph.getModuleById(resolvedVirtualModuleId);
|
|
210
154
|
if (mod) {
|
|
@@ -214,13 +158,13 @@ function routerPlugin() {
|
|
|
214
158
|
},
|
|
215
159
|
load(id) {
|
|
216
160
|
if (id === resolvedVirtualModuleId) {
|
|
217
|
-
const srcDir =
|
|
161
|
+
const srcDir = path2.resolve(root, "src");
|
|
218
162
|
const getRoutes = (dir, baseRoute = "", baseImportPath = "") => {
|
|
219
|
-
const entries =
|
|
163
|
+
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
220
164
|
let routes = [];
|
|
221
165
|
for (const entry of entries) {
|
|
222
166
|
const entryName = entry.name;
|
|
223
|
-
const fullPath =
|
|
167
|
+
const fullPath = path2.join(dir, entryName);
|
|
224
168
|
if (entry.isDirectory()) {
|
|
225
169
|
const isRouteGroup = /^\(.+\)$/.test(entryName);
|
|
226
170
|
if (isRouteGroup) {
|
|
@@ -239,7 +183,7 @@ function routerPlugin() {
|
|
|
239
183
|
));
|
|
240
184
|
}
|
|
241
185
|
} else {
|
|
242
|
-
const ext =
|
|
186
|
+
const ext = path2.extname(entryName);
|
|
243
187
|
const supportedExts = [".tsx", ".jsx", ".html", ".md"];
|
|
244
188
|
if (supportedExts.includes(ext)) {
|
|
245
189
|
const nameNoExt = entryName.replace(/\.(tsx|jsx|html|md)$/, "");
|
|
@@ -255,7 +199,7 @@ function routerPlugin() {
|
|
|
255
199
|
} else if (ext === ".md") {
|
|
256
200
|
routes.push(` "${normalizedRoutePath}": () => import("${importPath}?raw").then(m => ({ default: m.default, __isMd: true, __isStatic: true })),`);
|
|
257
201
|
} else {
|
|
258
|
-
const fileContent =
|
|
202
|
+
const fileContent = fs2.readFileSync(fullPath, "utf-8");
|
|
259
203
|
const firstLine = fileContent.trim().split("\n")[0].trim();
|
|
260
204
|
const hasStaticDirective = firstLine === '"static"' || firstLine === "'static'";
|
|
261
205
|
if (hasStaticDirective) {
|
|
@@ -270,7 +214,7 @@ function routerPlugin() {
|
|
|
270
214
|
return routes;
|
|
271
215
|
};
|
|
272
216
|
let routeLines = [];
|
|
273
|
-
if (
|
|
217
|
+
if (fs2.existsSync(srcDir)) {
|
|
274
218
|
routeLines = getRoutes(srcDir);
|
|
275
219
|
}
|
|
276
220
|
return `export const routes = {
|
|
@@ -282,7 +226,7 @@ ${routeLines.join("\n")}
|
|
|
282
226
|
}
|
|
283
227
|
|
|
284
228
|
// router/framework.ts
|
|
285
|
-
|
|
229
|
+
import { transformWithEsbuild } from "vite";
|
|
286
230
|
function frameworkPlugin() {
|
|
287
231
|
const virtualClientEntry = "olova/client";
|
|
288
232
|
const resolvedVirtualClientEntry = "\0" + virtualClientEntry;
|
|
@@ -410,7 +354,7 @@ loadRoute(path).then((result) => {
|
|
|
410
354
|
createRoot(document).render(app);
|
|
411
355
|
}
|
|
412
356
|
});`;
|
|
413
|
-
const result = await
|
|
357
|
+
const result = await transformWithEsbuild(code, "olova-client.tsx", {
|
|
414
358
|
loader: "tsx",
|
|
415
359
|
jsx: "automatic"
|
|
416
360
|
});
|
|
@@ -527,7 +471,7 @@ export function renderShellWithMetadata(metadata) {
|
|
|
527
471
|
|
|
528
472
|
// Re-export loadRoute so it can be used during SSG to extract metadata from any route
|
|
529
473
|
export { loadRoute };`;
|
|
530
|
-
const result = await
|
|
474
|
+
const result = await transformWithEsbuild(code, "olova-server.tsx", {
|
|
531
475
|
loader: "tsx",
|
|
532
476
|
jsx: "automatic"
|
|
533
477
|
});
|
|
@@ -538,8 +482,8 @@ export { loadRoute };`;
|
|
|
538
482
|
}
|
|
539
483
|
|
|
540
484
|
// router/virtual-html.ts
|
|
541
|
-
|
|
542
|
-
|
|
485
|
+
import fs3 from "fs";
|
|
486
|
+
import path3 from "path";
|
|
543
487
|
|
|
544
488
|
// router/hydration.ts
|
|
545
489
|
function generateOlovaHydration(data, buildId) {
|
|
@@ -752,30 +696,30 @@ function virtualHtmlPlugin() {
|
|
|
752
696
|
// Serve HTML for all routes in dev mode with SSR (like Next.js)
|
|
753
697
|
configureServer(server) {
|
|
754
698
|
const isStaticRoute = (routePath) => {
|
|
755
|
-
const srcDir =
|
|
699
|
+
const srcDir = path3.resolve("src");
|
|
756
700
|
let filePath = routePath === "/" ? "index" : routePath.slice(1);
|
|
757
701
|
const staticPaths = [
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
702
|
+
path3.join(srcDir, filePath, "index.html"),
|
|
703
|
+
path3.join(srcDir, filePath, "index.md"),
|
|
704
|
+
path3.join(srcDir, filePath + ".html"),
|
|
705
|
+
path3.join(srcDir, filePath + ".md")
|
|
762
706
|
];
|
|
763
707
|
for (const p of staticPaths) {
|
|
764
|
-
if (
|
|
708
|
+
if (fs3.existsSync(p)) {
|
|
765
709
|
return true;
|
|
766
710
|
}
|
|
767
711
|
}
|
|
768
712
|
const possiblePaths = [
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
713
|
+
path3.join(srcDir, filePath, "index.tsx"),
|
|
714
|
+
path3.join(srcDir, filePath, "index.jsx"),
|
|
715
|
+
path3.join(srcDir, filePath + ".tsx"),
|
|
716
|
+
path3.join(srcDir, filePath + ".jsx"),
|
|
717
|
+
path3.join(srcDir, "App.tsx"),
|
|
718
|
+
path3.join(srcDir, "App.jsx")
|
|
775
719
|
];
|
|
776
720
|
for (const p of possiblePaths) {
|
|
777
|
-
if (
|
|
778
|
-
const content =
|
|
721
|
+
if (fs3.existsSync(p)) {
|
|
722
|
+
const content = fs3.readFileSync(p, "utf-8");
|
|
779
723
|
const firstLine = content.trim().split("\n")[0].trim();
|
|
780
724
|
return firstLine === '"static"' || firstLine === "'static'";
|
|
781
725
|
}
|
|
@@ -869,10 +813,10 @@ function virtualHtmlPlugin() {
|
|
|
869
813
|
}
|
|
870
814
|
|
|
871
815
|
// router/ssg.ts
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
816
|
+
import { build } from "vite";
|
|
817
|
+
import fs4 from "fs";
|
|
818
|
+
import path4 from "path";
|
|
819
|
+
import { pathToFileURL } from "url";
|
|
876
820
|
|
|
877
821
|
// router/utils.ts
|
|
878
822
|
function minifyHtml(html) {
|
|
@@ -1041,7 +985,7 @@ function ssgPlugin() {
|
|
|
1041
985
|
logger.header("Generating static pages...");
|
|
1042
986
|
const serverBuildStart = performance.now();
|
|
1043
987
|
try {
|
|
1044
|
-
await
|
|
988
|
+
await build({
|
|
1045
989
|
configFile: "./vite.config.ts",
|
|
1046
990
|
build: {
|
|
1047
991
|
ssr: true,
|
|
@@ -1066,10 +1010,10 @@ function ssgPlugin() {
|
|
|
1066
1010
|
const scanStart = performance.now();
|
|
1067
1011
|
const allRoutes = [];
|
|
1068
1012
|
const scan = (dir, base = "") => {
|
|
1069
|
-
if (!
|
|
1070
|
-
const entries =
|
|
1013
|
+
if (!fs4.existsSync(dir)) return;
|
|
1014
|
+
const entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
1071
1015
|
for (const entry of entries) {
|
|
1072
|
-
const fullPath =
|
|
1016
|
+
const fullPath = path4.join(dir, entry.name);
|
|
1073
1017
|
if (entry.isDirectory()) {
|
|
1074
1018
|
const isRouteGroup = /^\(.+\)$/.test(entry.name);
|
|
1075
1019
|
if (isRouteGroup) {
|
|
@@ -1078,7 +1022,7 @@ function ssgPlugin() {
|
|
|
1078
1022
|
scan(fullPath, `${base}/${entry.name}`);
|
|
1079
1023
|
}
|
|
1080
1024
|
} else {
|
|
1081
|
-
const ext =
|
|
1025
|
+
const ext = path4.extname(entry.name);
|
|
1082
1026
|
const supportedExts = [".tsx", ".jsx", ".html", ".md"];
|
|
1083
1027
|
if (supportedExts.includes(ext)) {
|
|
1084
1028
|
const nameNoExt = entry.name.replace(/\.(tsx|jsx|html|md)$/, "");
|
|
@@ -1091,7 +1035,7 @@ function ssgPlugin() {
|
|
|
1091
1035
|
if (ext === ".html" || ext === ".md") {
|
|
1092
1036
|
allRoutes.push({ route, isStatic: true, filePath: fullPath });
|
|
1093
1037
|
} else {
|
|
1094
|
-
const fileContent =
|
|
1038
|
+
const fileContent = fs4.readFileSync(fullPath, "utf-8");
|
|
1095
1039
|
const firstLine = fileContent.trim().split("\n")[0].trim();
|
|
1096
1040
|
const isStatic = firstLine === '"static"' || firstLine === "'static'";
|
|
1097
1041
|
allRoutes.push({ route, isStatic, filePath: fullPath });
|
|
@@ -1100,36 +1044,36 @@ function ssgPlugin() {
|
|
|
1100
1044
|
}
|
|
1101
1045
|
}
|
|
1102
1046
|
};
|
|
1103
|
-
scan(
|
|
1047
|
+
scan(path4.resolve("src"));
|
|
1104
1048
|
logger.step(`Found ${allRoutes.length} routes`, performance.now() - scanStart);
|
|
1105
|
-
const serverDir =
|
|
1106
|
-
let serverFile =
|
|
1049
|
+
const serverDir = path4.resolve(".olova/server");
|
|
1050
|
+
let serverFile = fs4.readdirSync(serverDir).find(
|
|
1107
1051
|
(f) => (f === "server.js" || f.includes("server-entry")) && f.endsWith(".js")
|
|
1108
1052
|
);
|
|
1109
1053
|
if (!serverFile) {
|
|
1110
1054
|
logger.error("Could not find server build artifact");
|
|
1111
1055
|
return;
|
|
1112
1056
|
}
|
|
1113
|
-
const serverEntryPath =
|
|
1114
|
-
const { render, renderShell, renderShellWithMetadata, loadRoute } = await import(
|
|
1057
|
+
const serverEntryPath = path4.join(serverDir, serverFile);
|
|
1058
|
+
const { render, renderShell, renderShellWithMetadata, loadRoute } = await import(pathToFileURL(serverEntryPath).href);
|
|
1115
1059
|
const assetsStart = performance.now();
|
|
1116
|
-
const distDir =
|
|
1117
|
-
const clientHtmlPath =
|
|
1060
|
+
const distDir = path4.resolve(".olova/dist");
|
|
1061
|
+
const clientHtmlPath = path4.join(distDir, "olova.html");
|
|
1118
1062
|
let shellHtml = renderShell();
|
|
1119
1063
|
if (!shellHtml.startsWith("<!DOCTYPE html>")) {
|
|
1120
1064
|
shellHtml = `<!DOCTYPE html>
|
|
1121
1065
|
${shellHtml}`;
|
|
1122
1066
|
}
|
|
1123
1067
|
let template = "";
|
|
1124
|
-
if (
|
|
1125
|
-
template =
|
|
1068
|
+
if (fs4.existsSync(clientHtmlPath)) {
|
|
1069
|
+
template = fs4.readFileSync(clientHtmlPath, "utf-8");
|
|
1126
1070
|
}
|
|
1127
1071
|
const scripts = template.match(/<script[\s\S]*?>[\s\S]*?<\/script>/gi) || [];
|
|
1128
1072
|
const links = template.match(/<link[\s\S]*?>/gi) || [];
|
|
1129
|
-
const chunksDir =
|
|
1073
|
+
const chunksDir = path4.join(distDir, "pro_olova_static", "chunks");
|
|
1130
1074
|
let preloadLinks = [];
|
|
1131
|
-
if (
|
|
1132
|
-
const chunks =
|
|
1075
|
+
if (fs4.existsSync(chunksDir)) {
|
|
1076
|
+
const chunks = fs4.readdirSync(chunksDir).filter((f) => f.endsWith(".js"));
|
|
1133
1077
|
preloadLinks = chunks.map(
|
|
1134
1078
|
(chunk) => `<link rel="modulepreload" crossorigin href="/pro_olova_static/chunks/${chunk}" />`
|
|
1135
1079
|
);
|
|
@@ -1139,8 +1083,8 @@ ${shellHtml}`;
|
|
|
1139
1083
|
preloadLinks.unshift(`<link rel="modulepreload" crossorigin href="${mainScriptMatch[1]}" />`);
|
|
1140
1084
|
}
|
|
1141
1085
|
const chunkList = [];
|
|
1142
|
-
if (
|
|
1143
|
-
const chunks =
|
|
1086
|
+
if (fs4.existsSync(chunksDir)) {
|
|
1087
|
+
const chunks = fs4.readdirSync(chunksDir).filter((f) => f.endsWith(".js"));
|
|
1144
1088
|
chunks.forEach((chunk) => chunkList.push(`/pro_olova_static/chunks/${chunk}`));
|
|
1145
1089
|
}
|
|
1146
1090
|
const resourceHints = generateResourceHints();
|
|
@@ -1155,7 +1099,7 @@ ${shellHtml}`;
|
|
|
1155
1099
|
...links.map((l) => l.match(/href="([^"]+)"/)?.[1]).filter(Boolean)
|
|
1156
1100
|
];
|
|
1157
1101
|
const swContent = generateServiceWorkerContent(buildId, allAssetsForSW);
|
|
1158
|
-
|
|
1102
|
+
fs4.writeFileSync(path4.join(distDir, "sw.js"), swContent);
|
|
1159
1103
|
const assets = [performanceHead, ...links, ...preloadLinks, ...scripts, swScript].join("\n");
|
|
1160
1104
|
logger.step(`Assets optimized (${preloadLinks.length} preloads, SW ready)`, performance.now() - assetsStart);
|
|
1161
1105
|
console.log("");
|
|
@@ -1237,17 +1181,17 @@ ${finalHtml}`;
|
|
|
1237
1181
|
}
|
|
1238
1182
|
finalHtml = minifyHtml(finalHtml);
|
|
1239
1183
|
}
|
|
1240
|
-
const outPath =
|
|
1241
|
-
|
|
1242
|
-
|
|
1184
|
+
const outPath = path4.join(distDir, route === "/" ? "index.html" : `${route}/index.html`);
|
|
1185
|
+
fs4.mkdirSync(path4.dirname(outPath), { recursive: true });
|
|
1186
|
+
fs4.writeFileSync(outPath, finalHtml);
|
|
1243
1187
|
const routeTime = performance.now() - routeStart;
|
|
1244
1188
|
const routeSize = Buffer.byteLength(finalHtml, "utf8");
|
|
1245
1189
|
routeResults.push({ route, type: isStatic ? "static" : "ssr", size: routeSize, time: routeTime });
|
|
1246
1190
|
logger.route(route, isStatic ? "static" : "ssr", routeSize, routeTime);
|
|
1247
1191
|
}
|
|
1248
|
-
const fallbackPath =
|
|
1249
|
-
if (
|
|
1250
|
-
|
|
1192
|
+
const fallbackPath = path4.join(distDir, "404.html");
|
|
1193
|
+
if (fs4.existsSync(clientHtmlPath)) {
|
|
1194
|
+
fs4.copyFileSync(clientHtmlPath, fallbackPath);
|
|
1251
1195
|
}
|
|
1252
1196
|
const totalTime = performance.now() - totalStartTime;
|
|
1253
1197
|
logger.buildComplete(allRoutes.length, staticCount, totalTime);
|
|
@@ -1258,28 +1202,28 @@ ${finalHtml}`;
|
|
|
1258
1202
|
}
|
|
1259
1203
|
|
|
1260
1204
|
// router/clean-url.ts
|
|
1261
|
-
|
|
1262
|
-
|
|
1205
|
+
import fs5 from "fs";
|
|
1206
|
+
import path5 from "path";
|
|
1263
1207
|
function cleanUrlPlugin() {
|
|
1264
1208
|
return {
|
|
1265
1209
|
name: "olova-clean-url",
|
|
1266
1210
|
configurePreviewServer(server) {
|
|
1267
1211
|
server.middlewares.use((req, res, next) => {
|
|
1268
1212
|
const urlPath = (req.url || "/").split("?")[0];
|
|
1269
|
-
const distDir =
|
|
1213
|
+
const distDir = path5.resolve(".olova/dist");
|
|
1270
1214
|
if (urlPath === "/") {
|
|
1271
|
-
const indexPath2 =
|
|
1272
|
-
if (
|
|
1273
|
-
const content =
|
|
1215
|
+
const indexPath2 = path5.join(distDir, "index.html");
|
|
1216
|
+
if (fs5.existsSync(indexPath2)) {
|
|
1217
|
+
const content = fs5.readFileSync(indexPath2, "utf-8");
|
|
1274
1218
|
res.setHeader("Content-Type", "text/html");
|
|
1275
1219
|
res.end(content);
|
|
1276
1220
|
return;
|
|
1277
1221
|
}
|
|
1278
1222
|
}
|
|
1279
1223
|
if (urlPath.includes(".")) return next();
|
|
1280
|
-
const indexPath =
|
|
1281
|
-
if (
|
|
1282
|
-
const content =
|
|
1224
|
+
const indexPath = path5.join(distDir, urlPath, "index.html");
|
|
1225
|
+
if (fs5.existsSync(indexPath)) {
|
|
1226
|
+
const content = fs5.readFileSync(indexPath, "utf-8");
|
|
1283
1227
|
res.setHeader("Content-Type", "text/html");
|
|
1284
1228
|
res.end(content);
|
|
1285
1229
|
return;
|
|
@@ -1291,8 +1235,8 @@ function cleanUrlPlugin() {
|
|
|
1291
1235
|
}
|
|
1292
1236
|
|
|
1293
1237
|
// router/auto-generate.ts
|
|
1294
|
-
|
|
1295
|
-
|
|
1238
|
+
import fs6 from "fs";
|
|
1239
|
+
import path6 from "path";
|
|
1296
1240
|
function toPascalCase(str) {
|
|
1297
1241
|
const cleanStr = str.replace(/^\$/, "");
|
|
1298
1242
|
return cleanStr.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
|
|
@@ -1329,34 +1273,34 @@ function autoGeneratePlugin() {
|
|
|
1329
1273
|
return {
|
|
1330
1274
|
name: "olova-auto-generate",
|
|
1331
1275
|
configResolved(config) {
|
|
1332
|
-
srcDir =
|
|
1276
|
+
srcDir = path6.resolve(config.root, "src");
|
|
1333
1277
|
},
|
|
1334
1278
|
configureServer(server) {
|
|
1335
1279
|
console.log(
|
|
1336
1280
|
"\x1B[36m[olova] Auto-generate plugin active - watching for new route files\x1B[0m"
|
|
1337
1281
|
);
|
|
1338
1282
|
server.watcher.on("add", (filePath) => {
|
|
1339
|
-
const normalizedPath =
|
|
1340
|
-
const normalizedSrcDir =
|
|
1341
|
-
const ext =
|
|
1283
|
+
const normalizedPath = path6.normalize(filePath);
|
|
1284
|
+
const normalizedSrcDir = path6.normalize(srcDir);
|
|
1285
|
+
const ext = path6.extname(normalizedPath);
|
|
1342
1286
|
if (ext !== ".tsx" && ext !== ".jsx") {
|
|
1343
1287
|
return;
|
|
1344
1288
|
}
|
|
1345
1289
|
if (!normalizedPath.startsWith(normalizedSrcDir)) {
|
|
1346
1290
|
return;
|
|
1347
1291
|
}
|
|
1348
|
-
const fileName =
|
|
1292
|
+
const fileName = path6.basename(normalizedPath, ext);
|
|
1349
1293
|
if (fileName !== "index") {
|
|
1350
1294
|
return;
|
|
1351
1295
|
}
|
|
1352
|
-
const folderPath =
|
|
1353
|
-
const folderName =
|
|
1296
|
+
const folderPath = path6.dirname(normalizedPath);
|
|
1297
|
+
const folderName = path6.basename(folderPath);
|
|
1354
1298
|
if (folderName === "src" || folderName.startsWith("(")) {
|
|
1355
1299
|
return;
|
|
1356
1300
|
}
|
|
1357
1301
|
try {
|
|
1358
|
-
|
|
1359
|
-
const content =
|
|
1302
|
+
fs6.statSync(normalizedPath);
|
|
1303
|
+
const content = fs6.readFileSync(normalizedPath, "utf-8");
|
|
1360
1304
|
if (content.trim().length > 10) {
|
|
1361
1305
|
return;
|
|
1362
1306
|
}
|
|
@@ -1366,7 +1310,7 @@ function autoGeneratePlugin() {
|
|
|
1366
1310
|
const isDynamic = folderName.startsWith("$");
|
|
1367
1311
|
const boilerplate = generateBoilerplate(folderName, isDynamic);
|
|
1368
1312
|
try {
|
|
1369
|
-
|
|
1313
|
+
fs6.writeFileSync(normalizedPath, boilerplate, "utf-8");
|
|
1370
1314
|
console.log(
|
|
1371
1315
|
`\x1B[32m\u2713 [olova] Auto-generated: ${folderName}/index${ext}\x1B[0m`
|
|
1372
1316
|
);
|
|
@@ -1382,20 +1326,20 @@ function autoGeneratePlugin() {
|
|
|
1382
1326
|
}
|
|
1383
1327
|
|
|
1384
1328
|
// router/error-overlay.ts
|
|
1385
|
-
|
|
1329
|
+
import path7 from "path";
|
|
1386
1330
|
function proactiveErrorPlugin() {
|
|
1387
1331
|
return {
|
|
1388
1332
|
name: "olova-proactive-error",
|
|
1389
1333
|
enforce: "post",
|
|
1390
1334
|
configureServer(devServer) {
|
|
1391
|
-
const srcDir =
|
|
1335
|
+
const srcDir = path7.resolve(process.cwd(), "src");
|
|
1392
1336
|
const validateFile = async (filePath) => {
|
|
1393
1337
|
if (!filePath.startsWith(srcDir)) return;
|
|
1394
1338
|
if (!/\.(tsx?|jsx?)$/.test(filePath)) return;
|
|
1395
|
-
const relativePath =
|
|
1339
|
+
const relativePath = path7.relative(srcDir, filePath);
|
|
1396
1340
|
console.log("\x1B[36m[olova]\x1B[0m Checking:", relativePath);
|
|
1397
1341
|
try {
|
|
1398
|
-
const url = "/" +
|
|
1342
|
+
const url = "/" + path7.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
1399
1343
|
await devServer.transformRequest(url);
|
|
1400
1344
|
console.log("\x1B[32m[olova]\x1B[0m \u2713", relativePath, "OK");
|
|
1401
1345
|
} catch (err) {
|
|
@@ -1571,15 +1515,14 @@ function olovaPlugins() {
|
|
|
1571
1515
|
// Checks all files on save for instant error detection
|
|
1572
1516
|
];
|
|
1573
1517
|
}
|
|
1574
|
-
|
|
1575
|
-
0 && (module.exports = {
|
|
1518
|
+
export {
|
|
1576
1519
|
autoGeneratePlugin,
|
|
1577
1520
|
cleanUrlPlugin,
|
|
1578
|
-
colors,
|
|
1521
|
+
colors3 as colors,
|
|
1579
1522
|
configPlugin,
|
|
1580
1523
|
createTimer,
|
|
1581
|
-
formatBytes,
|
|
1582
|
-
formatTime,
|
|
1524
|
+
formatBytes2 as formatBytes,
|
|
1525
|
+
formatTime2 as formatTime,
|
|
1583
1526
|
frameworkPlugin,
|
|
1584
1527
|
generateBuildId,
|
|
1585
1528
|
generateCriticalCSS,
|
|
@@ -1589,13 +1532,13 @@ function olovaPlugins() {
|
|
|
1589
1532
|
generateResourceHints,
|
|
1590
1533
|
generateServiceWorkerContent,
|
|
1591
1534
|
generateServiceWorkerScript,
|
|
1592
|
-
logger,
|
|
1535
|
+
logger2 as logger,
|
|
1593
1536
|
minifyHtml,
|
|
1594
1537
|
olovaPlugins,
|
|
1595
1538
|
parseFlightData,
|
|
1596
1539
|
proactiveErrorPlugin,
|
|
1597
1540
|
routerPlugin,
|
|
1598
1541
|
ssgPlugin,
|
|
1599
|
-
symbols,
|
|
1542
|
+
symbols2 as symbols,
|
|
1600
1543
|
virtualHtmlPlugin
|
|
1601
|
-
}
|
|
1544
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "olovaplugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Vite plugins for Olova framework",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/olova-plugins.cjs",
|
|
7
|
+
"module": "dist/olova-plugins.js",
|
|
7
8
|
"types": "dist/olova-plugins.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/olova-plugins.d.ts",
|
|
13
|
+
"default": "./dist/olova-plugins.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/olova-plugins.d.cts",
|
|
17
|
+
"default": "./dist/olova-plugins.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
8
21
|
"scripts": {
|
|
9
22
|
"build": "tsup olova-plugins.ts --format cjs,esm --dts --clean"
|
|
10
23
|
},
|
|
@@ -27,4 +40,5 @@
|
|
|
27
40
|
"typescript": "^5.0.0",
|
|
28
41
|
"vite": "^6.0.0"
|
|
29
42
|
}
|
|
43
|
+
|
|
30
44
|
}
|
|
File without changes
|