@wildix/xbees-conversations-utils 1.3.1 → 2.0.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/README.md +0 -4
- package/dist-cjs/normalization.js +20 -10
- package/dist-es/normalization.js +21 -11
- package/dist-types/normalization.d.ts +3 -3
- package/dist-types/stream.d.ts +3 -3
- package/dist-types/types.d.ts +1 -1
- package/package.json +7 -9
- package/dist-cjs/rateLimits/RedisCooldown.js +0 -66
- package/dist-cjs/rateLimits/constants.js +0 -43
- package/dist-cjs/rateLimits/createRateLimitedStreamProxy.js +0 -92
- package/dist-cjs/rateLimits/exception/createRateLimitExceededException.js +0 -21
- package/dist-cjs/rateLimits/exception/processStreamRateLimitException.js +0 -47
- package/dist-cjs/rateLimits/executeStreamRequestWithRateLimitHandling.js +0 -94
- package/dist-cjs/rateLimits/generatedMethodNames.js +0 -320
- package/dist-cjs/rateLimits/helpers/RedisCooldown.js +0 -174
- package/dist-cjs/rateLimits/helpers/createRateLimitExceededException.js +0 -32
- package/dist-cjs/rateLimits/helpers/executeWithRateLimitHandling.js +0 -144
- package/dist-cjs/rateLimits/helpers/headerUtils.js +0 -40
- package/dist-cjs/rateLimits/helpers/isStreamChannelLike.js +0 -23
- package/dist-cjs/rateLimits/helpers/processStreamBudgetHeaders.js +0 -93
- package/dist-cjs/rateLimits/helpers/processStreamRateLimitException.js +0 -63
- package/dist-cjs/rateLimits/helpers/processStreamRateLimitHeaders.js +0 -50
- package/dist-cjs/rateLimits/helpers/rateLimitSnapshot.js +0 -31
- package/dist-cjs/rateLimits/helpers/registerStreamBudgetInterceptors.js +0 -48
- package/dist-cjs/rateLimits/helpers/registerStreamInterceptors.js +0 -58
- package/dist-cjs/rateLimits/helpers/splitCallArgsAndOptions.js +0 -21
- package/dist-cjs/rateLimits/index.js +0 -7
- package/dist-cjs/rateLimits/types.js +0 -3
- package/dist-cjs/rateLimits/withStreamRateLimitOptions.js +0 -10
- package/dist-cjs/streamRateLimitHandlingProxy/constants.js +0 -42
- package/dist-cjs/streamRateLimitHandlingProxy/createRateLimitedStreamProxy.js +0 -92
- package/dist-cjs/streamRateLimitHandlingProxy/generatedMethodNames.js +0 -320
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/RedisCooldown.js +0 -174
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/createRateLimitExceededException.js +0 -29
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/executeWithRateLimitHandling.js +0 -153
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/headerUtils.js +0 -48
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/isStreamChannelLike.js +0 -23
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/processStreamBudgetHeaders.js +0 -93
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/processStreamRateLimitException.js +0 -63
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/processStreamRateLimitHeaders.js +0 -46
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/rateLimitSnapshot.js +0 -31
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/registerStreamInterceptors.js +0 -64
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/sleep.js +0 -6
- package/dist-cjs/streamRateLimitHandlingProxy/helpers/splitCallArgsAndOptions.js +0 -21
- package/dist-cjs/streamRateLimitHandlingProxy/index.js +0 -5
- package/dist-cjs/streamRateLimitHandlingProxy/types.js +0 -3
- package/dist-cjs/streamRateLimitHandlingProxy/withStreamRateLimitOptions.js +0 -10
- package/dist-es/rateLimits/RedisCooldown.js +0 -62
- package/dist-es/rateLimits/constants.js +0 -33
- package/dist-es/rateLimits/createRateLimitedStreamProxy.js +0 -88
- package/dist-es/rateLimits/exception/createRateLimitExceededException.js +0 -17
- package/dist-es/rateLimits/exception/processStreamRateLimitException.js +0 -37
- package/dist-es/rateLimits/executeStreamRequestWithRateLimitHandling.js +0 -93
- package/dist-es/rateLimits/generatedMethodNames.js +0 -317
- package/dist-es/rateLimits/helpers/RedisCooldown.js +0 -170
- package/dist-es/rateLimits/helpers/createRateLimitExceededException.js +0 -28
- package/dist-es/rateLimits/helpers/executeWithRateLimitHandling.js +0 -140
- package/dist-es/rateLimits/helpers/headerUtils.js +0 -34
- package/dist-es/rateLimits/helpers/isStreamChannelLike.js +0 -19
- package/dist-es/rateLimits/helpers/processStreamBudgetHeaders.js +0 -89
- package/dist-es/rateLimits/helpers/processStreamRateLimitException.js +0 -59
- package/dist-es/rateLimits/helpers/processStreamRateLimitHeaders.js +0 -46
- package/dist-es/rateLimits/helpers/rateLimitSnapshot.js +0 -26
- package/dist-es/rateLimits/helpers/registerStreamBudgetInterceptors.js +0 -44
- package/dist-es/rateLimits/helpers/registerStreamInterceptors.js +0 -54
- package/dist-es/rateLimits/helpers/splitCallArgsAndOptions.js +0 -17
- package/dist-es/rateLimits/index.js +0 -4
- package/dist-es/rateLimits/types.js +0 -1
- package/dist-es/rateLimits/withStreamRateLimitOptions.js +0 -6
- package/dist-es/streamRateLimitHandlingProxy/constants.js +0 -32
- package/dist-es/streamRateLimitHandlingProxy/createRateLimitedStreamProxy.js +0 -88
- package/dist-es/streamRateLimitHandlingProxy/generatedMethodNames.js +0 -317
- package/dist-es/streamRateLimitHandlingProxy/helpers/RedisCooldown.js +0 -170
- package/dist-es/streamRateLimitHandlingProxy/helpers/createRateLimitExceededException.js +0 -25
- package/dist-es/streamRateLimitHandlingProxy/helpers/executeWithRateLimitHandling.js +0 -148
- package/dist-es/streamRateLimitHandlingProxy/helpers/headerUtils.js +0 -42
- package/dist-es/streamRateLimitHandlingProxy/helpers/isStreamChannelLike.js +0 -19
- package/dist-es/streamRateLimitHandlingProxy/helpers/processStreamBudgetHeaders.js +0 -89
- package/dist-es/streamRateLimitHandlingProxy/helpers/processStreamRateLimitException.js +0 -59
- package/dist-es/streamRateLimitHandlingProxy/helpers/processStreamRateLimitHeaders.js +0 -42
- package/dist-es/streamRateLimitHandlingProxy/helpers/rateLimitSnapshot.js +0 -26
- package/dist-es/streamRateLimitHandlingProxy/helpers/registerStreamInterceptors.js +0 -60
- package/dist-es/streamRateLimitHandlingProxy/helpers/sleep.js +0 -4
- package/dist-es/streamRateLimitHandlingProxy/helpers/splitCallArgsAndOptions.js +0 -17
- package/dist-es/streamRateLimitHandlingProxy/index.js +0 -2
- package/dist-es/streamRateLimitHandlingProxy/types.js +0 -1
- package/dist-es/streamRateLimitHandlingProxy/withStreamRateLimitOptions.js +0 -6
- package/dist-types/rateLimits/RedisCooldown.d.ts +0 -7
- package/dist-types/rateLimits/constants.d.ts +0 -29
- package/dist-types/rateLimits/createRateLimitedStreamProxy.d.ts +0 -11
- package/dist-types/rateLimits/exception/createRateLimitExceededException.d.ts +0 -12
- package/dist-types/rateLimits/exception/processStreamRateLimitException.d.ts +0 -8
- package/dist-types/rateLimits/executeStreamRequestWithRateLimitHandling.d.ts +0 -8
- package/dist-types/rateLimits/generatedMethodNames.d.ts +0 -11
- package/dist-types/rateLimits/helpers/RedisCooldown.d.ts +0 -11
- package/dist-types/rateLimits/helpers/createRateLimitExceededException.d.ts +0 -10
- package/dist-types/rateLimits/helpers/executeWithRateLimitHandling.d.ts +0 -2
- package/dist-types/rateLimits/helpers/headerUtils.d.ts +0 -4
- package/dist-types/rateLimits/helpers/isStreamChannelLike.d.ts +0 -6
- package/dist-types/rateLimits/helpers/processStreamBudgetHeaders.d.ts +0 -9
- package/dist-types/rateLimits/helpers/processStreamRateLimitException.d.ts +0 -3
- package/dist-types/rateLimits/helpers/processStreamRateLimitHeaders.d.ts +0 -6
- package/dist-types/rateLimits/helpers/rateLimitSnapshot.d.ts +0 -3
- package/dist-types/rateLimits/helpers/registerStreamBudgetInterceptors.d.ts +0 -2
- package/dist-types/rateLimits/helpers/registerStreamInterceptors.d.ts +0 -2
- package/dist-types/rateLimits/helpers/splitCallArgsAndOptions.d.ts +0 -6
- package/dist-types/rateLimits/index.d.ts +0 -4
- package/dist-types/rateLimits/types.d.ts +0 -68
- package/dist-types/rateLimits/withStreamRateLimitOptions.d.ts +0 -6
- package/dist-types/streamRateLimitHandlingProxy/constants.d.ts +0 -28
- package/dist-types/streamRateLimitHandlingProxy/createRateLimitedStreamProxy.d.ts +0 -11
- package/dist-types/streamRateLimitHandlingProxy/generatedMethodNames.d.ts +0 -11
- package/dist-types/streamRateLimitHandlingProxy/helpers/RedisCooldown.d.ts +0 -11
- package/dist-types/streamRateLimitHandlingProxy/helpers/createRateLimitExceededException.d.ts +0 -10
- package/dist-types/streamRateLimitHandlingProxy/helpers/executeWithRateLimitHandling.d.ts +0 -2
- package/dist-types/streamRateLimitHandlingProxy/helpers/headerUtils.d.ts +0 -4
- package/dist-types/streamRateLimitHandlingProxy/helpers/isStreamChannelLike.d.ts +0 -6
- package/dist-types/streamRateLimitHandlingProxy/helpers/processStreamBudgetHeaders.d.ts +0 -9
- package/dist-types/streamRateLimitHandlingProxy/helpers/processStreamRateLimitException.d.ts +0 -3
- package/dist-types/streamRateLimitHandlingProxy/helpers/processStreamRateLimitHeaders.d.ts +0 -6
- package/dist-types/streamRateLimitHandlingProxy/helpers/rateLimitSnapshot.d.ts +0 -3
- package/dist-types/streamRateLimitHandlingProxy/helpers/registerStreamInterceptors.d.ts +0 -2
- package/dist-types/streamRateLimitHandlingProxy/helpers/sleep.d.ts +0 -2
- package/dist-types/streamRateLimitHandlingProxy/helpers/splitCallArgsAndOptions.d.ts +0 -6
- package/dist-types/streamRateLimitHandlingProxy/index.d.ts +0 -2
- package/dist-types/streamRateLimitHandlingProxy/types.d.ts +0 -68
- package/dist-types/streamRateLimitHandlingProxy/withStreamRateLimitOptions.d.ts +0 -6
package/README.md
CHANGED
|
@@ -12,7 +12,3 @@ Utility helpers for working with x-bees conversations data.
|
|
|
12
12
|
Shared Stream Chat types used by normalization helpers and downstream consumers.
|
|
13
13
|
- `types`
|
|
14
14
|
Localized conversation and presence-related TypeScript types.
|
|
15
|
-
|
|
16
|
-
## Notes
|
|
17
|
-
|
|
18
|
-
The Stream rate-limit handling proxy was moved into the dedicated `@wildix/stream-proxy` package.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.normalizeStreamChannelMembersUserPresencesToMap = exports.normalizeStreamChannelsUserPresencesToMap = exports.normalizeStreamChannelsUsers = exports.normalizeStreamChannelsUsersToMap = exports.normalizeStreamChannelUsersToMap = exports.normalizeStreamChannelUsers = exports.normalizeStreamChannelOwnReadIndicators = exports.normalizeStreamChannelReadIndicators = exports.normalizeStreamChannelReadIndicator = exports.localizeStreamChannel = exports.localizeStreamChannelsMembersToMapByChannelId = exports.localizeStreamChannelMembers = exports.localizeStreamMember = exports.normalizeStreamMember = exports.normalizeStreamChannel = exports.localizeStreamMessage = exports.normalizeStreamMessage = exports.normalizeStreamReaction = exports.localizeStreamUser = exports.normalizeStreamUser = void 0;
|
|
4
|
-
const types_1 = require("./types");
|
|
5
4
|
const xbees_conversations_client_1 = require("@wildix/xbees-conversations-client");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
6
|
function normalizeStreamUser(streamUser) {
|
|
7
7
|
return {
|
|
8
8
|
id: streamUser.id,
|
|
@@ -60,7 +60,9 @@ function normalizeStreamMessage(streamMessage, channelId) {
|
|
|
60
60
|
latestReactions,
|
|
61
61
|
reactionCounts: reaction_counts || {},
|
|
62
62
|
createdAt: streamMessage.created_at,
|
|
63
|
-
updatedAt: streamMessage.updated_at !== streamMessage.created_at && streamMessage.updated_at
|
|
63
|
+
updatedAt: streamMessage.updated_at !== streamMessage.created_at && streamMessage.updated_at
|
|
64
|
+
? streamMessage.updated_at
|
|
65
|
+
: undefined,
|
|
64
66
|
user,
|
|
65
67
|
quote,
|
|
66
68
|
forward,
|
|
@@ -80,9 +82,13 @@ function localizeStreamMessage(streamMessage, channelId, userId) {
|
|
|
80
82
|
const normalizedMessage = normalizeStreamMessage(streamMessage, channelId);
|
|
81
83
|
const createdAt = new Date(normalizedMessage.createdAt);
|
|
82
84
|
const updatedAt = normalizedMessage.updatedAt ? new Date(normalizedMessage.updatedAt) : undefined;
|
|
83
|
-
const latestReactions = streamMessage.latest_reactions
|
|
85
|
+
const latestReactions = streamMessage.latest_reactions
|
|
86
|
+
? streamMessage.latest_reactions.map(normalizeStreamReaction)
|
|
87
|
+
: [];
|
|
84
88
|
const ownReactionsFromLatestReactions = latestReactions.filter((r) => userId === r.userId);
|
|
85
|
-
const ownReactions = streamMessage.own_reactions
|
|
89
|
+
const ownReactions = streamMessage.own_reactions
|
|
90
|
+
? streamMessage.own_reactions.map(normalizeStreamReaction).filter((r) => userId === r.userId)
|
|
91
|
+
: [];
|
|
86
92
|
ownReactionsFromLatestReactions.forEach((reaction) => {
|
|
87
93
|
if (!ownReactions.find((ownReaction) => ownReaction.type === reaction.type)) {
|
|
88
94
|
ownReactions.push(reaction);
|
|
@@ -112,7 +118,7 @@ function normalizeStreamChannel(channel) {
|
|
|
112
118
|
if (!data) {
|
|
113
119
|
throw new Error(`Illegal channel data`);
|
|
114
120
|
}
|
|
115
|
-
let context
|
|
121
|
+
let context;
|
|
116
122
|
if (data.context) {
|
|
117
123
|
try {
|
|
118
124
|
if (typeof data.context === 'string') {
|
|
@@ -126,7 +132,7 @@ function normalizeStreamChannel(channel) {
|
|
|
126
132
|
console.error('Context Issue: ', e);
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
|
-
let assignee
|
|
135
|
+
let assignee;
|
|
130
136
|
if (data.assignee) {
|
|
131
137
|
assignee = data.assignee;
|
|
132
138
|
}
|
|
@@ -188,7 +194,9 @@ exports.localizeStreamMember = localizeStreamMember;
|
|
|
188
194
|
function localizeStreamChannelMembers(streamChannel) {
|
|
189
195
|
const { state } = streamChannel;
|
|
190
196
|
const wid = streamChannel.getClient().userID;
|
|
191
|
-
return Object.values(state.members)
|
|
197
|
+
return Object.values(state.members)
|
|
198
|
+
.map(localizeStreamMember)
|
|
199
|
+
.filter((member) => member.id !== wid);
|
|
192
200
|
}
|
|
193
201
|
exports.localizeStreamChannelMembers = localizeStreamChannelMembers;
|
|
194
202
|
function localizeStreamChannelsMembersToMapByChannelId(streamChannels) {
|
|
@@ -210,7 +218,9 @@ function localizeStreamChannel(streamChannel) {
|
|
|
210
218
|
const userId = data?.type === xbees_conversations_client_1.ChannelType.DIRECT && members.length > 0 ? members[0].user_id : null;
|
|
211
219
|
const unread = state.read[wid]?.unread_messages || 0;
|
|
212
220
|
const lastMessage = streamChannel.lastMessage();
|
|
213
|
-
const normalizedLastMessage = lastMessage
|
|
221
|
+
const normalizedLastMessage = lastMessage
|
|
222
|
+
? localizeStreamMessage(lastMessage, normalizedChannel.channelId, wid)
|
|
223
|
+
: null;
|
|
214
224
|
const lastMessageAt = normalizedLastMessage ? normalizedLastMessage.createdAt : updatedAt || createdAt;
|
|
215
225
|
const lastRead = state.read[wid]?.last_read || null;
|
|
216
226
|
const role = state.membership.role || xbees_conversations_client_1.ChannelMemberRole.MEMBER;
|
|
@@ -245,7 +255,7 @@ function normalizeStreamChannelReadIndicator(channelReadStatus, channelId) {
|
|
|
245
255
|
exports.normalizeStreamChannelReadIndicator = normalizeStreamChannelReadIndicator;
|
|
246
256
|
function normalizeStreamChannelReadIndicators(streamChannel) {
|
|
247
257
|
const wid = streamChannel.getClient().userID;
|
|
248
|
-
const { state: { read }, data } = streamChannel;
|
|
258
|
+
const { state: { read }, data, } = streamChannel;
|
|
249
259
|
return Object.values(read)
|
|
250
260
|
.filter(({ user }) => wid !== user.id)
|
|
251
261
|
.map((readIndicator) => {
|
|
@@ -255,7 +265,7 @@ function normalizeStreamChannelReadIndicators(streamChannel) {
|
|
|
255
265
|
exports.normalizeStreamChannelReadIndicators = normalizeStreamChannelReadIndicators;
|
|
256
266
|
function normalizeStreamChannelOwnReadIndicators(streamChannel) {
|
|
257
267
|
const wid = streamChannel.getClient().userID;
|
|
258
|
-
const { state: { read }, data } = streamChannel;
|
|
268
|
+
const { state: { read }, data, } = streamChannel;
|
|
259
269
|
return Object.values(read)
|
|
260
270
|
.filter(({ user }) => wid === user.id)
|
|
261
271
|
.map((readIndicator) => {
|
package/dist-es/normalization.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ChannelMemberRole, ChannelType, } from '@wildix/xbees-conversations-client';
|
|
2
|
+
import { MessageDirection, } from './types';
|
|
3
3
|
export function normalizeStreamUser(streamUser) {
|
|
4
4
|
return {
|
|
5
5
|
id: streamUser.id,
|
|
@@ -54,7 +54,9 @@ export function normalizeStreamMessage(streamMessage, channelId) {
|
|
|
54
54
|
latestReactions,
|
|
55
55
|
reactionCounts: reaction_counts || {},
|
|
56
56
|
createdAt: streamMessage.created_at,
|
|
57
|
-
updatedAt: streamMessage.updated_at !== streamMessage.created_at && streamMessage.updated_at
|
|
57
|
+
updatedAt: streamMessage.updated_at !== streamMessage.created_at && streamMessage.updated_at
|
|
58
|
+
? streamMessage.updated_at
|
|
59
|
+
: undefined,
|
|
58
60
|
user,
|
|
59
61
|
quote,
|
|
60
62
|
forward,
|
|
@@ -73,9 +75,13 @@ export function localizeStreamMessage(streamMessage, channelId, userId) {
|
|
|
73
75
|
const normalizedMessage = normalizeStreamMessage(streamMessage, channelId);
|
|
74
76
|
const createdAt = new Date(normalizedMessage.createdAt);
|
|
75
77
|
const updatedAt = normalizedMessage.updatedAt ? new Date(normalizedMessage.updatedAt) : undefined;
|
|
76
|
-
const latestReactions = streamMessage.latest_reactions
|
|
78
|
+
const latestReactions = streamMessage.latest_reactions
|
|
79
|
+
? streamMessage.latest_reactions.map(normalizeStreamReaction)
|
|
80
|
+
: [];
|
|
77
81
|
const ownReactionsFromLatestReactions = latestReactions.filter((r) => userId === r.userId);
|
|
78
|
-
const ownReactions = streamMessage.own_reactions
|
|
82
|
+
const ownReactions = streamMessage.own_reactions
|
|
83
|
+
? streamMessage.own_reactions.map(normalizeStreamReaction).filter((r) => userId === r.userId)
|
|
84
|
+
: [];
|
|
79
85
|
ownReactionsFromLatestReactions.forEach((reaction) => {
|
|
80
86
|
if (!ownReactions.find((ownReaction) => ownReaction.type === reaction.type)) {
|
|
81
87
|
ownReactions.push(reaction);
|
|
@@ -104,7 +110,7 @@ export function normalizeStreamChannel(channel) {
|
|
|
104
110
|
if (!data) {
|
|
105
111
|
throw new Error(`Illegal channel data`);
|
|
106
112
|
}
|
|
107
|
-
let context
|
|
113
|
+
let context;
|
|
108
114
|
if (data.context) {
|
|
109
115
|
try {
|
|
110
116
|
if (typeof data.context === 'string') {
|
|
@@ -118,7 +124,7 @@ export function normalizeStreamChannel(channel) {
|
|
|
118
124
|
console.error('Context Issue: ', e);
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
|
-
let assignee
|
|
127
|
+
let assignee;
|
|
122
128
|
if (data.assignee) {
|
|
123
129
|
assignee = data.assignee;
|
|
124
130
|
}
|
|
@@ -177,7 +183,9 @@ export function localizeStreamMember(member) {
|
|
|
177
183
|
export function localizeStreamChannelMembers(streamChannel) {
|
|
178
184
|
const { state } = streamChannel;
|
|
179
185
|
const wid = streamChannel.getClient().userID;
|
|
180
|
-
return Object.values(state.members)
|
|
186
|
+
return Object.values(state.members)
|
|
187
|
+
.map(localizeStreamMember)
|
|
188
|
+
.filter((member) => member.id !== wid);
|
|
181
189
|
}
|
|
182
190
|
export function localizeStreamChannelsMembersToMapByChannelId(streamChannels) {
|
|
183
191
|
return streamChannels.reduce((accumulator, channel) => {
|
|
@@ -197,7 +205,9 @@ export function localizeStreamChannel(streamChannel) {
|
|
|
197
205
|
const userId = data?.type === ChannelType.DIRECT && members.length > 0 ? members[0].user_id : null;
|
|
198
206
|
const unread = state.read[wid]?.unread_messages || 0;
|
|
199
207
|
const lastMessage = streamChannel.lastMessage();
|
|
200
|
-
const normalizedLastMessage = lastMessage
|
|
208
|
+
const normalizedLastMessage = lastMessage
|
|
209
|
+
? localizeStreamMessage(lastMessage, normalizedChannel.channelId, wid)
|
|
210
|
+
: null;
|
|
201
211
|
const lastMessageAt = normalizedLastMessage ? normalizedLastMessage.createdAt : updatedAt || createdAt;
|
|
202
212
|
const lastRead = state.read[wid]?.last_read || null;
|
|
203
213
|
const role = state.membership.role || ChannelMemberRole.MEMBER;
|
|
@@ -230,7 +240,7 @@ export function normalizeStreamChannelReadIndicator(channelReadStatus, channelId
|
|
|
230
240
|
}
|
|
231
241
|
export function normalizeStreamChannelReadIndicators(streamChannel) {
|
|
232
242
|
const wid = streamChannel.getClient().userID;
|
|
233
|
-
const { state: { read }, data } = streamChannel;
|
|
243
|
+
const { state: { read }, data, } = streamChannel;
|
|
234
244
|
return Object.values(read)
|
|
235
245
|
.filter(({ user }) => wid !== user.id)
|
|
236
246
|
.map((readIndicator) => {
|
|
@@ -239,7 +249,7 @@ export function normalizeStreamChannelReadIndicators(streamChannel) {
|
|
|
239
249
|
}
|
|
240
250
|
export function normalizeStreamChannelOwnReadIndicators(streamChannel) {
|
|
241
251
|
const wid = streamChannel.getClient().userID;
|
|
242
|
-
const { state: { read }, data } = streamChannel;
|
|
252
|
+
const { state: { read }, data, } = streamChannel;
|
|
243
253
|
return Object.values(read)
|
|
244
254
|
.filter(({ user }) => wid === user.id)
|
|
245
255
|
.map((readIndicator) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { type Channel, type ChannelMember, type Message, type Reaction, type User } from '@wildix/xbees-conversations-client';
|
|
2
|
+
import type { StreamChannel, StreamChannelMemberResponse, StreamChannelResponse, StreamMessageResponse, StreamReactionResponse, StreamReadIndicator, StreamUserResponse } from './stream';
|
|
3
|
+
import { type LocalizedChannel, type LocalizedChannelMember, type LocalizedMessage, type LocalizedReadIndicator, type LocalizedUser, type UserPresence } from './types';
|
|
4
4
|
export declare function normalizeStreamUser(streamUser: StreamUserResponse): User;
|
|
5
5
|
export declare function localizeStreamUser(streamUser: StreamUserResponse): LocalizedUser;
|
|
6
6
|
export declare function normalizeStreamReaction(streamReaction: StreamReactionResponse): Reaction;
|
package/dist-types/stream.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { ChannelAccess, ChannelContext, ChannelWhatsAppStatus, Element, MessageAttachment, MessageForward, MessageGiphy, MessageQuote, MessageSmsStatus, MessageWhatsAppStatus, User as NormalizedUser } from '@wildix/xbees-conversations-client';
|
|
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;
|
|
5
5
|
description?: string;
|
|
@@ -114,4 +114,4 @@ export type StreamGetRepliesAPIResponse = GetRepliesAPIResponse<StreamType>;
|
|
|
114
114
|
export type StreamOwnUserResponse = OwnUserResponse<StreamType>;
|
|
115
115
|
export type StreamChannelState = ChannelState<StreamType>;
|
|
116
116
|
export type StreamGetReactionsAPIResponse = GetReactionsAPIResponse<StreamType>;
|
|
117
|
-
export type StreamReadIndicator =
|
|
117
|
+
export type StreamReadIndicator = StreamChannelState['read'][keyof StreamChannelState['read']];
|
package/dist-types/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Channel, ChannelMember, ChannelMemberRole, Message, Reaction, User } from '@wildix/xbees-conversations-client';
|
|
1
|
+
import type { Channel, ChannelMember, ChannelMemberRole, Message, Reaction, User } from '@wildix/xbees-conversations-client';
|
|
2
2
|
export declare enum MessageDirection {
|
|
3
3
|
INCOMING = "incoming",
|
|
4
4
|
OUTGOING = "outgoing"
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wildix/xbees-conversations-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist-cjs/index.js",
|
|
6
6
|
"module": "./dist-es/index.js",
|
|
7
7
|
"types": "./dist-types/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"build": "concurrently '
|
|
9
|
+
"build": "concurrently 'pnpm run build:cjs' 'pnpm run build:es' 'pnpm run build:types'",
|
|
10
10
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
11
11
|
"build:es": "tsc -p tsconfig.es.json",
|
|
12
|
-
"build:include:deps": "
|
|
12
|
+
"build:include:deps": "pnpm --filter \"$npm_package_name\"... run build",
|
|
13
13
|
"build:types": "tsc -p tsconfig.types.json",
|
|
14
14
|
"build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4",
|
|
15
15
|
"build:api-extractor": "mkdir -p etc && api-extractor run --local --verbose",
|
|
16
16
|
"check-types": "tsc --noemit",
|
|
17
17
|
"clean": "rimraf ./dist-* && rimraf *.tsbuildinfo",
|
|
18
|
-
"lint": "
|
|
19
|
-
"lint:fix": "
|
|
18
|
+
"lint": "biome check . && pnpm run check-types",
|
|
19
|
+
"lint:fix": "biome check --write . && pnpm run check-types",
|
|
20
20
|
"postpublish": "node ../../scripts/postpublish.js"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
@@ -24,18 +24,16 @@
|
|
|
24
24
|
},
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@wildix/xbees-conversations-client": "1.
|
|
27
|
+
"@wildix/xbees-conversations-client": "3.1.1",
|
|
28
28
|
"stream-chat": "8.12.1",
|
|
29
|
-
"tslib": "2.
|
|
29
|
+
"tslib": "^2.6.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@tsconfig/node18": "18.2.4",
|
|
33
33
|
"@tsconfig/recommended": "1.0.1",
|
|
34
34
|
"@types/uuid": "10.0.0",
|
|
35
|
-
"@wildix/eslint-config-style-guide": "1.2.1",
|
|
36
35
|
"concurrently": "7.0.0",
|
|
37
36
|
"downlevel-dts": "0.10.1",
|
|
38
|
-
"eslint": "8.57.1",
|
|
39
37
|
"rimraf": "^3.0.0",
|
|
40
38
|
"typescript": "~5.2.2"
|
|
41
39
|
},
|
|
@@ -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;
|