@lotics/app-sdk 0.46.0 → 0.46.1

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 (2) hide show
  1. package/dist/src/rpc.js +32 -5
  2. package/package.json +1 -1
package/dist/src/rpc.js CHANGED
@@ -365,6 +365,12 @@ export function transportErrorMessage(status, parsed) {
365
365
  ? gatewayErrorMessage(status)
366
366
  : jsonMessage;
367
367
  }
368
+ // Standalone requests carried no timeout: a hung or slow backend pinned the
369
+ // fetch — and one of the browser's few per-origin connections — indefinitely,
370
+ // surfacing as an app that "loads forever". Bound every standalone call the way
371
+ // the bridged host path already bounds its own (`apiFetch`, 30s): a stalled
372
+ // request fails fast with a gateway-timeout message instead of spinning.
373
+ const API_TIMEOUT_MS = 30_000;
368
374
  async function apiCall(method, path, body, opts) {
369
375
  const headers = {};
370
376
  if (body)
@@ -372,11 +378,32 @@ async function apiCall(method, path, body, opts) {
372
378
  if (sessionToken && !opts?.skipAuth) {
373
379
  headers["authorization"] = `Bearer ${sessionToken}`;
374
380
  }
375
- const res = await fetch(`${API_BASE}${path}`, {
376
- method,
377
- headers,
378
- body: body ? JSON.stringify(body) : undefined,
379
- });
381
+ const controller = new AbortController();
382
+ let didTimeout = false;
383
+ const timeoutId = setTimeout(() => {
384
+ didTimeout = true;
385
+ controller.abort();
386
+ }, API_TIMEOUT_MS);
387
+ let res;
388
+ try {
389
+ res = await fetch(`${API_BASE}${path}`, {
390
+ method,
391
+ headers,
392
+ body: body ? JSON.stringify(body) : undefined,
393
+ signal: controller.signal,
394
+ });
395
+ }
396
+ catch (err) {
397
+ // A timeout abort surfaces as an AbortError — convert it to the same
398
+ // body-free gateway-timeout message a 524 produces, never a raw abort.
399
+ if (didTimeout && err instanceof DOMException && err.name === "AbortError") {
400
+ throw new Error(gatewayErrorMessage(524));
401
+ }
402
+ throw err;
403
+ }
404
+ finally {
405
+ clearTimeout(timeoutId);
406
+ }
380
407
  const text = await res.text();
381
408
  let parsed = null;
382
409
  if (text) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.46.0",
3
+ "version": "0.46.1",
4
4
  "description": "Runtime SDK for Lotics custom-code apps — typed hooks, postMessage bridge, mount entry point",
5
5
  "type": "module",
6
6
  "exports": {