@wildix/xbees-conversations-utils 4.0.2 → 4.1.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.
Files changed (128) hide show
  1. package/dist-cjs/anonymousEmail/index.js +3 -3
  2. package/dist-cjs/normalization.js +6 -0
  3. package/dist-es/anonymousEmail/index.js +1 -1
  4. package/dist-es/normalization.js +6 -0
  5. package/dist-types/anonymousEmail/index.d.ts +0 -1
  6. package/dist-types/normalization.d.ts +25 -0
  7. package/dist-types/stream.d.ts +7 -1
  8. package/package.json +3 -3
  9. package/dist-cjs/rateLimits/RedisCooldown.js +0 -66
  10. package/dist-cjs/rateLimits/constants.js +0 -43
  11. package/dist-cjs/rateLimits/createRateLimitedStreamProxy.js +0 -92
  12. package/dist-cjs/rateLimits/exception/createRateLimitExceededException.js +0 -21
  13. package/dist-cjs/rateLimits/exception/processStreamRateLimitException.js +0 -47
  14. package/dist-cjs/rateLimits/executeStreamRequestWithRateLimitHandling.js +0 -94
  15. package/dist-cjs/rateLimits/generatedMethodNames.js +0 -320
  16. package/dist-cjs/rateLimits/helpers/RedisCooldown.js +0 -174
  17. package/dist-cjs/rateLimits/helpers/createRateLimitExceededException.js +0 -32
  18. package/dist-cjs/rateLimits/helpers/executeWithRateLimitHandling.js +0 -144
  19. package/dist-cjs/rateLimits/helpers/headerUtils.js +0 -40
  20. package/dist-cjs/rateLimits/helpers/isStreamChannelLike.js +0 -23
  21. package/dist-cjs/rateLimits/helpers/processStreamBudgetHeaders.js +0 -93
  22. package/dist-cjs/rateLimits/helpers/processStreamRateLimitException.js +0 -63
  23. package/dist-cjs/rateLimits/helpers/processStreamRateLimitHeaders.js +0 -50
  24. package/dist-cjs/rateLimits/helpers/rateLimitSnapshot.js +0 -31
  25. package/dist-cjs/rateLimits/helpers/registerStreamBudgetInterceptors.js +0 -48
  26. package/dist-cjs/rateLimits/helpers/registerStreamInterceptors.js +0 -58
  27. package/dist-cjs/rateLimits/helpers/splitCallArgsAndOptions.js +0 -21
  28. package/dist-cjs/rateLimits/index.js +0 -7
  29. package/dist-cjs/rateLimits/types.js +0 -3
  30. package/dist-cjs/rateLimits/withStreamRateLimitOptions.js +0 -10
  31. package/dist-cjs/streamRateLimitHandlingProxy/constants.js +0 -42
  32. package/dist-cjs/streamRateLimitHandlingProxy/createRateLimitedStreamProxy.js +0 -92
  33. package/dist-cjs/streamRateLimitHandlingProxy/generatedMethodNames.js +0 -320
  34. package/dist-cjs/streamRateLimitHandlingProxy/helpers/RedisCooldown.js +0 -174
  35. package/dist-cjs/streamRateLimitHandlingProxy/helpers/createRateLimitExceededException.js +0 -29
  36. package/dist-cjs/streamRateLimitHandlingProxy/helpers/executeWithRateLimitHandling.js +0 -153
  37. package/dist-cjs/streamRateLimitHandlingProxy/helpers/headerUtils.js +0 -48
  38. package/dist-cjs/streamRateLimitHandlingProxy/helpers/isStreamChannelLike.js +0 -23
  39. package/dist-cjs/streamRateLimitHandlingProxy/helpers/processStreamBudgetHeaders.js +0 -93
  40. package/dist-cjs/streamRateLimitHandlingProxy/helpers/processStreamRateLimitException.js +0 -63
  41. package/dist-cjs/streamRateLimitHandlingProxy/helpers/processStreamRateLimitHeaders.js +0 -46
  42. package/dist-cjs/streamRateLimitHandlingProxy/helpers/rateLimitSnapshot.js +0 -31
  43. package/dist-cjs/streamRateLimitHandlingProxy/helpers/registerStreamInterceptors.js +0 -64
  44. package/dist-cjs/streamRateLimitHandlingProxy/helpers/sleep.js +0 -6
  45. package/dist-cjs/streamRateLimitHandlingProxy/helpers/splitCallArgsAndOptions.js +0 -21
  46. package/dist-cjs/streamRateLimitHandlingProxy/index.js +0 -5
  47. package/dist-cjs/streamRateLimitHandlingProxy/types.js +0 -3
  48. package/dist-cjs/streamRateLimitHandlingProxy/withStreamRateLimitOptions.js +0 -10
  49. package/dist-es/rateLimits/RedisCooldown.js +0 -62
  50. package/dist-es/rateLimits/constants.js +0 -33
  51. package/dist-es/rateLimits/createRateLimitedStreamProxy.js +0 -88
  52. package/dist-es/rateLimits/exception/createRateLimitExceededException.js +0 -17
  53. package/dist-es/rateLimits/exception/processStreamRateLimitException.js +0 -37
  54. package/dist-es/rateLimits/executeStreamRequestWithRateLimitHandling.js +0 -93
  55. package/dist-es/rateLimits/generatedMethodNames.js +0 -317
  56. package/dist-es/rateLimits/helpers/RedisCooldown.js +0 -170
  57. package/dist-es/rateLimits/helpers/createRateLimitExceededException.js +0 -28
  58. package/dist-es/rateLimits/helpers/executeWithRateLimitHandling.js +0 -140
  59. package/dist-es/rateLimits/helpers/headerUtils.js +0 -34
  60. package/dist-es/rateLimits/helpers/isStreamChannelLike.js +0 -19
  61. package/dist-es/rateLimits/helpers/processStreamBudgetHeaders.js +0 -89
  62. package/dist-es/rateLimits/helpers/processStreamRateLimitException.js +0 -59
  63. package/dist-es/rateLimits/helpers/processStreamRateLimitHeaders.js +0 -46
  64. package/dist-es/rateLimits/helpers/rateLimitSnapshot.js +0 -26
  65. package/dist-es/rateLimits/helpers/registerStreamBudgetInterceptors.js +0 -44
  66. package/dist-es/rateLimits/helpers/registerStreamInterceptors.js +0 -54
  67. package/dist-es/rateLimits/helpers/splitCallArgsAndOptions.js +0 -17
  68. package/dist-es/rateLimits/index.js +0 -4
  69. package/dist-es/rateLimits/types.js +0 -1
  70. package/dist-es/rateLimits/withStreamRateLimitOptions.js +0 -6
  71. package/dist-es/streamRateLimitHandlingProxy/constants.js +0 -32
  72. package/dist-es/streamRateLimitHandlingProxy/createRateLimitedStreamProxy.js +0 -88
  73. package/dist-es/streamRateLimitHandlingProxy/generatedMethodNames.js +0 -317
  74. package/dist-es/streamRateLimitHandlingProxy/helpers/RedisCooldown.js +0 -170
  75. package/dist-es/streamRateLimitHandlingProxy/helpers/createRateLimitExceededException.js +0 -25
  76. package/dist-es/streamRateLimitHandlingProxy/helpers/executeWithRateLimitHandling.js +0 -148
  77. package/dist-es/streamRateLimitHandlingProxy/helpers/headerUtils.js +0 -42
  78. package/dist-es/streamRateLimitHandlingProxy/helpers/isStreamChannelLike.js +0 -19
  79. package/dist-es/streamRateLimitHandlingProxy/helpers/processStreamBudgetHeaders.js +0 -89
  80. package/dist-es/streamRateLimitHandlingProxy/helpers/processStreamRateLimitException.js +0 -59
  81. package/dist-es/streamRateLimitHandlingProxy/helpers/processStreamRateLimitHeaders.js +0 -42
  82. package/dist-es/streamRateLimitHandlingProxy/helpers/rateLimitSnapshot.js +0 -26
  83. package/dist-es/streamRateLimitHandlingProxy/helpers/registerStreamInterceptors.js +0 -60
  84. package/dist-es/streamRateLimitHandlingProxy/helpers/sleep.js +0 -4
  85. package/dist-es/streamRateLimitHandlingProxy/helpers/splitCallArgsAndOptions.js +0 -17
  86. package/dist-es/streamRateLimitHandlingProxy/index.js +0 -2
  87. package/dist-es/streamRateLimitHandlingProxy/types.js +0 -1
  88. package/dist-es/streamRateLimitHandlingProxy/withStreamRateLimitOptions.js +0 -6
  89. package/dist-types/rateLimits/RedisCooldown.d.ts +0 -7
  90. package/dist-types/rateLimits/constants.d.ts +0 -29
  91. package/dist-types/rateLimits/createRateLimitedStreamProxy.d.ts +0 -11
  92. package/dist-types/rateLimits/exception/createRateLimitExceededException.d.ts +0 -12
  93. package/dist-types/rateLimits/exception/processStreamRateLimitException.d.ts +0 -8
  94. package/dist-types/rateLimits/executeStreamRequestWithRateLimitHandling.d.ts +0 -8
  95. package/dist-types/rateLimits/generatedMethodNames.d.ts +0 -11
  96. package/dist-types/rateLimits/helpers/RedisCooldown.d.ts +0 -11
  97. package/dist-types/rateLimits/helpers/createRateLimitExceededException.d.ts +0 -10
  98. package/dist-types/rateLimits/helpers/executeWithRateLimitHandling.d.ts +0 -2
  99. package/dist-types/rateLimits/helpers/headerUtils.d.ts +0 -4
  100. package/dist-types/rateLimits/helpers/isStreamChannelLike.d.ts +0 -6
  101. package/dist-types/rateLimits/helpers/processStreamBudgetHeaders.d.ts +0 -9
  102. package/dist-types/rateLimits/helpers/processStreamRateLimitException.d.ts +0 -3
  103. package/dist-types/rateLimits/helpers/processStreamRateLimitHeaders.d.ts +0 -6
  104. package/dist-types/rateLimits/helpers/rateLimitSnapshot.d.ts +0 -3
  105. package/dist-types/rateLimits/helpers/registerStreamBudgetInterceptors.d.ts +0 -2
  106. package/dist-types/rateLimits/helpers/registerStreamInterceptors.d.ts +0 -2
  107. package/dist-types/rateLimits/helpers/splitCallArgsAndOptions.d.ts +0 -6
  108. package/dist-types/rateLimits/index.d.ts +0 -4
  109. package/dist-types/rateLimits/types.d.ts +0 -68
  110. package/dist-types/rateLimits/withStreamRateLimitOptions.d.ts +0 -6
  111. package/dist-types/streamRateLimitHandlingProxy/constants.d.ts +0 -28
  112. package/dist-types/streamRateLimitHandlingProxy/createRateLimitedStreamProxy.d.ts +0 -11
  113. package/dist-types/streamRateLimitHandlingProxy/generatedMethodNames.d.ts +0 -11
  114. package/dist-types/streamRateLimitHandlingProxy/helpers/RedisCooldown.d.ts +0 -11
  115. package/dist-types/streamRateLimitHandlingProxy/helpers/createRateLimitExceededException.d.ts +0 -10
  116. package/dist-types/streamRateLimitHandlingProxy/helpers/executeWithRateLimitHandling.d.ts +0 -2
  117. package/dist-types/streamRateLimitHandlingProxy/helpers/headerUtils.d.ts +0 -4
  118. package/dist-types/streamRateLimitHandlingProxy/helpers/isStreamChannelLike.d.ts +0 -6
  119. package/dist-types/streamRateLimitHandlingProxy/helpers/processStreamBudgetHeaders.d.ts +0 -9
  120. package/dist-types/streamRateLimitHandlingProxy/helpers/processStreamRateLimitException.d.ts +0 -3
  121. package/dist-types/streamRateLimitHandlingProxy/helpers/processStreamRateLimitHeaders.d.ts +0 -6
  122. package/dist-types/streamRateLimitHandlingProxy/helpers/rateLimitSnapshot.d.ts +0 -3
  123. package/dist-types/streamRateLimitHandlingProxy/helpers/registerStreamInterceptors.d.ts +0 -2
  124. package/dist-types/streamRateLimitHandlingProxy/helpers/sleep.d.ts +0 -2
  125. package/dist-types/streamRateLimitHandlingProxy/helpers/splitCallArgsAndOptions.d.ts +0 -6
  126. package/dist-types/streamRateLimitHandlingProxy/index.d.ts +0 -2
  127. package/dist-types/streamRateLimitHandlingProxy/types.d.ts +0 -68
  128. package/dist-types/streamRateLimitHandlingProxy/withStreamRateLimitOptions.d.ts +0 -6
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isAnonymousUserEmail = exports.generateAnonymousUserEmailOrThrowError = exports.ANONYMOUS_EMAIL_DOMAIN = void 0;
4
- exports.ANONYMOUS_EMAIL_DOMAIN = 'anonymous.wildix.com';
3
+ exports.isAnonymousUserEmail = exports.generateAnonymousUserEmailOrThrowError = void 0;
4
+ const ANONYMOUS_EMAIL_DOMAIN = 'anonymous.wildix.com';
5
5
  const ANONYMOUS_EMAIL_PREFIX = 'anonymous-';
6
6
  const ANONYMOUS_STREAM_ID_REGEXP = /^[0-9A-Za-z]{12}$/;
7
7
  const ANONYMOUS_USER_EMAIL_REGEXP = /^anonymous-[0-9A-Za-z]{12}@anonymous\.wildix\.com$/;
@@ -12,7 +12,7 @@ function generateAnonymousUserEmailOrThrowError(streamId) {
12
12
  if (!ANONYMOUS_STREAM_ID_REGEXP.test(streamId)) {
13
13
  throw new Error('Anonymous stream id must contain only uppercase letters, lowercase letters, digits, and have 12 symbols length');
14
14
  }
15
- return `${ANONYMOUS_EMAIL_PREFIX}${streamId}@${exports.ANONYMOUS_EMAIL_DOMAIN}`;
15
+ return `${ANONYMOUS_EMAIL_PREFIX}${streamId}@${ANONYMOUS_EMAIL_DOMAIN}`;
16
16
  }
17
17
  exports.generateAnonymousUserEmailOrThrowError = generateAnonymousUserEmailOrThrowError;
18
18
  function isAnonymousUserEmail(value) {
@@ -71,6 +71,8 @@ function normalizeStreamMessage(streamMessage, channelId) {
71
71
  smsStatus: streamMessage.sms_status,
72
72
  whatsapp: streamMessage.whatsapp,
73
73
  whatsappStatus: streamMessage.whatsapp_status,
74
+ messenger: streamMessage.messenger,
75
+ messengerStatus: streamMessage.messenger_status,
74
76
  markdown: streamMessage.markdown,
75
77
  silent,
76
78
  event,
@@ -167,6 +169,10 @@ function normalizeStreamChannel(channel) {
167
169
  updatedAt: data.updated_at,
168
170
  whatsapp: data.whatsapp,
169
171
  whatsappStatus: data.whatsapp_status,
172
+ messenger: data.messenger,
173
+ messengerStatus: data.messenger_status,
174
+ messengerPageId: data.messenger_page_id,
175
+ messengerReplyUntil: data.messenger_reply_until,
170
176
  autoRecord: data.is_auto_record,
171
177
  transcriptionLanguage: data.transcription_language,
172
178
  wizyGuestViewOnly: data.is_wizy_guest_view_only,
@@ -1,4 +1,4 @@
1
- export const ANONYMOUS_EMAIL_DOMAIN = 'anonymous.wildix.com';
1
+ const ANONYMOUS_EMAIL_DOMAIN = 'anonymous.wildix.com';
2
2
  const ANONYMOUS_EMAIL_PREFIX = 'anonymous-';
3
3
  const ANONYMOUS_STREAM_ID_REGEXP = /^[0-9A-Za-z]{12}$/;
4
4
  const ANONYMOUS_USER_EMAIL_REGEXP = /^anonymous-[0-9A-Za-z]{12}@anonymous\.wildix\.com$/;
@@ -65,6 +65,8 @@ export function normalizeStreamMessage(streamMessage, channelId) {
65
65
  smsStatus: streamMessage.sms_status,
66
66
  whatsapp: streamMessage.whatsapp,
67
67
  whatsappStatus: streamMessage.whatsapp_status,
68
+ messenger: streamMessage.messenger,
69
+ messengerStatus: streamMessage.messenger_status,
68
70
  markdown: streamMessage.markdown,
69
71
  silent,
70
72
  event,
@@ -159,6 +161,10 @@ export function normalizeStreamChannel(channel) {
159
161
  updatedAt: data.updated_at,
160
162
  whatsapp: data.whatsapp,
161
163
  whatsappStatus: data.whatsapp_status,
164
+ messenger: data.messenger,
165
+ messengerStatus: data.messenger_status,
166
+ messengerPageId: data.messenger_page_id,
167
+ messengerReplyUntil: data.messenger_reply_until,
162
168
  autoRecord: data.is_auto_record,
163
169
  transcriptionLanguage: data.transcription_language,
164
170
  wizyGuestViewOnly: data.is_wizy_guest_view_only,
@@ -1,3 +1,2 @@
1
- export declare const ANONYMOUS_EMAIL_DOMAIN = "anonymous.wildix.com";
2
1
  export declare function generateAnonymousUserEmailOrThrowError(streamId: string): string;
3
2
  export declare function isAnonymousUserEmail(value: string): boolean;
@@ -6,6 +6,31 @@ export declare function localizeStreamUser(streamUser: StreamUserResponse): Loca
6
6
  export declare function normalizeStreamReaction(streamReaction: StreamReactionResponse): Reaction;
7
7
  export declare function normalizeStreamMessage(streamMessage: StreamMessageResponse, channelId: string): Message;
8
8
  export declare function localizeStreamMessage(streamMessage: StreamMessageResponse, channelId: string, userId: string): LocalizedMessage;
9
+ /**
10
+ * The hand written field list a channel reaches a consumer through. A flag not named here is
11
+ * dropped on the way out, which is why `messenger` and the three fields beside it were added
12
+ * (WMS-26043).
13
+ *
14
+ * What publishing that addition unblocks, because the commit that made it framed the consequence
15
+ * as workaround removal and it is not only that. Two live reads are hard dependencies rather than
16
+ * workarounds, and both are dead until this package ships and is pinned:
17
+ *
18
+ * - `rnc-api src/features/webhooks/handlers/processStreamEventForWebhook.ts` computes `isKiteEvent`
19
+ * from `webhookChannel?.messenger` off a channel it normalized through this package, and the
20
+ * event reaches the kite queue only when that is true.
21
+ * - `xbees-kite src/handlers/sqs/handleSqsEvent.ts` then dispatches on
22
+ * `payload.data.channel.messenger`.
23
+ *
24
+ * So with the published package an agent's reply in a Messenger channel is filtered out at rnc-api
25
+ * and never reaches kite: the whole slice 2 reply path is inert, not merely paying for a
26
+ * workaround.
27
+ *
28
+ * One claim in that commit message is stale and is corrected here rather than in history: kite's
29
+ * `handleMessengerInboundEvent` no longer guards its channel update with `if (!channel.messenger)`.
30
+ * That guard existed at 6f18e46; 3f347ef and 8dc6df2 restructured the handler and the update is now
31
+ * unconditional and needed for `messengerPageId`, `messengerReplyUntil` and the `messengerStatus`
32
+ * unset, so publishing this does not remove it.
33
+ */
9
34
  export declare function normalizeStreamChannel(channel: StreamChannel | StreamChannelResponse): Channel;
10
35
  export declare function normalizeStreamMember(member: StreamChannelMemberResponse): ChannelMember;
11
36
  export declare function localizeStreamMember(member: Partial<StreamChannelMemberResponse>): LocalizedChannelMember;
@@ -1,4 +1,4 @@
1
- import type { ChannelAccess, ChannelContext, ChannelWhatsAppStatus, Element, MessageAttachment, MessageForward, MessageGiphy, MessageQuote, MessageSmsStatus, MessageWhatsAppStatus, User as NormalizedUser } from '@wildix/xbees-conversations-client';
1
+ import type { ChannelAccess, ChannelContext, ChannelMessengerStatus, ChannelWhatsAppStatus, Element, MessageAttachment, MessageForward, MessageGiphy, MessageMessengerStatus, MessageQuote, MessageSmsStatus, MessageWhatsAppStatus, User as NormalizedUser } from '@wildix/xbees-conversations-client';
2
2
  import type { Channel, ChannelAPIResponse, ChannelData, ChannelFilters, ChannelMemberResponse, ChannelMembership, ChannelResponse, ChannelSort, ChannelState, Event, ExtendableGenerics, GetReactionsAPIResponse, GetRepliesAPIResponse, LiteralStringForUnion, Message, MessageResponse, OwnUserResponse, PartialMessageUpdate, PartialUpdateChannel, Reaction, ReactionResponse, SearchAPIResponse, SyncResponse, UpdatedMessage, UR, User, UserResponse } from 'stream-chat';
3
3
  export interface StreamChannelFields extends UR {
4
4
  subject?: string;
@@ -23,6 +23,10 @@ export interface StreamChannelFields extends UR {
23
23
  mms?: boolean;
24
24
  whatsapp?: boolean;
25
25
  whatsapp_status?: ChannelWhatsAppStatus | string;
26
+ messenger?: boolean;
27
+ messenger_status?: ChannelMessengerStatus | string;
28
+ messenger_page_id?: string;
29
+ messenger_reply_until?: number;
26
30
  broadcast?: boolean;
27
31
  is_broadcast?: boolean;
28
32
  external?: boolean;
@@ -55,6 +59,8 @@ export interface StreamMessageFields extends UR {
55
59
  sms_status?: MessageSmsStatus | string;
56
60
  whatsapp?: boolean;
57
61
  whatsapp_status?: MessageWhatsAppStatus | string;
62
+ messenger?: boolean;
63
+ messenger_status?: MessageMessengerStatus | string;
58
64
  markdown?: boolean;
59
65
  created_at: string;
60
66
  updated_at: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wildix/xbees-conversations-utils",
3
- "version": "4.0.2",
3
+ "version": "4.1.0",
4
4
  "description": "",
5
5
  "main": "./dist-cjs/index.js",
6
6
  "module": "./dist-es/index.js",
@@ -35,7 +35,7 @@
35
35
  "downlevel-dts": "0.10.1",
36
36
  "rimraf": "^3.0.0",
37
37
  "typescript": "~5.2.2",
38
- "@wildix/xbees-conversations-client": "^4.0.1"
38
+ "@wildix/xbees-conversations-client": "^4.0.5"
39
39
  },
40
40
  "typesVersions": {
41
41
  "<4.0": {
@@ -48,6 +48,6 @@
48
48
  "dist-*/**"
49
49
  ],
50
50
  "peerDependencies": {
51
- "@wildix/xbees-conversations-client": "^4.0.1"
51
+ "@wildix/xbees-conversations-client": "^4.0.5"
52
52
  }
53
53
  }
@@ -1,66 +0,0 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', {value: true});
3
- exports.RedisCooldown = void 0;
4
- const constants_1 = require('./constants');
5
-
6
- class RedisCooldown {
7
- static async getRemainingMs(cooldownKey, context) {
8
- const {redis, logger} = context;
9
-
10
- try {
11
- const ttlMs = await redis.pttl(`${constants_1.STREAM_RATE_LIMIT_COOLDOWN_KEY_PREFIX}${cooldownKey}`);
12
-
13
- if (ttlMs > 0) {
14
- return ttlMs;
15
- }
16
- } catch (error) {
17
- logger.warn('Failed to read stream rate-limit cooldown from Redis', {
18
- cooldownKey,
19
- error,
20
- });
21
- }
22
-
23
- return 0;
24
- }
25
-
26
- static async setRemainingMs(cooldownKey, cooldownMs, context) {
27
- if (cooldownMs <= 0) {
28
- return;
29
- }
30
-
31
- const {redis, logger} = context;
32
- const redisKey = `${constants_1.STREAM_RATE_LIMIT_COOLDOWN_KEY_PREFIX}${cooldownKey}`;
33
-
34
- try {
35
- await redis.eval(
36
- `
37
- local key = KEYS[1]
38
- local new_ttl = tonumber(ARGV[1])
39
- local current_ttl = redis.call('PTTL', key)
40
-
41
- if current_ttl == -2 then
42
- redis.call('SET', key, '1', 'PX', new_ttl)
43
- return 1
44
- end
45
-
46
- if current_ttl == -1 or current_ttl < new_ttl then
47
- redis.call('PEXPIRE', key, new_ttl)
48
- return 2
49
- end
50
-
51
- return 0
52
- `,
53
- 1,
54
- redisKey,
55
- cooldownMs.toString(),
56
- );
57
- } catch (error) {
58
- logger.warn('Failed to write stream rate-limit cooldown to Redis', {
59
- cooldownKey,
60
- cooldownMs,
61
- error,
62
- });
63
- }
64
- }
65
- }
66
- exports.RedisCooldown = RedisCooldown;
@@ -1,43 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_OPTIONS = exports.SOFT_THROTTLE_DELAY_HIGH_MS = exports.SOFT_THROTTLE_DELAY_MEDIUM_MS = exports.SOFT_THROTTLE_DELAY_LOW_MS = exports.SOFT_THROTTLE_USAGE_HIGH = exports.SOFT_THROTTLE_USAGE_MEDIUM = exports.SOFT_THROTTLE_USAGE_LOW = exports.BUDGET_COOLDOWN_SLEEP_CHUNK_MS = exports.BUDGET_MINIMAL_DELAY_MAX_MS = exports.BUDGET_MINIMAL_DELAY_MIN_MS = exports.BUDGET_RELAXED_DELAY_MAX_MS = exports.BUDGET_RELAXED_DELAY_MIN_MS = exports.BUDGET_RELAXED_USAGE_THRESHOLD = exports.BUDGET_CLEAR_USAGE_THRESHOLD = exports.BUDGET_DELAY_MAX_MS = exports.BUDGET_DELAY_MIN_MS = exports.BUDGET_THRESHOLD = exports.STREAM_BUDGET_COOLDOWN_KEY = exports.STREAM_RATE_LIMIT_METADATA_KEY_SUFFIX = exports.STREAM_RATE_LIMIT_SOFT_COOLDOWN_KEY = exports.STREAM_RATE_LIMIT_OPTIONS_MARKER = exports.STREAM_BUDGET_COOLDOWN_KEY_PREFIX = exports.STREAM_RATE_LIMIT_COOLDOWN_KEY_PREFIX = exports.RETRY_AFTER_BUFFER_MS = exports.DEFAULT_JITTER_MS = exports.DEFAULT_RETRY_AFTER_MS = exports.DEFAULT_MAX_DELAY_MS = exports.STREAM_SYNC_METHOD_NAMES = exports.STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES = exports.STREAM_METHOD_NAMES = exports.STREAM_CHANNEL_RESULT_METHOD_NAMES = exports.CHANNEL_SYNC_PROXY_RESULT_METHOD_NAMES = exports.CHANNEL_SYNC_METHOD_NAMES = exports.CHANNEL_METHOD_NAMES = void 0;
4
- var generatedMethodNames_1 = require("./generatedMethodNames");
5
- Object.defineProperty(exports, "CHANNEL_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.CHANNEL_METHOD_NAMES; } });
6
- Object.defineProperty(exports, "CHANNEL_SYNC_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.CHANNEL_SYNC_METHOD_NAMES; } });
7
- Object.defineProperty(exports, "CHANNEL_SYNC_PROXY_RESULT_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.CHANNEL_SYNC_PROXY_RESULT_METHOD_NAMES; } });
8
- Object.defineProperty(exports, "STREAM_CHANNEL_RESULT_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.STREAM_CHANNEL_RESULT_METHOD_NAMES; } });
9
- Object.defineProperty(exports, "STREAM_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.STREAM_METHOD_NAMES; } });
10
- Object.defineProperty(exports, "STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES; } });
11
- Object.defineProperty(exports, "STREAM_SYNC_METHOD_NAMES", { enumerable: true, get: function () { return generatedMethodNames_1.STREAM_SYNC_METHOD_NAMES; } });
12
- exports.DEFAULT_MAX_DELAY_MS = 5000;
13
- exports.DEFAULT_RETRY_AFTER_MS = 10000;
14
- exports.DEFAULT_JITTER_MS = 150;
15
- exports.RETRY_AFTER_BUFFER_MS = 1000;
16
- exports.STREAM_RATE_LIMIT_COOLDOWN_KEY_PREFIX = 'stream-rate-limit-cooldown:';
17
- exports.STREAM_BUDGET_COOLDOWN_KEY_PREFIX = 'stream-budget-cooldown:';
18
- exports.STREAM_RATE_LIMIT_OPTIONS_MARKER = '__xbsRateLimitOptions';
19
- exports.STREAM_RATE_LIMIT_SOFT_COOLDOWN_KEY = 'stream-rate-limit-soft-global';
20
- exports.STREAM_RATE_LIMIT_METADATA_KEY_SUFFIX = ':meta';
21
- exports.STREAM_BUDGET_COOLDOWN_KEY = 'stream-budget-global';
22
- exports.BUDGET_THRESHOLD = 0.8;
23
- exports.BUDGET_DELAY_MIN_MS = 30000;
24
- exports.BUDGET_DELAY_MAX_MS = 60000;
25
- exports.BUDGET_CLEAR_USAGE_THRESHOLD = 0.6;
26
- exports.BUDGET_RELAXED_USAGE_THRESHOLD = 0.7;
27
- exports.BUDGET_RELAXED_DELAY_MIN_MS = 5000;
28
- exports.BUDGET_RELAXED_DELAY_MAX_MS = 10000;
29
- exports.BUDGET_MINIMAL_DELAY_MIN_MS = 1000;
30
- exports.BUDGET_MINIMAL_DELAY_MAX_MS = 2000;
31
- exports.BUDGET_COOLDOWN_SLEEP_CHUNK_MS = 3000;
32
- exports.SOFT_THROTTLE_USAGE_LOW = 0.7;
33
- exports.SOFT_THROTTLE_USAGE_MEDIUM = 0.85;
34
- exports.SOFT_THROTTLE_USAGE_HIGH = 0.95;
35
- exports.SOFT_THROTTLE_DELAY_LOW_MS = 500;
36
- exports.SOFT_THROTTLE_DELAY_MEDIUM_MS = 1500;
37
- exports.SOFT_THROTTLE_DELAY_HIGH_MS = 3000;
38
- exports.DEFAULT_OPTIONS = {
39
- maxAttempts: 3,
40
- enableCooldown: true,
41
- maxDelayMs: 5000,
42
- maxRetryableDelayMs: 10000,
43
- };
@@ -1,92 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createRateLimitedStreamProxy = void 0;
4
- const constants_1 = require("./constants");
5
- const executeWithRateLimitHandling_1 = require("./helpers/executeWithRateLimitHandling");
6
- const isStreamChannelLike_1 = require("./helpers/isStreamChannelLike");
7
- const registerStreamInterceptors_1 = require("./helpers/registerStreamInterceptors");
8
- const splitCallArgsAndOptions_1 = require("./helpers/splitCallArgsAndOptions");
9
- const STREAM_SYNC_METHODS = new Set(constants_1.STREAM_SYNC_METHOD_NAMES);
10
- const STREAM_CHANNEL_RESULT_METHODS = new Set(constants_1.STREAM_CHANNEL_RESULT_METHOD_NAMES);
11
- const STREAM_SYNC_CHANNEL_RESULT_METHODS = new Set(constants_1.STREAM_SYNC_CHANNEL_RESULT_METHOD_NAMES);
12
- const CHANNEL_SYNC_METHODS = new Set(constants_1.CHANNEL_SYNC_METHOD_NAMES);
13
- const CHANNEL_SYNC_PROXY_RESULT_METHODS = new Set(constants_1.CHANNEL_SYNC_PROXY_RESULT_METHOD_NAMES);
14
- function wrapKnownChannelResult(result, dependencies) {
15
- if (Array.isArray(result)) {
16
- return result.map((item) => wrapKnownChannelResult(item, dependencies));
17
- }
18
- if (typeof result !== 'object' || result === null) {
19
- return result;
20
- }
21
- return wrapTarget(result, dependencies);
22
- }
23
- function normalizeStreamCallResult(result, dependencies, wrapAsChannelResult = false) {
24
- if (wrapAsChannelResult) {
25
- return wrapKnownChannelResult(result, dependencies);
26
- }
27
- if (Array.isArray(result)) {
28
- return result.map((item) => normalizeStreamCallResult(item, dependencies));
29
- }
30
- if (!(0, isStreamChannelLike_1.isStreamChannelLike)(result)) {
31
- return result;
32
- }
33
- return wrapTarget(result, dependencies);
34
- }
35
- function createRateLimitedMethodWrapper(target, value, operation, dependencies, wrapAsChannelResult) {
36
- return async (...args) => {
37
- const { callArgs, callOptions } = (0, splitCallArgsAndOptions_1.splitCallArgsAndOptions)(args);
38
- const result = await (0, executeWithRateLimitHandling_1.executeWithRateLimitHandling)(() => Reflect.apply(value, target, callArgs), operation, dependencies.context, {
39
- ...constants_1.DEFAULT_OPTIONS,
40
- ...callOptions,
41
- });
42
- return normalizeStreamCallResult(result, dependencies, wrapAsChannelResult);
43
- };
44
- }
45
- function wrapTarget(target, dependencies) {
46
- const cachedObject = dependencies.cache.get(target);
47
- if (cachedObject) {
48
- return cachedObject;
49
- }
50
- const proxy = new Proxy(target, {
51
- get: (originalTarget, property, receiver) => {
52
- const value = Reflect.get(originalTarget, property, receiver);
53
- if (typeof property !== 'string' || typeof value !== 'function') {
54
- return value;
55
- }
56
- if (STREAM_SYNC_CHANNEL_RESULT_METHODS.has(property)) {
57
- return (...args) => {
58
- const { callArgs } = (0, splitCallArgsAndOptions_1.splitCallArgsAndOptions)(args);
59
- const result = Reflect.apply(value, originalTarget, callArgs);
60
- return normalizeStreamCallResult(result, dependencies, true);
61
- };
62
- }
63
- if (CHANNEL_SYNC_PROXY_RESULT_METHODS.has(property)) {
64
- return (...args) => {
65
- const { callArgs } = (0, splitCallArgsAndOptions_1.splitCallArgsAndOptions)(args);
66
- const result = Reflect.apply(value, originalTarget, callArgs);
67
- if (typeof result === 'object' && result !== null) {
68
- return wrapTarget(result, dependencies);
69
- }
70
- return result;
71
- };
72
- }
73
- if (STREAM_SYNC_METHODS.has(property) || CHANNEL_SYNC_METHODS.has(property)) {
74
- return (...args) => {
75
- const { callArgs } = (0, splitCallArgsAndOptions_1.splitCallArgsAndOptions)(args);
76
- return Reflect.apply(value, originalTarget, callArgs);
77
- };
78
- }
79
- return createRateLimitedMethodWrapper(originalTarget, value, property, dependencies, STREAM_CHANNEL_RESULT_METHODS.has(property));
80
- },
81
- });
82
- dependencies.cache.set(target, proxy);
83
- return proxy;
84
- }
85
- function createRateLimitedStreamProxy(stream, context) {
86
- (0, registerStreamInterceptors_1.registerStreamInterceptors)(stream, context);
87
- return wrapTarget(stream, {
88
- context,
89
- cache: new WeakMap(),
90
- });
91
- }
92
- exports.createRateLimitedStreamProxy = createRateLimitedStreamProxy;
@@ -1,21 +0,0 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', {value: true});
3
- exports.createRateLimitExceededException = void 0;
4
- const xbees_conversations_client_1 = require('@wildix/xbees-conversations-client');
5
- const constants_1 = require('../constants');
6
-
7
- function createRateLimitExceededException(options = {}) {
8
- const {rateLimit, message, operation, retryAfterMs = constants_1.DEFAULT_RETRY_AFTER_MS} = options;
9
- const defaultMessage = operation ? `Rate limit exceeded for ${operation}` : 'Rate limit exceeded';
10
-
11
- return new xbees_conversations_client_1.RateLimitExceededException({
12
- $metadata: {},
13
- message: message || defaultMessage,
14
- rateLimitRemaining: rateLimit?.remaining || 0,
15
- retryAfter: rateLimit?.reset ? rateLimit.reset - Date.now() : retryAfterMs,
16
- rateLimit: rateLimit?.limit?.toString() || 'unknown',
17
- rateLimitReset: rateLimit?.reset || Date.now() + retryAfterMs,
18
- });
19
- }
20
-
21
- exports.createRateLimitExceededException = createRateLimitExceededException;
@@ -1,47 +0,0 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', {value: true});
3
- exports.processStreamRateLimitException = void 0;
4
- const createRateLimitExceededException_1 = require('./createRateLimitExceededException');
5
-
6
- function isStreamException(error) {
7
- return (
8
- typeof error === 'object' &&
9
- error !== null &&
10
- 'metadata' in error &&
11
- typeof error.metadata === 'object' &&
12
- error.metadata !== null &&
13
- 'responseCode' in error.metadata
14
- );
15
- }
16
-
17
- function isStreamAPIException(error) {
18
- return typeof error === 'object' && !!error.code;
19
- }
20
-
21
- function processStreamRateLimitException(error, logger) {
22
- if (isStreamException(error) && error.metadata?.responseCode === 429) {
23
- const rateLimit = error.metadata?.rateLimit;
24
- logger.warn('Stream rate limit exceeded [StreamException]', {rateLimit});
25
-
26
- return (0, createRateLimitExceededException_1.createRateLimitExceededException)({
27
- rateLimit,
28
- message: error.message || 'Rate limit exceeded',
29
- });
30
- }
31
-
32
- if (isStreamAPIException(error) && (error.code === 429 || error.StatusCode === 429)) {
33
- logger.warn('Stream rate limit exceeded [StreamAPIException]', {code: error.code, StatusCode: error.StatusCode});
34
-
35
- return (0, createRateLimitExceededException_1.createRateLimitExceededException)({
36
- message: error.message || 'Rate limit exceeded',
37
- });
38
- }
39
-
40
- if (typeof error === 'object' && error !== null && 'status' in error && error.status === 429) {
41
- logger.warn('Stream rate limit exceeded [error.status === 429]');
42
-
43
- return (0, createRateLimitExceededException_1.createRateLimitExceededException)({message: 'Rate limit exceeded'});
44
- }
45
- }
46
-
47
- exports.processStreamRateLimitException = processStreamRateLimitException;
@@ -1,94 +0,0 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', {value: true});
3
- exports.executeStreamRequestWithRateLimitHandling = void 0;
4
- const promises_1 = require('node:timers/promises');
5
- const constants_1 = require('./constants');
6
- const createRateLimitExceededException_1 = require('./exception/createRateLimitExceededException');
7
- const processStreamRateLimitException_1 = require('./exception/processStreamRateLimitException');
8
- const RedisCooldown_1 = require('./RedisCooldown');
9
-
10
- function calculateRateLimitDelayMs(error, maxDelayMs) {
11
- const retryAfterMs =
12
- typeof error.retryAfter === 'number'
13
- ? error.retryAfter + constants_1.RETRY_AFTER_BUFFER_MS
14
- : constants_1.DEFAULT_RETRY_AFTER_MS;
15
-
16
- if (retryAfterMs > 0) {
17
- const jitterMs = Math.floor(Math.random() * constants_1.DEFAULT_JITTER_MS);
18
-
19
- return Math.min(maxDelayMs, retryAfterMs + jitterMs);
20
- }
21
-
22
- return Math.min(maxDelayMs, constants_1.DEFAULT_FIXED_RATE_LIMIT_DELAY_MS);
23
- }
24
-
25
- async function executeStreamRequestWithRateLimitHandling(execute, operation, context, options = {}) {
26
- const {logger, redis} = context;
27
- const {enableCooldown, maxAttempts, maxDelayMs, maxRetryableDelayMs} = {
28
- ...constants_1.DEFAULT_OPTS_1_ATTEMPT_NO_COOLDOWN,
29
- ...options,
30
- };
31
- let attempt = 1;
32
-
33
- if (enableCooldown) {
34
- const cooldownMs = await RedisCooldown_1.RedisCooldown.getRemainingMs(operation, {redis, logger});
35
-
36
- if (cooldownMs > 0) {
37
- logger.warn('Skipping stream request due to active rate-limit cooldown', {
38
- operation,
39
- cooldown: cooldownMs,
40
- });
41
- throw (0, createRateLimitExceededException_1.createRateLimitExceededException)({
42
- operation,
43
- retryAfterMs: cooldownMs,
44
- });
45
- }
46
- }
47
-
48
- for (;;) {
49
- try {
50
- return await execute();
51
- } catch (error) {
52
- const rateLimitError = (0, processStreamRateLimitException_1.processStreamRateLimitException)(error, logger);
53
-
54
- if (!rateLimitError) {
55
- throw error;
56
- }
57
-
58
- const retryAfterMs = calculateRateLimitDelayMs(rateLimitError, maxDelayMs);
59
-
60
- if (enableCooldown) {
61
- await RedisCooldown_1.RedisCooldown.setRemainingMs(operation, retryAfterMs, {redis, logger});
62
- }
63
-
64
- if (attempt < maxAttempts && retryAfterMs <= maxRetryableDelayMs) {
65
- logger.warn('Retrying stream request after rate limit', {
66
- operation,
67
- attempt,
68
- maxAttempts,
69
- retryAfterMs,
70
- rateLimit: rateLimitError.rateLimit,
71
- rateLimitRemaining: rateLimitError.rateLimitRemaining,
72
- rateLimitReset: rateLimitError.rateLimitReset,
73
- });
74
- await (0, promises_1.setTimeout)(retryAfterMs);
75
- attempt++;
76
- continue;
77
- }
78
-
79
- logger.warn('Propagating stream rate limit w/o retry', {
80
- operation,
81
- attempt,
82
- maxAttempts,
83
- retryAfterMs,
84
- maxRetryableDelayMs,
85
- rateLimit: rateLimitError.rateLimit,
86
- rateLimitRemaining: rateLimitError.rateLimitRemaining,
87
- rateLimitReset: rateLimitError.rateLimitReset,
88
- });
89
- throw rateLimitError;
90
- }
91
- }
92
- }
93
-
94
- exports.executeStreamRequestWithRateLimitHandling = executeStreamRequestWithRateLimitHandling;