@oxy-hq/sdk 2.12.0 → 2.16.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/README.md +67 -0
- package/dist/{function-context-D8eyZuw_.d.cts → function-context-BNpL5bFb.d.cts} +223 -20
- package/dist/function-context-BNpL5bFb.d.cts.map +1 -0
- package/dist/{function-context-D8eyZuw_.d.mts → function-context-BNpL5bFb.d.mts} +223 -20
- package/dist/function-context-BNpL5bFb.d.mts.map +1 -0
- package/dist/index.cjs +80 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +164 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +164 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +78 -16
- package/dist/index.mjs.map +1 -1
- package/dist/ops.d.cts +1 -1
- package/dist/ops.d.mts +1 -1
- package/dist/{react-DW7Z96sD.d.mts → react-CljeXJuw.d.cts} +142 -8
- package/dist/react-CljeXJuw.d.cts.map +1 -0
- package/dist/{react-DW7Z96sD.d.cts → react-CljeXJuw.d.mts} +142 -8
- package/dist/react-CljeXJuw.d.mts.map +1 -0
- package/dist/{react-DcT-mUPj.cjs → react-Dvkv2deI.cjs} +110 -59
- package/dist/react-Dvkv2deI.cjs.map +1 -0
- package/dist/{react-BXGyzgz0.mjs → react-OW1t_J0M.mjs} +103 -26
- package/dist/react-OW1t_J0M.mjs.map +1 -0
- package/dist/rolldown-runtime-KC0qvQup.cjs +34 -0
- package/dist/shell.cjs +38 -3
- package/dist/shell.cjs.map +1 -1
- package/dist/shell.d.cts +26 -3
- package/dist/shell.d.cts.map +1 -1
- package/dist/shell.d.mts +26 -3
- package/dist/shell.d.mts.map +1 -1
- package/dist/shell.mjs +34 -2
- package/dist/shell.mjs.map +1 -1
- package/dist/testing.cjs +4431 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +656 -0
- package/dist/testing.d.cts.map +1 -0
- package/dist/testing.d.mts +656 -0
- package/dist/testing.d.mts.map +1 -0
- package/dist/testing.mjs +4395 -0
- package/dist/testing.mjs.map +1 -0
- package/package.json +22 -9
- package/dist/function-context-D8eyZuw_.d.cts.map +0 -1
- package/dist/function-context-D8eyZuw_.d.mts.map +0 -1
- package/dist/react-BXGyzgz0.mjs.map +0 -1
- package/dist/react-DW7Z96sD.d.cts.map +0 -1
- package/dist/react-DW7Z96sD.d.mts.map +0 -1
- package/dist/react-DcT-mUPj.cjs.map +0 -1
|
@@ -1,33 +1,7 @@
|
|
|
1
1
|
// @oxy/sdk - TypeScript SDK for Oxy data platform
|
|
2
|
-
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
-
key = keys[i];
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
-
__defProp(to, key, {
|
|
15
|
-
get: ((k) => from[k]).bind(null, key),
|
|
16
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
24
|
-
value: mod,
|
|
25
|
-
enumerable: true
|
|
26
|
-
}) : target, mod));
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
2
|
+
const require_rolldown_runtime = require('./rolldown-runtime-KC0qvQup.cjs');
|
|
29
3
|
let react = require("react");
|
|
30
|
-
react = __toESM(react, 1);
|
|
4
|
+
react = require_rolldown_runtime.__toESM(react, 1);
|
|
31
5
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
32
6
|
|
|
33
7
|
//#region src/custom-app/logger.ts
|
|
@@ -115,6 +89,25 @@ async function apiErrorFromResponse(resp) {
|
|
|
115
89
|
message: snippet || `HTTP ${resp.status}`
|
|
116
90
|
});
|
|
117
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Normalize a rejected request into the `Error` a hook reports.
|
|
94
|
+
*
|
|
95
|
+
* An `AbortError` reaching a hook's `.catch` is by construction an abort the
|
|
96
|
+
* hook did NOT cause — its own teardown is marked separately — so it is a
|
|
97
|
+
* fetcher's request timeout, a dropped socket, or a navigation. The platform's
|
|
98
|
+
* wording for those ("The user aborted a request.") is wrong on its face by
|
|
99
|
+
* the time a bundle renders it, so rephrase and keep the original as `cause`.
|
|
100
|
+
*
|
|
101
|
+
* The name is used only to WORD an error already being reported. Whether to
|
|
102
|
+
* report at all is the caller's teardown flag, never the name — that
|
|
103
|
+
* conflation is what left hooks loading forever.
|
|
104
|
+
*/
|
|
105
|
+
function asReportableError(err) {
|
|
106
|
+
const name = typeof err === "object" && err !== null && "name" in err ? String(err.name) : "";
|
|
107
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
108
|
+
if (name !== "AbortError" && e.name !== "AbortError") return e;
|
|
109
|
+
return Object.assign(/* @__PURE__ */ new Error("request was interrupted (the connection dropped or timed out)"), { cause: e });
|
|
110
|
+
}
|
|
118
111
|
const ARCH_DOC = "internal-docs/customer-apps.md";
|
|
119
112
|
/** Interpret a thrown error as a structured report for UI display. */
|
|
120
113
|
function interpretCustomAppError(err) {
|
|
@@ -327,7 +320,7 @@ const FUNCTION_NAME_RE = /^[a-z][a-z0-9-]{0,63}$/;
|
|
|
327
320
|
*
|
|
328
321
|
* This runs at manifest LOAD (app boot / `pnpm dev`), not at `oxy build` — the
|
|
329
322
|
* build-time gate is the vite plugin's `validateManifest`, which now checks
|
|
330
|
-
* function names too. `
|
|
323
|
+
* function names too. `oxyc publish` also validates them locally before esbuild,
|
|
331
324
|
* so a bad name fails before the upload regardless.
|
|
332
325
|
*/
|
|
333
326
|
function validateFunctions(raw) {
|
|
@@ -366,6 +359,10 @@ function validateFunctions(raw) {
|
|
|
366
359
|
if (typeof t !== "number" || !Number.isInteger(t) || t < 1 || t > 300) throw new Error(`oxy-app.json: function "${fnName}" \`timeoutSeconds\` must be an integer in [1, 300]`);
|
|
367
360
|
fn.timeoutSeconds = t;
|
|
368
361
|
}
|
|
362
|
+
if (value.check !== void 0) {
|
|
363
|
+
if (typeof value.check !== "boolean") throw new Error(`oxy-app.json: function "${fnName}" \`check\` must be a boolean`);
|
|
364
|
+
fn.check = value.check;
|
|
365
|
+
}
|
|
369
366
|
if (value.cache !== void 0) {
|
|
370
367
|
const c = value.cache;
|
|
371
368
|
if (!isRecord(c)) throw new Error(`oxy-app.json: function "${fnName}" \`cache\` must be an object`);
|
|
@@ -392,10 +389,25 @@ function validateFunctions(raw) {
|
|
|
392
389
|
}
|
|
393
390
|
fn.retries = retries;
|
|
394
391
|
}
|
|
392
|
+
if (value.webhook !== void 0) {
|
|
393
|
+
const w = value.webhook;
|
|
394
|
+
if (!isRecord(w)) throw new Error(`oxy-app.json: function "${fnName}" \`webhook\` must be an object`);
|
|
395
|
+
for (const key of ["secretVar", "signatureHeader"]) if (typeof w[key] !== "string" || !w[key].trim()) throw new Error(`oxy-app.json: function "${fnName}" \`webhook.${key}\` must be a non-empty string`);
|
|
396
|
+
const webhook = {
|
|
397
|
+
secretVar: w.secretVar,
|
|
398
|
+
signatureHeader: w.signatureHeader
|
|
399
|
+
};
|
|
400
|
+
if (w.encoding !== void 0) {
|
|
401
|
+
if (w.encoding !== "hex" && w.encoding !== "base64") throw new Error(`oxy-app.json: function "${fnName}" \`webhook.encoding\` must be "hex" or "base64"`);
|
|
402
|
+
webhook.encoding = w.encoding;
|
|
403
|
+
}
|
|
404
|
+
fn.webhook = webhook;
|
|
405
|
+
}
|
|
395
406
|
if (value.inputExample !== void 0) fn.inputExample = value.inputExample;
|
|
396
407
|
const hasSchedule = fn.schedule !== void 0;
|
|
397
408
|
const hasAirway = fn.airwayStep !== void 0;
|
|
398
|
-
|
|
409
|
+
const hasWebhook = fn.webhook !== void 0;
|
|
410
|
+
if (!(fn.route ?? !(hasSchedule || hasAirway || hasWebhook)) && !hasSchedule && !hasAirway && !hasWebhook) throw new Error(`oxy-app.json: function "${fnName}" must enable at least one of route/schedule/airwayStep/webhook`);
|
|
399
411
|
out[fnName] = fn;
|
|
400
412
|
}
|
|
401
413
|
return out;
|
|
@@ -649,6 +661,44 @@ async function sharedQuery(fetcher, projectId, sql, db, opts = {}) {
|
|
|
649
661
|
return p;
|
|
650
662
|
}
|
|
651
663
|
|
|
664
|
+
//#endregion
|
|
665
|
+
//#region src/custom-app/traceparent.ts
|
|
666
|
+
const HEX = "0123456789abcdef";
|
|
667
|
+
function randomHex(bytes) {
|
|
668
|
+
const buf = new Uint8Array(bytes);
|
|
669
|
+
const c = globalThis.crypto;
|
|
670
|
+
if (c && typeof c.getRandomValues === "function") c.getRandomValues(buf);
|
|
671
|
+
else for (let i = 0; i < bytes; i++) buf[i] = Math.floor(Math.random() * 256);
|
|
672
|
+
let out = "";
|
|
673
|
+
for (let i = 0; i < bytes; i++) out += HEX[buf[i] >> 4] + HEX[buf[i] & 15];
|
|
674
|
+
return out;
|
|
675
|
+
}
|
|
676
|
+
/** Mint a fresh, sampled `traceparent`. All-zero ids are invalid per the spec;
|
|
677
|
+
* the loop guards the astronomically unlikely draw. */
|
|
678
|
+
function newTraceparent() {
|
|
679
|
+
let traceId = randomHex(16);
|
|
680
|
+
while (/^0+$/.test(traceId)) traceId = randomHex(16);
|
|
681
|
+
let spanId = randomHex(8);
|
|
682
|
+
while (/^0+$/.test(spanId)) spanId = randomHex(8);
|
|
683
|
+
return {
|
|
684
|
+
header: `00-${traceId}-${spanId}-01`,
|
|
685
|
+
traceId
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Stamp the ids of a failed invoke onto whatever was thrown, so the app (and
|
|
690
|
+
* the platform's error beacon, which reads `traceId`) can name the trace and
|
|
691
|
+
* the server-minted request id. Non-objects are returned untouched.
|
|
692
|
+
*/
|
|
693
|
+
function withInvocationIds(err, traceId, requestId) {
|
|
694
|
+
if (err && typeof err === "object") {
|
|
695
|
+
const target = err;
|
|
696
|
+
if (!target.traceId) target.traceId = traceId;
|
|
697
|
+
if (requestId && !target.requestId) target.requestId = requestId;
|
|
698
|
+
}
|
|
699
|
+
return err;
|
|
700
|
+
}
|
|
701
|
+
|
|
652
702
|
//#endregion
|
|
653
703
|
//#region src/custom-app/react.tsx
|
|
654
704
|
function defaultFetcher(input, init) {
|
|
@@ -867,7 +917,7 @@ function useQuery(input, opts = {}) {
|
|
|
867
917
|
setState((s) => ({
|
|
868
918
|
...s,
|
|
869
919
|
loading: false,
|
|
870
|
-
error:
|
|
920
|
+
error: asReportableError(err)
|
|
871
921
|
}));
|
|
872
922
|
});
|
|
873
923
|
return () => {
|
|
@@ -921,9 +971,11 @@ function useFunction(name) {
|
|
|
921
971
|
error: null
|
|
922
972
|
}));
|
|
923
973
|
try {
|
|
974
|
+
const trace = newTraceparent();
|
|
924
975
|
const headers = {
|
|
925
976
|
"content-type": "application/json",
|
|
926
|
-
accept: "text/event-stream"
|
|
977
|
+
accept: "text/event-stream",
|
|
978
|
+
traceparent: trace.header
|
|
927
979
|
};
|
|
928
980
|
if (opts?.idempotencyKey) headers["idempotency-key"] = opts.idempotencyKey;
|
|
929
981
|
const result = await sharedFunctionInvoke(functionInvokeKey(name, body), async () => {
|
|
@@ -932,8 +984,13 @@ function useFunction(name) {
|
|
|
932
984
|
headers,
|
|
933
985
|
body: JSON.stringify(body ?? {})
|
|
934
986
|
});
|
|
935
|
-
|
|
936
|
-
|
|
987
|
+
const requestId = resp.headers?.get?.("x-oxy-request-id") ?? null;
|
|
988
|
+
if (!resp.ok && resp.status !== 200) throw withInvocationIds(await apiErrorFromResponse(resp), trace.traceId, requestId);
|
|
989
|
+
try {
|
|
990
|
+
return await readFunctionSseStream(resp);
|
|
991
|
+
} catch (err) {
|
|
992
|
+
throw withInvocationIds(err, trace.traceId, requestId);
|
|
993
|
+
}
|
|
937
994
|
});
|
|
938
995
|
setState({
|
|
939
996
|
data: result.value,
|
|
@@ -1038,11 +1095,10 @@ function useSemanticQuery(input, opts = {}) {
|
|
|
1038
1095
|
});
|
|
1039
1096
|
}).catch((err) => {
|
|
1040
1097
|
if (cancelled) return;
|
|
1041
|
-
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
1042
1098
|
setState((s) => ({
|
|
1043
1099
|
...s,
|
|
1044
1100
|
loading: false,
|
|
1045
|
-
error:
|
|
1101
|
+
error: asReportableError(err)
|
|
1046
1102
|
}));
|
|
1047
1103
|
});
|
|
1048
1104
|
return () => {
|
|
@@ -1199,13 +1255,13 @@ function useProcedureRun(input, opts = {}) {
|
|
|
1199
1255
|
return;
|
|
1200
1256
|
}
|
|
1201
1257
|
} catch (e) {
|
|
1202
|
-
if (
|
|
1258
|
+
if (ctrl.signal.aborted) return;
|
|
1203
1259
|
inflight.current.runId = void 0;
|
|
1204
1260
|
setState({
|
|
1205
1261
|
state: "failed",
|
|
1206
1262
|
progress: null,
|
|
1207
1263
|
result: null,
|
|
1208
|
-
error:
|
|
1264
|
+
error: asReportableError(e)
|
|
1209
1265
|
});
|
|
1210
1266
|
}
|
|
1211
1267
|
})();
|
|
@@ -1306,6 +1362,8 @@ function useAgentRun(input) {
|
|
|
1306
1362
|
if (ctrl.signal.aborted) return;
|
|
1307
1363
|
if (terminated) return;
|
|
1308
1364
|
attempts += 1;
|
|
1365
|
+
const idBeforeAttempt = lastEventId;
|
|
1366
|
+
let windowError;
|
|
1309
1367
|
try {
|
|
1310
1368
|
await consumeSseStream({
|
|
1311
1369
|
url: `/api/projects/${projectId}/agents/runs/${encodeURIComponent(run_id)}/events`,
|
|
@@ -1355,36 +1413,29 @@ function useAgentRun(input) {
|
|
|
1355
1413
|
}
|
|
1356
1414
|
});
|
|
1357
1415
|
} catch (err) {
|
|
1358
|
-
if (
|
|
1359
|
-
|
|
1360
|
-
inflight.current.runId = void 0;
|
|
1361
|
-
setState((s) => ({
|
|
1362
|
-
...s,
|
|
1363
|
-
state: "failed",
|
|
1364
|
-
error: err instanceof Error ? err : new Error(String(err))
|
|
1365
|
-
}));
|
|
1366
|
-
return;
|
|
1367
|
-
}
|
|
1416
|
+
if (ctrl.signal.aborted) return;
|
|
1417
|
+
windowError = err;
|
|
1368
1418
|
}
|
|
1369
1419
|
if (terminated) return;
|
|
1370
|
-
if (
|
|
1420
|
+
if (lastEventId !== idBeforeAttempt) attempts = 0;
|
|
1421
|
+
else if (attempts >= 5) {
|
|
1371
1422
|
inflight.current.runId = void 0;
|
|
1372
1423
|
setState((s) => ({
|
|
1373
1424
|
...s,
|
|
1374
1425
|
state: "failed",
|
|
1375
|
-
error: /* @__PURE__ */ new Error("run event stream closed without a terminal event")
|
|
1426
|
+
error: windowError ? asReportableError(windowError) : /* @__PURE__ */ new Error("run event stream closed without a terminal event")
|
|
1376
1427
|
}));
|
|
1377
1428
|
return;
|
|
1378
1429
|
}
|
|
1379
1430
|
await sleep(1e3, ctrl.signal);
|
|
1380
1431
|
}
|
|
1381
1432
|
} catch (e) {
|
|
1382
|
-
if (
|
|
1433
|
+
if (ctrl.signal.aborted) return;
|
|
1383
1434
|
inflight.current.runId = void 0;
|
|
1384
1435
|
setState((s) => ({
|
|
1385
1436
|
...s,
|
|
1386
1437
|
state: "failed",
|
|
1387
|
-
error:
|
|
1438
|
+
error: asReportableError(e)
|
|
1388
1439
|
}));
|
|
1389
1440
|
}
|
|
1390
1441
|
})();
|
|
@@ -2348,12 +2399,6 @@ Object.defineProperty(exports, 'OxyChat', {
|
|
|
2348
2399
|
return OxyChat;
|
|
2349
2400
|
}
|
|
2350
2401
|
});
|
|
2351
|
-
Object.defineProperty(exports, '__toESM', {
|
|
2352
|
-
enumerable: true,
|
|
2353
|
-
get: function () {
|
|
2354
|
-
return __toESM;
|
|
2355
|
-
}
|
|
2356
|
-
});
|
|
2357
2402
|
Object.defineProperty(exports, '_resetCustomAppManifestCacheForTest', {
|
|
2358
2403
|
enumerable: true,
|
|
2359
2404
|
get: function () {
|
|
@@ -2366,6 +2411,12 @@ Object.defineProperty(exports, 'apiErrorFromResponse', {
|
|
|
2366
2411
|
return apiErrorFromResponse;
|
|
2367
2412
|
}
|
|
2368
2413
|
});
|
|
2414
|
+
Object.defineProperty(exports, 'asReportableError', {
|
|
2415
|
+
enumerable: true,
|
|
2416
|
+
get: function () {
|
|
2417
|
+
return asReportableError;
|
|
2418
|
+
}
|
|
2419
|
+
});
|
|
2369
2420
|
Object.defineProperty(exports, 'getOxyAppLogger', {
|
|
2370
2421
|
enumerable: true,
|
|
2371
2422
|
get: function () {
|
|
@@ -2444,4 +2495,4 @@ Object.defineProperty(exports, 'useTrackEvent', {
|
|
|
2444
2495
|
return useTrackEvent;
|
|
2445
2496
|
}
|
|
2446
2497
|
});
|
|
2447
|
-
//# sourceMappingURL=react-
|
|
2498
|
+
//# sourceMappingURL=react-Dvkv2deI.cjs.map
|