@wildix/xbees-conversations-utils 1.1.80 → 1.1.83
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-cjs/index.js +1 -2
- package/dist-es/index.js +1 -2
- package/dist-types/index.d.ts +1 -2
- package/dist-types/types.d.ts +1 -1
- package/package.json +2 -10
- package/dist-cjs/rateLimits/RedisCooldown.js +0 -66
- package/dist-cjs/rateLimits/constants.js +0 -43
- package/dist-cjs/rateLimits/createRateLimitedStreamProxy.js +0 -87
- 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 -48
- 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-es/rateLimits/RedisCooldown.js +0 -62
- package/dist-es/rateLimits/constants.js +0 -33
- package/dist-es/rateLimits/createRateLimitedStreamProxy.js +0 -83
- 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 -44
- 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-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-cjs/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./types"), exports);
|
|
4
5
|
tslib_1.__exportStar(require("./normalization"), exports);
|
|
5
|
-
tslib_1.__exportStar(require("./rateLimits"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./stream"), exports);
|
|
7
|
-
tslib_1.__exportStar(require("./types"), exports);
|
package/dist-es/index.js
CHANGED
package/dist-types/index.d.ts
CHANGED
package/dist-types/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Channel,
|
|
1
|
+
import { Channel, ChannelMemberRole, ChannelMember, 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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wildix/xbees-conversations-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.83",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist-cjs/index.js",
|
|
6
6
|
"module": "./dist-es/index.js",
|
|
@@ -13,11 +13,7 @@
|
|
|
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
|
-
"check-types": "tsc --noemit",
|
|
17
|
-
"generate:rate-limit-method-names": "node ./scripts/generateRateLimitMethodNames.mjs",
|
|
18
16
|
"clean": "rimraf ./dist-* && rimraf *.tsbuildinfo",
|
|
19
|
-
"lint": "eslint . && npm run check-types",
|
|
20
|
-
"lint:fix": "eslint . --fix",
|
|
21
17
|
"postpublish": "node ../../scripts/postpublish.js"
|
|
22
18
|
},
|
|
23
19
|
"engines": {
|
|
@@ -25,19 +21,15 @@
|
|
|
25
21
|
},
|
|
26
22
|
"license": "Apache-2.0",
|
|
27
23
|
"dependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"@wildix/xbees-conversations-client": "1.2.5",
|
|
30
|
-
"ioredis": "^5.10.0",
|
|
24
|
+
"@wildix/xbees-conversations-client": "1.2.13",
|
|
31
25
|
"stream-chat": "8.12.1",
|
|
32
26
|
"tslib": "^2.5.0"
|
|
33
27
|
},
|
|
34
28
|
"devDependencies": {
|
|
35
29
|
"@tsconfig/node18": "18.2.4",
|
|
36
30
|
"@tsconfig/recommended": "1.0.1",
|
|
37
|
-
"@wildix/eslint-config-style-guide": "1.2.1",
|
|
38
31
|
"concurrently": "7.0.0",
|
|
39
32
|
"downlevel-dts": "0.10.1",
|
|
40
|
-
"eslint": "8.57.1",
|
|
41
33
|
"rimraf": "^3.0.0",
|
|
42
34
|
"typescript": "~5.2.2"
|
|
43
35
|
},
|
|
@@ -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,87 +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 result = Reflect.apply(value, originalTarget, args);
|
|
59
|
-
return normalizeStreamCallResult(result, dependencies, true);
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (CHANNEL_SYNC_PROXY_RESULT_METHODS.has(property)) {
|
|
63
|
-
return (...args) => {
|
|
64
|
-
const result = Reflect.apply(value, originalTarget, args);
|
|
65
|
-
if (typeof result === 'object' && result !== null) {
|
|
66
|
-
return wrapTarget(result, dependencies);
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
if (STREAM_SYNC_METHODS.has(property) || CHANNEL_SYNC_METHODS.has(property)) {
|
|
72
|
-
return (...args) => Reflect.apply(value, originalTarget, args);
|
|
73
|
-
}
|
|
74
|
-
return createRateLimitedMethodWrapper(originalTarget, value, property, dependencies, STREAM_CHANNEL_RESULT_METHODS.has(property));
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
dependencies.cache.set(target, proxy);
|
|
78
|
-
return proxy;
|
|
79
|
-
}
|
|
80
|
-
function createRateLimitedStreamProxy(stream, context) {
|
|
81
|
-
(0, registerStreamInterceptors_1.registerStreamInterceptors)(stream, context);
|
|
82
|
-
return wrapTarget(stream, {
|
|
83
|
-
context,
|
|
84
|
-
cache: new WeakMap(),
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
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;
|