@ezetgalaxy/titan 26.13.9 → 26.14.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/index.js +7 -12
- package/package.json +1 -1
- package/templates/common/app/t.native.d.ts +0 -82
- package/templates/extension/jsconfig.json +2 -1
- package/templates/js/jsconfig.json +2 -1
- package/templates/js/server/Cargo.toml +19 -1
- package/templates/js/server/src/action_management.rs +159 -177
- package/templates/js/server/src/errors.rs +10 -10
- package/templates/js/server/src/extensions/builtin.rs +66 -165
- package/templates/js/server/src/extensions/external.rs +11 -86
- package/templates/js/server/src/extensions/mod.rs +136 -62
- package/templates/js/server/src/extensions/titan_core.js +200 -186
- package/templates/js/server/src/fast_path.rs +654 -0
- package/templates/js/server/src/main.rs +555 -406
- package/templates/js/server/src/runtime.rs +97 -80
- package/templates/js/server/src/utils.rs +32 -33
- package/templates/js/titan/dev.js +2 -2
- package/templates/js/titan/error-box.js +10 -1
- package/templates/rust-js/jsconfig.json +2 -1
- package/templates/rust-ts/tsconfig.json +2 -1
- package/templates/ts/server/Cargo.toml +19 -1
- package/templates/ts/server/src/action_management.rs +159 -177
- package/templates/ts/server/src/errors.rs +10 -10
- package/templates/ts/server/src/extensions/builtin.rs +66 -165
- package/templates/ts/server/src/extensions/external.rs +11 -86
- package/templates/ts/server/src/extensions/mod.rs +136 -62
- package/templates/ts/server/src/extensions/titan_core.js +200 -186
- package/templates/ts/server/src/fast_path.rs +654 -0
- package/templates/ts/server/src/main.rs +555 -406
- package/templates/ts/server/src/runtime.rs +97 -80
- package/templates/ts/server/src/utils.rs +32 -33
- package/templates/ts/tsconfig.json +2 -1
- package/titanpl-sdk/package.json +1 -1
- package/titanpl-sdk/templates/app/t.native.d.ts +1983 -0
- package/titanpl-sdk/templates/app/t.native.js +39 -0
- package/titanpl-sdk/templates/server/Cargo.toml +19 -1
- package/titanpl-sdk/templates/server/src/action_management.rs +159 -177
- package/titanpl-sdk/templates/server/src/errors.rs +10 -10
- package/titanpl-sdk/templates/server/src/extensions/builtin.rs +66 -165
- package/titanpl-sdk/templates/server/src/extensions/external.rs +11 -86
- package/titanpl-sdk/templates/server/src/extensions/mod.rs +136 -62
- package/titanpl-sdk/templates/server/src/extensions/titan_core.js +200 -186
- package/titanpl-sdk/templates/server/src/fast_path.rs +654 -0
- package/titanpl-sdk/templates/server/src/main.rs +555 -406
- package/titanpl-sdk/templates/server/src/runtime.rs +97 -80
- package/titanpl-sdk/templates/server/src/utils.rs +32 -33
- package/templates/rust-js/server/Cargo.lock +0 -2869
- package/templates/rust-ts/server/Cargo.lock +0 -2869
- package/titanpl-sdk/templates/app/titan.d.ts +0 -87
- package/titanpl-sdk/templates/index.d.ts +0 -249
package/index.js
CHANGED
|
@@ -574,20 +574,15 @@ export function updateTitan() {
|
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
576
|
|
|
577
|
-
//
|
|
577
|
+
// ----------------------------------------------------------
|
|
578
|
+
// 3. Update app/ with common files (t.native.js, definitions)
|
|
579
|
+
// ----------------------------------------------------------
|
|
578
580
|
const appDir = path.join(root, "app");
|
|
579
|
-
const
|
|
580
|
-
const commonDts = path.join(commonRoot, "app", "titan.d.ts");
|
|
581
|
+
const commonApp = path.join(commonRoot, "app");
|
|
581
582
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
if (finalDtsSrc) {
|
|
586
|
-
if (!fs.existsSync(appDir)) {
|
|
587
|
-
fs.mkdirSync(appDir);
|
|
588
|
-
}
|
|
589
|
-
fs.copyFileSync(finalDtsSrc, destDts);
|
|
590
|
-
console.log(green("✔ Updated app/titan.d.ts"));
|
|
583
|
+
if (fs.existsSync(commonApp)) {
|
|
584
|
+
copyDir(commonApp, appDir);
|
|
585
|
+
console.log(green("✔ Updated app/ common files"));
|
|
591
586
|
}
|
|
592
587
|
|
|
593
588
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ezetgalaxy/titan",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.14.1",
|
|
4
4
|
"description": "Titan Planet is a JavaScript-first backend framework that embeds JS actions into a Rust + Axum server and ships as a single native binary. Routes are compiled to static metadata; only actions run in the embedded JS runtime. No Node.js. No event loop in production.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "ezetgalaxy",
|
|
@@ -325,14 +325,6 @@ export const time: typeof t.time;
|
|
|
325
325
|
*/
|
|
326
326
|
export const url: typeof t.url;
|
|
327
327
|
|
|
328
|
-
/**
|
|
329
|
-
* HTTP response builder for controlling status codes, headers, and content types.
|
|
330
|
-
*
|
|
331
|
-
* Re-exported from the `t` global for module-style imports.
|
|
332
|
-
* @see {@link TitanCore.ResponseModule} for full documentation.
|
|
333
|
-
*/
|
|
334
|
-
export const response: typeof t.response;
|
|
335
|
-
|
|
336
328
|
/**
|
|
337
329
|
* Runtime validation utilities.
|
|
338
330
|
*
|
|
@@ -1046,15 +1038,6 @@ declare global {
|
|
|
1046
1038
|
|
|
1047
1039
|
/**
|
|
1048
1040
|
|
|
1049
|
-
|
|
1050
|
-
/**
|
|
1051
|
-
* HTTP response builder utilities.
|
|
1052
|
-
* @see https://www.npmjs.com/package/@titanpl/13-titan-core — TitanCore Valid Extension
|
|
1053
|
-
*/
|
|
1054
|
-
response: TitanCore.ResponseModule;
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
1041
|
/**
|
|
1059
1042
|
* Runtime validation utilities.
|
|
1060
1043
|
*
|
|
@@ -1994,71 +1977,6 @@ declare global {
|
|
|
1994
1977
|
SearchParams: any;
|
|
1995
1978
|
}
|
|
1996
1979
|
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
interface ResponseModule {
|
|
2000
|
-
|
|
2001
|
-
/**
|
|
2002
|
-
* Return a JSON response.
|
|
2003
|
-
* Body is automatically JSON.stringify-ed.
|
|
2004
|
-
*
|
|
2005
|
-
* @example
|
|
2006
|
-
* ```js
|
|
2007
|
-
* return t.response.json({ ok: true });
|
|
2008
|
-
* ```
|
|
2009
|
-
*/
|
|
2010
|
-
json(
|
|
2011
|
-
data: any,
|
|
2012
|
-
status?: number,
|
|
2013
|
-
extraHeaders?: Record<string, string>
|
|
2014
|
-
): TitanResponse;
|
|
2015
|
-
|
|
2016
|
-
/**
|
|
2017
|
-
* Return a plain-text response.
|
|
2018
|
-
* Content-Type: text/plain
|
|
2019
|
-
*
|
|
2020
|
-
* @example
|
|
2021
|
-
* ```js
|
|
2022
|
-
* return t.response.text("Hello World");
|
|
2023
|
-
* ```
|
|
2024
|
-
*/
|
|
2025
|
-
text(
|
|
2026
|
-
content: string,
|
|
2027
|
-
status?: number,
|
|
2028
|
-
extraHeaders?: Record<string, string>
|
|
2029
|
-
): TitanResponse;
|
|
2030
|
-
|
|
2031
|
-
/**
|
|
2032
|
-
* Return an HTML response.
|
|
2033
|
-
* Content-Type: text/html
|
|
2034
|
-
*
|
|
2035
|
-
* @example
|
|
2036
|
-
* ```js
|
|
2037
|
-
* return t.response.html("<h1>Hello</h1>");
|
|
2038
|
-
* ```
|
|
2039
|
-
*/
|
|
2040
|
-
html(
|
|
2041
|
-
content: string,
|
|
2042
|
-
status?: number,
|
|
2043
|
-
extraHeaders?: Record<string, string>
|
|
2044
|
-
): TitanResponse;
|
|
2045
|
-
|
|
2046
|
-
/**
|
|
2047
|
-
* Return a redirect response.
|
|
2048
|
-
* Defaults to HTTP 302.
|
|
2049
|
-
*
|
|
2050
|
-
* @example
|
|
2051
|
-
* ```js
|
|
2052
|
-
* return t.response.redirect("/login");
|
|
2053
|
-
* ```
|
|
2054
|
-
*/
|
|
2055
|
-
redirect(
|
|
2056
|
-
url: string,
|
|
2057
|
-
status?: number,
|
|
2058
|
-
extraHeaders?: Record<string, string>
|
|
2059
|
-
): TitanResponse;
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
1980
|
}
|
|
2063
1981
|
}
|
|
2064
1982
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
[package]
|
|
3
2
|
name = "titan-server"
|
|
4
3
|
version = "0.1.0"
|
|
@@ -30,3 +29,22 @@ dashmap = "6.1.0"
|
|
|
30
29
|
bytes = "1.11.0"
|
|
31
30
|
smallvec = "1.15.1"
|
|
32
31
|
num_cpus = "1.17.0"
|
|
32
|
+
|
|
33
|
+
# Performance: Global Allocator
|
|
34
|
+
mimalloc = { version = "0.1", default-features = false }
|
|
35
|
+
|
|
36
|
+
# Static Analysis: OXC (Zero runtime cost, used at startup)
|
|
37
|
+
oxc = { version = "0.108", features = ["semantic"] }
|
|
38
|
+
|
|
39
|
+
# Release Profile
|
|
40
|
+
[profile.release]
|
|
41
|
+
opt-level = 3
|
|
42
|
+
lto = "fat"
|
|
43
|
+
codegen-units = 1
|
|
44
|
+
panic = "abort"
|
|
45
|
+
strip = true
|
|
46
|
+
|
|
47
|
+
# Dev Profile
|
|
48
|
+
[profile.dev]
|
|
49
|
+
opt-level = 0
|
|
50
|
+
debug = 1
|
|
@@ -1,177 +1,159 @@
|
|
|
1
|
-
|
|
2
|
-
use std::
|
|
3
|
-
use std::
|
|
4
|
-
use
|
|
5
|
-
use
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
#[derive(Debug, Deserialize, Clone)]
|
|
9
|
-
pub struct RouteVal {
|
|
10
|
-
pub r#type: String,
|
|
11
|
-
#[serde(alias = "target")]
|
|
12
|
-
pub value: Value,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
#[derive(Debug, Deserialize, Clone)]
|
|
16
|
-
pub struct DynamicRoute {
|
|
17
|
-
pub method: String,
|
|
18
|
-
pub pattern: String,
|
|
19
|
-
pub action: String,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
let path = entry.path();
|
|
161
|
-
if !path.is_file() { continue; }
|
|
162
|
-
|
|
163
|
-
let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("");
|
|
164
|
-
if ext != "js" && ext != "jsbundle" {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
let file_stem = path.file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
|
169
|
-
if file_stem.is_empty() { continue; }
|
|
170
|
-
|
|
171
|
-
// Found action
|
|
172
|
-
map.insert(file_stem.to_string(), path);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
map
|
|
177
|
-
}
|
|
1
|
+
|
|
2
|
+
use std::collections::HashMap;
|
|
3
|
+
use std::env;
|
|
4
|
+
use std::path::{Path, PathBuf};
|
|
5
|
+
use serde::Deserialize;
|
|
6
|
+
use serde_json::Value;
|
|
7
|
+
|
|
8
|
+
#[derive(Debug, Deserialize, Clone)]
|
|
9
|
+
pub struct RouteVal {
|
|
10
|
+
pub r#type: String,
|
|
11
|
+
#[serde(alias = "target")]
|
|
12
|
+
pub value: Value,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#[derive(Debug, Deserialize, Clone)]
|
|
16
|
+
pub struct DynamicRoute {
|
|
17
|
+
pub method: String,
|
|
18
|
+
pub pattern: String,
|
|
19
|
+
pub action: String,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn resolve_actions_dir() -> PathBuf {
|
|
23
|
+
if let Ok(override_dir) = env::var("TITAN_ACTIONS_DIR") {
|
|
24
|
+
return PathBuf::from(override_dir);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if Path::new("/app/actions").exists() {
|
|
28
|
+
return PathBuf::from("/app/actions");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if let Ok(exe) = std::env::current_exe() {
|
|
32
|
+
if let Some(parent) = exe.parent() {
|
|
33
|
+
if let Some(target_dir) = parent.parent() {
|
|
34
|
+
if let Some(server_dir) = target_dir.parent() {
|
|
35
|
+
let candidate = server_dir.join("src").join("actions");
|
|
36
|
+
if candidate.exists() {
|
|
37
|
+
return candidate;
|
|
38
|
+
}
|
|
39
|
+
let candidate2 = server_dir.join("actions");
|
|
40
|
+
if candidate2.exists() {
|
|
41
|
+
return candidate2;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
PathBuf::from("./src/actions")
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pub fn find_actions_dir(project_root: &PathBuf) -> Option<PathBuf> {
|
|
52
|
+
let candidates = [
|
|
53
|
+
project_root.join("server").join("src").join("actions"),
|
|
54
|
+
project_root.join("server").join("actions"),
|
|
55
|
+
project_root.join("app").join("actions"),
|
|
56
|
+
project_root.join("actions"),
|
|
57
|
+
|
|
58
|
+
project_root.join("..").join("server").join("actions"),
|
|
59
|
+
PathBuf::from("/app").join("actions"),
|
|
60
|
+
PathBuf::from("actions"),
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
for p in &candidates {
|
|
64
|
+
if p.exists() && p.is_dir() {
|
|
65
|
+
return Some(p.clone());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
None
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
pub fn match_dynamic_route(
|
|
73
|
+
method: &str,
|
|
74
|
+
path: &str,
|
|
75
|
+
routes: &[DynamicRoute],
|
|
76
|
+
) -> Option<(String, HashMap<String, String>)> {
|
|
77
|
+
let path_segments: Vec<&str> =
|
|
78
|
+
path.trim_matches('/').split('/').collect();
|
|
79
|
+
|
|
80
|
+
for route in routes {
|
|
81
|
+
if route.method != method {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let pattern_segments: Vec<&str> =
|
|
86
|
+
route.pattern.trim_matches('/').split('/').collect();
|
|
87
|
+
|
|
88
|
+
if pattern_segments.len() != path_segments.len() {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let mut params = HashMap::new();
|
|
93
|
+
let mut matched = true;
|
|
94
|
+
|
|
95
|
+
for (pat, val) in pattern_segments.iter().zip(path_segments.iter()) {
|
|
96
|
+
if pat.starts_with(':') {
|
|
97
|
+
let inner = &pat[1..];
|
|
98
|
+
|
|
99
|
+
let (name, ty) = inner
|
|
100
|
+
.split_once('<')
|
|
101
|
+
.map(|(n, t)| (n, t.trim_end_matches('>')))
|
|
102
|
+
.unwrap_or((inner, "string"));
|
|
103
|
+
|
|
104
|
+
let valid = match ty {
|
|
105
|
+
"number" => val.parse::<i64>().is_ok(),
|
|
106
|
+
"string" => true,
|
|
107
|
+
_ => false,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
if !valid {
|
|
111
|
+
matched = false;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
params.insert(name.to_string(), (*val).to_string());
|
|
116
|
+
} else if pat != val {
|
|
117
|
+
matched = false;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if matched {
|
|
123
|
+
return Some((route.action.clone(), params));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
None
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
pub fn scan_actions(root: &PathBuf) -> HashMap<String, PathBuf> {
|
|
131
|
+
let mut map = HashMap::new();
|
|
132
|
+
|
|
133
|
+
let dir = match find_actions_dir(root) {
|
|
134
|
+
Some(d) => d,
|
|
135
|
+
None => {
|
|
136
|
+
let ad = resolve_actions_dir();
|
|
137
|
+
if ad.exists() { ad } else { return map; }
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
if let Ok(entries) = std::fs::read_dir(dir) {
|
|
142
|
+
for entry in entries.flatten() {
|
|
143
|
+
let path = entry.path();
|
|
144
|
+
if !path.is_file() { continue; }
|
|
145
|
+
|
|
146
|
+
let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("");
|
|
147
|
+
if ext != "js" && ext != "jsbundle" {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
let file_stem = path.file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
|
152
|
+
if file_stem.is_empty() { continue; }
|
|
153
|
+
|
|
154
|
+
map.insert(file_stem.to_string(), path);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
map
|
|
159
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
pub fn format_js_error(err: JsError, action: &str) -> String {
|
|
5
|
-
format!(
|
|
6
|
-
"Action: {}\n{}",
|
|
7
|
-
action,
|
|
8
|
-
err.to_string()
|
|
9
|
-
)
|
|
10
|
-
}
|
|
1
|
+
|
|
2
|
+
use v8::JsError;
|
|
3
|
+
|
|
4
|
+
pub fn format_js_error(err: JsError, action: &str) -> String {
|
|
5
|
+
format!(
|
|
6
|
+
"Action: {}\n{}",
|
|
7
|
+
action,
|
|
8
|
+
err.to_string()
|
|
9
|
+
)
|
|
10
|
+
}
|