@ezetgalaxy/titan 25.15.5 → 25.15.6
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/package.json +1 -1
- package/templates/titan/bundle.js +62 -0
- package/templates/titan/dev.js +67 -0
- package/templates/titan/titan.js +82 -0
package/package.json
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import esbuild from "esbuild";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const actionsDir = path.join(root, "app", "actions");
|
|
7
|
+
const outDir = path.join(root, "server", "actions");
|
|
8
|
+
|
|
9
|
+
export async function bundle() {
|
|
10
|
+
console.log("[Titan] Bundling actions...");
|
|
11
|
+
|
|
12
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
13
|
+
|
|
14
|
+
// Clean old bundles
|
|
15
|
+
for (const file of fs.readdirSync(outDir)) {
|
|
16
|
+
fs.unlinkSync(path.join(outDir, file));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const files = fs.readdirSync(actionsDir).filter(f => f.endsWith(".js"));
|
|
20
|
+
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
const actionName = path.basename(file, ".js");
|
|
23
|
+
|
|
24
|
+
const entry = path.join(actionsDir, file);
|
|
25
|
+
|
|
26
|
+
// Rust runtime expects `.jsbundle` extension — consistent with previous design
|
|
27
|
+
const outfile = path.join(outDir, file.replace(".js", ".jsbundle"));
|
|
28
|
+
|
|
29
|
+
console.log(`[Titan] Bundling ${entry} → ${outfile}`);
|
|
30
|
+
|
|
31
|
+
await esbuild.build({
|
|
32
|
+
entryPoints: [entry],
|
|
33
|
+
outfile,
|
|
34
|
+
bundle: true,
|
|
35
|
+
format: "iife",
|
|
36
|
+
globalName: "__titan_exports",
|
|
37
|
+
platform: "neutral",
|
|
38
|
+
target: "es2020",
|
|
39
|
+
|
|
40
|
+
footer: {
|
|
41
|
+
js: `
|
|
42
|
+
(function () {
|
|
43
|
+
const fn =
|
|
44
|
+
__titan_exports["${actionName}"] ||
|
|
45
|
+
__titan_exports.default;
|
|
46
|
+
|
|
47
|
+
if (typeof fn !== "function") {
|
|
48
|
+
throw new Error("[Titan] Action '${actionName}' not found or not a function");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
globalThis["${actionName}"] = fn;
|
|
52
|
+
})();
|
|
53
|
+
`
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log("[Titan] Bundling finished.");
|
|
62
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import chokidar from "chokidar";
|
|
2
|
+
import { spawn, execSync } from "child_process";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { bundle } from "./bundle.js";
|
|
6
|
+
|
|
7
|
+
// Required for __dirname in ES modules
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
let serverProcess = null;
|
|
12
|
+
|
|
13
|
+
function startRustServer() {
|
|
14
|
+
if (serverProcess) {
|
|
15
|
+
serverProcess.kill();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const serverPath = path.join(process.cwd(), "server");
|
|
19
|
+
|
|
20
|
+
serverProcess = spawn("cargo", ["run"], {
|
|
21
|
+
cwd: serverPath,
|
|
22
|
+
stdio: "inherit",
|
|
23
|
+
shell: true
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
serverProcess.on("close", (code) => {
|
|
27
|
+
console.log(`[Titan] Rust server exited: ${code}`);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function rebuild() {
|
|
32
|
+
console.log("[Titan] Regenerating routes.json & action_map.json...");
|
|
33
|
+
execSync("node app/app.js", { stdio: "inherit" });
|
|
34
|
+
|
|
35
|
+
console.log("[Titan] Bundling JS actions...");
|
|
36
|
+
await bundle();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function startDev() {
|
|
40
|
+
console.log("[Titan] Dev mode starting...");
|
|
41
|
+
|
|
42
|
+
// FIRST BUILD
|
|
43
|
+
await rebuild();
|
|
44
|
+
startRustServer();
|
|
45
|
+
|
|
46
|
+
const watcher = chokidar.watch("app", {
|
|
47
|
+
ignoreInitial: true
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
let timer = null;
|
|
51
|
+
|
|
52
|
+
watcher.on("all", async (event, file) => {
|
|
53
|
+
if (timer) clearTimeout(timer);
|
|
54
|
+
|
|
55
|
+
timer = setTimeout(async () => {
|
|
56
|
+
console.log(`[Titan] Change detected: ${file}`);
|
|
57
|
+
|
|
58
|
+
await rebuild();
|
|
59
|
+
|
|
60
|
+
console.log("[Titan] Restarting Rust server...");
|
|
61
|
+
startRustServer();
|
|
62
|
+
|
|
63
|
+
}, 200);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
startDev();
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { bundle } from "./bundle.js";
|
|
4
|
+
|
|
5
|
+
const cyan = (t) => `\x1b[36m${t}\x1b[0m`;
|
|
6
|
+
const green = (t) => `\x1b[32m${t}\x1b[0m`;
|
|
7
|
+
|
|
8
|
+
const routes = {};
|
|
9
|
+
const dynamicRoutes = {};
|
|
10
|
+
const actionMap = {};
|
|
11
|
+
|
|
12
|
+
function addRoute(method, route) {
|
|
13
|
+
const key = `${method.toUpperCase()}:${route}`;
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
reply(value) {
|
|
18
|
+
routes[key] = {
|
|
19
|
+
type: typeof value === "object" ? "json" : "text",
|
|
20
|
+
value
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
action(name) {
|
|
25
|
+
if (route.includes(":")) {
|
|
26
|
+
if (!dynamicRoutes[method]) dynamicRoutes[method] = [];
|
|
27
|
+
dynamicRoutes[method].push({
|
|
28
|
+
method: method.toUpperCase(),
|
|
29
|
+
pattern: route,
|
|
30
|
+
action: name
|
|
31
|
+
});
|
|
32
|
+
} else {
|
|
33
|
+
routes[key] = {
|
|
34
|
+
type: "action",
|
|
35
|
+
value: name
|
|
36
|
+
};
|
|
37
|
+
actionMap[key] = name;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const t = {
|
|
44
|
+
get(route) {
|
|
45
|
+
return addRoute("GET", route);
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
post(route) {
|
|
49
|
+
return addRoute("POST", route);
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
async start(port = 3000, msg = "") {
|
|
53
|
+
console.log(cyan("[Titan] Bundling actions..."));
|
|
54
|
+
await bundle();
|
|
55
|
+
|
|
56
|
+
const base = path.join(process.cwd(), "server");
|
|
57
|
+
fs.mkdirSync(base, { recursive: true });
|
|
58
|
+
|
|
59
|
+
fs.writeFileSync(
|
|
60
|
+
path.join(base, "routes.json"),
|
|
61
|
+
JSON.stringify(
|
|
62
|
+
{
|
|
63
|
+
__config: { port },
|
|
64
|
+
routes,
|
|
65
|
+
__dynamic_routes: Object.values(dynamicRoutes).flat()
|
|
66
|
+
},
|
|
67
|
+
null,
|
|
68
|
+
2
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
fs.writeFileSync(
|
|
73
|
+
path.join(base, "action_map.json"),
|
|
74
|
+
JSON.stringify(actionMap, null, 2)
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
console.log(green(`Titan: routes.json + action_map.json written -> ${base}`));
|
|
78
|
+
if (msg) console.log(cyan(msg));
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default t;
|