@bugbug-io/sdk 14.4.3 → 14.6.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/dist/index.d.ts CHANGED
@@ -49,6 +49,7 @@ export declare function createBugBug(config: BugBugConfig): BugBugSDK;
49
49
  export { BugBugSDK } from './sdk';
50
50
  export type { BugBugConfig, RequestOptions, WaitOptions, RequestHook, RequestErrorHook, } from './types/config';
51
51
  export type { RateLimitConfig } from './services/rateLimiter/rateLimiter.types';
52
+ export { RateLimiter } from './services/rateLimiter/rateLimiter';
52
53
  export { TestsModule } from './modules/tests/tests';
53
54
  export type { ImportTestOptions, ListTestRunsOptions, ListTestsOptions, RunTestBaseOptions, RunTestNoWatchProgressOptions, RunTestWatchProgressOptions, } from './modules/tests/tests.types';
54
55
  export { SuitesModule } from './modules/suites/suites';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9596,7 +9596,7 @@ var buildUserAgent = (clientType, version) => `BugBug ${clientType.toUpperCase()
9596
9596
  // ../core/package.json
9597
9597
  var package_default = {
9598
9598
  name: "@bugbug-io/core",
9599
- version: "14.4.3",
9599
+ version: "14.6.0",
9600
9600
  private: true,
9601
9601
  type: "module",
9602
9602
  main: "dist/index.js",
@@ -9831,12 +9831,15 @@ var RATE_LIMIT_MAX_WINDOW_MS = 6e4;
9831
9831
  // src/services/rateLimiter/rateLimiter.ts
9832
9832
  var RateLimiter = class {
9833
9833
  #requests = [];
9834
+ #activeRequests = 0;
9835
+ #slotQueue = [];
9834
9836
  #config;
9835
9837
  constructor(config) {
9836
9838
  this.#warnIfUnsupportedConfig(config);
9837
9839
  this.#config = {
9838
9840
  maxRequests: config.maxRequests,
9839
9841
  windowMs: config.windowMs,
9842
+ maxConcurrentRequests: config.maxConcurrentRequests ?? Number.POSITIVE_INFINITY,
9840
9843
  retryAfter: config.retryAfter || 1e3,
9841
9844
  retryServer429: config.retryServer429 ?? true,
9842
9845
  exponentialBackoff: {
@@ -9874,51 +9877,67 @@ var RateLimiter = class {
9874
9877
  * @throws {RateLimitError} When retries are exhausted or `retryServer429` is
9875
9878
  * disabled and the server returned 429.
9876
9879
  */
9877
- async execute(fn) {
9880
+ async execute(fn, options = {}) {
9881
+ const retryServer429 = options.retryServer429 ?? this.#config.retryServer429;
9878
9882
  let lastError = null;
9879
- for (let attempt = 0; attempt <= this.#config.exponentialBackoff.maxRetries; attempt++) {
9880
- if (!this.#canMakeRequest()) {
9881
- const waitTime = this.#getWaitTime();
9882
- const gateError = new RateLimitError(
9883
- waitTime,
9884
- `Rate limit exceeded. Wait ${waitTime}ms before retrying.`
9885
- );
9886
- lastError = gateError;
9887
- if (attempt === this.#config.exponentialBackoff.maxRetries) {
9888
- throw gateError;
9889
- }
9890
- await this.#sleep(this.#computeBackoff(attempt, gateError.retryAfter));
9891
- continue;
9892
- }
9893
- const stamp = this.#recordRequest();
9894
- try {
9895
- return await fn();
9896
- } catch (fnError) {
9897
- this.#releaseRequest(stamp);
9898
- if (!(fnError instanceof RateLimitError)) {
9899
- throw fnError;
9900
- }
9901
- lastError = fnError;
9902
- if (!this.#config.retryServer429) {
9903
- throw fnError;
9883
+ await this.#acquireSlot();
9884
+ try {
9885
+ for (let attempt = 0; attempt <= this.#config.exponentialBackoff.maxRetries; attempt++) {
9886
+ if (!this.#canMakeRequest()) {
9887
+ const waitTime = this.#getWaitTime();
9888
+ const gateError = new RateLimitError(
9889
+ waitTime,
9890
+ `Rate limit exceeded. Wait ${waitTime}ms before retrying.`
9891
+ );
9892
+ lastError = gateError;
9893
+ if (attempt === this.#config.exponentialBackoff.maxRetries) {
9894
+ throw gateError;
9895
+ }
9896
+ await this.#sleep(this.#computeBackoff(attempt, gateError.retryAfter));
9897
+ continue;
9904
9898
  }
9905
- if (attempt === this.#config.exponentialBackoff.maxRetries) {
9906
- throw fnError;
9899
+ const stamp = this.#recordRequest();
9900
+ try {
9901
+ return await fn();
9902
+ } catch (fnError) {
9903
+ this.#releaseRequest(stamp);
9904
+ if (!(fnError instanceof RateLimitError)) {
9905
+ throw fnError;
9906
+ }
9907
+ lastError = fnError;
9908
+ if (!retryServer429) {
9909
+ throw fnError;
9910
+ }
9911
+ if (attempt === this.#config.exponentialBackoff.maxRetries) {
9912
+ throw fnError;
9913
+ }
9914
+ await this.#sleep(this.#computeBackoff(attempt, fnError.retryAfter));
9907
9915
  }
9908
- await this.#sleep(this.#computeBackoff(attempt, fnError.retryAfter));
9909
9916
  }
9917
+ throw lastError || new Error("Max retries exceeded");
9918
+ } finally {
9919
+ this.#releaseSlot();
9910
9920
  }
9911
- throw lastError || new Error("Max retries exceeded");
9912
9921
  }
9913
9922
  #computeBackoff = (attempt, retryAfter) => {
9914
- const baseDelay = retryAfter || this.#config.exponentialBackoff.baseDelay;
9915
- const delay = Math.min(
9916
- baseDelay * Math.pow(2, attempt),
9917
- this.#config.exponentialBackoff.maxDelay
9918
- );
9923
+ const baseDelay = retryAfter ?? this.#config.exponentialBackoff.baseDelay;
9924
+ const computedDelay = baseDelay * Math.pow(2, attempt);
9925
+ const delay = retryAfter !== void 0 ? Math.max(retryAfter, computedDelay) : Math.min(computedDelay, this.#config.exponentialBackoff.maxDelay);
9919
9926
  const jitter = Math.random() * 0.1 * delay;
9920
9927
  return delay + jitter;
9921
9928
  };
9929
+ async #acquireSlot() {
9930
+ while (this.#activeRequests >= this.#config.maxConcurrentRequests) {
9931
+ await new Promise((resolve4) => {
9932
+ this.#slotQueue.push(resolve4);
9933
+ });
9934
+ }
9935
+ this.#activeRequests++;
9936
+ }
9937
+ #releaseSlot() {
9938
+ this.#activeRequests = Math.max(0, this.#activeRequests - 1);
9939
+ this.#slotQueue.shift()?.();
9940
+ }
9922
9941
  /**
9923
9942
  * Sleep utility
9924
9943
  */
@@ -10127,6 +10146,16 @@ var BugBugApiClient = class {
10127
10146
  const resolved = resolveEnvConfig({
10128
10147
  overrides: { token: config.apiToken, apiUrl: config.apiUrl, projectId: config.projectId }
10129
10148
  });
10149
+ const rateLimit = config.rateLimit || {
10150
+ maxRequests: 100,
10151
+ windowMs: 6e4,
10152
+ exponentialBackoff: {
10153
+ baseDelay: 1e3,
10154
+ maxDelay: 3e4,
10155
+ maxRetries: 3
10156
+ }
10157
+ };
10158
+ const rateLimiter = config.rateLimiter ?? new RateLimiter(rateLimit);
10130
10159
  this.#config = {
10131
10160
  apiToken: resolved.token ?? "",
10132
10161
  projectId: resolved.projectId ?? "",
@@ -10135,15 +10164,7 @@ var BugBugApiClient = class {
10135
10164
  verbose: config.verbose || false,
10136
10165
  logLevel: config.logLevel || "info",
10137
10166
  timeout: config.timeout || 3e4,
10138
- rateLimit: config.rateLimit || {
10139
- maxRequests: 100,
10140
- windowMs: 6e4,
10141
- exponentialBackoff: {
10142
- baseDelay: 1e3,
10143
- maxDelay: 3e4,
10144
- maxRetries: 3
10145
- }
10146
- },
10167
+ rateLimit,
10147
10168
  requestHeaders: {
10148
10169
  "User-Agent": buildUserAgent("sdk", getVersion()),
10149
10170
  ...config.requestHeaders
@@ -10153,11 +10174,12 @@ var BugBugApiClient = class {
10153
10174
  onAfterRequest: config.onAfterRequest || (() => {
10154
10175
  }),
10155
10176
  onRequestError: config.onRequestError || (() => {
10156
- })
10177
+ }),
10178
+ rateLimiter
10157
10179
  };
10158
10180
  this.#validateConfig();
10159
10181
  this.#client = this.#createApiClient();
10160
- this.#rateLimiter = new RateLimiter(this.#config.rateLimit);
10182
+ this.#rateLimiter = rateLimiter;
10161
10183
  }
10162
10184
  #createApiClient = () => createClient({
10163
10185
  baseUrl: this.#config.apiUrl,
@@ -10237,71 +10259,75 @@ var BugBugApiClient = class {
10237
10259
  headers: customHeaders
10238
10260
  };
10239
10261
  this.#config.onBeforeRequest(requestData);
10240
- return this.#rateLimiter.execute(async () => {
10241
- const abortContext = this.#createAbortContext(signal, timeout);
10242
- try {
10243
- if (this.#config.verbose) {
10244
- this.#log("debug", `\u2192 ${method} ${path}`, { params, body });
10245
- }
10246
- const requestOptions = {
10247
- signal: abortContext.signal,
10248
- headers: {
10249
- ...customHeaders,
10250
- ...this.#identityHeaders()
10262
+ return this.#rateLimiter.execute(
10263
+ async () => {
10264
+ const abortContext = this.#createAbortContext(signal, timeout);
10265
+ try {
10266
+ this.#throwIfAlreadyAborted(abortContext, requestOrigin);
10267
+ if (this.#config.verbose) {
10268
+ this.#log("debug", `\u2192 ${method} ${path}`, { params, body });
10251
10269
  }
10252
- };
10253
- if (scopedParams) {
10254
- requestOptions.params = scopedParams;
10255
- }
10256
- if (body !== void 0) {
10257
- requestOptions.body = body;
10258
- }
10259
- let response;
10260
- switch (method) {
10261
- case "GET":
10262
- response = await this.#client.GET(path, requestOptions);
10263
- break;
10264
- case "POST":
10265
- response = await this.#client.POST(path, requestOptions);
10266
- break;
10267
- case "PUT":
10268
- response = await this.#client.PUT(path, requestOptions);
10269
- break;
10270
- case "DELETE":
10271
- response = await this.#client.DELETE(path, requestOptions);
10272
- break;
10273
- case "PATCH":
10274
- response = await this.#client.PATCH(path, requestOptions);
10275
- break;
10276
- default:
10277
- throw new ValidationError(`Unsupported HTTP method: ${method}`);
10278
- }
10279
- abortContext.clear();
10280
- if (this.#config.verbose) {
10281
- this.#log("debug", `\u2190 ${response.response?.status} ${method} ${path}`, {
10282
- status: response.response?.status,
10283
- statusText: response.response?.statusText
10284
- });
10285
- }
10286
- if (response.error) {
10287
- this.#config.onRequestError(requestData, response.response, response.error);
10288
- await this.#handleOpenApiError(response.error, response.response, requestOrigin);
10289
- }
10290
- const result = response.data;
10291
- this.#config.onAfterRequest(requestData);
10292
- return result;
10293
- } catch (error) {
10294
- abortContext.clear();
10295
- if (error instanceof SyntaxError) {
10296
- throw new UnexpectedResponseError(
10297
- formatUnexpectedResponseMessage(error, method, requestUrl),
10298
- error,
10299
- requestOrigin
10300
- );
10270
+ const requestOptions = {
10271
+ signal: abortContext.signal,
10272
+ headers: {
10273
+ ...customHeaders,
10274
+ ...this.#identityHeaders()
10275
+ }
10276
+ };
10277
+ if (scopedParams) {
10278
+ requestOptions.params = scopedParams;
10279
+ }
10280
+ if (body !== void 0) {
10281
+ requestOptions.body = body;
10282
+ }
10283
+ let response;
10284
+ switch (method) {
10285
+ case "GET":
10286
+ response = await this.#client.GET(path, requestOptions);
10287
+ break;
10288
+ case "POST":
10289
+ response = await this.#client.POST(path, requestOptions);
10290
+ break;
10291
+ case "PUT":
10292
+ response = await this.#client.PUT(path, requestOptions);
10293
+ break;
10294
+ case "DELETE":
10295
+ response = await this.#client.DELETE(path, requestOptions);
10296
+ break;
10297
+ case "PATCH":
10298
+ response = await this.#client.PATCH(path, requestOptions);
10299
+ break;
10300
+ default:
10301
+ throw new ValidationError(`Unsupported HTTP method: ${method}`);
10302
+ }
10303
+ abortContext.clear();
10304
+ if (this.#config.verbose) {
10305
+ this.#log("debug", `\u2190 ${response.response?.status} ${method} ${path}`, {
10306
+ status: response.response?.status,
10307
+ statusText: response.response?.statusText
10308
+ });
10309
+ }
10310
+ if (response.error) {
10311
+ this.#config.onRequestError(requestData, response.response, response.error);
10312
+ await this.#handleOpenApiError(response.error, response.response, requestOrigin);
10313
+ }
10314
+ const result = response.data;
10315
+ this.#config.onAfterRequest(requestData);
10316
+ return result;
10317
+ } catch (error) {
10318
+ abortContext.clear();
10319
+ if (error instanceof SyntaxError) {
10320
+ throw new UnexpectedResponseError(
10321
+ formatUnexpectedResponseMessage(error, method, requestUrl),
10322
+ error,
10323
+ requestOrigin
10324
+ );
10325
+ }
10326
+ throw this.#toTransportError(error, requestOrigin, abortContext);
10301
10327
  }
10302
- throw this.#toTransportError(error, requestOrigin, abortContext);
10303
- }
10304
- });
10328
+ },
10329
+ { retryServer429: this.#canRetryServer429(method) }
10330
+ );
10305
10331
  };
10306
10332
  /**
10307
10333
  * Handle OpenAPI fetch errors. Always reads the real `response.status` so
@@ -10609,46 +10635,59 @@ var BugBugApiClient = class {
10609
10635
  };
10610
10636
  const requestOrigin = { method, url };
10611
10637
  this.#config.onBeforeRequest(requestData);
10612
- return this.#rateLimiter.execute(async () => {
10613
- const abortContext = this.#createAbortContext(signal, timeout);
10614
- try {
10615
- if (this.#config.verbose) {
10616
- this.#log("debug", `\u2192 ${method} ${path} (raw)`, { queryParams, pathParams });
10617
- }
10618
- const response = await fetch(url, {
10619
- method,
10620
- redirect,
10621
- headers: {
10622
- // Caller headers go first so the SDK's auth + identification
10623
- // headers always win — a stray `Authorization` in caller-supplied
10624
- // headers would otherwise silently replace the SDK token.
10625
- ...customHeaders,
10626
- ...authenticated ? this.#identityHeaders() : this.#requestHeaders(),
10627
- ...contentType ? { "Content-Type": contentType } : {}
10628
- },
10629
- ...body !== void 0 ? { body } : {},
10630
- signal: abortContext.signal
10631
- });
10632
- abortContext.clear();
10633
- if (this.#config.verbose) {
10634
- this.#log("debug", `\u2190 ${response.status} ${method} ${path}`, {
10635
- status: response.status,
10636
- statusText: response.statusText
10638
+ return this.#rateLimiter.execute(
10639
+ async () => {
10640
+ const abortContext = this.#createAbortContext(signal, timeout);
10641
+ try {
10642
+ this.#throwIfAlreadyAborted(abortContext, requestOrigin);
10643
+ if (this.#config.verbose) {
10644
+ this.#log("debug", `\u2192 ${method} ${path} (raw)`, { queryParams, pathParams });
10645
+ }
10646
+ const response = await fetch(url, {
10647
+ method,
10648
+ redirect,
10649
+ headers: {
10650
+ // Caller headers go first so the SDK's auth + identification
10651
+ // headers always win — a stray `Authorization` in caller-supplied
10652
+ // headers would otherwise silently replace the SDK token.
10653
+ ...customHeaders,
10654
+ ...authenticated ? this.#identityHeaders() : this.#requestHeaders(),
10655
+ ...contentType ? { "Content-Type": contentType } : {}
10656
+ },
10657
+ ...body !== void 0 ? { body } : {},
10658
+ signal: abortContext.signal
10637
10659
  });
10660
+ abortContext.clear();
10661
+ if (this.#config.verbose) {
10662
+ this.#log("debug", `\u2190 ${response.status} ${method} ${path}`, {
10663
+ status: response.status,
10664
+ statusText: response.statusText
10665
+ });
10666
+ }
10667
+ if (!response.ok && !(acceptRedirect && response.status >= 300 && response.status < 400)) {
10668
+ const errorText = await response.text();
10669
+ this.#config.onRequestError(requestData, response, new Error(errorText));
10670
+ await this.#handleOpenApiError(errorText, response, requestOrigin);
10671
+ }
10672
+ const result = await readBody(response);
10673
+ this.#config.onAfterRequest(requestData);
10674
+ return result;
10675
+ } catch (error) {
10676
+ abortContext.clear();
10677
+ throw this.#toTransportError(error, requestOrigin, abortContext);
10638
10678
  }
10639
- if (!response.ok && !(acceptRedirect && response.status >= 300 && response.status < 400)) {
10640
- const errorText = await response.text();
10641
- this.#config.onRequestError(requestData, response, new Error(errorText));
10642
- await this.#handleOpenApiError(errorText, response, requestOrigin);
10643
- }
10644
- const result = await readBody(response);
10645
- this.#config.onAfterRequest(requestData);
10646
- return result;
10647
- } catch (error) {
10648
- abortContext.clear();
10649
- throw this.#toTransportError(error, requestOrigin, abortContext);
10650
- }
10651
- });
10679
+ },
10680
+ { retryServer429: this.#canRetryServer429(method) }
10681
+ );
10682
+ };
10683
+ #canRetryServer429 = (method) => method === "GET" && this.#config.rateLimit.retryServer429 !== false;
10684
+ #throwIfAlreadyAborted = (abortContext, requestOrigin) => {
10685
+ if (!abortContext.signal.aborted) return;
10686
+ throw this.#toTransportError(
10687
+ new DOMException("The operation was aborted.", "AbortError"),
10688
+ requestOrigin,
10689
+ abortContext
10690
+ );
10652
10691
  };
10653
10692
  #createAbortContext = (signal, timeout) => {
10654
10693
  const controller = new AbortController();
@@ -10713,9 +10752,12 @@ var BugBugApiClient = class {
10713
10752
  if (updates.apiToken || updates.apiUrl) {
10714
10753
  this.#client = this.#createApiClient();
10715
10754
  }
10716
- if (updates.rateLimit) {
10755
+ if (updates.rateLimiter) {
10756
+ this.#rateLimiter = updates.rateLimiter;
10757
+ } else if (updates.rateLimit) {
10717
10758
  this.#rateLimiter = new RateLimiter(this.#config.rateLimit);
10718
10759
  }
10760
+ this.#config.rateLimiter = this.#rateLimiter;
10719
10761
  };
10720
10762
  /**
10721
10763
  * Snapshot of the in-process rate-limiter state.
@@ -15606,6 +15648,7 @@ export {
15606
15648
  ProjectsModule,
15607
15649
  RUN_MODES,
15608
15650
  RateLimitError,
15651
+ RateLimiter,
15609
15652
  RunModeSchema,
15610
15653
  SDK_ERROR_CODES,
15611
15654
  STEP_ERROR_CODES,