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