@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.
197 lines (196 loc) • 8.06 kB
TypeScript
/**
* @module Task
*/
import { type AsyncMiddleware } from "../../hooks/_module.js";
import { type ITask } from "../../task/contracts/_module-exports.js";
import { type ITimeSpan } from "../../time-span/contracts/_module.js";
import { type AsyncLazy, type AsyncLazyable, type Invokable, type InvokableFn, type OneOrMore, type Promisable } from "../../utilities/_module.js";
/**
* IMPORT_PATH: `"@daiso-tech/core/task"`
* @group Derivables
*/
export type TaskResolve<TValue> = InvokableFn<[
value: Promisable<TValue>
], void>;
/**
* IMPORT_PATH: `"@daiso-tech/core/task"`
* @group Derivables
*/
export type TaskReject = InvokableFn<[error: unknown], void>;
/**
* IMPORT_PATH: `"@daiso-tech/core/task"`
* @group Derivables
*/
export type TaskCallback<TValue> = InvokableFn<[
resolve: TaskResolve<TValue>,
reject: TaskReject
], Promisable<void>>;
/**
* IMPORT_PATH: `"@daiso-tech/core/task"`
* @group Derivables
*/
export type TaskAllResult<T extends readonly unknown[]> = {
-readonly [P in keyof T]: Awaited<T[P]>;
};
/**
* IMPORT_PATH: `"@daiso-tech/core/task"`
* @group Derivables
*/
export type TaskAllSettledResult<T extends readonly unknown[]> = {
-readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>;
};
/**
* The `Task` class is used for creating lazy {@link PromiseLike | `PromiseLike`} object that will only execute when awaited or when `then` method is called.
* Note the class is immutable.
*
* IMPORT_PATH: `"@daiso-tech/core/task"`
* @group Derivables
*/
export declare class Task<TValue> implements ITask<TValue> {
/**
* The `wrapFn` is convience method used for wrapping async {@link Invokable | `Invokable`} with a `Task`.
* @example
* ```ts
* import { Task, retry } from "@daiso-tech/core/task";
* import { TimeSpan } from "@daiso-tech/core/time-span" from "@daiso-tech/core/time-span";
* import { readFile as readFileNodeJs } from "node:fs/promises";
*
* const readFile = Task.wrapFn(readFileNodeJs);
*
* const file = await readFile("none_existing_file.txt");
* ```
*/
static wrapFn<TArgs extends unknown[], TReturn>(fn: Invokable<TArgs, Promisable<TReturn>>): InvokableFn<TArgs, ITask<TReturn>>;
/**
* The `delay` method creates a {@link Task | `Task`} that will be fulfilled after given `time`.
*
* @example
* ```ts
* import { Task } from "@daiso-tech/core/task";
* import { TimeSpan } from "@daiso-tech/core/time-span" from "@daiso-tech/core/time-span";
*
* console.log("a");
* await Task.delay(TimeSpan.fromSeconds(2));
* console.log("b");
* ```
*/
static delay(time: ITimeSpan, abortSignal?: AbortSignal): ITask<void>;
/**
* The `resolve` method works similarly to {@link Promise.resolve | `Promise.resolve`} with the key distinction that it operates lazily.
*/
static resolve<TValue>(value: TValue | Task<TValue>): ITask<TValue>;
/**
* The `resolve` method works similarly to {@link Promise.resolve | `Promise.resolve`} with the key distinction that it operates lazily.
*/
static resolve(): ITask<void>;
/**
* The `reject` method works similarly to {@link Promise.reject | `Promise.reject`} with the key distinction that it operates lazily.
*/
static reject<TValue = never, TError = unknown>(reason?: TError): ITask<TValue>;
private static toTasks;
/**
* The `all` method works similarly to {@link Promise.all | `Promise.all`} with the key distinction that it operates lazily.
*/
static all<TValue extends readonly unknown[] | []>(tasks: TValue): ITask<TaskAllResult<TValue>>;
/**
* The `all` method works similarly to {@link Promise.all | `Promise.all`} with the key distinction that it operates lazily.
*/
static all<TValue>(tasks: Iterable<TValue | ITask<TValue>>): ITask<Awaited<TValue>[]>;
/**
* The `allSettled` method works similarly to {@link Promise.allSettled | `Promise.allSettled`} with the key distinction that it operates lazily.
*/
static allSettled<TValues extends readonly unknown[] | []>(tasks: TValues): ITask<TaskAllSettledResult<TValues>>;
/**
* The `allSettled` method works similarly to {@link Promise.allSettled | `Promise.allSettled`} with the key distinction that it operates lazily.
*/
static allSettled<TValue>(tasks: Iterable<ITask<TValue>>): ITask<PromiseSettledResult<TValue>[]>;
/**
* The `race` method works similarly to {@link Promise.race | `Promise.race`} with the key distinction that it operates lazily.
*/
static race<T extends readonly unknown[] | []>(tasks: T): ITask<Awaited<T[number]>>;
/**
* The `race` method works similarly to {@link Promise.race | `Promise.race`} with the key distinction that it operates lazily.
*/
static race<TValue>(tasks: Iterable<TValue | ITask<TValue>>): ITask<TValue>;
/**
* The `any` method works similarly to {@link Promise.any | `Promise.any`} with the key distinction that it operates lazily.
*/
static any<T extends readonly unknown[] | []>(tasks: T): ITask<Awaited<T[number]>>;
/**
* The `any` method works similarly to {@link Promise.any | `Promise.any`} with the key distinction that it operates lazily.
*/
static any<TValue>(tasks: Iterable<TValue | ITask<TValue>>): ITask<TValue>;
/**
* The `fromCallback` is convience method used for wrapping Node js callback functions with a `Task`.
* @example
* ```ts
* import { Task } from "@daiso-tech/core/task";
* import { readFile } from "node:fs";
*
* const task = Task.fromCallback<Buffer | string>((resolve, reject) => {
* readFile("FILE_PATH", (err, data) => {
* if (err !== null) {
* reject(err);
* return;
* }
* resolve(data);
* });
* });
* const file = await task;
* console.log(file);
* ```
*/
static fromCallback<TValue>(callback: TaskCallback<TValue>): ITask<TValue>;
private promise;
private readonly invokable;
/**
* @example
* ```ts
* import { Task, retry } from "@daiso-tech/core/task";
*
* const promise = new Task(async () => {
* console.log("I am lazy");
* },
* // You can also pass in one AsyncMiddleware or multiple (as an Array).
* retry()
* );
*
* // "I am lazy" will only logged when awaited or then method i called.
* await promise;
* ```
*
* You can pass sync or async {@link Invokable | `Invokable`}.
*/
constructor(invokable: AsyncLazy<TValue>, middlewares?: OneOrMore<AsyncMiddleware<[], TValue>>);
/**
* The `pipe` method returns a new `Task` instance with the additional `middlewares` applied.
*/
pipe(middlewares: OneOrMore<AsyncMiddleware<[], TValue>>): ITask<TValue>;
/**
* The `pipeWhen` method conditionally applies additional `middlewares`, returning a new `Task` instance only if the specified condition is met.
*/
pipeWhen(condition: AsyncLazyable<boolean>, middlewares: OneOrMore<AsyncMiddleware<[], TValue>>): ITask<TValue>;
then<TResult1 = TValue, TResult2 = never>(onfulfilled?: ((value: TValue) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
/**
* The `detach` method executes the `Task` without awaiting it.
* @example
* ```ts
* import { Task } from "@daiso-tech/core/task";
* import { TimeSpan } from "@daiso-tech/core/time-span" from "@daiso-tech/core/time-span";
*
* const promise =
* new Task(async () => {
* await Task.delay(TimeSpan.fromSeconds(1));
* // Will be loged after one second
* console.log("Done !");
* });
*
* promise.detach();
*
* // Will be logged immediately
* console.log("Hello");
* await Task.delay(TimeSpan.fromSeconds(2));
* ```
*/
detach(): void;
}