titanpl-sdk 3.0.0 → 6.0.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.
@@ -63,6 +63,7 @@ pub enum TitanAsyncOp {
63
63
  DbQuery {
64
64
  conn: String,
65
65
  query: String,
66
+ params: Vec<String>,
66
67
  },
67
68
  FsRead {
68
69
  path: String,
@@ -470,16 +471,15 @@ pub fn execute_action_optimized(
470
471
  let p_val = v8_str(scope, req_path);
471
472
  req_obj.set(scope, p_key.into(), p_val.into());
472
473
 
473
- // rawBodyzero-copy via ArrayBuffer backing store
474
+ // bodyattach raw bytes as ArrayBuffer under "rawBody" key
475
+ let rb_key = v8::Local::new(scope, &gk_raw_body);
474
476
  let body_val: v8::Local<v8::Value> = if let Some(bytes) = req_body {
475
- let vec = bytes.to_vec();
476
- let store = v8::ArrayBuffer::new_backing_store_from_boxed_slice(vec.into_boxed_slice());
477
- let ab = v8::ArrayBuffer::with_backing_store(scope, &store.make_shared());
477
+ let backing = v8::ArrayBuffer::new_backing_store_from_vec(bytes.to_vec());
478
+ let ab = v8::ArrayBuffer::with_backing_store(scope, &backing.make_shared());
478
479
  ab.into()
479
480
  } else {
480
481
  v8::null(scope).into()
481
482
  };
482
- let rb_key = v8::Local::new(scope, &gk_raw_body);
483
483
  req_obj.set(scope, rb_key.into(), body_val);
484
484
 
485
485
  // headers
@@ -577,4 +577,4 @@ pub fn throw(scope: &mut v8::HandleScope, msg: &str) {
577
577
  let message = v8_str(scope, msg);
578
578
  let exception = v8::Exception::error(scope, message);
579
579
  scope.throw_exception(exception);
580
- }
580
+ }
@@ -15,6 +15,32 @@ if (!globalThis.__TITAN_CORE_LOADED__) {
15
15
  const wrapped = function (req) {
16
16
  const requestId = req.__titan_request_id;
17
17
 
18
+ if (req.rawBody && req.rawBody.byteLength !== undefined) {
19
+ try {
20
+ const decoder = new TextDecoder();
21
+ const text = decoder.decode(req.rawBody);
22
+
23
+ const contentType =
24
+ (req.headers && req.headers["content-type"]) ||
25
+ (req.headers && req.headers["Content-Type"]) ||
26
+ "";
27
+
28
+ if (contentType.includes("application/json")) {
29
+ req.body = text ? JSON.parse(text) : {};
30
+ } else if (contentType.includes("application/x-www-form-urlencoded")) {
31
+ req.body = Object.fromEntries(new URLSearchParams(text));
32
+ } else {
33
+ req.body = text;
34
+ }
35
+ } catch (e) {
36
+ req.body = {};
37
+ }
38
+ } else {
39
+ req.body = {};
40
+ }
41
+
42
+ // ===============================
43
+
18
44
  const isSuspend = (err) => {
19
45
  const msg = err && (err.message || String(err));
20
46
  return msg && (msg.includes("__SUSPEND__") || msg.includes("SUSPEND"));
@@ -25,9 +51,7 @@ if (!globalThis.__TITAN_CORE_LOADED__) {
25
51
 
26
52
  if (result && typeof result.then === 'function') {
27
53
  result.then(
28
- (data) => {
29
- t._finish_request(requestId, data);
30
- },
54
+ (data) => t._finish_request(requestId, data),
31
55
  (err) => {
32
56
  if (isSuspend(err)) return;
33
57
  t._finish_request(requestId, { error: err.message || String(err) });
@@ -54,10 +78,8 @@ if (!globalThis.__TITAN_CORE_LOADED__) {
54
78
  }
55
79
  };
56
80
 
57
- // process.env
58
- globalThis.process = {
59
- env: t.loadEnv ? t.loadEnv() : {}
60
- };
81
+ // Titan Environment API
82
+ t.env = t.loadEnv ? t.loadEnv() : {};
61
83
 
62
84
  // Async Proxy Creator
63
85
  function createAsyncOp(op) {
@@ -73,8 +95,7 @@ if (!globalThis.__TITAN_CORE_LOADED__) {
73
95
  }
74
96
 
75
97
  throw new Error(
76
- `[Titan Error] Accessed '${String(prop)}' without drift(). ` +
77
- `Fix: const res = drift(t.fetch(...));`
98
+ `[Titan Error] Accessed '${String(prop)}' without drift(). `
78
99
  );
79
100
  }
80
101
  });
@@ -185,22 +206,37 @@ if (!globalThis.__TITAN_CORE_LOADED__) {
185
206
  t.fetch.__titanWrapped = true;
186
207
  }
187
208
 
209
+ // db.connect
188
210
  // db.connect
189
211
  if (t.db && !t.db.__titanWrapped) {
190
212
  const nativeDbConnect = t.db.connect;
191
213
 
192
- t.db.connect = function (connString) {
193
- const conn = nativeDbConnect(connString);
214
+ t.db.connect = function (connString, options = {}) {
215
+ const conn = nativeDbConnect(connString, options);
194
216
 
195
217
  if (!conn.query.__titanWrapped) {
196
218
  const nativeQuery = conn.query;
197
- conn.query = (sql) => {
219
+
220
+ conn.query = function (sql, params = []) {
221
+ if (typeof sql !== "string" || !sql.trim()) {
222
+ throw new Error("db.query(): SQL string required");
223
+ }
224
+
225
+ if (!Array.isArray(params)) {
226
+ throw new Error("db.query(): params must be array");
227
+ }
228
+
198
229
  return createAsyncOp({
199
230
  __titanAsync: true,
200
231
  type: "db_query",
201
- data: { conn: connString, query: sql }
232
+ data: {
233
+ conn: connString,
234
+ query: sql,
235
+ params
236
+ }
202
237
  });
203
238
  };
239
+
204
240
  conn.query.__titanWrapped = true;
205
241
  }
206
242
 
@@ -96,7 +96,7 @@ async fn handler(State(state): State<AppState>, req: Request<Body>) -> impl Into
96
96
  "Server-Timing",
97
97
  format!("reply;dur={:.2}", elapsed.as_secs_f64() * 1000.0)
98
98
  .parse()
99
- .unwrap(),
99
+ .unwrap_or_else(|_| axum::http::HeaderValue::from_static("")),
100
100
  );
101
101
 
102
102
  if log_enabled {
@@ -140,7 +140,7 @@ async fn handler(State(state): State<AppState>, req: Request<Body>) -> impl Into
140
140
  "Server-Timing",
141
141
  format!("fastpath;dur={:.2}", elapsed.as_secs_f64() * 1000.0)
142
142
  .parse()
143
- .unwrap(),
143
+ .unwrap_or_else(|_| axum::http::HeaderValue::from_static("")),
144
144
  );
145
145
 
146
146
  if log_enabled {
@@ -409,7 +409,7 @@ async fn handler(State(state): State<AppState>, req: Request<Body>) -> impl Into
409
409
  .join(", ");
410
410
  response
411
411
  .headers_mut()
412
- .insert("Server-Timing", server_timing.parse().unwrap());
412
+ .insert("Server-Timing", server_timing.parse().unwrap_or_else(|_| axum::http::HeaderValue::from_static("")));
413
413
  }
414
414
 
415
415
  // Logging