@ezetgalaxy/titan 26.8.0 → 26.8.2
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/js/server/src/main.rs +1 -6
- package/templates/js/titan/bundle.js +1 -1
- package/templates/js/titan/dev.js +258 -194
- package/templates/rust/server/Cargo.toml +12 -0
- package/templates/rust/server/src/main.rs +0 -6
- package/templates/rust/titan/bundle.js +157 -157
- package/templates/rust/titan/dev.js +266 -194
- package/templates/rust/titan/titan.js +122 -122
- package/templates/js/server/src/actions_rust/mod.rs +0 -15
|
@@ -1,157 +1,157 @@
|
|
|
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
|
-
const rustOutDir = path.join(root, "server", "src", "actions_rust");
|
|
9
|
-
|
|
10
|
-
export async function bundle() {
|
|
11
|
-
const start = Date.now();
|
|
12
|
-
await bundleJs();
|
|
13
|
-
await bundleRust();
|
|
14
|
-
// console.log(`[Titan] Bundle finished in ${((Date.now() - start) / 1000).toFixed(2)}s`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function bundleJs() {
|
|
18
|
-
// console.log("[Titan] Bundling JS actions...");
|
|
19
|
-
|
|
20
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
21
|
-
|
|
22
|
-
// Clean old bundles
|
|
23
|
-
const oldFiles = fs.readdirSync(outDir);
|
|
24
|
-
for (const file of oldFiles) {
|
|
25
|
-
fs.unlinkSync(path.join(outDir, file));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const files = fs.readdirSync(actionsDir).filter(f => f.endsWith(".js") || f.endsWith(".ts"));
|
|
29
|
-
if (files.length === 0) return;
|
|
30
|
-
|
|
31
|
-
console.log(`[Titan] Bundling ${files.length} JS actions...`);
|
|
32
|
-
|
|
33
|
-
for (const file of files) {
|
|
34
|
-
const actionName = path.basename(file, path.extname(file));
|
|
35
|
-
|
|
36
|
-
const entry = path.join(actionsDir, file);
|
|
37
|
-
|
|
38
|
-
// Rust runtime expects `.jsbundle` extension — consistent with previous design
|
|
39
|
-
const outfile = path.join(outDir, actionName + ".jsbundle");
|
|
40
|
-
|
|
41
|
-
// console.log(`[Titan] Bundling ${entry} → ${outfile}`);
|
|
42
|
-
|
|
43
|
-
await esbuild.build({
|
|
44
|
-
entryPoints: [entry],
|
|
45
|
-
outfile,
|
|
46
|
-
bundle: true,
|
|
47
|
-
format: "iife",
|
|
48
|
-
globalName: "__titan_exports",
|
|
49
|
-
platform: "neutral",
|
|
50
|
-
target: "es2020",
|
|
51
|
-
logLevel: "silent",
|
|
52
|
-
banner: {
|
|
53
|
-
js: "const defineAction = (fn) => fn;"
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
footer: {
|
|
57
|
-
js: `
|
|
58
|
-
(function () {
|
|
59
|
-
const fn =
|
|
60
|
-
__titan_exports["${actionName}"] ||
|
|
61
|
-
__titan_exports.default;
|
|
62
|
-
|
|
63
|
-
if (typeof fn !== "function") {
|
|
64
|
-
throw new Error("[Titan] Action '${actionName}' not found or not a function");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
globalThis["${actionName}"] = function(request_arg) {
|
|
68
|
-
globalThis.req = request_arg;
|
|
69
|
-
return fn(request_arg);
|
|
70
|
-
};
|
|
71
|
-
})();
|
|
72
|
-
`
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// console.log("[Titan] JS Bundling finished.");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export async function bundleRust() {
|
|
81
|
-
// console.log("[Titan] Bundling Rust actions...");
|
|
82
|
-
|
|
83
|
-
if (!fs.existsSync(rustOutDir)) {
|
|
84
|
-
fs.mkdirSync(rustOutDir, { recursive: true });
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Clean old rust actions
|
|
88
|
-
for (const file of fs.readdirSync(rustOutDir)) {
|
|
89
|
-
fs.unlinkSync(path.join(rustOutDir, file));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const files = fs.readdirSync(actionsDir).filter(f => f.endsWith(".rs"));
|
|
93
|
-
if (files.length > 0) {
|
|
94
|
-
console.log(`[Titan] Bundling ${files.length} Rust actions...`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const modules = [];
|
|
98
|
-
|
|
99
|
-
for (const file of files) {
|
|
100
|
-
const actionName = path.basename(file, ".rs");
|
|
101
|
-
const entry = path.join(actionsDir, file);
|
|
102
|
-
let outfile = path.join(rustOutDir, file);
|
|
103
|
-
|
|
104
|
-
let content = fs.readFileSync(entry, 'utf-8');
|
|
105
|
-
|
|
106
|
-
// Prepend implicit imports if not present
|
|
107
|
-
let finalContent = content;
|
|
108
|
-
if (!content.includes("use crate::extensions::t;")) {
|
|
109
|
-
finalContent = "use crate::extensions::t;\n" + content;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Basic validation - check if it has a run function
|
|
113
|
-
if (!content.includes("async fn run")) {
|
|
114
|
-
console.warn(`[Titan] Warning: ${file} does not appear to have an 'async fn run'. It might fail to compile.`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
fs.writeFileSync(outfile, finalContent);
|
|
118
|
-
modules.push(actionName);
|
|
119
|
-
// console.log(`[Titan] Copied Rust action ${actionName}`);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Generate mod.rs
|
|
123
|
-
let modContent = `// Auto-generated by Titan. Do not edit.
|
|
124
|
-
use axum::response::IntoResponse;
|
|
125
|
-
use axum::http::Request;
|
|
126
|
-
use axum::body::Body;
|
|
127
|
-
use std::future::Future;
|
|
128
|
-
use std::pin::Pin;
|
|
129
|
-
|
|
130
|
-
`;
|
|
131
|
-
|
|
132
|
-
// Add mod declarations
|
|
133
|
-
for (const mod of modules) {
|
|
134
|
-
modContent += `pub mod ${mod};\n`;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
modContent += `
|
|
138
|
-
pub type ActionFn = fn(Request<Body>) -> Pin<Box<dyn Future<Output = axum::response::Response> + Send>>;
|
|
139
|
-
|
|
140
|
-
pub fn get_action(name: &str) -> Option<ActionFn> {
|
|
141
|
-
match name {
|
|
142
|
-
`;
|
|
143
|
-
|
|
144
|
-
for (const mod of modules) {
|
|
145
|
-
modContent += ` "${mod}" => Some(|req| Box::pin(async move {
|
|
146
|
-
${mod}::run(req).await.into_response()
|
|
147
|
-
})),\n`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
modContent += ` _ => None
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
`;
|
|
154
|
-
|
|
155
|
-
fs.writeFileSync(path.join(rustOutDir, "mod.rs"), modContent);
|
|
156
|
-
// console.log("[Titan] Rust Bundling finished.");
|
|
157
|
-
}
|
|
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
|
+
const rustOutDir = path.join(root, "server", "src", "actions_rust");
|
|
9
|
+
|
|
10
|
+
export async function bundle() {
|
|
11
|
+
const start = Date.now();
|
|
12
|
+
await bundleJs();
|
|
13
|
+
await bundleRust();
|
|
14
|
+
// console.log(`[Titan] Bundle finished in ${((Date.now() - start) / 1000).toFixed(2)}s`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function bundleJs() {
|
|
18
|
+
// console.log("[Titan] Bundling JS actions...");
|
|
19
|
+
|
|
20
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
21
|
+
|
|
22
|
+
// Clean old bundles
|
|
23
|
+
const oldFiles = fs.readdirSync(outDir);
|
|
24
|
+
for (const file of oldFiles) {
|
|
25
|
+
fs.unlinkSync(path.join(outDir, file));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const files = fs.readdirSync(actionsDir).filter(f => f.endsWith(".js") || f.endsWith(".ts"));
|
|
29
|
+
if (files.length === 0) return;
|
|
30
|
+
|
|
31
|
+
// console.log(`[Titan] Bundling ${files.length} JS actions...`);
|
|
32
|
+
|
|
33
|
+
for (const file of files) {
|
|
34
|
+
const actionName = path.basename(file, path.extname(file));
|
|
35
|
+
|
|
36
|
+
const entry = path.join(actionsDir, file);
|
|
37
|
+
|
|
38
|
+
// Rust runtime expects `.jsbundle` extension — consistent with previous design
|
|
39
|
+
const outfile = path.join(outDir, actionName + ".jsbundle");
|
|
40
|
+
|
|
41
|
+
// console.log(`[Titan] Bundling ${entry} → ${outfile}`);
|
|
42
|
+
|
|
43
|
+
await esbuild.build({
|
|
44
|
+
entryPoints: [entry],
|
|
45
|
+
outfile,
|
|
46
|
+
bundle: true,
|
|
47
|
+
format: "iife",
|
|
48
|
+
globalName: "__titan_exports",
|
|
49
|
+
platform: "neutral",
|
|
50
|
+
target: "es2020",
|
|
51
|
+
logLevel: "silent",
|
|
52
|
+
banner: {
|
|
53
|
+
js: "const defineAction = (fn) => fn;"
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
footer: {
|
|
57
|
+
js: `
|
|
58
|
+
(function () {
|
|
59
|
+
const fn =
|
|
60
|
+
__titan_exports["${actionName}"] ||
|
|
61
|
+
__titan_exports.default;
|
|
62
|
+
|
|
63
|
+
if (typeof fn !== "function") {
|
|
64
|
+
throw new Error("[Titan] Action '${actionName}' not found or not a function");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
globalThis["${actionName}"] = function(request_arg) {
|
|
68
|
+
globalThis.req = request_arg;
|
|
69
|
+
return fn(request_arg);
|
|
70
|
+
};
|
|
71
|
+
})();
|
|
72
|
+
`
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// console.log("[Titan] JS Bundling finished.");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function bundleRust() {
|
|
81
|
+
// console.log("[Titan] Bundling Rust actions...");
|
|
82
|
+
|
|
83
|
+
if (!fs.existsSync(rustOutDir)) {
|
|
84
|
+
fs.mkdirSync(rustOutDir, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Clean old rust actions
|
|
88
|
+
for (const file of fs.readdirSync(rustOutDir)) {
|
|
89
|
+
fs.unlinkSync(path.join(rustOutDir, file));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const files = fs.readdirSync(actionsDir).filter(f => f.endsWith(".rs"));
|
|
93
|
+
if (files.length > 0) {
|
|
94
|
+
// console.log(`[Titan] Bundling ${files.length} Rust actions...`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const modules = [];
|
|
98
|
+
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
const actionName = path.basename(file, ".rs");
|
|
101
|
+
const entry = path.join(actionsDir, file);
|
|
102
|
+
let outfile = path.join(rustOutDir, file);
|
|
103
|
+
|
|
104
|
+
let content = fs.readFileSync(entry, 'utf-8');
|
|
105
|
+
|
|
106
|
+
// Prepend implicit imports if not present
|
|
107
|
+
let finalContent = content;
|
|
108
|
+
if (!content.includes("use crate::extensions::t;")) {
|
|
109
|
+
finalContent = "use crate::extensions::t;\n" + content;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Basic validation - check if it has a run function
|
|
113
|
+
if (!content.includes("async fn run")) {
|
|
114
|
+
console.warn(`[Titan] Warning: ${file} does not appear to have an 'async fn run'. It might fail to compile.`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fs.writeFileSync(outfile, finalContent);
|
|
118
|
+
modules.push(actionName);
|
|
119
|
+
// console.log(`[Titan] Copied Rust action ${actionName}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Generate mod.rs
|
|
123
|
+
let modContent = `// Auto-generated by Titan. Do not edit.
|
|
124
|
+
use axum::response::IntoResponse;
|
|
125
|
+
use axum::http::Request;
|
|
126
|
+
use axum::body::Body;
|
|
127
|
+
use std::future::Future;
|
|
128
|
+
use std::pin::Pin;
|
|
129
|
+
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
// Add mod declarations
|
|
133
|
+
for (const mod of modules) {
|
|
134
|
+
modContent += `pub mod ${mod};\n`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
modContent += `
|
|
138
|
+
pub type ActionFn = fn(Request<Body>) -> Pin<Box<dyn Future<Output = axum::response::Response> + Send>>;
|
|
139
|
+
|
|
140
|
+
pub fn get_action(name: &str) -> Option<ActionFn> {
|
|
141
|
+
match name {
|
|
142
|
+
`;
|
|
143
|
+
|
|
144
|
+
for (const mod of modules) {
|
|
145
|
+
modContent += ` "${mod}" => Some(|req| Box::pin(async move {
|
|
146
|
+
${mod}::run(req).await.into_response()
|
|
147
|
+
})),\n`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
modContent += ` _ => None
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
fs.writeFileSync(path.join(rustOutDir, "mod.rs"), modContent);
|
|
156
|
+
// console.log("[Titan] Rust Bundling finished.");
|
|
157
|
+
}
|