@iblai/data-layer 1.4.4 → 1.5.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.
package/dist/index.js CHANGED
@@ -39166,44 +39166,71 @@ const getHeaders = async (service) => {
39166
39166
  }
39167
39167
  return token ? { Authorization: `${prefix} ${token}` } : undefined;
39168
39168
  };
39169
+ /** Status codes that should not be retried for queryFn endpoints. */
39170
+ const QUERYFN_NON_RETRYABLE_STATUSES = [401, 403];
39171
+ /** Default max retries for queryFn endpoints. */
39172
+ const QUERYFN_MAX_RETRIES = 10;
39173
+ /** Base delay in ms for exponential backoff. */
39174
+ const QUERYFN_BASE_DELAY_MS = 1000;
39169
39175
  /**
39170
39176
  * Build a generic RTK Query endpoint from a service function.
39177
+ * Includes built-in retry with exponential backoff (since RTK Query
39178
+ * skips baseQuery retry for queryFn endpoints).
39171
39179
  */
39172
- const buildEndpointFromService = (service, serviceFn) => {
39180
+ const buildEndpointFromService = (service, serviceFn, options) => {
39181
+ var _a;
39182
+ const maxRetries = (_a = void 0 ) !== null && _a !== void 0 ? _a : QUERYFN_MAX_RETRIES;
39173
39183
  return {
39174
39184
  async queryFn(args) {
39175
- try {
39176
- OpenAPI.BASE = getServiceUrl(service);
39177
- OpenAPI.HEADERS = await getHeaders(service);
39178
- OpenAPI.CREDENTIALS = service === exports.SERVICES.LEGACY_LMS ? 'include' : 'omit';
39179
- // API request initiated
39180
- const data = await serviceFn(args);
39181
- // API response received
39182
- return { data };
39183
- }
39184
- catch (err) {
39185
- console.error('[data-layer] API error:', JSON.stringify(err, Object.getOwnPropertyNames(err)));
39186
- if (Object.prototype.hasOwnProperty.call(Config.httpErrorHandlers, err === null || err === void 0 ? void 0 : err.status)) {
39187
- Config.httpErrorHandlers[err === null || err === void 0 ? void 0 : err.status]({ ...((err === null || err === void 0 ? void 0 : err.data) || {}) });
39185
+ let lastError;
39186
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
39187
+ try {
39188
+ OpenAPI.BASE = getServiceUrl(service);
39189
+ OpenAPI.HEADERS = await getHeaders(service);
39190
+ OpenAPI.CREDENTIALS = service === exports.SERVICES.LEGACY_LMS ? 'include' : 'omit';
39191
+ const data = await serviceFn(args);
39192
+ return { data };
39188
39193
  }
39189
- return {
39190
- error: {
39191
- status: (err === null || err === void 0 ? void 0 : err.status) || 500,
39192
- data: (err === null || err === void 0 ? void 0 : err.body) || (err === null || err === void 0 ? void 0 : err.data) || (err === null || err === void 0 ? void 0 : err.message) || 'Unknown error',
39193
- },
39194
- };
39194
+ catch (err) {
39195
+ lastError = err;
39196
+ const status = err === null || err === void 0 ? void 0 : err.status;
39197
+ // Don't retry auth errors
39198
+ if (QUERYFN_NON_RETRYABLE_STATUSES.includes(status)) {
39199
+ break;
39200
+ }
39201
+ // If we have retries left, wait with exponential backoff
39202
+ if (attempt < maxRetries) {
39203
+ const delay = QUERYFN_BASE_DELAY_MS * Math.pow(2, attempt);
39204
+ console.warn(`[data-layer] Retry ${attempt + 1}/${maxRetries}:`, `service=${service}, fn=${serviceFn.name || 'anonymous'}`);
39205
+ await new Promise((resolve) => setTimeout(resolve, delay));
39206
+ continue;
39207
+ }
39208
+ }
39209
+ }
39210
+ // All retries exhausted or non-retryable error
39211
+ console.error('[data-layer] API error:', `service=${service}, fn=${serviceFn.name || 'anonymous'}`, JSON.stringify(lastError, Object.getOwnPropertyNames(lastError)));
39212
+ if (Object.prototype.hasOwnProperty.call(Config.httpErrorHandlers, lastError === null || lastError === void 0 ? void 0 : lastError.status)) {
39213
+ Config.httpErrorHandlers[lastError === null || lastError === void 0 ? void 0 : lastError.status]({
39214
+ ...((lastError === null || lastError === void 0 ? void 0 : lastError.data) || {}),
39215
+ });
39195
39216
  }
39217
+ return {
39218
+ error: {
39219
+ status: (lastError === null || lastError === void 0 ? void 0 : lastError.status) || 500,
39220
+ data: (lastError === null || lastError === void 0 ? void 0 : lastError.body) || (lastError === null || lastError === void 0 ? void 0 : lastError.data) || (lastError === null || lastError === void 0 ? void 0 : lastError.message) || 'Unknown error',
39221
+ },
39222
+ };
39196
39223
  },
39197
39224
  };
39198
39225
  };
39199
39226
  /**
39200
39227
  * Shortcut for building an endpoint using the DM service.
39201
39228
  */
39202
- const buildEndpointFromDmService = (serviceFn) => buildEndpointFromService(exports.SERVICES.DM, serviceFn);
39229
+ const buildEndpointFromDmService = (serviceFn, options) => buildEndpointFromService(exports.SERVICES.DM, serviceFn);
39203
39230
  /**
39204
39231
  * Shortcut for building an endpoint using the AXD service.
39205
39232
  */
39206
- const buildEndpointFromAxdService = (serviceFn) => buildEndpointFromService(exports.SERVICES.AXD, serviceFn);
39233
+ const buildEndpointFromAxdService = (serviceFn, options) => buildEndpointFromService(exports.SERVICES.AXD, serviceFn);
39207
39234
  const isErrorObject = (data) => {
39208
39235
  return (typeof data === 'object' &&
39209
39236
  data !== null &&
@@ -39335,40 +39362,57 @@ const iblFetchBaseQuery = async (args, api, extraOptions) => {
39335
39362
  }
39336
39363
  };
39337
39364
  /**
39338
- * Build a generic RTK Query endpoint from a service function.
39365
+ * Build a generic RTK Query endpoint from a service function (legacy variant).
39366
+ * Includes built-in retry with exponential backoff.
39339
39367
  */
39340
- const buildEndpointFromServiceLegacy = (service, serviceFn) => {
39368
+ const buildEndpointFromServiceLegacy = (service, serviceFn, options) => {
39369
+ var _a;
39370
+ const maxRetries = (_a = void 0 ) !== null && _a !== void 0 ? _a : QUERYFN_MAX_RETRIES;
39341
39371
  return {
39342
39372
  async queryFn(args) {
39343
- try {
39344
- OpenAPI.BASE = getServiceUrl(service);
39345
- OpenAPI.HEADERS = await getHeaders(service);
39346
- OpenAPI.CREDENTIALS = service === exports.SERVICES.LEGACY_LMS ? 'include' : 'omit';
39347
- const data = await serviceFn(...args);
39348
- return { data };
39349
- }
39350
- catch (err) {
39351
- if (Object.prototype.hasOwnProperty.call(Config.httpErrorHandlers, err === null || err === void 0 ? void 0 : err.status)) {
39352
- Config.httpErrorHandlers[err === null || err === void 0 ? void 0 : err.status]({
39353
- status: err === null || err === void 0 ? void 0 : err.status,
39354
- body: err === null || err === void 0 ? void 0 : err.body,
39355
- message: err === null || err === void 0 ? void 0 : err.message,
39356
- });
39373
+ let lastError;
39374
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
39375
+ try {
39376
+ OpenAPI.BASE = getServiceUrl(service);
39377
+ OpenAPI.HEADERS = await getHeaders(service);
39378
+ OpenAPI.CREDENTIALS = service === exports.SERVICES.LEGACY_LMS ? 'include' : 'omit';
39379
+ const data = await serviceFn(...args);
39380
+ return { data };
39381
+ }
39382
+ catch (err) {
39383
+ lastError = err;
39384
+ const status = err === null || err === void 0 ? void 0 : err.status;
39385
+ if (QUERYFN_NON_RETRYABLE_STATUSES.includes(status)) {
39386
+ break;
39387
+ }
39388
+ if (attempt < maxRetries) {
39389
+ const delay = QUERYFN_BASE_DELAY_MS * Math.pow(2, attempt);
39390
+ console.warn(`[data-layer] Retry ${attempt + 1}/${maxRetries}:`, `service=${service}, fn=${serviceFn.name || 'anonymous'}`);
39391
+ await new Promise((resolve) => setTimeout(resolve, delay));
39392
+ continue;
39393
+ }
39357
39394
  }
39358
- return {
39359
- error: {
39360
- status: (err === null || err === void 0 ? void 0 : err.status) || 500,
39361
- data: (err === null || err === void 0 ? void 0 : err.body) || (err === null || err === void 0 ? void 0 : err.message) || 'Unknown error',
39362
- },
39363
- };
39364
39395
  }
39396
+ if (Object.prototype.hasOwnProperty.call(Config.httpErrorHandlers, lastError === null || lastError === void 0 ? void 0 : lastError.status)) {
39397
+ Config.httpErrorHandlers[lastError === null || lastError === void 0 ? void 0 : lastError.status]({
39398
+ status: lastError === null || lastError === void 0 ? void 0 : lastError.status,
39399
+ body: lastError === null || lastError === void 0 ? void 0 : lastError.body,
39400
+ message: lastError === null || lastError === void 0 ? void 0 : lastError.message,
39401
+ });
39402
+ }
39403
+ return {
39404
+ error: {
39405
+ status: (lastError === null || lastError === void 0 ? void 0 : lastError.status) || 500,
39406
+ data: (lastError === null || lastError === void 0 ? void 0 : lastError.body) || (lastError === null || lastError === void 0 ? void 0 : lastError.message) || 'Unknown error',
39407
+ },
39408
+ };
39365
39409
  },
39366
39410
  };
39367
39411
  };
39368
39412
  /**
39369
39413
  * Shortcut for building an endpoint using the DM service.
39370
39414
  */
39371
- const buildEndpointFromDmServiceLegacy = (serviceFn) => buildEndpointFromServiceLegacy(exports.SERVICES.DM, serviceFn);
39415
+ const buildEndpointFromDmServiceLegacy = (serviceFn, options) => buildEndpointFromServiceLegacy(exports.SERVICES.DM, serviceFn);
39372
39416
 
39373
39417
  const apiKeysApiSlice = react.createApi({
39374
39418
  reducerPath: 'apiKeysApiSlice',