@xylabs/threads
Version:
Web workers & worker threads as simple as a function call
1 lines • 9.36 kB
Source Map (JSON)
{"version":3,"sources":["../../src/observable-promise.ts"],"sourcesContent":["/* eslint-disable unicorn/no-thenable */\n/* eslint-disable @typescript-eslint/member-ordering */\n/* eslint-disable @typescript-eslint/no-floating-promises */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-this-alias */\n/* eslint-disable unicorn/no-this-assignment */\nimport type { ObservableLike, SubscriptionObserver } from 'observable-fns'\nimport { Observable } from 'observable-fns'\n\ntype OnFulfilled<T, Result = void> = (value: T) => Result\ntype OnRejected<Result = void> = (error: Error) => Result\n\ntype Initializer<T> = (observer: SubscriptionObserver<T>) => UnsubscribeFn | void\n\ntype Thenable<T> = { then: (onFulfilled?: (value: T) => any, onRejected?: (error: any) => any) => any }\n\ntype UnsubscribeFn = () => void\n\nconst doNothing = () => {}\nconst returnInput = <T>(input: T): T => input\nconst runDeferred = (fn: () => void) => Promise.resolve().then(fn)\n\nfunction fail(error: Error): never {\n throw error\n}\n\nfunction isThenable(thing: any): thing is Thenable<any> {\n return thing && typeof thing.then === 'function'\n}\n\n/**\n * Creates a hybrid, combining the APIs of an Observable and a Promise.\n *\n * It is used to proxy async process states when we are initially not sure\n * if that async process will yield values once (-> Promise) or multiple\n * times (-> Observable).\n *\n * Note that the observable promise inherits some of the observable's characteristics:\n * The `init` function will be called *once for every time anyone subscribes to it*.\n *\n * If this is undesired, derive a hot observable from it using `makeHot()` and\n * subscribe to that.\n */\nexport class ObservablePromise<T> extends Observable<T> implements Promise<T> {\n readonly [Symbol.toStringTag] = '[object ObservablePromise]'\n private initHasRun = false\n private fulfillmentCallbacks: Array<OnFulfilled<T>> = []\n private rejectionCallbacks: OnRejected[] = []\n\n private firstValue: T | undefined\n private firstValueSet = false\n private rejection: Error | undefined\n private state: 'fulfilled' | 'pending' | 'rejected' = 'pending'\n\n constructor(init: Initializer<T>) {\n super((originalObserver: SubscriptionObserver<T>) => {\n // tslint:disable-next-line no-this-assignment\n const self = this\n const observer: SubscriptionObserver<T> = {\n ...originalObserver,\n complete() {\n originalObserver.complete()\n self.onCompletion()\n },\n error(error: Error) {\n originalObserver.error(error)\n self.onError(error)\n },\n next(value: T) {\n originalObserver.next(value)\n self.onNext(value)\n },\n }\n\n try {\n this.initHasRun = true\n return init(observer)\n } catch (error) {\n observer.error(error)\n }\n })\n }\n\n private onNext(value: T) {\n if (!this.firstValueSet) {\n this.firstValue = value\n this.firstValueSet = true\n }\n }\n\n private onError(error: Error) {\n this.state = 'rejected'\n this.rejection = error\n\n for (const onRejected of this.rejectionCallbacks) {\n // Promisifying the call to turn errors into unhandled promise rejections\n // instead of them failing sync and cancelling the iteration\n runDeferred(() => onRejected(error))\n }\n }\n\n private onCompletion() {\n this.state = 'fulfilled'\n\n for (const onFulfilled of this.fulfillmentCallbacks) {\n // Promisifying the call to turn errors into unhandled promise rejections\n // instead of them failing sync and cancelling the iteration\n runDeferred(() => onFulfilled(this.firstValue as T))\n }\n }\n\n then<TResult1 = T, TResult2 = never>(\n onFulfilledRaw?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onRejectedRaw?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,\n ): Promise<TResult1 | TResult2> {\n const onFulfilled: OnFulfilled<T, TResult1> = onFulfilledRaw || (returnInput as any)\n const onRejected = onRejectedRaw || fail\n let onRejectedCalled = false\n\n return new Promise<TResult1 | TResult2>((resolve, reject) => {\n const rejectionCallback = (error: Error) => {\n if (onRejectedCalled) return\n onRejectedCalled = true\n\n try {\n resolve(onRejected(error))\n } catch (anotherError) {\n reject(anotherError)\n }\n }\n const fulfillmentCallback = (value: T) => {\n try {\n resolve(onFulfilled(value))\n } catch (ex) {\n const error = ex as Error\n rejectionCallback(error)\n }\n }\n if (!this.initHasRun) {\n this.subscribe({ error: rejectionCallback })\n }\n if (this.state === 'fulfilled') {\n return resolve(onFulfilled(this.firstValue as T))\n }\n if (this.state === 'rejected') {\n onRejectedCalled = true\n return resolve(onRejected(this.rejection as Error))\n }\n this.fulfillmentCallbacks.push(fulfillmentCallback)\n this.rejectionCallbacks.push(rejectionCallback)\n })\n }\n\n catch<Result = never>(onRejected: ((error: Error) => Promise<Result> | Result) | null | undefined) {\n return this.then(undefined, onRejected) as Promise<Result>\n }\n\n finally(onCompleted?: (() => void) | null | undefined) {\n const handler = onCompleted || doNothing\n return this.then(\n (value: T) => {\n handler()\n return value\n },\n () => handler(),\n ) as Promise<T>\n }\n\n static override from<T>(thing: Observable<T> | ObservableLike<T> | ArrayLike<T> | Thenable<T>): ObservablePromise<T> {\n return isThenable(thing)\n ? new ObservablePromise((observer) => {\n const onFulfilled = (value: T) => {\n observer.next(value)\n observer.complete()\n }\n const onRejected = (error: any) => {\n observer.error(error)\n }\n thing.then(onFulfilled, onRejected)\n })\n : (super.from(thing) as ObservablePromise<T>)\n }\n}\n"],"mappings":"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","names":["Observable","doNothing","returnInput","input","runDeferred","fn","Promise","resolve","then","fail","error","isThenable","thing","ObservablePromise","Observable","Symbol","toStringTag","initHasRun","fulfillmentCallbacks","rejectionCallbacks","firstValue","firstValueSet","rejection","state","init","originalObserver","self","observer","complete","onCompletion","onError","next","value","onNext","onRejected","onFulfilled","onFulfilledRaw","onRejectedRaw","onRejectedCalled","reject","rejectionCallback","anotherError","fulfillmentCallback","ex","subscribe","push","catch","undefined","finally","onCompleted","handler","from"]}