@ezetgalaxy/titan 26.13.8 → 26.14.0
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/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/src/extensions/external.rs +10 -80
- package/templates/rust-js/jsconfig.json +2 -1
- package/templates/rust-ts/tsconfig.json +2 -1
- package/templates/ts/server/src/extensions/external.rs +10 -80
- package/templates/ts/tsconfig.json +2 -1
- package/titanpl-sdk/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ezetgalaxy/titan",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.14.0",
|
|
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
|
|
|
@@ -16,19 +16,15 @@ pub struct Registry {
|
|
|
16
16
|
pub _libs: Vec<Library>,
|
|
17
17
|
pub modules: Vec<ModuleDef>,
|
|
18
18
|
pub natives: Vec<NativeFnEntry>,
|
|
19
|
-
pub v8_natives: Vec<usize>,
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
23
21
|
#[derive(Clone)]
|
|
24
22
|
pub struct ModuleDef {
|
|
25
23
|
pub name: String,
|
|
26
24
|
pub js: String,
|
|
27
25
|
pub native_indices: HashMap<String, usize>,
|
|
28
|
-
pub v8_native_indices: HashMap<String, usize>,
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
|
|
32
28
|
#[derive(Clone, Debug, PartialEq)]
|
|
33
29
|
pub enum ParamType {
|
|
34
30
|
String, F64, Bool, Json, Buffer,
|
|
@@ -60,18 +56,9 @@ struct TitanConfig {
|
|
|
60
56
|
#[derive(serde::Deserialize)]
|
|
61
57
|
struct TitanNativeConfig {
|
|
62
58
|
path: String,
|
|
63
|
-
#[serde(default)]
|
|
64
59
|
functions: HashMap<String, TitanNativeFunc>,
|
|
65
|
-
#[serde(default)]
|
|
66
|
-
v8_functions: HashMap<String, TitanV8Func>,
|
|
67
60
|
}
|
|
68
61
|
|
|
69
|
-
#[derive(serde::Deserialize)]
|
|
70
|
-
struct TitanV8Func {
|
|
71
|
-
symbol: String,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
62
|
#[derive(serde::Deserialize)]
|
|
76
63
|
struct TitanNativeFunc {
|
|
77
64
|
symbol: String,
|
|
@@ -108,8 +95,6 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
108
95
|
let mut modules = Vec::new();
|
|
109
96
|
let mut libs = Vec::new();
|
|
110
97
|
let mut all_natives = Vec::new();
|
|
111
|
-
let mut all_v8_natives = Vec::new();
|
|
112
|
-
|
|
113
98
|
|
|
114
99
|
let mut node_modules = root.join("node_modules");
|
|
115
100
|
if !node_modules.exists() {
|
|
@@ -120,8 +105,7 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
120
105
|
}
|
|
121
106
|
|
|
122
107
|
// Generic scanner helper
|
|
123
|
-
let scan_dir = |path: PathBuf, modules: &mut Vec<ModuleDef>, libs: &mut Vec<Library>, all_natives: &mut Vec<NativeFnEntry
|
|
124
|
-
|
|
108
|
+
let scan_dir = |path: PathBuf, modules: &mut Vec<ModuleDef>, libs: &mut Vec<Library>, all_natives: &mut Vec<NativeFnEntry>| {
|
|
125
109
|
if !path.exists() { return; }
|
|
126
110
|
for entry in WalkDir::new(&path).follow_links(true).min_depth(1).max_depth(4) {
|
|
127
111
|
let entry = match entry { Ok(e) => e, Err(_) => continue };
|
|
@@ -133,9 +117,7 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
133
117
|
Err(_) => continue,
|
|
134
118
|
};
|
|
135
119
|
let mut mod_natives_map = HashMap::new();
|
|
136
|
-
let mut mod_v8_natives_map = HashMap::new();
|
|
137
120
|
if let Some(native_conf) = config.native {
|
|
138
|
-
|
|
139
121
|
let lib_path = dir.join(&native_conf.path);
|
|
140
122
|
unsafe {
|
|
141
123
|
// Try loading library
|
|
@@ -144,28 +126,17 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
144
126
|
// But usually absolute path from `dir` works.
|
|
145
127
|
match lib_load {
|
|
146
128
|
Ok(lib) => {
|
|
147
|
-
for (fn_name, fn_conf) in
|
|
129
|
+
for (fn_name, fn_conf) in native_conf.functions {
|
|
148
130
|
let params = fn_conf.parameters.iter().map(|p| parse_type(&p.to_lowercase())).collect();
|
|
149
131
|
let ret = parse_return(&fn_conf.result.to_lowercase());
|
|
150
132
|
if let Ok(symbol) = lib.get::<*const ()>(fn_conf.symbol.as_bytes()) {
|
|
151
133
|
let idx = all_natives.len();
|
|
152
134
|
all_natives.push(NativeFnEntry { symbol_ptr: *symbol as usize, sig: Signature { params, ret } });
|
|
153
|
-
mod_natives_map.insert(fn_name
|
|
135
|
+
mod_natives_map.insert(fn_name, idx);
|
|
154
136
|
} else {
|
|
155
137
|
println!("{} {} {} -> {}", blue("[Titan]"), red("Symbol not found:"), fn_conf.symbol, config.name);
|
|
156
138
|
}
|
|
157
139
|
}
|
|
158
|
-
|
|
159
|
-
for (fn_name, fn_conf) in &native_conf.v8_functions {
|
|
160
|
-
if let Ok(symbol) = lib.get::<*const ()>(fn_conf.symbol.as_bytes()) {
|
|
161
|
-
let idx = all_v8_natives.len();
|
|
162
|
-
all_v8_natives.push(*symbol as usize);
|
|
163
|
-
mod_v8_natives_map.insert(fn_name.clone(), idx);
|
|
164
|
-
} else {
|
|
165
|
-
println!("{} {} {} -> {}", blue("[Titan]"), red("V8 Symbol not found:"), fn_conf.symbol, config.name);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
140
|
libs.push(lib);
|
|
170
141
|
},
|
|
171
142
|
Err(e) => {
|
|
@@ -175,13 +146,7 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
175
146
|
}
|
|
176
147
|
}
|
|
177
148
|
let js_path = dir.join(&config.main);
|
|
178
|
-
modules.push(ModuleDef {
|
|
179
|
-
name: config.name.clone(),
|
|
180
|
-
js: fs::read_to_string(js_path).unwrap_or_default(),
|
|
181
|
-
native_indices: mod_natives_map,
|
|
182
|
-
v8_native_indices: mod_v8_natives_map
|
|
183
|
-
});
|
|
184
|
-
|
|
149
|
+
modules.push(ModuleDef { name: config.name.clone(), js: fs::read_to_string(js_path).unwrap_or_default(), native_indices: mod_natives_map });
|
|
185
150
|
println!("{} {} {}", blue("[Titan]"), green("Extension loaded:"), config.name);
|
|
186
151
|
}
|
|
187
152
|
}
|
|
@@ -189,18 +154,16 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
189
154
|
|
|
190
155
|
// Scan node_modules
|
|
191
156
|
if node_modules.exists() {
|
|
192
|
-
scan_dir(node_modules, &mut modules, &mut libs, &mut all_natives
|
|
157
|
+
scan_dir(node_modules, &mut modules, &mut libs, &mut all_natives);
|
|
193
158
|
}
|
|
194
159
|
|
|
195
|
-
|
|
196
160
|
// Scan .ext (Production / Docker)
|
|
197
161
|
let ext_dir = root.join(".ext");
|
|
198
162
|
if ext_dir.exists() {
|
|
199
|
-
scan_dir(ext_dir, &mut modules, &mut libs, &mut all_natives
|
|
163
|
+
scan_dir(ext_dir, &mut modules, &mut libs, &mut all_natives);
|
|
200
164
|
}
|
|
201
165
|
|
|
202
|
-
*REGISTRY.lock().unwrap() = Some(Registry { _libs: libs, modules, natives: all_natives
|
|
203
|
-
|
|
166
|
+
*REGISTRY.lock().unwrap() = Some(Registry { _libs: libs, modules, natives: all_natives });
|
|
204
167
|
}
|
|
205
168
|
|
|
206
169
|
pub fn inject_external_extensions(scope: &mut v8::HandleScope, global: v8::Local<v8::Object>, t_obj: v8::Local<v8::Object>) {
|
|
@@ -208,10 +171,9 @@ pub fn inject_external_extensions(scope: &mut v8::HandleScope, global: v8::Local
|
|
|
208
171
|
let invoke_key = v8_str(scope, "__titan_invoke_native");
|
|
209
172
|
global.set(scope, invoke_key.into(), invoke_fn.into());
|
|
210
173
|
|
|
211
|
-
let
|
|
212
|
-
|
|
213
|
-
} else {
|
|
214
|
-
|
|
174
|
+
let modules = if let Ok(guard) = REGISTRY.lock() {
|
|
175
|
+
guard.as_ref().map(|r| r.modules.clone()).unwrap_or_default()
|
|
176
|
+
} else { vec![] };
|
|
215
177
|
|
|
216
178
|
for module in modules {
|
|
217
179
|
let mod_obj = v8::Object::new(scope);
|
|
@@ -225,24 +187,6 @@ pub fn inject_external_extensions(scope: &mut v8::HandleScope, global: v8::Local
|
|
|
225
187
|
}
|
|
226
188
|
}
|
|
227
189
|
}
|
|
228
|
-
|
|
229
|
-
for (fn_name, &idx) in &module.v8_native_indices {
|
|
230
|
-
if let Some(&ptr) = v8_native_ptrs.get(idx) {
|
|
231
|
-
if ptr != 0 {
|
|
232
|
-
unsafe {
|
|
233
|
-
let ext = v8::External::new(scope, ptr as *mut std::ffi::c_void);
|
|
234
|
-
let templ = v8::FunctionTemplate::builder(native_invoke_v8_proxy)
|
|
235
|
-
.data(ext.into())
|
|
236
|
-
.build(scope);
|
|
237
|
-
|
|
238
|
-
if let Some(func) = templ.get_function(scope) {
|
|
239
|
-
let key = v8_str(scope, fn_name);
|
|
240
|
-
mod_obj.set(scope, key.into(), func.into());
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
190
|
let mod_key = v8_str(scope, &module.name);
|
|
247
191
|
t_obj.set(scope, mod_key.into(), mod_obj.into());
|
|
248
192
|
|
|
@@ -330,20 +274,6 @@ fn native_invoke_extension(scope: &mut v8::HandleScope, args: v8::FunctionCallba
|
|
|
330
274
|
}
|
|
331
275
|
}
|
|
332
276
|
|
|
333
|
-
fn native_invoke_v8_proxy(scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, retval: v8::ReturnValue) {
|
|
334
|
-
let val = args.data();
|
|
335
|
-
if let Ok(ext) = v8::Local::<v8::External>::try_from(val) {
|
|
336
|
-
let ptr = ext.value() as *mut std::ffi::c_void;
|
|
337
|
-
if !ptr.is_null() {
|
|
338
|
-
unsafe {
|
|
339
|
-
type TitanV8Handler = extern "C" fn(&mut v8::HandleScope, v8::FunctionCallbackArguments, v8::ReturnValue);
|
|
340
|
-
let handler: TitanV8Handler = std::mem::transmute(ptr);
|
|
341
|
-
handler(scope, args, retval);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
277
|
fn arg_from_v8(scope: &mut v8::HandleScope, val: v8::Local<v8::Value>, ty: &ParamType) -> serde_json::Value {
|
|
348
278
|
match ty {
|
|
349
279
|
ParamType::String => serde_json::Value::String(val.to_rust_string_lossy(scope)),
|
|
@@ -16,19 +16,15 @@ pub struct Registry {
|
|
|
16
16
|
pub _libs: Vec<Library>,
|
|
17
17
|
pub modules: Vec<ModuleDef>,
|
|
18
18
|
pub natives: Vec<NativeFnEntry>,
|
|
19
|
-
pub v8_natives: Vec<usize>,
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
23
21
|
#[derive(Clone)]
|
|
24
22
|
pub struct ModuleDef {
|
|
25
23
|
pub name: String,
|
|
26
24
|
pub js: String,
|
|
27
25
|
pub native_indices: HashMap<String, usize>,
|
|
28
|
-
pub v8_native_indices: HashMap<String, usize>,
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
|
|
32
28
|
#[derive(Clone, Debug, PartialEq)]
|
|
33
29
|
pub enum ParamType {
|
|
34
30
|
String, F64, Bool, Json, Buffer,
|
|
@@ -60,18 +56,9 @@ struct TitanConfig {
|
|
|
60
56
|
#[derive(serde::Deserialize)]
|
|
61
57
|
struct TitanNativeConfig {
|
|
62
58
|
path: String,
|
|
63
|
-
#[serde(default)]
|
|
64
59
|
functions: HashMap<String, TitanNativeFunc>,
|
|
65
|
-
#[serde(default)]
|
|
66
|
-
v8_functions: HashMap<String, TitanV8Func>,
|
|
67
60
|
}
|
|
68
61
|
|
|
69
|
-
#[derive(serde::Deserialize)]
|
|
70
|
-
struct TitanV8Func {
|
|
71
|
-
symbol: String,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
62
|
#[derive(serde::Deserialize)]
|
|
76
63
|
struct TitanNativeFunc {
|
|
77
64
|
symbol: String,
|
|
@@ -108,8 +95,6 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
108
95
|
let mut modules = Vec::new();
|
|
109
96
|
let mut libs = Vec::new();
|
|
110
97
|
let mut all_natives = Vec::new();
|
|
111
|
-
let mut all_v8_natives = Vec::new();
|
|
112
|
-
|
|
113
98
|
|
|
114
99
|
let mut node_modules = root.join("node_modules");
|
|
115
100
|
if !node_modules.exists() {
|
|
@@ -120,8 +105,7 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
120
105
|
}
|
|
121
106
|
|
|
122
107
|
// Generic scanner helper
|
|
123
|
-
let scan_dir = |path: PathBuf, modules: &mut Vec<ModuleDef>, libs: &mut Vec<Library>, all_natives: &mut Vec<NativeFnEntry
|
|
124
|
-
|
|
108
|
+
let scan_dir = |path: PathBuf, modules: &mut Vec<ModuleDef>, libs: &mut Vec<Library>, all_natives: &mut Vec<NativeFnEntry>| {
|
|
125
109
|
if !path.exists() { return; }
|
|
126
110
|
for entry in WalkDir::new(&path).follow_links(true).min_depth(1).max_depth(4) {
|
|
127
111
|
let entry = match entry { Ok(e) => e, Err(_) => continue };
|
|
@@ -133,9 +117,7 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
133
117
|
Err(_) => continue,
|
|
134
118
|
};
|
|
135
119
|
let mut mod_natives_map = HashMap::new();
|
|
136
|
-
let mut mod_v8_natives_map = HashMap::new();
|
|
137
120
|
if let Some(native_conf) = config.native {
|
|
138
|
-
|
|
139
121
|
let lib_path = dir.join(&native_conf.path);
|
|
140
122
|
unsafe {
|
|
141
123
|
// Try loading library
|
|
@@ -144,28 +126,17 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
144
126
|
// But usually absolute path from `dir` works.
|
|
145
127
|
match lib_load {
|
|
146
128
|
Ok(lib) => {
|
|
147
|
-
for (fn_name, fn_conf) in
|
|
129
|
+
for (fn_name, fn_conf) in native_conf.functions {
|
|
148
130
|
let params = fn_conf.parameters.iter().map(|p| parse_type(&p.to_lowercase())).collect();
|
|
149
131
|
let ret = parse_return(&fn_conf.result.to_lowercase());
|
|
150
132
|
if let Ok(symbol) = lib.get::<*const ()>(fn_conf.symbol.as_bytes()) {
|
|
151
133
|
let idx = all_natives.len();
|
|
152
134
|
all_natives.push(NativeFnEntry { symbol_ptr: *symbol as usize, sig: Signature { params, ret } });
|
|
153
|
-
mod_natives_map.insert(fn_name
|
|
135
|
+
mod_natives_map.insert(fn_name, idx);
|
|
154
136
|
} else {
|
|
155
137
|
println!("{} {} {} -> {}", blue("[Titan]"), red("Symbol not found:"), fn_conf.symbol, config.name);
|
|
156
138
|
}
|
|
157
139
|
}
|
|
158
|
-
|
|
159
|
-
for (fn_name, fn_conf) in &native_conf.v8_functions {
|
|
160
|
-
if let Ok(symbol) = lib.get::<*const ()>(fn_conf.symbol.as_bytes()) {
|
|
161
|
-
let idx = all_v8_natives.len();
|
|
162
|
-
all_v8_natives.push(*symbol as usize);
|
|
163
|
-
mod_v8_natives_map.insert(fn_name.clone(), idx);
|
|
164
|
-
} else {
|
|
165
|
-
println!("{} {} {} -> {}", blue("[Titan]"), red("V8 Symbol not found:"), fn_conf.symbol, config.name);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
140
|
libs.push(lib);
|
|
170
141
|
},
|
|
171
142
|
Err(e) => {
|
|
@@ -175,13 +146,7 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
175
146
|
}
|
|
176
147
|
}
|
|
177
148
|
let js_path = dir.join(&config.main);
|
|
178
|
-
modules.push(ModuleDef {
|
|
179
|
-
name: config.name.clone(),
|
|
180
|
-
js: fs::read_to_string(js_path).unwrap_or_default(),
|
|
181
|
-
native_indices: mod_natives_map,
|
|
182
|
-
v8_native_indices: mod_v8_natives_map
|
|
183
|
-
});
|
|
184
|
-
|
|
149
|
+
modules.push(ModuleDef { name: config.name.clone(), js: fs::read_to_string(js_path).unwrap_or_default(), native_indices: mod_natives_map });
|
|
185
150
|
println!("{} {} {}", blue("[Titan]"), green("Extension loaded:"), config.name);
|
|
186
151
|
}
|
|
187
152
|
}
|
|
@@ -189,18 +154,16 @@ pub fn load_project_extensions(root: PathBuf) {
|
|
|
189
154
|
|
|
190
155
|
// Scan node_modules
|
|
191
156
|
if node_modules.exists() {
|
|
192
|
-
scan_dir(node_modules, &mut modules, &mut libs, &mut all_natives
|
|
157
|
+
scan_dir(node_modules, &mut modules, &mut libs, &mut all_natives);
|
|
193
158
|
}
|
|
194
159
|
|
|
195
|
-
|
|
196
160
|
// Scan .ext (Production / Docker)
|
|
197
161
|
let ext_dir = root.join(".ext");
|
|
198
162
|
if ext_dir.exists() {
|
|
199
|
-
scan_dir(ext_dir, &mut modules, &mut libs, &mut all_natives
|
|
163
|
+
scan_dir(ext_dir, &mut modules, &mut libs, &mut all_natives);
|
|
200
164
|
}
|
|
201
165
|
|
|
202
|
-
*REGISTRY.lock().unwrap() = Some(Registry { _libs: libs, modules, natives: all_natives
|
|
203
|
-
|
|
166
|
+
*REGISTRY.lock().unwrap() = Some(Registry { _libs: libs, modules, natives: all_natives });
|
|
204
167
|
}
|
|
205
168
|
|
|
206
169
|
pub fn inject_external_extensions(scope: &mut v8::HandleScope, global: v8::Local<v8::Object>, t_obj: v8::Local<v8::Object>) {
|
|
@@ -208,10 +171,9 @@ pub fn inject_external_extensions(scope: &mut v8::HandleScope, global: v8::Local
|
|
|
208
171
|
let invoke_key = v8_str(scope, "__titan_invoke_native");
|
|
209
172
|
global.set(scope, invoke_key.into(), invoke_fn.into());
|
|
210
173
|
|
|
211
|
-
let
|
|
212
|
-
|
|
213
|
-
} else {
|
|
214
|
-
|
|
174
|
+
let modules = if let Ok(guard) = REGISTRY.lock() {
|
|
175
|
+
guard.as_ref().map(|r| r.modules.clone()).unwrap_or_default()
|
|
176
|
+
} else { vec![] };
|
|
215
177
|
|
|
216
178
|
for module in modules {
|
|
217
179
|
let mod_obj = v8::Object::new(scope);
|
|
@@ -225,24 +187,6 @@ pub fn inject_external_extensions(scope: &mut v8::HandleScope, global: v8::Local
|
|
|
225
187
|
}
|
|
226
188
|
}
|
|
227
189
|
}
|
|
228
|
-
|
|
229
|
-
for (fn_name, &idx) in &module.v8_native_indices {
|
|
230
|
-
if let Some(&ptr) = v8_native_ptrs.get(idx) {
|
|
231
|
-
if ptr != 0 {
|
|
232
|
-
unsafe {
|
|
233
|
-
let ext = v8::External::new(scope, ptr as *mut std::ffi::c_void);
|
|
234
|
-
let templ = v8::FunctionTemplate::builder(native_invoke_v8_proxy)
|
|
235
|
-
.data(ext.into())
|
|
236
|
-
.build(scope);
|
|
237
|
-
|
|
238
|
-
if let Some(func) = templ.get_function(scope) {
|
|
239
|
-
let key = v8_str(scope, fn_name);
|
|
240
|
-
mod_obj.set(scope, key.into(), func.into());
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
190
|
let mod_key = v8_str(scope, &module.name);
|
|
247
191
|
t_obj.set(scope, mod_key.into(), mod_obj.into());
|
|
248
192
|
|
|
@@ -330,20 +274,6 @@ fn native_invoke_extension(scope: &mut v8::HandleScope, args: v8::FunctionCallba
|
|
|
330
274
|
}
|
|
331
275
|
}
|
|
332
276
|
|
|
333
|
-
fn native_invoke_v8_proxy(scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, retval: v8::ReturnValue) {
|
|
334
|
-
let val = args.data();
|
|
335
|
-
if let Ok(ext) = v8::Local::<v8::External>::try_from(val) {
|
|
336
|
-
let ptr = ext.value() as *mut std::ffi::c_void;
|
|
337
|
-
if !ptr.is_null() {
|
|
338
|
-
unsafe {
|
|
339
|
-
type TitanV8Handler = extern "C" fn(&mut v8::HandleScope, v8::FunctionCallbackArguments, v8::ReturnValue);
|
|
340
|
-
let handler: TitanV8Handler = std::mem::transmute(ptr);
|
|
341
|
-
handler(scope, args, retval);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
277
|
fn arg_from_v8(scope: &mut v8::HandleScope, val: v8::Local<v8::Value>, ty: &ParamType) -> serde_json::Value {
|
|
348
278
|
match ty {
|
|
349
279
|
ParamType::String => serde_json::Value::String(val.to_rust_string_lossy(scope)),
|
package/titanpl-sdk/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "titanpl-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Development SDK for Titan Planet. Provides TypeScript type definitions for the global 't' runtime object and a 'lite' test-harness runtime for building and verifying extensions.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|