UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

306 lines 9.72 kB
import { Alepha, KIND, Middleware, Primitive } from "alepha"; import "dayjs/plugin/relativeTime.js"; import dayjsDuration, { DurationUnitType } from "dayjs/plugin/duration.js"; import "dayjs/plugin/utc.js"; import "dayjs/plugin/timezone.js"; import "dayjs/plugin/localizedFormat.js"; import "dayjs/locale/ar.js"; import "dayjs/locale/fr.js"; import { Dayjs, ManipulateType, OpUnitType, PluginFunc, QUnitType } from "dayjs"; //#region ../../src/datetime/providers/DateTimeProvider.d.ts type DateTimeInput = string | number | Date | DateTime | Dayjs; type DurationLike = number | Duration | [number, ManipulateType]; /** * Immutable wrapper around the underlying date-time engine. * * Designed to isolate consumers from the engine in use (currently dayjs). * Methods that produce a new value return a new `DateTime` instance. */ declare class DateTime { protected readonly inner: Dayjs; constructor(inner: Dayjs); /** * Add a duration to this date-time. */ add(amount: number, unit?: ManipulateType): DateTime; add(duration: Duration): DateTime; /** * Subtract a duration from this date-time. */ subtract(amount: number, unit?: ManipulateType): DateTime; subtract(duration: Duration): DateTime; startOf(unit: OpUnitType): DateTime; endOf(unit: OpUnitType): DateTime; isAfter(other: DateTimeInput): boolean; isBefore(other: DateTimeInput): boolean; isSame(other: DateTimeInput, unit?: OpUnitType): boolean; diff(other: DateTimeInput, unit?: QUnitType | OpUnitType): number; tz(timezone: string): DateTime; locale(lang: string): DateTime; format(template?: string): string; fromNow(withoutSuffix?: boolean): string; toISOString(): string; toDate(): Date; valueOf(): number; unix(): number; toJSON(): string; toString(): string; /** * Escape hatch for the underlying dayjs instance. * * Use sparingly — anything calling this becomes coupled to dayjs and * will need to migrate when the engine is replaced. */ toDayjs(): Dayjs; } /** * Immutable wrapper around the underlying duration engine. */ declare class Duration { protected readonly inner: dayjsDuration.Duration; constructor(inner: dayjsDuration.Duration); asMilliseconds(): number; asSeconds(): number; asMinutes(): number; asHours(): number; asDays(): number; as(unit: DurationUnitType): number; toISOString(): string; /** * Escape hatch for the underlying dayjs duration. */ toDayjs(): dayjsDuration.Duration; } declare const isDateTime: (value: unknown) => value is DateTime; declare class DateTimeProvider { static PLUGINS: Array<PluginFunc<any>>; protected alepha: Alepha; protected ref: DateTime | null; protected readonly timeouts: Timeout[]; protected readonly intervals: Interval[]; constructor(); protected readonly onStart: import("alepha").HookPrimitive<"start">; protected readonly onStop: import("alepha").HookPrimitive<"stop">; setLocale(locale: string): void; isDateTime(value: unknown): value is DateTime; /** * Create a new UTC DateTime instance. */ utc(date: DateTimeInput | null | undefined): DateTime; /** * Create a new DateTime instance. */ of(date: DateTimeInput | null | undefined): DateTime; /** * Get the current date as a string. */ toISOString(date?: DateTimeInput): string; /** * Get the current date. */ now(): DateTime; /** * Get the current date as a string. * * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance. */ nowISOString(): string; /** * Get the current date as milliseconds since epoch. * * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance. */ nowMillis(): number; /** * Get the current date as a string. * * @protected */ protected getCurrentDate(): DateTime; /** * Create a new Duration instance. */ duration: (duration: DurationLike, unit?: ManipulateType) => Duration; isDurationLike(value: unknown): value is DurationLike; /** * Return a promise that resolves after the next tick. * It uses `setTimeout` with 0 ms delay. */ tick(): Promise<void>; /** * Wait for a certain duration. * * You can clear the timeout by using the `AbortSignal` API. * Aborted signal will resolve the promise immediately, it does not reject it. */ wait(duration: DurationLike, options?: { signal?: AbortSignal; now?: number; }): Promise<void>; createInterval(run: () => unknown, duration: DurationLike, start?: boolean): Interval; /** * Run a callback after a certain duration. */ createTimeout(callback: () => void, duration: DurationLike, now?: number): Timeout; clearTimeout(timeout: Timeout): void; clearInterval(interval: Interval): void; /** * Run a function with a deadline. */ deadline<T>(fn: (signal: AbortSignal) => Promise<T>, duration: DurationLike): Promise<T>; /** * Add time to the current date. */ travel(duration: DurationLike, unit?: ManipulateType): Promise<void>; /** * Stop the time. */ pause(): DateTime; /** * Reset the reference date. */ reset(): void; } interface Interval { timer?: any; duration: number; run: () => unknown; } interface Timeout { now: number; timer?: any; duration: number; callback: () => void; clear: () => void; } //#endregion //#region ../../src/datetime/primitives/$debounce.d.ts interface DebounceOptions { /** * Coalescing window. Concurrent calls within this window share one execution. */ delay: DurationLike; /** * Key function to group calls. Calls with the same key are coalesced. * Defaults to `JSON.stringify(args)`. */ key?: (...args: any[]) => string; } /** * Middleware that coalesces concurrent calls with the same key into a single handler execution. * * All callers within the delay window receive the same result. No storage — * once the handler finishes, the next call starts fresh. Process-local. * * **Use case**: thundering herd protection — cache expires, 100 requests * hit the same endpoint, debounce ensures one rebuild. * * ```typescript * class SearchController { * search = $action({ * use: [$debounce({ delay: [200, "ms"], key: (req) => req.query.q })], * handler: async ({ query }) => this.searchService.search(query.q), * }); * } * ``` */ declare const $debounce: (options: DebounceOptions) => Middleware; //#endregion //#region ../../src/datetime/primitives/$interval.d.ts /** * Run a function periodically. * It uses the `setInterval` internally. * It starts by default when the context starts and stops when the context stops. */ declare const $interval: { (options: IntervalPrimitiveOptions): IntervalPrimitive; [KIND]: typeof IntervalPrimitive; }; interface IntervalPrimitiveOptions { /** * The interval handler. */ handler: () => unknown; /** * The interval duration. */ duration: DurationLike; } declare class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> { protected readonly dateTimeProvider: DateTimeProvider; called: number; protected onInit(): void; } //#endregion //#region ../../src/datetime/primitives/$throttle.d.ts interface ThrottleOptions { /** * Max calls per window. */ rate: number; /** * Window duration. */ per: DurationLike; } /** * Middleware that rate-controls handler execution using a token bucket. * * Excess calls are **delayed** until capacity is available — never rejected. * Process-local (not distributed) — it cannot rate-limit across instances. * * **Limitation**: the token refill is time-based and re-checked only when a * waiter wakes, so a burst of *concurrent* calls can wake in the same window * and briefly exceed `rate`. Treat it as traffic smoothing, not a hard cap — * do not rely on it to enforce a strict quota. * * **Use case**: protect an external API from your own traffic. * * ```typescript * class PaymentController { * charge = $action({ * use: [$throttle({ rate: 80, per: [1, "second"] })], * handler: async ({ body }) => this.stripe.charges.create(body), * }); * } * ``` */ declare const $throttle: (options: ThrottleOptions) => Middleware; //#endregion //#region ../../src/datetime/primitives/$timeout.d.ts /** * Middleware that aborts handler execution if it exceeds a duration limit. * * Uses `Promise.race` with a managed timeout from `DateTimeProvider` — * if the handler doesn't resolve before the deadline, the promise rejects. * Uses managed timeouts so it works with `DateTimeProvider.travel()` in tests. * * ```typescript * class OrderService { * processOrder = $pipeline({ * use: [$timeout([30, "seconds"])], * handler: async (orderId: string) => { * return await this.orders.updateById(orderId, { status: "paid" }); * }, * }); * } * ``` */ declare const $timeout: (duration: DurationLike) => Middleware; //#endregion //#region ../../src/datetime/index.d.ts /** * Date and time operations. * * **Features:** * - Recurring interval definitions * - Duration parsing (ISO 8601, human-readable) * - Timezone support * - Dayjs integration * * @module alepha.datetime */ declare const AlephaDateTime: import("alepha").Service<import("alepha").Module>; //#endregion export { $debounce, $interval, $throttle, $timeout, AlephaDateTime, DateTime, DateTimeInput, DateTimeProvider, DebounceOptions, Duration, DurationLike, type DurationUnitType, Interval, IntervalPrimitive, IntervalPrimitiveOptions, type ManipulateType, type OpUnitType, type QUnitType, ThrottleOptions, Timeout, isDateTime }; //# sourceMappingURL=index.d.ts.map