{"version":3,"file":"Task.mjs","sourceRoot":"","sources":["../../../src/async/Task.ts"],"names":[],"mappings":"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","sourcesContent":["import { Thenable } from '@dojo/shim/interfaces';\nimport { isArrayLike, isIterable, Iterable } from '@dojo/shim/iterator';\nimport { Executor } from '@dojo/shim/Promise';\nimport ExtensiblePromise, { DictionaryOfPromises, ListOfPromises, unwrapPromises } from './ExtensiblePromise';\n\n/**\n * Describe the internal state of a task.\n */\nexport const enum State {\n\tFulfilled = 0,\n\tPending = 1,\n\tRejected = 2,\n\tCanceled = 3\n}\n\n/**\n * A type guard that determines if `value` is a `Task`\n * @param value The value to guard\n */\nexport function isTask<T>(value: any): value is Task<T> {\n\treturn Boolean(value && typeof value.cancel === 'function' && Array.isArray(value.children) && isThenable(value));\n}\n\n/**\n * Returns true if a given value has a `then` method.\n * @param {any} value The value to check if is Thenable\n * @returns {is Thenable<T>} A type guard if the value is thenable\n */\nexport function isThenable<T>(value: any): value is Thenable<T> {\n\treturn value && typeof value.then === 'function';\n}\n\n/**\n * Task is an extension of Promise that supports cancellation and the Task#finally method.\n */\nexport default class Task<T> extends ExtensiblePromise<T> {\n\t/**\n\t * Return a Task that resolves when one of the passed in objects have resolved\n\t *\n\t * @param iterable    An iterable of values to resolve. These can be Promises, ExtensiblePromises, or other objects\n\t * @returns {Task}\n\t */\n\tstatic race<T>(iterable: Iterable<T | Thenable<T>> | (T | Thenable<T>)[]): Task<T> {\n\t\treturn new this((resolve, reject) => {\n\t\t\tPromise.race(unwrapPromises(iterable)).then(resolve, reject);\n\t\t});\n\t}\n\n\t/**\n\t * Return a rejected promise wrapped in a Task\n\t *\n\t * @param reason The reason for the rejection\n\t * @returns A task\n\t */\n\tstatic reject<T>(reason?: Error): Task<T> {\n\t\treturn new this((resolve, reject) => reject(reason));\n\t}\n\n\t/**\n\t * Return a resolved task.\n\t *\n\t * @param value The value to resolve with\n\t *\n\t * @return A task\n\t */\n\tpublic static resolve(): Task<void>;\n\n\t/**\n\t * Return a resolved task.\n\t *\n\t * @param value The value to resolve with\n\t *\n\t * @return A task\n\t */\n\tpublic static resolve<T>(value: T | Thenable<T>): Task<T>;\n\n\t/**\n\t * Return a resolved task.\n\t *\n\t * @param value The value to resolve with\n\t *\n\t * @return A task\n\t */\n\tpublic static resolve<T>(value?: any): Task<T> {\n\t\treturn new this<T>((resolve, reject) => resolve(value));\n\t}\n\n\t/**\n\t * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value\n\t * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values.\n\t *\n\t * @example\n\t * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results));\n\t * // { one: 1, two: 2 }\n\t *\n\t * @param iterable    An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects\n\t * @returns An extensible promise\n\t */\n\tstatic all<T>(iterable: DictionaryOfPromises<T>): Task<{ [key: string]: T }>;\n\n\t/**\n\t * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value\n\t * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values.\n\t *\n\t * @example\n\t * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results));\n\t * // { one: 1, two: 2 }\n\t *\n\t * @param iterable    An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects\n\t * @returns An extensible promise\n\t */\n\tstatic all<T>(iterable: (T | Thenable<T>)[]): Task<T[]>;\n\n\t/**\n\t * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value\n\t * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values.\n\t *\n\t * @example\n\t * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results));\n\t * // { one: 1, two: 2 }\n\t *\n\t * @param iterable    An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects\n\t * @returns An extensible promise\n\t */\n\tstatic all<T>(iterable: T | Thenable<T>): Task<T[]>;\n\n\t/**\n\t * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value\n\t * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values.\n\t *\n\t * @example\n\t * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results));\n\t * // { one: 1, two: 2 }\n\t *\n\t * @param iterable    An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects\n\t * @returns An extensible promise\n\t */\n\tstatic all<T>(iterable: ListOfPromises<T>): Task<T[]>;\n\n\t/**\n\t * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value\n\t * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values.\n\t *\n\t * @example\n\t * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results));\n\t * // { one: 1, two: 2 }\n\t *\n\t * @param iterable    An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects\n\t * @returns An extensible promise\n\t */\n\tstatic all<T>(iterable: DictionaryOfPromises<T> | ListOfPromises<T>): Task<any> {\n\t\treturn new Task(\n\t\t\t(resolve, reject) => {\n\t\t\t\tsuper.all(iterable).then(resolve, reject);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (isArrayLike(iterable)) {\n\t\t\t\t\tfor (let i = 0; i < iterable.length; i++) {\n\t\t\t\t\t\tconst promiseLike = iterable[i];\n\n\t\t\t\t\t\tif (isTask(promiseLike)) {\n\t\t\t\t\t\t\tpromiseLike.cancel();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (isIterable(iterable)) {\n\t\t\t\t\tfor (const promiseLike of iterable) {\n\t\t\t\t\t\tif (isTask(promiseLike)) {\n\t\t\t\t\t\t\tpromiseLike.cancel();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tObject.keys(iterable).forEach((key: any) => {\n\t\t\t\t\t\tconst promiseLike = iterable[key];\n\n\t\t\t\t\t\tif (isTask(promiseLike)) {\n\t\t\t\t\t\t\tpromiseLike.cancel();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * A cancelation handler that will be called if this task is canceled.\n\t */\n\tprivate canceler: () => void;\n\n\t/**\n\t * Children of this Task (i.e., Tasks that were created from this Task with `then` or `catch`).\n\t */\n\tprivate readonly children: Task<any>[];\n\n\t/**\n\t * The finally callback for this Task (if it was created by a call to `finally`).\n\t */\n\tprivate _finally: undefined | (() => void);\n\n\t/**\n\t * The state of the task\n\t */\n\tprotected _state: State;\n\n\tget state() {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * @constructor\n\t *\n\t * Create a new task. Executor is run immediately. The canceler will be called when the task is canceled.\n\t *\n\t * @param executor Method that initiates some task\n\t * @param canceler Method to call when the task is canceled\n\t *\n\t */\n\tconstructor(executor: Executor<T>, canceler?: () => void) {\n\t\t// we have to initialize these to avoid a compiler error of using them before they are initialized\n\t\tlet superResolve: (value?: T | Thenable<T> | undefined) => void = () => {};\n\t\tlet superReject: (reason?: any) => void = () => {};\n\n\t\tsuper((resolve, reject) => {\n\t\t\tsuperResolve = resolve;\n\t\t\tsuperReject = reject;\n\t\t});\n\n\t\tthis._state = State.Pending;\n\n\t\tthis.children = [];\n\t\tthis.canceler = () => {\n\t\t\tif (canceler) {\n\t\t\t\tcanceler();\n\t\t\t}\n\t\t\tthis._cancel();\n\t\t};\n\n\t\t// Don't let the Task resolve if it's been canceled\n\t\ttry {\n\t\t\texecutor(\n\t\t\t\t(value) => {\n\t\t\t\t\tif (this._state === State.Canceled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis._state = State.Fulfilled;\n\t\t\t\t\tsuperResolve(value);\n\t\t\t\t},\n\t\t\t\t(reason) => {\n\t\t\t\t\tif (this._state === State.Canceled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis._state = State.Rejected;\n\t\t\t\t\tsuperReject(reason);\n\t\t\t\t}\n\t\t\t);\n\t\t} catch (reason) {\n\t\t\tthis._state = State.Rejected;\n\t\t\tsuperReject(reason);\n\t\t}\n\t}\n\n\t/**\n\t * Propagates cancellation down through a Task tree. The Task's state is immediately set to canceled. If a Thenable\n\t * finally task was passed in, it is resolved before calling this Task's finally callback; otherwise, this Task's\n\t * finally callback is immediately executed. `_cancel` is called for each child Task, passing in the value returned\n\t * by this Task's finally callback or a Promise chain that will eventually resolve to that value.\n\t */\n\tprivate _cancel(finallyTask?: void | Thenable<any>): void {\n\t\tthis._state = State.Canceled;\n\n\t\tconst runFinally = () => {\n\t\t\ttry {\n\t\t\t\treturn this._finally && this._finally();\n\t\t\t} catch (error) {\n\t\t\t\t// Any errors in a `finally` callback are completely ignored during cancelation\n\t\t\t}\n\t\t};\n\n\t\tif (this._finally) {\n\t\t\tif (isThenable(finallyTask)) {\n\t\t\t\tfinallyTask = (<Thenable<any>>finallyTask).then(runFinally, runFinally);\n\t\t\t} else {\n\t\t\t\tfinallyTask = runFinally();\n\t\t\t}\n\t\t}\n\n\t\tthis.children.forEach(function(child) {\n\t\t\tchild._cancel(finallyTask);\n\t\t});\n\t}\n\n\t/**\n\t * Immediately cancels this task if it has not already resolved. This Task and any descendants are synchronously set\n\t * to the Canceled state and any `finally` added downstream from the canceled Task are invoked.\n\t */\n\tcancel(): void {\n\t\tif (this._state === State.Pending) {\n\t\t\tthis.canceler();\n\t\t}\n\t}\n\n\tcatch<TResult = never>(\n\t\tonRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined\n\t): Task<T | TResult> {\n\t\treturn this.then(undefined, onRejected) as Task<T | TResult>;\n\t}\n\n\t/**\n\t * Allows for cleanup actions to be performed after resolution of a Promise.\n\t */\n\tfinally(callback: () => void): Task<T> {\n\t\t// if this task is already canceled, call the task\n\t\tif (this._state === State.Canceled) {\n\t\t\tcallback();\n\t\t\treturn this;\n\t\t}\n\n\t\tconst task = this.then<any>(\n\t\t\t(value) => Task.resolve(callback()).then(() => value),\n\t\t\t(reason) =>\n\t\t\t\tTask.resolve(callback()).then(() => {\n\t\t\t\t\tthrow reason;\n\t\t\t\t})\n\t\t);\n\n\t\t// Keep a reference to the callback; it will be called if the Task is canceled\n\t\ttask._finally = callback;\n\t\treturn task;\n\t}\n\n\t/**\n\t * Adds a callback to be invoked when the Task resolves or is rejected.\n\t *\n\t * @param onFulfilled   A function to call to handle the resolution. The paramter to the function will be the resolved value, if any.\n\t * @param onRejected    A function to call to handle the error. The parameter to the function will be the caught error.\n\t *\n\t * @returns A task\n\t */\n\tthen<TResult1 = T, TResult2 = never>(\n\t\tonFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n\t\tonRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null\n\t): Task<TResult1 | TResult2> {\n\t\t// FIXME\n\t\t// tslint:disable-next-line:no-var-keyword\n\t\tvar task = super.then(\n\t\t\t// Don't call the onFulfilled or onRejected handlers if this Task is canceled\n\t\t\tfunction(value) {\n\t\t\t\tif (task._state === State.Canceled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (onFulfilled) {\n\t\t\t\t\treturn onFulfilled(value);\n\t\t\t\t}\n\t\t\t\treturn <any>value;\n\t\t\t},\n\t\t\tfunction(error) {\n\t\t\t\tif (task._state === State.Canceled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (onRejected) {\n\t\t\t\t\treturn onRejected(error);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t) as Task<TResult1 | TResult2>;\n\n\t\ttask.canceler = () => {\n\t\t\t// If task's parent (this) hasn't been resolved, cancel it; downward propagation will start at the first\n\t\t\t// unresolved parent\n\t\t\tif (this._state === State.Pending) {\n\t\t\t\tthis.cancel();\n\t\t\t} else {\n\t\t\t\t// If task's parent has been resolved, propagate cancelation to the task's descendants\n\t\t\t\ttask._cancel();\n\t\t\t}\n\t\t};\n\n\t\t// Keep track of child Tasks for propogating cancelation back down the chain\n\t\tthis.children.push(task);\n\n\t\treturn task;\n\t}\n}\n"]}