@kubb/studio 5.3.3 → 5.3.4

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/dist/index.d.ts CHANGED
@@ -98,7 +98,9 @@ export declare function createJob({ studioUrl, token, type, agentId, name, versi
98
98
  config?: Record<string, unknown>;
99
99
  }): Promise<StudioJob>;
100
100
  /**
101
- * Polls `GET /api/jobs/{id}` until the job reaches `success` or `failed`.
101
+ * Polls `GET /api/jobs/{id}` until the job reaches `success` or `failed`, waiting
102
+ * {@link INITIAL_POLL_DELAY_MS} first and doubling up to {@link MAX_POLL_INTERVAL_MS} so a long
103
+ * job stays inside the API key's rate limit.
102
104
  *
103
105
  * A `failed` job resolves normally. Check `job.status` and `job.error`. Throws only when the
104
106
  * deadline passes before Studio finishes.
package/dist/index.js CHANGED
@@ -609,18 +609,41 @@ async function createJob({ studioUrl, token, type, agentId, name, version, confi
609
609
  return job;
610
610
  }
611
611
  /**
612
- * Polls `GET /api/jobs/{id}` until the job reaches `success` or `failed`.
612
+ * A job runs a generation and packs a tarball, so it is never done the instant it is queued.
613
+ */
614
+ const INITIAL_POLL_DELAY_MS = 2e3;
615
+ /**
616
+ * Slowest the poll backs off to. Requests per run are roughly `timeoutMs` divided by this, and
617
+ * every concurrent run on the same organization key draws on one budget.
618
+ */
619
+ const MAX_POLL_INTERVAL_MS = 3e4;
620
+ /**
621
+ * Polls `GET /api/jobs/{id}` until the job reaches `success` or `failed`, waiting
622
+ * {@link INITIAL_POLL_DELAY_MS} first and doubling up to {@link MAX_POLL_INTERVAL_MS} so a long
623
+ * job stays inside the API key's rate limit.
613
624
  *
614
625
  * A `failed` job resolves normally. Check `job.status` and `job.error`. Throws only when the
615
626
  * deadline passes before Studio finishes.
616
627
  */
617
628
  async function waitForJob({ studioUrl, token, id, timeoutMs = 6e4 }) {
618
629
  const deadline = Date.now() + timeoutMs;
630
+ let interval = INITIAL_POLL_DELAY_MS;
619
631
  for (;;) {
620
- const { job } = await ofetch(`${studioUrl}/api/jobs/${id}`, { headers: { "x-api-key": token } });
621
- if (job.status === "success" || job.status === "failed") return job;
632
+ await new Promise((resolve) => setTimeout(resolve, Math.max(Math.min(interval, deadline - Date.now()), 0)));
622
633
  if (Date.now() >= deadline) throw new Error("Timed out waiting for the Studio job");
623
- await new Promise((resolve) => setTimeout(resolve, 1e3));
634
+ interval = Math.min(interval * 2, MAX_POLL_INTERVAL_MS);
635
+ try {
636
+ const { job } = await ofetch(`${studioUrl}/api/jobs/${id}`, {
637
+ headers: { "x-api-key": token },
638
+ retry: false
639
+ });
640
+ if (job.status === "success" || job.status === "failed") return job;
641
+ } catch (error) {
642
+ const response = error.response;
643
+ if (response?.status !== 429) throw error;
644
+ const retryAfter = response._data?.data?.tryAgainIn;
645
+ interval = Math.max(interval, typeof retryAfter === "number" && Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : MAX_POLL_INTERVAL_MS);
646
+ }
624
647
  }
625
648
  }
626
649
  /**
@@ -650,7 +673,7 @@ async function createAgent({ studioUrl, token, name, machineToken }) {
650
673
  }
651
674
  //#endregion
652
675
  //#region package.json
653
- var version = "5.3.3";
676
+ var version = "5.3.4";
654
677
  //#endregion
655
678
  //#region src/hooks.ts
656
679
  /**