talizen 0.2.10 → 0.2.12

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/README.md CHANGED
@@ -216,6 +216,10 @@ export function list(input: { offset?: number }, ctx: TalizenFuncContext) {
216
216
 
217
217
  `ctx.db`, `ctx.cache`, `ctx.auth`, `ctx.request`, and `ctx.cookies` are injected by the Talizen Func runtime. `talizen/func-runtime` is a type-only authoring module; do not import runtime values from it.
218
218
 
219
+ `ctx.request` exposes Fetch-style one-shot body readers. Use `await ctx.request.text()` when a webhook signature must be verified against the exact request bytes, `await ctx.request.json()` for parsed JSON, or `await ctx.request.arrayBuffer()` for binary input. Reading the body sets `ctx.request.bodyUsed`; a second read rejects. `ctx.response.status(code)` sets the actual HTTP response status (100-599), including statuses returned when a Func throws after setting the status. The runtime also provides `TextEncoder` and the HMAC SHA-256 subset of `crypto.subtle` (`importKey`, `sign`, and `verify`) for webhook verification.
220
+
221
+ Func HTTP responses use the HTTP status code rather than a top-level `ok` field. Successful responses contain `{ result: ... }`; failed responses contain `{ error: ... }`. `invoke()` unwraps `result` for callers.
222
+
219
223
  ## Package Layout
220
224
 
221
225
  - `talizen/core`: shared runtime config, request helpers, and base data types.
package/func-runtime.d.ts CHANGED
@@ -74,6 +74,13 @@ export interface FuncRequestRuntime {
74
74
  path: string;
75
75
  headers: FuncReadonlyStringMap;
76
76
  cookies: FuncReadonlyStringMap;
77
+ readonly bodyUsed: boolean;
78
+ text(): Promise<string>;
79
+ json<T = unknown>(): Promise<T>;
80
+ arrayBuffer(): Promise<ArrayBuffer>;
81
+ }
82
+ export interface FuncResponseRuntime {
83
+ status(code: number): void;
77
84
  }
78
85
  export interface FuncCookieSetOptions {
79
86
  path?: string;
@@ -96,6 +103,7 @@ export interface TalizenFuncContext {
96
103
  trace_id: string;
97
104
  extra?: Record<string, unknown>;
98
105
  request: FuncRequestRuntime;
106
+ response: FuncResponseRuntime;
99
107
  db: FuncDbRuntime;
100
108
  auth: FuncAuthRuntime;
101
109
  cache: FuncCacheRuntime;
package/func.d.ts CHANGED
@@ -4,7 +4,6 @@ export interface FuncLogEntry {
4
4
  text: string;
5
5
  }
6
6
  export interface FuncRunResponse<T = unknown> {
7
- ok: boolean;
8
7
  result?: T;
9
8
  logs?: FuncLogEntry[];
10
9
  error?: string;
@@ -13,11 +12,14 @@ export declare class TalizenFuncError extends Error {
13
12
  readonly key: string;
14
13
  readonly method: string;
15
14
  readonly logs: FuncLogEntry[];
16
- constructor(key: string, method: string, message: string, logs?: FuncLogEntry[]);
15
+ readonly status: number;
16
+ constructor(key: string, method: string, message: string, logs?: FuncLogEntry[], status?: number);
17
17
  }
18
- export declare function invoke<T = unknown>(name: string, input?: unknown, options?: TalizenRequestOptions): Promise<T>;
18
+ export declare function invoke<T = unknown>(name: string, input?: unknown, options?: RunFuncOptions): Promise<T>;
19
19
  export interface RunFuncOptions extends TalizenRequestOptions {
20
20
  method?: string;
21
+ timeoutMS?: number;
22
+ timeoutMs?: number;
21
23
  }
22
24
  export declare function runFunc<T = unknown>(key: string, input?: unknown, options?: RunFuncOptions): Promise<T>;
23
25
  export declare function parseInvokeName(name: string): {
package/func.js CHANGED
@@ -1,14 +1,16 @@
1
- import { requestJson, } from "./core.js";
1
+ import { requestJson, TalizenHttpError, } from "./core.js";
2
2
  export class TalizenFuncError extends Error {
3
3
  key;
4
4
  method;
5
5
  logs;
6
- constructor(key, method, message, logs) {
6
+ status;
7
+ constructor(key, method, message, logs, status = 200) {
7
8
  super(message);
8
9
  this.name = "TalizenFuncError";
9
10
  this.key = key;
10
11
  this.method = method;
11
12
  this.logs = logs ?? [];
13
+ this.status = status;
12
14
  }
13
15
  }
14
16
  export async function invoke(name, input, options) {
@@ -21,15 +23,44 @@ export async function invoke(name, input, options) {
21
23
  export async function runFunc(key, input, options) {
22
24
  const normalizedKey = normalizeFuncKey(key);
23
25
  const method = normalizeFuncMethod(options?.method);
24
- const response = await requestJson(`/func/${encodeFuncKey(normalizedKey)}${method === "main" ? "" : `.${encodeURIComponent(method)}`}`, {
25
- method: "POST",
26
- body: JSON.stringify(input ?? {}),
27
- }, options);
28
- if (!response.ok) {
26
+ const timeoutMS = normalizeTimeoutMS(options?.timeoutMS ?? options?.timeoutMs);
27
+ const path = `/func/${encodeFuncKey(normalizedKey)}${method === "main" ? "" : `.${encodeURIComponent(method)}`}${timeoutMS ? `?timeout_ms=${timeoutMS}` : ""}`;
28
+ let response;
29
+ try {
30
+ response = await requestJson(path, {
31
+ method: "POST",
32
+ body: JSON.stringify(input ?? {}),
33
+ }, options);
34
+ }
35
+ catch (error) {
36
+ if (error instanceof TalizenHttpError) {
37
+ throw new TalizenFuncError(normalizedKey, method, funcHttpErrorMessage(error), undefined, error.status);
38
+ }
39
+ throw error;
40
+ }
41
+ if (response.error) {
29
42
  throw new TalizenFuncError(normalizedKey, method, response.error || "Talizen func failed.", response.logs);
30
43
  }
31
44
  return response.result;
32
45
  }
46
+ function funcHttpErrorMessage(error) {
47
+ try {
48
+ const payload = JSON.parse(error.body);
49
+ if (typeof payload.error === "string") {
50
+ return payload.error;
51
+ }
52
+ if (payload.error && typeof payload.error === "object") {
53
+ const message = payload.error.message;
54
+ if (typeof message === "string") {
55
+ return message;
56
+ }
57
+ }
58
+ }
59
+ catch {
60
+ // Fall through to the HTTP error body.
61
+ }
62
+ return error.body || error.message || "Talizen func failed.";
63
+ }
33
64
  export function parseInvokeName(name) {
34
65
  const normalized = normalizeFuncKey(name);
35
66
  const lastSlash = normalized.lastIndexOf("/");
@@ -67,3 +98,12 @@ function normalizeFuncMethod(method) {
67
98
  function encodeFuncKey(key) {
68
99
  return key.split("/").map(encodeURIComponent).join("/");
69
100
  }
101
+ function normalizeTimeoutMS(timeoutMS) {
102
+ if (timeoutMS == null) {
103
+ return undefined;
104
+ }
105
+ if (!Number.isFinite(timeoutMS) || timeoutMS <= 0) {
106
+ throw new Error(`Invalid Talizen func timeoutMS: ${timeoutMS}`);
107
+ }
108
+ return Math.floor(timeoutMS);
109
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "talizen",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Talizen frontend SDK types for cms, form and core.",
5
5
  "type": "module",
6
6
  "license": "MIT",