spica
Version:
Supervisor, Coroutine, Channel, select, AtomicPromise, Cancellation, Cache, List, Queue, Stack, and some utils.
62 lines (58 loc) • 2.06 kB
text/typescript
import { AtomicPromise, Internal, internal } from './promise';
const state = Symbol('spica/future::state');
export class Future<T = undefined> extends Promise<T> {
public static get [Symbol.species]() {
return Promise;
}
constructor(private readonly strict: boolean = true) {
let resolve!: (v: T | PromiseLike<T>) => void;
super(r => resolve = r);
this[state] = {
pending: true,
resolve,
};
}
private readonly [state]: {
pending: boolean,
resolve: (value: T | PromiseLike<T>) => void,
};
private bind$(value: T | PromiseLike<T>): Promise<T>;
private bind$(this: Future<undefined>, value?: T | PromiseLike<T>): Promise<T>;
private bind$(value: T | PromiseLike<T>): Promise<T> {
if (this[state].pending) {
this[state].pending = false;
this[state].resolve(value);
}
else if (this.strict) {
throw new Error(`Spica: Future: Cannot rebind the value`);
}
return this;
}
public get bind(): Future<T>['bind$'] {
return value => this.bind$(value!);
}
}
export interface AtomicFuture<T> extends AtomicPromise<T> { }
export class AtomicFuture<T = undefined> implements AtomicPromise<T> {
public readonly [Symbol.toStringTag]: string = 'Promise';
constructor(private readonly strict: boolean = true) {
}
public readonly [internal] = new Internal<T>();
private bind$(value: T | PromiseLike<T>): AtomicPromise<T>;
private bind$(this: AtomicFuture<undefined>, value?: T | PromiseLike<T>): AtomicPromise<T>;
private bind$(value: T | PromiseLike<T>): AtomicPromise<T> {
if (this[internal].isPending()) {
this[internal].resolve(value);
}
else if (this.strict) {
throw new Error(`Spica: AtomicFuture: Cannot rebind the value`);
}
return this;
}
public get bind(): AtomicFuture<T>['bind$'] {
return value => this.bind$(value!);
}
}
AtomicFuture.prototype.then = AtomicPromise.prototype.then;
AtomicFuture.prototype.catch = AtomicPromise.prototype.catch;
AtomicFuture.prototype.finally = AtomicPromise.prototype.finally;