alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
306 lines • 9.72 kB
TypeScript
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