UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

161 lines (160 loc) 6.24 kB
/** * @module RateLimiter */ import { type EventBusInput } from "../../../../event-bus/contracts/_module.js"; import { type IExecutionContext } from "../../../../execution-context/contracts/_module.js"; import { type INamespace } from "../../../../namespace/contracts/_module.js"; import { type IRateLimiter, type IRateLimiterAdapter, type IRateLimiterListenable, type IRateLimiterFactory, type RateLimiterFactoryCreateSettings } from "../../../../rate-limiter/contracts/_module.js"; import { type ISerderRegister } from "../../../../serde/contracts/_module.js"; import { type ErrorPolicy, type OneOrMore, type WaitUntil } from "../../../../utilities/_module.js"; /** * Base configuration shared by all `RateLimiterFactory` variants. * * IMPORT_PATH: `"@daiso-tech/core/rate-limiter"` * @group Derivables */ export type RateLimiterFactorySettingsBase = { /** * @default * ```ts * import { NoOpNamespace } from "@daiso-tech/core/namespace"; * * new NoOpNamespace() * ``` */ namespace?: INamespace; /** * You can provide an {@link IEventBus | `IEventBus`} or an {@link IEventBusAdapter | `IEventBusAdapter`} instance to handle the component's events. * If you provide an adapter, it will be automatically wrapped in an {@link EventBus | `EventBus`} instance. * * @default * ```ts * import { NoOpEventBusAdapter } from "@daiso-tech/core/event-bus/no-op-event-bus-adapter"; * * new NoOpEventBusAdapter() * ``` */ eventBus?: EventBusInput; /** * You can set the default `ErrorPolicy` * * @default * ```ts * (_error: unknown) => true * ``` */ defaultErrorPolicy?: ErrorPolicy; /** * If true will only apply rate limiting when function errors and not when function is called. * @default false */ onlyError?: boolean; /** * If true, metric tracking will run asynchronously in the background and won't block the function utilizing the circuit breaker logic. * This will only have effect if `onlyError` settings is true. * @default true */ enableAsyncTracking?: boolean; /** * You can pass an {@link ISerderRegister | `ISerderRegister`} instance to the {@link RateLimiterFactory | `RateLimiterFactory`} to register the rate limiter's serialization and deserialization logic for the provided adapter. * @default * ```ts * import { Serde } from "@daiso-tech/core/serde"; * import { NoOpSerdeAdapter } from "@daiso-tech/core/serde/no-op-serde-adapter"; * * new Serde(new NoOpSerdeAdapter()) * ``` */ serde?: OneOrMore<ISerderRegister>; /** * The serde transformer name used to identify rate-limiter serializers and deserializers when there are adapters with the same name. * @default "" */ serdeTransformerName?: string; /** * You can pass the `waitUntil` function to handle background promises. * This is required when working with environments like Cloudflare Workers or Vercel Functions to ensure tasks complete after the response is sent. * @default * ```ts * import { defaultWaitUntil } from "@daiso-tech/core/utilities" * ``` */ waitUntil?: WaitUntil; /** * You can pass {@link IExecutionContext | `IExecutionContext`} that will be used by context-aware adapters. * @default * ```ts * import { ExecutionContext } from "@daiso-tech/core/execution-context" * import { NoOpExecutionContextAdapter } from "@daiso-tech/core/execution-context/no-op-execution-context-adapter" * * new ExecutionContext(new NoOpExecutionContextAdapter()) * ``` */ executionContext?: IExecutionContext; }; /** * Configuration for `RateLimiterFactory`. * Extends {@link RateLimiterFactorySettingsBase | `RateLimiterFactorySettingsBase`} with a required adapter. * * IMPORT_PATH: `"@daiso-tech/core/rate-limiter"` * @group Derivables */ export type RateLimiterFactorySettings = RateLimiterFactorySettingsBase & { /** * The underlying rate-limiter adapter that handles the actual throttling operations. */ adapter: IRateLimiterAdapter; }; /** * The `RateLimiterFactory` class can be derived from any {@link IRateLimiterAdapter | `IRateLimiterAdapter`}. * * IMPORT_PATH: `"@daiso-tech/core/rate-limiter"` * @group Derivables */ export declare class RateLimiterFactory implements IRateLimiterFactory { private readonly namespace; private readonly eventBus; private readonly adapter; private readonly onlyError; private readonly defaultErrorPolicy; private readonly enableAsyncTracking; private readonly serde; private readonly serdeTransformerName; private readonly waitUntil; private readonly executionContext; /** * @example * ```ts * import { KyselyRateLimiterStorageAdapter } from "@daiso-tech/core/rate-limiter/kysely-rate-limiter-storage-adapter"; * import { DatabaseRateLimiterAdapter } from "@daiso-tech/core/rate-limiter/database-rate-limiter-adapter"; * import { Serde } from "@daiso-tech/core/serde"; * import { SuperJsonSerdeAdapter } from "@daiso-tech/core/serde/super-json-serde-adapter" * import Sqlite from "better-sqlite3"; * import { Kysely, SqliteDialect } from "kysely"; * * const serde = new Serde(new SuperJsonSerdeAdapter()); * const rateLimiterStorageAdapter = new KyselyRateLimiterStorageAdapter({ * kysely: new Kysely({ * dialect: new SqliteDialect({ * database: new Sqlite("local.db"), * }), * }), * serde * }); * // You need initialize the adapter once before using it. * await rateLimiterStorageAdapter.init(); * * const rateLimiterAdapter = new DatabaseRateLimiterAdapter({ * adapter: rateLimiterStorageAdapter * }); * * const rateLimiterFactory = new RateLimiterFactory({ * adapter: rateLimiterAdapter * }) * ``` */ constructor(settings: RateLimiterFactorySettings); private registerToSerde; get events(): IRateLimiterListenable; create(key: string, settings: RateLimiterFactoryCreateSettings): IRateLimiter; }