@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.
Files changed (47) hide show
  1. package/README.md +67 -0
  2. package/dist/{function-context-D8eyZuw_.d.cts → function-context-BNpL5bFb.d.cts} +223 -20
  3. package/dist/function-context-BNpL5bFb.d.cts.map +1 -0
  4. package/dist/{function-context-D8eyZuw_.d.mts → function-context-BNpL5bFb.d.mts} +223 -20
  5. package/dist/function-context-BNpL5bFb.d.mts.map +1 -0
  6. package/dist/index.cjs +80 -16
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +164 -3
  9. package/dist/index.d.cts.map +1 -1
  10. package/dist/index.d.mts +164 -3
  11. package/dist/index.d.mts.map +1 -1
  12. package/dist/index.mjs +78 -16
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/ops.d.cts +1 -1
  15. package/dist/ops.d.mts +1 -1
  16. package/dist/{react-DW7Z96sD.d.mts → react-CljeXJuw.d.cts} +142 -8
  17. package/dist/react-CljeXJuw.d.cts.map +1 -0
  18. package/dist/{react-DW7Z96sD.d.cts → react-CljeXJuw.d.mts} +142 -8
  19. package/dist/react-CljeXJuw.d.mts.map +1 -0
  20. package/dist/{react-DcT-mUPj.cjs → react-Dvkv2deI.cjs} +110 -59
  21. package/dist/react-Dvkv2deI.cjs.map +1 -0
  22. package/dist/{react-BXGyzgz0.mjs → react-OW1t_J0M.mjs} +103 -26
  23. package/dist/react-OW1t_J0M.mjs.map +1 -0
  24. package/dist/rolldown-runtime-KC0qvQup.cjs +34 -0
  25. package/dist/shell.cjs +38 -3
  26. package/dist/shell.cjs.map +1 -1
  27. package/dist/shell.d.cts +26 -3
  28. package/dist/shell.d.cts.map +1 -1
  29. package/dist/shell.d.mts +26 -3
  30. package/dist/shell.d.mts.map +1 -1
  31. package/dist/shell.mjs +34 -2
  32. package/dist/shell.mjs.map +1 -1
  33. package/dist/testing.cjs +4431 -0
  34. package/dist/testing.cjs.map +1 -0
  35. package/dist/testing.d.cts +656 -0
  36. package/dist/testing.d.cts.map +1 -0
  37. package/dist/testing.d.mts +656 -0
  38. package/dist/testing.d.mts.map +1 -0
  39. package/dist/testing.mjs +4395 -0
  40. package/dist/testing.mjs.map +1 -0
  41. package/package.json +22 -9
  42. package/dist/function-context-D8eyZuw_.d.cts.map +0 -1
  43. package/dist/function-context-D8eyZuw_.d.mts.map +0 -1
  44. package/dist/react-BXGyzgz0.mjs.map +0 -1
  45. package/dist/react-DW7Z96sD.d.cts.map +0 -1
  46. package/dist/react-DW7Z96sD.d.mts.map +0 -1
  47. package/dist/react-DcT-mUPj.cjs.map +0 -1
@@ -1,33 +1,7 @@
1
1
  // @oxy/sdk - TypeScript SDK for Oxy data platform
2
- //#region \0rolldown/runtime.js
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. `oxy publish` also validates them locally before esbuild,
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
- if (!(fn.route ?? !(hasSchedule || hasAirway)) && !hasSchedule && !hasAirway) throw new Error(`oxy-app.json: function "${fnName}" must enable at least one of route/schedule/airwayStep`);
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: err instanceof Error ? err : new Error(String(err))
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
- if (!resp.ok && resp.status !== 200) throw await apiErrorFromResponse(resp);
936
- return readFunctionSseStream(resp);
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: err instanceof Error ? err : new Error(String(err))
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 (e instanceof DOMException && e.name === "AbortError") return;
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: e instanceof Error ? e : new Error(String(e))
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 (err instanceof DOMException && err.name === "AbortError") return;
1359
- if (attempts >= 5) {
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 (attempts >= 5) {
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 (e instanceof DOMException && e.name === "AbortError") return;
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: e instanceof Error ? e : new Error(String(e))
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-DcT-mUPj.cjs.map
2498
+ //# sourceMappingURL=react-Dvkv2deI.cjs.map