src/types/base.ts
import type { OrderAssurable } from './assure-order-types';
import type { FluentIterableEmitter } from './emitter';
import type TypedEmitter from 'typed-emitter';
import type {
Predicate as FunctionPredicate,
AsyncPredicate as AsyncFunctionPredicate,
AnyIterable,
} from 'augmentative-iterable';
export const head = Symbol.for('@head');
export const tail = Symbol.for('@tail');
export type AnyHack<T> = T extends never ? 'A' : 'B';
/**
* Returns true wether T is any or unknown
*/
export type IsAnyOrUnknown<T> = unknown extends T
? true
: AnyHack<T> extends 'A'
? false
: AnyHack<T> extends 'B'
? false
: true;
/**
* Represents the first string or non iterable item from chained iterables
*/
export type ItemOrSelfType<T> = T extends string
? T
: T extends Iterable<infer R>
? ItemOrSelfType<R>
: T;
/**
* Represents the type of the item of an iterable
*/
export type ItemType<T> = T extends Iterable<infer R> ? R : never;
/**
* Represents the first string or non iterable item from chained iterables
*/
export type AsyncItemOrSelfType<T> = T extends string
? T
: T extends AnyIterable<infer R>
? AsyncItemOrSelfType<R>
: T;
/**
* Represents the type of the item of an iterable or an async iterable
*/
export type AsyncItemType<T> = T extends AnyIterable<infer R> ? R : never;
/**
* represent the options that can be used with fluentEmit
*/
export interface FluentEmitOptions {
/**
* The event which yields a new iterable item. Default 'data'
*/
event?: string;
/**
* The event which throws an error. Default 'error'
*/
error?: string;
/**
* The list of events which ends the iterable. Default ['end', 'close']
*/
end?: string[];
/**
* The timeout for event awaiting. If specified, an error will be thrown when no event is emitted
* before the deadline
*/
timeout?: number;
}
export interface ErrorCallback {
(error: Error, index: number): unknown;
}
export type Predicate<T> = FunctionPredicate<T> | keyof T;
export type AsyncPredicate<T> = AsyncFunctionPredicate<T> | keyof T;
/**
* Represents a reducer of type `T` into the accumulator type `A`.<br>
* Example: `const sumReducer: Reducer<number, number> = (sum, next) => sum + next;`
* @typeparam T The source type.
* @typeparam A The accumulator type.
*/
export interface Reducer<T, A> {
/**
* Generates the next accumulator item based on the previous one and the next item under reduce.
* @param current The previous accumulator value.
* @param next The next item.
* @returns The new accumulator value.
*/
(current: A, next: T): A;
}
/**
* Represents a reducer of type `T` into the accumulator type `A`.<br>
* Example: `const sumReducer: Reducer<number, number> = (sum, next) => sum + next;`
* @typeparam T The source type.
* @typeparam A The accumulator type.
*/
export interface AnyReducer<T, A> {
/**
* Generates the next accumulator item based on the previous one and the next item under reduce.
* @param current The previous accumulator value.
* @param next The next item.
* @returns The new accumulator value.
*/
(current: A, next: T): Promise<A> | A;
}
/**
* Represents an asynchronous reducer of type `T` into the accumulator type `A`.<br>
* Example: `const sumReducer: AsyncReducer<Channel, number> = async (sum, next) => sum + await getNumberOfMessages(next)`
* @typeparam T The source type.
* @typeparam A The accumulator type.
*/
export interface AsyncReducer<T, A> {
/**
* Asynchronously generates the next accumulator item based on the previous one and the next item under reduce.
* @param current The previous accumulator value.
* @param next The next item.
* @returns A promise of the new accumulator value.
*/
(current: A, next: T): Promise<A> | A;
}
/**
* Compares two instances of type `T`.<br>
* Example: `const levelComparer: Comparer<User> = (userA, userB) => userA.level - userB.level;`
* @typeparam T The type of the compared instances.
*/
export interface Comparer<T> {
/**
* Compares `a` and `b`.
* @param a The first instance (the left hand side of the comparison).
* @param b The second instance (the right hand side of the comparison).
* @returns A number which represents the result of the comparison. If **negative**, `a` precedes `b`, if **positive**, `b` precedes `a`, if **zero**, `a` equals to `b` in the comparison.
*/
(a: T, b: T): number;
}
/**
* Represents an action on an item of type `T`.<br>
* Example: ``const logUserAction: Action<User> = user => console.log(`User ${user.name} (id: ${user.id})`);``
* @typeparam T The type of the item the action is defined on.
*/
export interface Action<T> {
/**
* Specifies the action to perform on `item`.
* @param item The item the action is performed against.
*/
(item: T): void;
}
/**
* Represents an asynchronous action on an item of type `T`.<br>
* Example: `const createUserAction: AsyncAction<User> = async user => await database.put(user);`
* @typeparam T The type of the item the action is defined on.
*/
export interface AsyncAction<T> {
/**
* Specifies the asynchronous action to perform on `item`.
* @param item The item the action is performed against.
* @returns The promise of any action.
*/
(item: T): Promise<unknown> | unknown;
}
/**
* Represents a group of items of type `T` with a key of type `R`.
* @typeparam T The type of the items in the [[Group]].
* @typeparam R The type of the key of the [[Group]].
*/
export interface Group<T, R> {
/**
* The key of the [[Group]].
*/
key: R;
/**
* The items in the [[Group]].
*/
values: Iterable<T>;
}
/**
* Represents an indexed value of type `T`.
* @typeparam T The type of the value the index is associated to.
*/
export interface Indexed<T> {
/**
* The index of the value.
*/
idx: number;
/**
* The value.
*/
value: T;
}
/**
* A structure to controls the calculation of iterative means
*/
export interface AverageStepper {
/**
* Return the current avg/mean
*/
readonly avg: number;
/**
* Return total number of computed items
*/
readonly count: number;
/**
* Calculates next avg
* @param y the next number to be considered
*/
step(y: number): number;
}
export interface Equality<T> {
(a: T, b: T): boolean;
}
export interface FluentEvents<T> {
data(t: T): void;
error(error: any): void;
end(): void;
}
/**
* Represents a page of a paginated resource.
* @typeparam T The type of the elements of the page.
* @typeparam TToken The type of the next page token associated to the page.
*/
export interface Page<T, TToken> {
/**
* The elements of the page.
*/
results: T[];
/**
* The next page token associated to the page.
*/
nextPageToken?: TToken;
}
/**
* Represents a pager - responsible to retrieve pages from a paginated resource.
* @typeparam T The type of the elements of the page.
* @typeparam TToken The type of the next page token associated to the page.
*/
export interface Pager<T, TToken> {
/**
* Retrieves a page from a paginated resource.
* @param nextPageToken The token represents the page to retrieve or the first page if undefined.
* @returns A promise of the page requested.
*/
(nextPageToken?: TToken): Promise<Page<T, TToken> | undefined>;
}
export interface FluentEmitter<T> extends TypedEmitter<FluentEvents<T>> {}
export interface KVGroupTransform<K, V, NewV = V> {
(key: K, value: V, previous: NewV[]): Iterable<NewV> | undefined;
}
export interface AsyncKVGroupTransform<K, V, NewV = V> {
(key: K, value: V, previous: NewV[]): AnyIterable<NewV> | undefined;
}
/**
* Represents a group of [[fluent]] items of type `T` with a key of type `R`.
* @typeparam T The type of the items in the [[FluentGroup]].
* @typeparam R The type of the key of the [[FluentGroup]].
*/
export interface FluentGroup<T, R> extends Group<T, R> {
/**
* The [[fluent]] items in the [[FluentGroup]].
*/
values: FluentIterable<T>;
}
export type ToObjectKeyType<T, R1 extends keyof T> = T[R1] extends
| string
| number
| symbol
? T[R1]
: any;
/**
* Represents an iterable extended with common processing and mutating capabilities.<br>
* The capabilities introduced are defined as a [fluent interface](https://en.wikipedia.org/wiki/Fluent_interface) and thus they support *method chaining*.
* @typeparam T The type of the items in the iterable.
*/
export interface FluentIterable<T>
extends Iterable<T>,
OrderAssurable<FluentIterable<T>>,
FluentIterableEmitter<T> {}
/**
* Represents an asynchronous iterable extended with common processing and mutating capabilities.<br>
* The capabilities introduced are defined as a [fluent interface](https://en.wikipedia.org/wiki/Fluent_interface) and thus they support *method chaining*.
* @typeparam T The type of the items in the asynchronous iterable.
*/
export interface FluentAsyncIterable<T>
extends AsyncIterable<T>,
OrderAssurable<FluentAsyncIterable<T>>,
FluentIterableEmitter<T> {}
export type KeysOfType<T, V> = {
[K in keyof T]-?: T[K] extends V ? K : never;
}[keyof T];