defuss-ssg 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.cjs +272 -24
- package/dist/index.d.cts +41 -3
- package/dist/index.d.mts +41 -3
- package/dist/index.mjs +1 -1
- package/dist/plugins/index.d.cts +1 -1
- package/dist/plugins/index.d.mts +1 -1
- package/dist/runtime.cjs +66 -48
- package/dist/runtime.d.cts +0 -7
- package/dist/runtime.d.mts +0 -7
- package/dist/runtime.mjs +66 -48
- package/dist/{serve-BZhZ9J90.mjs → serve-w6eyG8f3.mjs} +269 -25
- package/dist/{types-QQrIkB7n.d.cts → types-Be8_Y5-t.d.cts} +7 -0
- package/dist/{types-QQrIkB7n.d.mts → types-Be8_Y5-t.d.mts} +7 -0
- package/package.json +12 -4
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { v as validateProjectDir, b as build, s as serve } from './serve-
|
|
2
|
+
import { v as validateProjectDir, b as build, s as serve } from './serve-w6eyG8f3.mjs';
|
|
3
3
|
import { join, dirname, resolve } from 'node:path';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { spawn } from 'node:child_process';
|
package/dist/index.cjs
CHANGED
|
@@ -57,14 +57,28 @@ const autoHydratePlugin = {
|
|
|
57
57
|
if (Array.isArray(node)) {
|
|
58
58
|
node.map((child) => processDefussComponents(child));
|
|
59
59
|
} else if (node && typeof node === "object") {
|
|
60
|
+
const vnode = node;
|
|
60
61
|
let clientSrcFile = null;
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
clientSrcFile =
|
|
62
|
+
if (vnode.sourceInfo && typeof vnode.sourceInfo === "object" && typeof vnode.sourceInfo.fileName === "string" && vnode.sourceInfo.fileName.includes(tmpComponents) && vnode.type !== "script" && // skip already inserted hydration scripts
|
|
63
|
+
vnode.type !== "head" && // skip head elements
|
|
64
|
+
vnode.type !== "link" && // skip head elements
|
|
65
|
+
vnode.type !== "meta" && // skip head elements
|
|
66
|
+
vnode.type !== "title") {
|
|
67
|
+
clientSrcFile = vnode.sourceInfo.fileName.replaceAll(tmp, "").replaceAll(node_path.sep, "/").replace(/\.t?sx?$/, ".js");
|
|
67
68
|
const id = `dh_${Math.random().toString(36).slice(2)}`;
|
|
69
|
+
console.log(`[auto-hydrate] Found component node. type="${vnode.type}", sourceInfo.fileName="${vnode.sourceInfo?.fileName}", hasComponentProps=${!!vnode.componentProps}, componentProps=`, JSON.stringify(vnode.componentProps)?.slice(0, 300));
|
|
70
|
+
console.log(`[auto-hydrate] Node keys:`, Object.keys(vnode));
|
|
71
|
+
const componentProps = {};
|
|
72
|
+
if (vnode.componentProps) {
|
|
73
|
+
for (const [key, value] of Object.entries(vnode.componentProps)) {
|
|
74
|
+
if (typeof value === "function" || typeof value === "undefined") continue;
|
|
75
|
+
try {
|
|
76
|
+
JSON.stringify(value);
|
|
77
|
+
componentProps[key] = value;
|
|
78
|
+
} catch {
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
68
82
|
node = {
|
|
69
83
|
// Hydration wrapper
|
|
70
84
|
type: "div",
|
|
@@ -73,7 +87,7 @@ const autoHydratePlugin = {
|
|
|
73
87
|
"data-hydrate": "true"
|
|
74
88
|
},
|
|
75
89
|
children: [
|
|
76
|
-
|
|
90
|
+
vnode,
|
|
77
91
|
{
|
|
78
92
|
// Hydration script
|
|
79
93
|
type: "script",
|
|
@@ -82,7 +96,7 @@ const autoHydratePlugin = {
|
|
|
82
96
|
`
|
|
83
97
|
;(async function(){
|
|
84
98
|
|
|
85
|
-
const props = ${JSON.stringify(
|
|
99
|
+
const props = ${JSON.stringify(componentProps)};
|
|
86
100
|
const cacheBust = "?v=" + Date.now();
|
|
87
101
|
console.log("[hydrate:${id}] Starting hydration, cacheBust=" + cacheBust);
|
|
88
102
|
console.log("[hydrate:${id}] Importing runtime from /components/runtime.js" + cacheBust);
|
|
@@ -142,10 +156,11 @@ const autoHydratePlugin = {
|
|
|
142
156
|
};
|
|
143
157
|
}
|
|
144
158
|
if (!clientSrcFile) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
159
|
+
const v = node;
|
|
160
|
+
if (typeof v.children !== "undefined" && Array.isArray(v.children)) {
|
|
161
|
+
for (let i = 0; i < v.children.length; i++) {
|
|
162
|
+
v.children[i] = processDefussComponents(
|
|
163
|
+
v.children[i]
|
|
149
164
|
);
|
|
150
165
|
}
|
|
151
166
|
}
|
|
@@ -185,6 +200,7 @@ const readConfig = async (projectDir, debug) => {
|
|
|
185
200
|
config.tmp = config.tmp || configDefaults.tmp;
|
|
186
201
|
config.remarkPlugins = config.remarkPlugins || configDefaults.remarkPlugins;
|
|
187
202
|
config.rehypePlugins = config.rehypePlugins || configDefaults.rehypePlugins;
|
|
203
|
+
config.rpc = config.rpc ?? configDefaults.rpc;
|
|
188
204
|
return config;
|
|
189
205
|
};
|
|
190
206
|
const configDefaults = {
|
|
@@ -195,7 +211,8 @@ const configDefaults = {
|
|
|
195
211
|
tmp: ".ssg-temp",
|
|
196
212
|
plugins: [tailwind.tailwindPlugin, autoHydratePlugin],
|
|
197
213
|
remarkPlugins,
|
|
198
|
-
rehypePlugins
|
|
214
|
+
rehypePlugins,
|
|
215
|
+
rpc: true
|
|
199
216
|
};
|
|
200
217
|
|
|
201
218
|
const validateProjectDir = (projectDir) => {
|
|
@@ -557,6 +574,7 @@ const build = async ({
|
|
|
557
574
|
if (debug) {
|
|
558
575
|
console.log(`Incremental build \u2014 changeKind: ${changeKind}, file: ${changedRelative}`);
|
|
559
576
|
}
|
|
577
|
+
console.log(`[build] changeKind=${changeKind}, changedRelative=${changedRelative}`);
|
|
560
578
|
}
|
|
561
579
|
const isFullBuild = changeKind === "full" || changeKind === "config";
|
|
562
580
|
const tempExists = node_fs.existsSync(config.tmp);
|
|
@@ -621,10 +639,17 @@ const build = async ({
|
|
|
621
639
|
node_path.join(tmpComponentsDir, "runtime.ts")
|
|
622
640
|
);
|
|
623
641
|
console.timeEnd("[build] copy-hydration");
|
|
642
|
+
if (changeKind === "component" || isFullBuild) {
|
|
643
|
+
const staleJsFiles = await glob.async(node_path.join(tmpComponentsDir, "**/*.js"));
|
|
644
|
+
for (const f of staleJsFiles) {
|
|
645
|
+
node_fs.rmSync(f);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
let pageBuildResult = null;
|
|
624
649
|
if (changeKind !== "asset") {
|
|
625
650
|
console.time("[build] esbuild-pages");
|
|
626
651
|
const pageEntryPoints = changeKind === "page" ? [node_path.join(config.tmp, changedRelative)] : [node_path.join(tmpPagesDir, "**/*.mdx")];
|
|
627
|
-
await esbuild.build({
|
|
652
|
+
pageBuildResult = await esbuild.build({
|
|
628
653
|
entryPoints: pageEntryPoints,
|
|
629
654
|
format: "esm",
|
|
630
655
|
bundle: true,
|
|
@@ -632,6 +657,7 @@ const build = async ({
|
|
|
632
657
|
jsxDev: true,
|
|
633
658
|
target: ["esnext"],
|
|
634
659
|
outdir: tmpPagesDir,
|
|
660
|
+
metafile: true,
|
|
635
661
|
plugins: [
|
|
636
662
|
mdx({
|
|
637
663
|
jsxImportSource: "defuss",
|
|
@@ -654,7 +680,8 @@ const build = async ({
|
|
|
654
680
|
bundle: true,
|
|
655
681
|
splitting: true,
|
|
656
682
|
target: ["esnext"],
|
|
657
|
-
outdir: tmpComponentsDir
|
|
683
|
+
outdir: tmpComponentsDir,
|
|
684
|
+
allowOverwrite: true
|
|
658
685
|
});
|
|
659
686
|
console.timeEnd("[build] esbuild-components");
|
|
660
687
|
}
|
|
@@ -664,6 +691,33 @@ const build = async ({
|
|
|
664
691
|
if (changeKind === "page") {
|
|
665
692
|
const jsFile = node_path.join(config.tmp, changedRelative.replace(/\.mdx$/, ".js"));
|
|
666
693
|
outputFiles = node_fs.existsSync(jsFile) ? [jsFile] : [];
|
|
694
|
+
} else if (changeKind === "component" && pageBuildResult?.metafile) {
|
|
695
|
+
const changedBaseName = changedRelative.replace(/\.[^.]+$/, "");
|
|
696
|
+
outputFiles = [];
|
|
697
|
+
console.log(`[build] component-dep: looking for pages depending on "${changedBaseName}"`);
|
|
698
|
+
for (const [outputPath, meta] of Object.entries(pageBuildResult.metafile.outputs)) {
|
|
699
|
+
if (outputPath.endsWith(".map")) continue;
|
|
700
|
+
const inputPaths = Object.keys(meta.inputs);
|
|
701
|
+
const dependsOnChanged = inputPaths.some((input) => {
|
|
702
|
+
const inputNorm = input.replace(/\.[^.]+$/, "");
|
|
703
|
+
return inputNorm.endsWith(changedBaseName);
|
|
704
|
+
});
|
|
705
|
+
console.log(`[build] component-dep: output="${outputPath}", inputs=${inputPaths.length}, dependsOnChanged=${dependsOnChanged}`);
|
|
706
|
+
if (dependsOnChanged) {
|
|
707
|
+
console.log(`[build] component-dep: matching inputs: ${inputPaths.filter((i) => i.replace(/\.[^.]+$/, "").endsWith(changedBaseName)).join(", ")}`);
|
|
708
|
+
}
|
|
709
|
+
if (dependsOnChanged) {
|
|
710
|
+
const resolved = node_path.resolve(outputPath);
|
|
711
|
+
if (resolved.endsWith(".js") && node_fs.existsSync(resolved)) {
|
|
712
|
+
outputFiles.push(resolved);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
console.log(`[build] component-dep: ${outputFiles.length} page(s) affected out of ${Object.keys(pageBuildResult.metafile.outputs).filter((p) => !p.endsWith(".map")).length} total`);
|
|
717
|
+
if (outputFiles.length === 0) {
|
|
718
|
+
console.log(`[build] component-dep: FALLBACK \u2014 rendering all pages`);
|
|
719
|
+
outputFiles = await glob.async(node_path.join(tmpPagesDir, "**/*.js"));
|
|
720
|
+
}
|
|
667
721
|
} else {
|
|
668
722
|
outputFiles = await glob.async(node_path.join(tmpPagesDir, "**/*.js"));
|
|
669
723
|
}
|
|
@@ -672,10 +726,8 @@ const build = async ({
|
|
|
672
726
|
}
|
|
673
727
|
for (const outputFile of outputFiles) {
|
|
674
728
|
const outputHtmlFilePath = outputFile.replace(".js", ".html");
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
""
|
|
678
|
-
);
|
|
729
|
+
const resolvedTmpPagesDir = node_path.resolve(tmpPagesDir);
|
|
730
|
+
const relativeOutputHtmlFilePath = outputHtmlFilePath.replace(`${resolvedTmpPagesDir}${node_path.sep}`, "").replace(`${tmpPagesDir}${node_path.sep}`, "");
|
|
679
731
|
const pageLabel = relativeOutputHtmlFilePath;
|
|
680
732
|
if (debug) {
|
|
681
733
|
console.log("Processing output file (JS):", outputFile);
|
|
@@ -814,6 +866,157 @@ const filePathToRoute = (filePath, config, cwd) => {
|
|
|
814
866
|
return normalizedPath;
|
|
815
867
|
};
|
|
816
868
|
|
|
869
|
+
const discoverRpcFile = (projectDir) => {
|
|
870
|
+
const candidates = ["rpc.ts", "rpc.js"];
|
|
871
|
+
for (const candidate of candidates) {
|
|
872
|
+
const filePath = node_path.join(projectDir, candidate);
|
|
873
|
+
if (node_fs.existsSync(filePath)) {
|
|
874
|
+
return filePath;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return null;
|
|
878
|
+
};
|
|
879
|
+
const compileRpcModule = async (rpcFilePath, projectDir, debug = false) => {
|
|
880
|
+
const outDir = node_path.join(projectDir, ".rpc");
|
|
881
|
+
if (!node_fs.existsSync(outDir)) {
|
|
882
|
+
node_fs.mkdirSync(outDir, { recursive: true });
|
|
883
|
+
}
|
|
884
|
+
if (debug) {
|
|
885
|
+
console.log(`Compiling RPC module: ${rpcFilePath}`);
|
|
886
|
+
}
|
|
887
|
+
console.time("[rpc] esbuild-compile");
|
|
888
|
+
await esbuild.build({
|
|
889
|
+
entryPoints: [rpcFilePath],
|
|
890
|
+
format: "esm",
|
|
891
|
+
bundle: true,
|
|
892
|
+
platform: "node",
|
|
893
|
+
target: ["esnext"],
|
|
894
|
+
outdir: outDir,
|
|
895
|
+
outExtension: { ".js": ".mjs" },
|
|
896
|
+
// Mark defuss-rpc as external so it uses the installed version
|
|
897
|
+
external: ["defuss-rpc", "defuss-rpc/*"]
|
|
898
|
+
});
|
|
899
|
+
console.timeEnd("[rpc] esbuild-compile");
|
|
900
|
+
const compiledPath = node_path.join(outDir, "rpc.mjs");
|
|
901
|
+
if (debug) {
|
|
902
|
+
console.log(`RPC module compiled to: ${compiledPath}`);
|
|
903
|
+
}
|
|
904
|
+
return compiledPath;
|
|
905
|
+
};
|
|
906
|
+
const loadRpcModule = async (compiledPath) => {
|
|
907
|
+
const code = await promises.readFile(compiledPath, "utf-8");
|
|
908
|
+
const encoded = Buffer.from(code).toString("base64");
|
|
909
|
+
const dataUrl = `data:text/javascript;base64,${encoded}`;
|
|
910
|
+
return import(dataUrl);
|
|
911
|
+
};
|
|
912
|
+
const buildRpcNamespace = (moduleExports) => {
|
|
913
|
+
const namespace = {};
|
|
914
|
+
if (moduleExports.default && typeof moduleExports.default === "object") {
|
|
915
|
+
const defaultObj = moduleExports.default;
|
|
916
|
+
for (const [key, value] of Object.entries(defaultObj)) {
|
|
917
|
+
if (value && (typeof value === "object" || typeof value === "function")) {
|
|
918
|
+
namespace[key] = value;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
for (const [key, value] of Object.entries(moduleExports)) {
|
|
923
|
+
if (key === "default") continue;
|
|
924
|
+
if (value && (typeof value === "object" || typeof value === "function")) {
|
|
925
|
+
namespace[key] = value;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return namespace;
|
|
929
|
+
};
|
|
930
|
+
const initializeRpc = async (projectDir, config, debug = false) => {
|
|
931
|
+
if (config.rpc === false) {
|
|
932
|
+
if (debug) {
|
|
933
|
+
console.log("RPC disabled in config");
|
|
934
|
+
}
|
|
935
|
+
return false;
|
|
936
|
+
}
|
|
937
|
+
let rpcFilePath = null;
|
|
938
|
+
if (typeof config.rpc === "string") {
|
|
939
|
+
const customPath = node_path.resolve(projectDir, config.rpc);
|
|
940
|
+
if (node_fs.existsSync(customPath)) {
|
|
941
|
+
rpcFilePath = customPath;
|
|
942
|
+
}
|
|
943
|
+
} else {
|
|
944
|
+
rpcFilePath = discoverRpcFile(projectDir);
|
|
945
|
+
}
|
|
946
|
+
if (!rpcFilePath) {
|
|
947
|
+
if (debug) {
|
|
948
|
+
console.log("No rpc.ts/rpc.js found in project root");
|
|
949
|
+
}
|
|
950
|
+
return false;
|
|
951
|
+
}
|
|
952
|
+
let rpcServer;
|
|
953
|
+
try {
|
|
954
|
+
rpcServer = await import('defuss-rpc/server.js');
|
|
955
|
+
} catch {
|
|
956
|
+
console.warn(
|
|
957
|
+
"[defuss-ssg] defuss-rpc is not installed. Install it to enable RPC support:\n npm install defuss-rpc"
|
|
958
|
+
);
|
|
959
|
+
return false;
|
|
960
|
+
}
|
|
961
|
+
try {
|
|
962
|
+
const compiledPath = await compileRpcModule(rpcFilePath, projectDir, debug);
|
|
963
|
+
const moduleExports = await loadRpcModule(compiledPath);
|
|
964
|
+
const namespace = buildRpcNamespace(moduleExports);
|
|
965
|
+
if (Object.keys(namespace).length === 0) {
|
|
966
|
+
console.warn(
|
|
967
|
+
"[defuss-ssg] rpc.ts was found but exports no RPC namespace entries"
|
|
968
|
+
);
|
|
969
|
+
return false;
|
|
970
|
+
}
|
|
971
|
+
rpcServer.clearRpcServer();
|
|
972
|
+
rpcServer.createRpcServer(namespace);
|
|
973
|
+
console.log(
|
|
974
|
+
`RPC initialized with ${Object.keys(namespace).length} namespace(s): ${Object.keys(namespace).join(", ")}`
|
|
975
|
+
);
|
|
976
|
+
return true;
|
|
977
|
+
} catch (error) {
|
|
978
|
+
console.error("[defuss-ssg] Failed to initialize RPC:", error);
|
|
979
|
+
return false;
|
|
980
|
+
}
|
|
981
|
+
};
|
|
982
|
+
const handleRpcRequest = async (req, res) => {
|
|
983
|
+
try {
|
|
984
|
+
const { rpcRoute } = await import('defuss-rpc/server.js');
|
|
985
|
+
const protocol = req.protocol || "http";
|
|
986
|
+
const host = req.get?.("host") || req.headers?.host || "localhost";
|
|
987
|
+
const url = `${protocol}://${host}${req.originalUrl}`;
|
|
988
|
+
const reqInit = {
|
|
989
|
+
method: req.method,
|
|
990
|
+
headers: req.headers
|
|
991
|
+
};
|
|
992
|
+
if (["POST", "PUT", "PATCH", "DELETE"].includes(req.method)) {
|
|
993
|
+
try {
|
|
994
|
+
const chunks = [];
|
|
995
|
+
await new Promise((resolve2, reject) => {
|
|
996
|
+
req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
997
|
+
req.on("end", resolve2);
|
|
998
|
+
req.on("error", reject);
|
|
999
|
+
});
|
|
1000
|
+
if (chunks.length > 0) {
|
|
1001
|
+
reqInit.body = Buffer.concat(chunks);
|
|
1002
|
+
}
|
|
1003
|
+
} catch {
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
const request = new Request(url, reqInit);
|
|
1007
|
+
const response = await rpcRoute({ request });
|
|
1008
|
+
const responseText = await response.text();
|
|
1009
|
+
const contentType = response.headers.get("content-type") || "application/json";
|
|
1010
|
+
res.status(response.status).set("Content-Type", contentType).send(responseText);
|
|
1011
|
+
} catch (error) {
|
|
1012
|
+
console.error("[defuss-ssg] RPC request error:", error);
|
|
1013
|
+
res.status(500).json({
|
|
1014
|
+
error: "Internal server error",
|
|
1015
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
817
1020
|
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
818
1021
|
const { WebSocketServer } = require$1("ultimate-ws");
|
|
819
1022
|
const isPortAvailable = async (port) => {
|
|
@@ -851,6 +1054,21 @@ const serve = async ({
|
|
|
851
1054
|
console.time("[serve] register-endpoints");
|
|
852
1055
|
await registerEndpoints(app, projectDir, config, debug);
|
|
853
1056
|
console.timeEnd("[serve] register-endpoints");
|
|
1057
|
+
let rpcActive = false;
|
|
1058
|
+
console.time("[serve] rpc-init");
|
|
1059
|
+
try {
|
|
1060
|
+
rpcActive = await initializeRpc(projectDir, config, debug);
|
|
1061
|
+
if (rpcActive) {
|
|
1062
|
+
app.post("/rpc", handleRpcRequest);
|
|
1063
|
+
app.post("/rpc/schema", handleRpcRequest);
|
|
1064
|
+
console.log("RPC routes mounted at /rpc and /rpc/schema");
|
|
1065
|
+
}
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
if (debug) {
|
|
1068
|
+
console.warn("[serve] RPC initialization failed:", error);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
console.timeEnd("[serve] rpc-init");
|
|
854
1072
|
app.use((_req, res, next) => {
|
|
855
1073
|
res.set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
|
|
856
1074
|
res.set("Pragma", "no-cache");
|
|
@@ -879,15 +1097,36 @@ const serve = async ({
|
|
|
879
1097
|
}
|
|
880
1098
|
isBuilding = true;
|
|
881
1099
|
try {
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1100
|
+
const rpcFile2 = discoverRpcFile(projectDir);
|
|
1101
|
+
const isRpcFile = rpcFile2 && filePath === rpcFile2;
|
|
1102
|
+
if (isRpcFile) {
|
|
1103
|
+
console.time("[serve] rpc-reload");
|
|
1104
|
+
try {
|
|
1105
|
+
const wasActive = rpcActive;
|
|
1106
|
+
rpcActive = await initializeRpc(projectDir, config, debug);
|
|
1107
|
+
if (!wasActive && rpcActive) {
|
|
1108
|
+
app.post("/rpc", handleRpcRequest);
|
|
1109
|
+
app.post("/rpc/schema", handleRpcRequest);
|
|
1110
|
+
console.log("RPC routes mounted at /rpc and /rpc/schema");
|
|
1111
|
+
}
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
console.error("RPC reload failed:", error);
|
|
1114
|
+
}
|
|
1115
|
+
console.timeEnd("[serve] rpc-reload");
|
|
1116
|
+
} else {
|
|
1117
|
+
console.time("[serve] rebuild");
|
|
1118
|
+
await build({ projectDir, debug, mode: "serve", changedFile: filePath });
|
|
1119
|
+
console.timeEnd("[serve] rebuild");
|
|
1120
|
+
}
|
|
1121
|
+
const pagesDir2 = node_path.join(projectDir, config.pages);
|
|
1122
|
+
const isPageFile = filePath.startsWith(pagesDir2 + "/") || filePath.startsWith(pagesDir2 + node_path.sep);
|
|
1123
|
+
const reloadPath = isPageFile ? filePathToRoute(filePath, config, projectDir) : void 0;
|
|
885
1124
|
liveReloadServer.clients.forEach((client) => {
|
|
886
1125
|
if (client.readyState === 1) {
|
|
887
1126
|
client.send(
|
|
888
1127
|
JSON.stringify({
|
|
889
1128
|
command: "reload",
|
|
890
|
-
path:
|
|
1129
|
+
...reloadPath ? { path: reloadPath } : {}
|
|
891
1130
|
})
|
|
892
1131
|
);
|
|
893
1132
|
}
|
|
@@ -906,7 +1145,12 @@ const serve = async ({
|
|
|
906
1145
|
}
|
|
907
1146
|
}
|
|
908
1147
|
};
|
|
909
|
-
const
|
|
1148
|
+
const watchPaths = [pagesDir, componentsDir, assetsDir];
|
|
1149
|
+
const rpcFile = discoverRpcFile(projectDir);
|
|
1150
|
+
if (rpcFile) {
|
|
1151
|
+
watchPaths.push(rpcFile);
|
|
1152
|
+
}
|
|
1153
|
+
const watcher = chokidar.watch(watchPaths, {
|
|
910
1154
|
ignored: /(^|[\/\\])\../,
|
|
911
1155
|
// Ignore dotfiles
|
|
912
1156
|
persistent: true,
|
|
@@ -938,9 +1182,13 @@ exports.HTTP_METHODS = HTTP_METHODS;
|
|
|
938
1182
|
exports.build = build;
|
|
939
1183
|
exports.buildEndpoints = buildEndpoints;
|
|
940
1184
|
exports.compileEndpoints = compileEndpoints;
|
|
1185
|
+
exports.compileRpcModule = compileRpcModule;
|
|
941
1186
|
exports.configDefaults = configDefaults;
|
|
942
1187
|
exports.discoverEndpointSourceFiles = discoverEndpointSourceFiles;
|
|
1188
|
+
exports.discoverRpcFile = discoverRpcFile;
|
|
943
1189
|
exports.endpointFileToRoute = endpointFileToRoute;
|
|
1190
|
+
exports.handleRpcRequest = handleRpcRequest;
|
|
1191
|
+
exports.initializeRpc = initializeRpc;
|
|
944
1192
|
exports.readConfig = readConfig;
|
|
945
1193
|
exports.registerEndpoints = registerEndpoints;
|
|
946
1194
|
exports.rehypePlugins = rehypePlugins;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-
|
|
2
|
-
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-
|
|
1
|
+
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-Be8_Y5-t.cjs';
|
|
2
|
+
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-Be8_Y5-t.cjs';
|
|
3
3
|
import '@mdx-js/esbuild';
|
|
4
4
|
import 'defuss/server';
|
|
5
5
|
|
|
@@ -158,5 +158,43 @@ declare const buildEndpoints: (projectDir: string, config: SsgConfig, debug?: bo
|
|
|
158
158
|
*/
|
|
159
159
|
declare const registerEndpoints: (app: any, projectDir: string, config: SsgConfig, debug?: boolean) => Promise<void>;
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Discover the RPC file in the project root.
|
|
163
|
+
* Looks for `rpc.ts` or `rpc.js`.
|
|
164
|
+
*
|
|
165
|
+
* @param projectDir The project root directory
|
|
166
|
+
* @returns The absolute path to the RPC file, or null if not found
|
|
167
|
+
*/
|
|
168
|
+
declare const discoverRpcFile: (projectDir: string) => string | null;
|
|
169
|
+
/**
|
|
170
|
+
* Compile the RPC module source file with esbuild into the `.rpc/` directory.
|
|
171
|
+
*
|
|
172
|
+
* @param rpcFilePath Absolute path to the rpc.ts / rpc.js source file
|
|
173
|
+
* @param projectDir The project root directory
|
|
174
|
+
* @param debug Enable verbose logging
|
|
175
|
+
* @returns Absolute path to the compiled .mjs file
|
|
176
|
+
*/
|
|
177
|
+
declare const compileRpcModule: (rpcFilePath: string, projectDir: string, debug?: boolean) => Promise<string>;
|
|
178
|
+
/**
|
|
179
|
+
* Initialize the RPC server from the project's rpc.ts/rpc.js file.
|
|
180
|
+
*
|
|
181
|
+
* This function discovers, compiles, loads, and registers the RPC module.
|
|
182
|
+
* It dynamically imports `defuss-rpc/server.js` to avoid a hard dependency.
|
|
183
|
+
*
|
|
184
|
+
* @param projectDir The project root directory
|
|
185
|
+
* @param config The SSG config
|
|
186
|
+
* @param debug Enable verbose logging
|
|
187
|
+
* @returns true if RPC was set up successfully, false if no rpc.ts found or defuss-rpc not installed
|
|
188
|
+
*/
|
|
189
|
+
declare const initializeRpc: (projectDir: string, config: SsgConfig, debug?: boolean) => Promise<boolean>;
|
|
190
|
+
/**
|
|
191
|
+
* Handle an RPC request by forwarding to defuss-rpc's rpcRoute handler.
|
|
192
|
+
* Converts Express req/res to Web Request/Response.
|
|
193
|
+
*
|
|
194
|
+
* @param req Express request
|
|
195
|
+
* @param res Express response
|
|
196
|
+
*/
|
|
197
|
+
declare const handleRpcRequest: (req: any, res: any) => Promise<void>;
|
|
198
|
+
|
|
199
|
+
export { BuildOptions, HTTP_METHODS, RehypePlugins, RemarkPlugins, SsgConfig, Status, build, buildEndpoints, compileEndpoints, compileRpcModule, configDefaults, discoverEndpointSourceFiles, discoverRpcFile, endpointFileToRoute, handleRpcRequest, initializeRpc, readConfig, registerEndpoints, rehypePlugins, remarkPlugins, resolveEndpoints, serve };
|
|
162
200
|
export type { APIRoute, EndpointContext, EndpointHandler, EndpointModule, HttpMethod, ResolvedEndpoint };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-
|
|
2
|
-
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-
|
|
1
|
+
import { R as RehypePlugins, a as RemarkPlugins, S as SsgConfig, B as BuildOptions, b as Status } from './types-Be8_Y5-t.mjs';
|
|
2
|
+
export { c as BuildMode, P as PluginFn, d as PluginFnPageDom, e as PluginFnPageHtml, f as PluginFnPageVdom, g as PluginFnPrePost, h as SsgPlugin, i as StatusCode } from './types-Be8_Y5-t.mjs';
|
|
3
3
|
import '@mdx-js/esbuild';
|
|
4
4
|
import 'defuss/server';
|
|
5
5
|
|
|
@@ -158,5 +158,43 @@ declare const buildEndpoints: (projectDir: string, config: SsgConfig, debug?: bo
|
|
|
158
158
|
*/
|
|
159
159
|
declare const registerEndpoints: (app: any, projectDir: string, config: SsgConfig, debug?: boolean) => Promise<void>;
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Discover the RPC file in the project root.
|
|
163
|
+
* Looks for `rpc.ts` or `rpc.js`.
|
|
164
|
+
*
|
|
165
|
+
* @param projectDir The project root directory
|
|
166
|
+
* @returns The absolute path to the RPC file, or null if not found
|
|
167
|
+
*/
|
|
168
|
+
declare const discoverRpcFile: (projectDir: string) => string | null;
|
|
169
|
+
/**
|
|
170
|
+
* Compile the RPC module source file with esbuild into the `.rpc/` directory.
|
|
171
|
+
*
|
|
172
|
+
* @param rpcFilePath Absolute path to the rpc.ts / rpc.js source file
|
|
173
|
+
* @param projectDir The project root directory
|
|
174
|
+
* @param debug Enable verbose logging
|
|
175
|
+
* @returns Absolute path to the compiled .mjs file
|
|
176
|
+
*/
|
|
177
|
+
declare const compileRpcModule: (rpcFilePath: string, projectDir: string, debug?: boolean) => Promise<string>;
|
|
178
|
+
/**
|
|
179
|
+
* Initialize the RPC server from the project's rpc.ts/rpc.js file.
|
|
180
|
+
*
|
|
181
|
+
* This function discovers, compiles, loads, and registers the RPC module.
|
|
182
|
+
* It dynamically imports `defuss-rpc/server.js` to avoid a hard dependency.
|
|
183
|
+
*
|
|
184
|
+
* @param projectDir The project root directory
|
|
185
|
+
* @param config The SSG config
|
|
186
|
+
* @param debug Enable verbose logging
|
|
187
|
+
* @returns true if RPC was set up successfully, false if no rpc.ts found or defuss-rpc not installed
|
|
188
|
+
*/
|
|
189
|
+
declare const initializeRpc: (projectDir: string, config: SsgConfig, debug?: boolean) => Promise<boolean>;
|
|
190
|
+
/**
|
|
191
|
+
* Handle an RPC request by forwarding to defuss-rpc's rpcRoute handler.
|
|
192
|
+
* Converts Express req/res to Web Request/Response.
|
|
193
|
+
*
|
|
194
|
+
* @param req Express request
|
|
195
|
+
* @param res Express response
|
|
196
|
+
*/
|
|
197
|
+
declare const handleRpcRequest: (req: any, res: any) => Promise<void>;
|
|
198
|
+
|
|
199
|
+
export { BuildOptions, HTTP_METHODS, RehypePlugins, RemarkPlugins, SsgConfig, Status, build, buildEndpoints, compileEndpoints, compileRpcModule, configDefaults, discoverEndpointSourceFiles, discoverRpcFile, endpointFileToRoute, handleRpcRequest, initializeRpc, readConfig, registerEndpoints, rehypePlugins, remarkPlugins, resolveEndpoints, serve };
|
|
162
200
|
export type { APIRoute, EndpointContext, EndpointHandler, EndpointModule, HttpMethod, ResolvedEndpoint };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { H as HTTP_METHODS, b as build, a as buildEndpoints, c as compileEndpoints, d as
|
|
1
|
+
export { H as HTTP_METHODS, b as build, a as buildEndpoints, c as compileEndpoints, d as compileRpcModule, e as configDefaults, f as discoverEndpointSourceFiles, g as discoverRpcFile, h as endpointFileToRoute, i as handleRpcRequest, j as initializeRpc, r as readConfig, k as registerEndpoints, l as rehypePlugins, m as remarkPlugins, n as resolveEndpoints, s as serve } from './serve-w6eyG8f3.mjs';
|
|
2
2
|
import 'chokidar';
|
|
3
3
|
import 'ultimate-express';
|
|
4
4
|
import 'node:path';
|
package/dist/plugins/index.d.cts
CHANGED
package/dist/plugins/index.d.mts
CHANGED