import { Redis } from "ioredis"; //#region src/bus/types/config.d.ts interface BusConfigAbstract { /** * Where the messages are sent through * * `local` - Local memory. Only intended for single-process instances. * `redis` - Redis instance */ type: "local" | "redis"; } interface BusConfigLocal extends BusConfigAbstract { type: "local"; } interface BusConfigRedis extends BusConfigAbstract { type: "redis"; /** * Used to prefix the keys in Redis */ namespace: string; /** * Enable Gzip compression * * @default true */ compression?: boolean; /** * Minimum byte size of the value before compression is enabled. * * There's a trade-off in size versus time spent compressing values with Gzip. For values lower * than ~1k in byte size, the juice isn't worth the squeeze * * @default 1000 */ compressionMinSize?: number; /** * Existing or new Redis connection to use with this memory class */ redis: Redis; } type BusConfig = BusConfigLocal | BusConfigRedis; //#endregion //#region src/bus/types/class.d.ts type MessageHandler = (payload: T) => void; interface Bus { /** * Publish a message to subscribed clients in the given channel * * @param channel Channel to publish to * @param payload Value to send to the subscribed clients */ publish(channel: string, payload: T): Promise; /** * Subscribe to messages in the given channel * * @param channel Channel to subscribe to * @param callback Payload that was published to the given channel */ subscribe(channel: string, callback: MessageHandler): Promise; /** * Unsubscribe from a channel * * @param channel Channel to unsubscribe from * @param callback Callback to remove from the stack */ unsubscribe(channel: string, callback: MessageHandler): Promise; } //#endregion //#region src/bus/lib/local.d.ts declare class BusLocal implements Bus { private handlers; constructor(_config: Omit); publish(channel: string, payload: T): Promise; subscribe(channel: string, callback: MessageHandler): Promise; unsubscribe(channel: string, callback: MessageHandler): Promise; } //#endregion //#region src/bus/lib/redis.d.ts declare class BusRedis implements Bus { private pub; private sub; private namespace; private compression; private compressionMinSize; private handlers; constructor(config: Omit); publish(channel: string, message: T): Promise; subscribe(channel: string, callback: MessageHandler): Promise; unsubscribe(channel: string, callback: MessageHandler): Promise; /** * To avoid adding unnecessary active handles in node, we have 1 listener for all messages from * Redis, and call the individual registered callbacks from the handlers object * * @NOTE this method expects the namespaced channel name * * @param channel The namespaced channel the message was sent in * @param message Buffer of the message value that was sent in the given channel */ private messageBufferHandler; } //#endregion //#region src/bus/lib/create.d.ts declare function createBus(config: Extract): BusLocal; declare function createBus(config: Extract): BusRedis; //#endregion //#region src/cache/types/config.d.ts interface CacheConfigAbstract { /** * Where the data is stored * * `local` - Local memory * `redis` - Redis instance * `multi` - Multi-stage cache. In-memory as L1, Redis as L2 */ type: "local" | "redis" | "multi"; } interface CacheConfigLocal extends CacheConfigAbstract { type: "local"; /** * Maximum number of keys to store in the cache */ maxKeys?: number; /** * Time-to-Live expires keys after duration in milliseconds */ ttl?: number; } interface CacheConfigRedis extends CacheConfigAbstract { type: "redis"; /** * Used to prefix the keys */ namespace: string; /** * Enable Gzip compression * * @default true */ compression?: boolean; /** * Minimum byte size of the value before compression is enabled. * * There's a trade-off in size versus time spent compressing values with Gzip. For values lower * than ~1k in byte size, the juice isn't worth the squeeze * * @default 1000 */ compressionMinSize?: number; /** * Time-to-Live expires keys after duration in milliseconds. */ ttl?: number; /** * Existing or new Redis connection to use with this memory class */ redis: Redis; } interface CacheConfigMulti extends CacheConfigAbstract { type: "multi"; /** * Configuration for the L1 cache */ local: Omit; /** * Configuration for the L2 cache */ redis: Omit; } type CacheConfig = CacheConfigLocal | CacheConfigRedis | CacheConfigMulti; //#endregion //#region src/kv/types/lock.d.ts interface Lock { release(): Promise; extend(duration: number): Promise; } //#endregion //#region src/cache/types/class.d.ts interface Cache { /** * Get the cached value by key. Returns undefined if the key doesn't exist in the cache * * @param key Key to retrieve from the cache * @returns Cached value, or undefined if key doesn't exist */ get(key: string): Promise; /** * Save the given value to the cache * * @param key Key to save in the cache * @param value Value to save to the cache. Can be any JavaScript primitive, plain object, or array */ set(key: string, value: T): Promise; /** * Remove the given key from the cache * * @param key Key to remove from the cache */ delete(key: string): Promise; /** * Check if a given key exists in the cache * * @param key Key to check */ has(key: string): Promise; /** * Remove all keys from the cache */ clear(): Promise; acquireLock(key: string): Promise; usingLock(key: string, callback: () => Promise): Promise; } //#endregion //#region src/cache/lib/local.d.ts declare class CacheLocal implements Cache { private store; constructor(config: Omit); get(key: string): Promise; set(key: string, value: unknown): Promise; delete(key: string): Promise; has(key: string): Promise; clear(): Promise; acquireLock(key: string): Promise; usingLock(key: string, callback: () => Promise): Promise; } //#endregion //#region src/cache/lib/redis.d.ts declare class CacheRedis implements Cache { private store; constructor(config: Omit); get(key: string): Promise; set(key: string, value: T): Promise; delete(key: string): Promise; has(key: string): Promise; clear(): Promise; acquireLock(key: string): Promise; usingLock(key: string, callback: () => Promise): Promise; } //#endregion //#region src/cache/lib/multi.d.ts declare const CACHE_CHANNEL_KEY = "multi-cache"; type CacheMultiMessageClear = { type: "clear"; /** Process this message came from */ origin: string; /** * Key to clear from the local memory * Will clear all keys when left undefined */ key?: string; }; declare class CacheMulti implements Cache { processId: string; local: CacheLocal; redis: CacheRedis; bus: Bus; constructor(config: Omit); get(key: string): Promise; set(key: string, value: unknown): Promise; delete(key: string): Promise; has(key: string): Promise; private clearOthers; clear(): Promise; acquireLock(key: string): Promise; usingLock(key: string, callback: () => Promise): Promise; private onMessageClear; } //#endregion //#region src/cache/lib/create.d.ts declare const createCache: (config: CacheConfig) => CacheLocal | CacheRedis | CacheMulti; //#endregion //#region src/cache/lib/define.d.ts declare const defineCache: (config: CacheConfig) => (() => Cache); //#endregion //#region src/kv/types/config.d.ts interface ExtendedRedis extends Redis { setMax(key: string, value: number): Promise; release(key: string, value: string): Promise; } interface KvConfigAbstract { /** * Where the data is stored * * `local` - Local memory * `redis` - Redis instance */ type: "local" | "redis"; } interface KvConfigLocal extends KvConfigAbstract { type: "local"; /** * Maximum number of keys in the store */ maxKeys?: number; /** * Time-to-Live expires keys after duration in milliseconds */ ttl?: number; } interface KvConfigRedis extends KvConfigAbstract { type: "redis"; /** * Used to prefix the keys */ namespace: string; /** * Enable Gzip compression * * @default true */ compression?: boolean; /** * Minimum byte size of the value before compression is enabled. * * There's a trade-off in size versus time spent compressing values with Gzip. For values lower * than ~1k in byte size, the juice isn't worth the squeeze * * @default 1000 */ compressionMinSize?: number; /** * Requested lock duration in miliseconds */ lockTimeout?: number; /** * Existing or new Redis connection to use with this memory class */ redis: Redis | ExtendedRedis; /** * Time-to-Live expires keys after duration in milliseconds */ ttl?: number; } type KvConfig = KvConfigLocal | KvConfigRedis; //#endregion //#region src/kv/types/class.d.ts interface Kv { /** * Get the stored value by key. Returns undefined if the key doesn't exist in the store * * @param key Key to retrieve from the store * @returns Stored value, or undefined if key doesn't exist */ get(key: string): Promise; /** * Save the given value to the store * * @param key Key to save in the store * @param value Value to save to the store. Can be any JavaScript primitive, plain object, or array */ set(key: string, value: T): Promise; /** * Remove the given key from the store * * @param key Key to remove from the store */ delete(key: string): Promise; /** * Check if a given key exists in the store * * @param key Key to check */ has(key: string): Promise; /** * Increment the given stored value by the given amount * * @param key Key to increment in the store * @param [amount=1] Amount to increment. Defaults to 1 * @returns Updated value */ increment(key: string, amount?: number): Promise; /** * Save the given value to the store if the given value is larger than the existing value * * @param key Key to save in the store * @param value Number to save to the store if it's bigger than the current value * @returns Whether or not the given value was saved */ setMax(key: string, value: number): Promise; acquireLock(key: string): Promise; usingLock(key: string, callback: () => Promise): Promise; /** * Remove all keys from the kv store */ clear(): Promise; } //#endregion //#region src/kv/lib/local.d.ts declare class KvLocal implements Kv { private store; constructor(config: Omit); get(key: string): Promise; set(key: string, value: unknown): Promise; delete(key: string): Promise; has(key: string): Promise; increment(key: string, amount?: number): Promise; setMax(key: string, value: number): Promise; acquireLock(_key: string): Promise<{ release: () => Promise; extend: (_duration: number) => Promise; }>; usingLock(_key: string, callback: () => Promise): Promise; clear(): Promise; } //#endregion //#region src/kv/lib/redis.d.ts declare const SET_MAX_SCRIPT = "\n local key = KEYS[1]\n local value = tonumber(ARGV[1])\n\n if redis.call(\"EXISTS\", key) == 1 then\n local oldValue = tonumber(redis.call('GET', key))\n\n if value <= oldValue then\n return false\n end\n end\n\n redis.call('SET', key, value)\n\n return true\n"; declare class KvRedis implements Kv { private redis; private namespace; private compression; private compressionMinSize; private lockTimeout; private redlock; private ttl; constructor(config: Omit); get(key: string): Promise; set(key: string, value: T): Promise; delete(key: string): Promise; has(key: string): Promise; increment(key: string, amount?: number): Promise; setMax(key: string, value: number): Promise; acquireLock(key: string): Promise<{ release: () => Promise; extend: (duration: number) => Promise; }>; usingLock(key: string, callback: () => Promise): Promise; clear(): Promise; } //#endregion //#region src/kv/lib/create.d.ts declare const createKv: (config: KvConfig) => KvLocal | KvRedis; //#endregion //#region src/limiter/types/config.d.ts interface LimiterConfigAbstract { /** * Where the limit consumption is tracked * * `local` - Local memory. Only intended for single-process instances. * `redis` - Redis instance */ type: "local" | "redis"; duration: number; points: number; } interface LimiterConfigLocal extends LimiterConfigAbstract { type: "local"; } interface LimiterConfigRedis extends LimiterConfigAbstract { type: "redis"; /** * Used to prefix the keys in Redis */ namespace: string; /** * Existing or new Redis connection to use with this memory class */ redis: Redis; } type LimiterConfig = LimiterConfigLocal | LimiterConfigRedis; //#endregion //#region src/limiter/types/class.d.ts interface Limiter { /** * Consume a point for the given key * * @param key IP address, URL path, or any other string */ consume(key: string): Promise; /** * Delete the tracked information for a given key * * @param key IP address, URL path, or any other string */ delete(key: string): Promise; } //#endregion //#region src/limiter/lib/local.d.ts declare class LimiterLocal implements Limiter { private limiter; private points; constructor(config: Omit); consume(key: string): Promise; delete(key: string): Promise; } //#endregion //#region src/limiter/lib/redis.d.ts declare class LimiterRedis implements Limiter { private limiter; private points; constructor(config: Omit); consume(key: string): Promise; delete(key: string): Promise; } //#endregion //#region src/limiter/lib/create.d.ts declare const createLimiter: (config: LimiterConfig) => LimiterLocal | LimiterRedis; //#endregion export { Bus, BusConfig, BusConfigAbstract, BusConfigLocal, BusConfigRedis, BusLocal, BusRedis, CACHE_CHANNEL_KEY, Cache, CacheConfig, CacheConfigAbstract, CacheConfigLocal, CacheConfigMulti, CacheConfigRedis, CacheLocal, CacheMulti, CacheMultiMessageClear, CacheRedis, ExtendedRedis, Kv, KvConfig, KvConfigAbstract, KvConfigLocal, KvConfigRedis, KvLocal, KvRedis, Limiter, LimiterConfig, LimiterConfigAbstract, LimiterConfigLocal, LimiterConfigRedis, LimiterLocal, LimiterRedis, MessageHandler, SET_MAX_SCRIPT, createBus, createCache, createKv, createLimiter, defineCache };