import * as _alepha_core1 from "alepha";
import * as _alepha_core0 from "alepha";
import { Alepha, Descriptor, KIND } from "alepha";
import dayjs, { Dayjs, ManipulateType } from "dayjs";
import dayjsDuration from "dayjs/plugin/duration.js";

//#region src/providers/DateTimeProvider.d.ts
type DateTimeApi = typeof dayjs;
type DateTime = dayjs.Dayjs;
type Duration = dayjsDuration.Duration;
type DurationLike = number | dayjsDuration.Duration | [number, ManipulateType];
declare class DateTimeProvider {
  protected alepha: Alepha;
  protected log: _alepha_core1.Logger;
  protected ref: DateTime | null;
  protected readonly timeouts: Timeout[];
  protected readonly intervals: Interval[];
  constructor();
  /**
   * Load Day.js plugins.
   *
   * You can override this method to add custom plugins.
   */
  protected plugins(api: DateTimeApi): void;
  protected readonly start: _alepha_core1.HookDescriptor<"start">;
  protected readonly stop: _alepha_core1.HookDescriptor<"stop">;
  /**
   * Create a new DateTime instance.
   */
  of(date: string | number | Date | Dayjs | null | undefined): DateTime;
  /**
   * Get the current date.
   */
  now(): DateTime;
  /**
   * Get the current date as a string.
   *
   * @param date
   */
  toISOString(date?: Date | string | DateTime): string;
  /**
   * Get the current date as a string.
   */
  nowISOString(): string;
  /**
   * 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, distance: DurationLike): Interval;
  /**
   * Run a callback after a certain duration.
   */
  createTimeout(callback: () => void, duration: DurationLike, now?: number): Timeout;
  clearTimeout(timeout: Timeout): 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;
}
//# sourceMappingURL=DateTimeProvider.d.ts.map
//#endregion
//#region src/descriptors/$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: IntervalDescriptorOptions): IntervalDescriptor;
  [KIND]: typeof IntervalDescriptor;
};
interface IntervalDescriptorOptions {
  /**
   * The interval handler.
   */
  handler: () => unknown;
  /**
   * The interval duration.
   */
  duration: DurationLike;
}
declare class IntervalDescriptor extends Descriptor<IntervalDescriptorOptions> {
  protected readonly dateTimeProvider: DateTimeProvider;
  called: number;
  protected onInit(): void;
}
//# sourceMappingURL=$interval.d.ts.map
//#endregion
//#region src/index.d.ts
declare const AlephaDateTime: _alepha_core0.Service<_alepha_core0.Module>;
//# sourceMappingURL=index.d.ts.map

//#endregion
export { $interval, AlephaDateTime, DateTime, DateTimeApi, DateTimeProvider, Duration, DurationLike, Interval, IntervalDescriptor, IntervalDescriptorOptions, Timeout };
//# sourceMappingURL=index.d.ts.map