@wildix/xbees-conversations-utils 1.1.74 → 1.1.76

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.
@@ -16,9 +16,9 @@ exports.BUDGET_DELAY_MAX_MS = 60000;
16
16
  exports.SOFT_THROTTLE_USAGE_LOW = 0.7;
17
17
  exports.SOFT_THROTTLE_USAGE_MEDIUM = 0.85;
18
18
  exports.SOFT_THROTTLE_USAGE_HIGH = 0.95;
19
- exports.SOFT_THROTTLE_DELAY_LOW_MS = 150;
20
- exports.SOFT_THROTTLE_DELAY_MEDIUM_MS = 500;
21
- exports.SOFT_THROTTLE_DELAY_HIGH_MS = 1200;
19
+ exports.SOFT_THROTTLE_DELAY_LOW_MS = 500;
20
+ exports.SOFT_THROTTLE_DELAY_MEDIUM_MS = 1500;
21
+ exports.SOFT_THROTTLE_DELAY_HIGH_MS = 3000;
22
22
  exports.STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES = [
23
23
  'channel',
24
24
  'getChannelById',
@@ -3,20 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createRateLimitExceededException = void 0;
4
4
  const xbees_conversations_client_1 = require("@wildix/xbees-conversations-client");
5
5
  const constants_1 = require("../constants");
6
+ const RETRY_AFTER_HEADER_PADDING_MS = 1500;
6
7
  function toPositiveMilliseconds(milliseconds) {
7
8
  return Math.max(0, Math.ceil(milliseconds));
8
9
  }
9
- function toUnixEpochSecondsFromDelayMs(delayMs) {
10
+ function toRetryAfterSecondsFromDelayMs(delayMs) {
10
11
  const positiveDelayMs = toPositiveMilliseconds(delayMs);
11
- return Math.ceil((Date.now() + positiveDelayMs) / 1000);
12
+ return Math.ceil(positiveDelayMs / 1000);
12
13
  }
13
14
  function createRateLimitExceededException(options = {}) {
14
15
  const { rateLimit, message, operation, retryAfterMs = constants_1.DEFAULT_RETRY_AFTER_MS } = options;
15
16
  const defaultMessage = operation ? `Rate limit exceeded for ${operation}` : 'Rate limit exceeded';
16
17
  const retryAfterFromResetMs = rateLimit?.reset ? rateLimit.reset - Date.now() : undefined;
17
18
  const effectiveRetryAfterMs = retryAfterFromResetMs ?? retryAfterMs;
19
+ const paddedRetryAfterMs = effectiveRetryAfterMs + RETRY_AFTER_HEADER_PADDING_MS;
18
20
  const retryAfterMilliseconds = toPositiveMilliseconds(effectiveRetryAfterMs);
19
- const retryAfterUnixEpochSeconds = toUnixEpochSecondsFromDelayMs(effectiveRetryAfterMs);
21
+ const retryAfterSeconds = toRetryAfterSecondsFromDelayMs(paddedRetryAfterMs);
20
22
  const rateLimitResetMilliseconds = rateLimit?.reset
21
23
  ? toPositiveMilliseconds(retryAfterFromResetMs ?? 0)
22
24
  : retryAfterMilliseconds;
@@ -24,7 +26,7 @@ function createRateLimitExceededException(options = {}) {
24
26
  $metadata: {},
25
27
  message: message || defaultMessage,
26
28
  rateLimitRemaining: rateLimit?.remaining || 0,
27
- retryAfter: retryAfterUnixEpochSeconds,
29
+ retryAfter: retryAfterSeconds,
28
30
  rateLimit: rateLimit?.limit?.toString() || 'unknown',
29
31
  rateLimitReset: rateLimitResetMilliseconds,
30
32
  });
@@ -7,6 +7,20 @@ const createRateLimitExceededException_1 = require("./createRateLimitExceededExc
7
7
  const processStreamRateLimitException_1 = require("./processStreamRateLimitException");
8
8
  const RedisCooldown_1 = require("./RedisCooldown");
9
9
  function normalizeRetryAfterToDelayMs(retryAfter) {
10
+ if (typeof retryAfter === 'string') {
11
+ const asDateMs = Date.parse(retryAfter);
12
+ if (!Number.isNaN(asDateMs)) {
13
+ return Math.max(0, Math.round(asDateMs - Date.now()));
14
+ }
15
+ const asSeconds = Number(retryAfter);
16
+ if (Number.isFinite(asSeconds) && asSeconds > 0) {
17
+ return Math.max(0, Math.round(asSeconds * 1000));
18
+ }
19
+ return 0;
20
+ }
21
+ if (typeof retryAfter !== 'number' || !Number.isFinite(retryAfter) || retryAfter <= 0) {
22
+ return 0;
23
+ }
10
24
  if (retryAfter > 1000000000) {
11
25
  return Math.max(0, Math.round(retryAfter * 1000 - Date.now()));
12
26
  }
@@ -16,8 +30,8 @@ function normalizeRetryAfterToDelayMs(retryAfter) {
16
30
  return Math.max(0, Math.round(retryAfter * 1000));
17
31
  }
18
32
  function calculateRateLimitDelayMs(error, maxDelayMs) {
19
- const hasServerRetryAfter = typeof error.retryAfter === 'number' && error.retryAfter > 0;
20
- const retryAfterMsFromError = hasServerRetryAfter ? normalizeRetryAfterToDelayMs(error.retryAfter) : 0;
33
+ const retryAfterMsFromError = normalizeRetryAfterToDelayMs(error.retryAfter);
34
+ const hasServerRetryAfter = retryAfterMsFromError > 0;
21
35
  const baseDelayMs = hasServerRetryAfter ? retryAfterMsFromError + constants_1.RETRY_AFTER_BUFFER_MS : constants_1.DEFAULT_RETRY_AFTER_MS;
22
36
  if (baseDelayMs > 0) {
23
37
  const jitterMs = Math.floor(Math.random() * constants_1.DEFAULT_JITTER_MS);
@@ -13,9 +13,9 @@ export const BUDGET_DELAY_MAX_MS = 60000;
13
13
  export const SOFT_THROTTLE_USAGE_LOW = 0.7;
14
14
  export const SOFT_THROTTLE_USAGE_MEDIUM = 0.85;
15
15
  export const SOFT_THROTTLE_USAGE_HIGH = 0.95;
16
- export const SOFT_THROTTLE_DELAY_LOW_MS = 150;
17
- export const SOFT_THROTTLE_DELAY_MEDIUM_MS = 500;
18
- export const SOFT_THROTTLE_DELAY_HIGH_MS = 1200;
16
+ export const SOFT_THROTTLE_DELAY_LOW_MS = 500;
17
+ export const SOFT_THROTTLE_DELAY_MEDIUM_MS = 1500;
18
+ export const SOFT_THROTTLE_DELAY_HIGH_MS = 3000;
19
19
  export const STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES = [
20
20
  'channel',
21
21
  'getChannelById',
@@ -1,19 +1,21 @@
1
1
  import { RateLimitExceededException } from '@wildix/xbees-conversations-client';
2
2
  import { DEFAULT_RETRY_AFTER_MS } from '../constants';
3
+ const RETRY_AFTER_HEADER_PADDING_MS = 1500;
3
4
  function toPositiveMilliseconds(milliseconds) {
4
5
  return Math.max(0, Math.ceil(milliseconds));
5
6
  }
6
- function toUnixEpochSecondsFromDelayMs(delayMs) {
7
+ function toRetryAfterSecondsFromDelayMs(delayMs) {
7
8
  const positiveDelayMs = toPositiveMilliseconds(delayMs);
8
- return Math.ceil((Date.now() + positiveDelayMs) / 1000);
9
+ return Math.ceil(positiveDelayMs / 1000);
9
10
  }
10
11
  export function createRateLimitExceededException(options = {}) {
11
12
  const { rateLimit, message, operation, retryAfterMs = DEFAULT_RETRY_AFTER_MS } = options;
12
13
  const defaultMessage = operation ? `Rate limit exceeded for ${operation}` : 'Rate limit exceeded';
13
14
  const retryAfterFromResetMs = rateLimit?.reset ? rateLimit.reset - Date.now() : undefined;
14
15
  const effectiveRetryAfterMs = retryAfterFromResetMs ?? retryAfterMs;
16
+ const paddedRetryAfterMs = effectiveRetryAfterMs + RETRY_AFTER_HEADER_PADDING_MS;
15
17
  const retryAfterMilliseconds = toPositiveMilliseconds(effectiveRetryAfterMs);
16
- const retryAfterUnixEpochSeconds = toUnixEpochSecondsFromDelayMs(effectiveRetryAfterMs);
18
+ const retryAfterSeconds = toRetryAfterSecondsFromDelayMs(paddedRetryAfterMs);
17
19
  const rateLimitResetMilliseconds = rateLimit?.reset
18
20
  ? toPositiveMilliseconds(retryAfterFromResetMs ?? 0)
19
21
  : retryAfterMilliseconds;
@@ -21,7 +23,7 @@ export function createRateLimitExceededException(options = {}) {
21
23
  $metadata: {},
22
24
  message: message || defaultMessage,
23
25
  rateLimitRemaining: rateLimit?.remaining || 0,
24
- retryAfter: retryAfterUnixEpochSeconds,
26
+ retryAfter: retryAfterSeconds,
25
27
  rateLimit: rateLimit?.limit?.toString() || 'unknown',
26
28
  rateLimitReset: rateLimitResetMilliseconds,
27
29
  });
@@ -4,6 +4,20 @@ import { createRateLimitExceededException } from './createRateLimitExceededExcep
4
4
  import { processStreamRateLimitException } from './processStreamRateLimitException';
5
5
  import { RedisCooldown } from './RedisCooldown';
6
6
  function normalizeRetryAfterToDelayMs(retryAfter) {
7
+ if (typeof retryAfter === 'string') {
8
+ const asDateMs = Date.parse(retryAfter);
9
+ if (!Number.isNaN(asDateMs)) {
10
+ return Math.max(0, Math.round(asDateMs - Date.now()));
11
+ }
12
+ const asSeconds = Number(retryAfter);
13
+ if (Number.isFinite(asSeconds) && asSeconds > 0) {
14
+ return Math.max(0, Math.round(asSeconds * 1000));
15
+ }
16
+ return 0;
17
+ }
18
+ if (typeof retryAfter !== 'number' || !Number.isFinite(retryAfter) || retryAfter <= 0) {
19
+ return 0;
20
+ }
7
21
  if (retryAfter > 1000000000) {
8
22
  return Math.max(0, Math.round(retryAfter * 1000 - Date.now()));
9
23
  }
@@ -13,8 +27,8 @@ function normalizeRetryAfterToDelayMs(retryAfter) {
13
27
  return Math.max(0, Math.round(retryAfter * 1000));
14
28
  }
15
29
  function calculateRateLimitDelayMs(error, maxDelayMs) {
16
- const hasServerRetryAfter = typeof error.retryAfter === 'number' && error.retryAfter > 0;
17
- const retryAfterMsFromError = hasServerRetryAfter ? normalizeRetryAfterToDelayMs(error.retryAfter) : 0;
30
+ const retryAfterMsFromError = normalizeRetryAfterToDelayMs(error.retryAfter);
31
+ const hasServerRetryAfter = retryAfterMsFromError > 0;
18
32
  const baseDelayMs = hasServerRetryAfter ? retryAfterMsFromError + RETRY_AFTER_BUFFER_MS : DEFAULT_RETRY_AFTER_MS;
19
33
  if (baseDelayMs > 0) {
20
34
  const jitterMs = Math.floor(Math.random() * DEFAULT_JITTER_MS);
@@ -14,9 +14,9 @@ export declare const BUDGET_DELAY_MAX_MS = 60000;
14
14
  export declare const SOFT_THROTTLE_USAGE_LOW = 0.7;
15
15
  export declare const SOFT_THROTTLE_USAGE_MEDIUM = 0.85;
16
16
  export declare const SOFT_THROTTLE_USAGE_HIGH = 0.95;
17
- export declare const SOFT_THROTTLE_DELAY_LOW_MS = 150;
18
- export declare const SOFT_THROTTLE_DELAY_MEDIUM_MS = 500;
19
- export declare const SOFT_THROTTLE_DELAY_HIGH_MS = 1200;
17
+ export declare const SOFT_THROTTLE_DELAY_LOW_MS = 500;
18
+ export declare const SOFT_THROTTLE_DELAY_MEDIUM_MS = 1500;
19
+ export declare const SOFT_THROTTLE_DELAY_HIGH_MS = 3000;
20
20
  export declare const STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES: readonly ["channel", "getChannelById", "getChannelByMembers", "hydrateActiveChannels"];
21
21
  export declare const STREAM_SYNC_METHOD_NAMES: readonly ["_addChannelConfig", "_buildWSPayload", "_callClientListeners", "_deleteUserMessageReference", "_enrichAxiosOptions", "_getConnectionID", "_getToken", "_handleClientEvent", "_handleUserEvent", "_hasConnectionID", "_isUsingServerAuth", "_logApiError", "_logApiRequest", "_logApiResponse", "_muteStatus", "_normalizeDate", "_normalizeExpiration", "_sayHi", "_setUser", "_startCleaning", "_updateMemberWatcherReferences", "_updateUserMessageReferences", "_updateUserReferences", "_validateAndGetMessageId", "createAbortControllerForNextRequest", "createToken", "devToken", "dispatchEvent", "errorFromResponse", "getAuthType", "getUserAgent", "handleEvent", "handleResponse", "off", "on", "setBaseURL", "setLocalDevice", "setUserAgent", "userMuteStatus", "verifyWebhook"];
22
22
  export declare const CHANNEL_SYNC_METHOD_NAMES: readonly ["_channelURL", "countUnread", "countUnreadMentions", "getConfig", "lastMessage", "lastRead", "muteStatus", "off", "on"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wildix/xbees-conversations-utils",
3
- "version": "1.1.74",
3
+ "version": "1.1.76",
4
4
  "description": "",
5
5
  "main": "./dist-cjs/index.js",
6
6
  "module": "./dist-es/index.js",