@shushed/helpers 0.0.99 → 0.0.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import * as _google_cloud_scheduler_build_protos_protos from '@google-cloud/sche
7
7
  import { CloudSchedulerClient } from '@google-cloud/scheduler';
8
8
  import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
9
9
  import { BigQuery } from '@google-cloud/bigquery';
10
+ import { RedisClientType } from 'redis';
10
11
 
11
12
  declare const schema$r: {
12
13
  readonly $schema: "http://json-schema.org/draft-07/schema#";
@@ -33120,6 +33121,23 @@ declare class BigQueryHelper extends Runtime {
33120
33121
  }): Promise<string>;
33121
33122
  }
33122
33123
 
33124
+ interface RateLimitLockInfo {
33125
+ id: string;
33126
+ workflowId: string;
33127
+ triggerId: string;
33128
+ url: string;
33129
+ envName: string;
33130
+ creation_time: number;
33131
+ expiration_time: number;
33132
+ }
33133
+ declare class RateLimit extends Runtime {
33134
+ private redisInstance;
33135
+ constructor(opts: Opts, redisInstance: RedisClientType);
33136
+ acquireLock(id: string, maxConcurrentExecutions: number, expirationInSeconds?: number): Promise<boolean>;
33137
+ releaseLock(id: string): Promise<void>;
33138
+ viewLocks(id: string): Promise<RateLimitLockInfo[]>;
33139
+ }
33140
+
33123
33141
  type TriggerOnExecuteOptions = {
33124
33142
  req: {
33125
33143
  status?: number;
@@ -33366,6 +33384,8 @@ type index_Message = Message;
33366
33384
  type index_NodeOptions = NodeOptions;
33367
33385
  type index_PubSubHelper = PubSubHelper;
33368
33386
  declare const index_PubSubHelper: typeof PubSubHelper;
33387
+ type index_RateLimit = RateLimit;
33388
+ declare const index_RateLimit: typeof RateLimit;
33369
33389
  type index_Runtime = Runtime;
33370
33390
  declare const index_Runtime: typeof Runtime;
33371
33391
  type index_SchedulerHelper = SchedulerHelper;
@@ -33385,7 +33405,7 @@ declare const index_shortHash: typeof shortHash;
33385
33405
  declare const index_validate: typeof validate;
33386
33406
  declare const index_validateGoogleAuth: typeof validateGoogleAuth;
33387
33407
  declare namespace index {
33388
- export { index_BigQueryHelper as BigQueryHelper, index_CloudTasksHelper as CloudTasksHelper, index_EnvEngine as EnvEngine, type index_ILogging as ILogging, index_JWKSHelper as JWKSHelper, index_Logging as Logging, type index_Message as Message, type index_NodeOptions as NodeOptions, index_PubSubHelper as PubSubHelper, index_Runtime as Runtime, index_SchedulerHelper as SchedulerHelper, index_Secrets as Secrets, type index_TriggerOnCreateOptions as TriggerOnCreateOptions, type index_TriggerOnExecuteOptions as TriggerOnExecuteOptions, index_getEventTime as getEventTime, index_isCloudTask as isCloudTask, index_isCronMessage as isCronMessage, index_isPubSubRequest as isPubSubRequest, index_parseDateOrDefault as parseDateOrDefault, index_sanitize as sanitize, index_sanitizeToString as sanitizeToString, index_shortHash as shortHash, index_validate as validate, index_validateGoogleAuth as validateGoogleAuth };
33408
+ export { index_BigQueryHelper as BigQueryHelper, index_CloudTasksHelper as CloudTasksHelper, index_EnvEngine as EnvEngine, type index_ILogging as ILogging, index_JWKSHelper as JWKSHelper, index_Logging as Logging, type index_Message as Message, type index_NodeOptions as NodeOptions, index_PubSubHelper as PubSubHelper, index_RateLimit as RateLimit, index_Runtime as Runtime, index_SchedulerHelper as SchedulerHelper, index_Secrets as Secrets, type index_TriggerOnCreateOptions as TriggerOnCreateOptions, type index_TriggerOnExecuteOptions as TriggerOnExecuteOptions, index_getEventTime as getEventTime, index_isCloudTask as isCloudTask, index_isCronMessage as isCronMessage, index_isPubSubRequest as isPubSubRequest, index_parseDateOrDefault as parseDateOrDefault, index_sanitize as sanitize, index_sanitizeToString as sanitizeToString, index_shortHash as shortHash, index_validate as validate, index_validateGoogleAuth as validateGoogleAuth };
33389
33409
  }
33390
33410
 
33391
33411
  export { index as lib, index$9 as schema, index$1 as types };
package/dist/index.js CHANGED
@@ -316,6 +316,7 @@ __export(src_public_exports, {
316
316
  JWKSHelper: () => jwks_default,
317
317
  Logging: () => Logging,
318
318
  PubSubHelper: () => pubsub_default,
319
+ RateLimit: () => RateLimit,
319
320
  Runtime: () => Runtime,
320
321
  SchedulerHelper: () => scheduler_default,
321
322
  Secrets: () => secret_default,
@@ -1880,6 +1881,87 @@ var BigQueryHelper = class extends Runtime {
1880
1881
  }
1881
1882
  };
1882
1883
  var bigquery_default = BigQueryHelper;
1884
+
1885
+ // src-public/rateLimit.ts
1886
+ function normalizeId(id) {
1887
+ return encodeURIComponent(id);
1888
+ }
1889
+ var RateLimit = class extends Runtime {
1890
+ redisInstance;
1891
+ constructor(opts, redisInstance) {
1892
+ super(opts);
1893
+ this.redisInstance = redisInstance;
1894
+ }
1895
+ async acquireLock(id, maxConcurrentExecutions, expirationInSeconds = 60 * 5) {
1896
+ const key = `ratelimit:${normalizeId(id)}`;
1897
+ const now = Date.now();
1898
+ const lockInfo = {
1899
+ id,
1900
+ workflowId: this.workflowId,
1901
+ triggerId: this.triggerId,
1902
+ url: this.runtimeUrl,
1903
+ envName: this.envName,
1904
+ creation_time: now,
1905
+ expiration_time: now + expirationInSeconds * 1e3
1906
+ };
1907
+ try {
1908
+ const timeout = 300;
1909
+ const redis = this.redisInstance;
1910
+ await Promise.race([
1911
+ redis.zRemRangeByScore(key, "-inf", now),
1912
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Redis timeout")), timeout))
1913
+ ]);
1914
+ const count = await Promise.race([
1915
+ redis.zCard(key),
1916
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Redis timeout")), timeout))
1917
+ ]);
1918
+ if (count >= maxConcurrentExecutions) {
1919
+ return false;
1920
+ }
1921
+ await Promise.race([
1922
+ redis.zAdd(key, { score: lockInfo.expiration_time, value: JSON.stringify(lockInfo) }),
1923
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Redis timeout")), timeout))
1924
+ ]);
1925
+ await Promise.race([
1926
+ redis.expire(key, expirationInSeconds),
1927
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Redis timeout")), timeout))
1928
+ ]);
1929
+ return true;
1930
+ } catch {
1931
+ return false;
1932
+ }
1933
+ }
1934
+ async releaseLock(id) {
1935
+ const key = `ratelimit:${normalizeId(id)}`;
1936
+ const redis = this.redisInstance;
1937
+ const locks = await redis.zRange(key, 0, -1);
1938
+ const filtered = locks.filter((lockStr) => {
1939
+ try {
1940
+ const lock = JSON.parse(lockStr);
1941
+ return lock.workflowId === this.workflowId && lock.triggerId === this.triggerId && lock.envName === this.envName && lock.url === this.runtimeUrl;
1942
+ } catch {
1943
+ return false;
1944
+ }
1945
+ });
1946
+ for (const lockStr of filtered) {
1947
+ await redis.zRem(key, lockStr);
1948
+ }
1949
+ }
1950
+ async viewLocks(id) {
1951
+ const key = `ratelimit:${normalizeId(id)}`;
1952
+ const redis = this.redisInstance;
1953
+ const now = Date.now();
1954
+ await redis.zRemRangeByScore(key, "-inf", now);
1955
+ const locks = await redis.zRange(key, 0, -1);
1956
+ return locks.reduce((acc, lockStr) => {
1957
+ try {
1958
+ acc.push(JSON.parse(lockStr));
1959
+ } catch {
1960
+ }
1961
+ return acc;
1962
+ }, []);
1963
+ }
1964
+ };
1883
1965
  // Annotate the CommonJS export names for ESM import in node:
1884
1966
  0 && (module.exports = {
1885
1967
  lib,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shushed/helpers",
3
- "version": "0.0.99",
3
+ "version": "0.0.100",
4
4
  "author": "",
5
5
  "license": "UNLICENSED",
6
6
  "description": "",