+21
| MIT License | ||
| Copyright (c) 2025 RanolP | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
+7
-3
@@ -40,2 +40,3 @@ //#region src/index.d.ts | ||
| declare function abortable<TParams extends readonly unknown[], TReturn>(fn: ($: AbortableUtility) => (...params: TParams) => TReturn | PromiseLike<TReturn>): AbortableOperation<TParams, TReturn>; | ||
| declare function runAbortable<TReturn>(fn: ($: AbortableUtility) => TReturn | PromiseLike<TReturn>): AbortableTask<TReturn>; | ||
| /** | ||
@@ -50,3 +51,3 @@ * Utility interface for abort-aware operations. | ||
| */ | ||
| <UReturn>(value: NotFunction<PromiseLike<UReturn> | UReturn>): Promise<UReturn>; | ||
| <UReturn>(value: NotFunction<UReturn>): Promise<Awaited<UReturn>>; | ||
| /** | ||
@@ -64,2 +65,4 @@ * Wraps a function to make it abort-aware. | ||
| cleanup: (fn: () => void) => void; | ||
| abort: () => void; | ||
| all: <T extends readonly unknown[] | []>(array: T) => Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>; | ||
| } | ||
@@ -69,3 +72,4 @@ /** | ||
| */ | ||
| type AbortableOperation<TParams extends readonly unknown[], TReturn> = (...params: TParams) => Promise<{ | ||
| type AbortableOperation<TParams extends readonly unknown[], TReturn> = (...params: TParams) => AbortableTask<TReturn>; | ||
| type AbortableTask<TReturn> = Promise<{ | ||
| ok: true; | ||
@@ -79,3 +83,3 @@ data: TReturn; | ||
| //#endregion | ||
| export { AbortedError, abortable }; | ||
| export { AbortableTask, AbortedError, abortable, runAbortable }; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;AAGA;AAEC;AAKe,cAPH,YAAA,SAAqB,KAAK,CAOvB;EAAA,IAAM,EAAA,MAAA;;AAAwD;AA6B9E;;KA7BK,WA+BE,CAAA,CAAA,CAAA,GA/Be,CA+Bf,UAAA,CAAA,GAAA,MAAA,EAAA,SAAA,GAAA,EAAA,EAAA,GAAA,GAAA,IAAA,KAAA,GA/BsE,CA+BtE;;;;;;;;AAEc;AAuFpB;;;;;;;;;;;;;;;AAsBmC;AAAA;;;AAeL,iBAhIf,SAgIe,CAAA,gBAAA,SAAA,OAAA,EAAA,EAAA,OAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EA9HxB,gBA8HwB,EAAA,GAAA,CAAA,GAAA,MAAA,EA7HZ,OA6HY,EAAA,GA7HA,OA6HA,GA7HU,WA6HV,CA7HsB,OA6HtB,CAAA,CAAA,EA5H5B,kBA4H4B,CA5HT,OA4HS,EA5HA,OA4HA,CAAA;;AAAnB;;UAhCF,gBAAA;;;;;;mBAOC,YAAY,YAAY,WAAW,WACzC,QAAQ;;;;;;+DAQM,YAAY,UAAU,YAAY,uBACpC,YAAY,QAAQ;;;;;;;;;;;KAahC,8EACQ,YACR;;QAA0B"} | ||
| {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;AAGA;AAEC;AAKe,cAPH,YAAA,SAAqB,KAAK,CAOvB;EAAA,IAAM,EAAA,MAAA;;AAAwD;AA6B9E;;KA7BK,WA+BE,CAAA,CAAA,CAAA,GA/Be,CA+Bf,UAAA,CAAA,GAAA,MAAA,EAAA,SAAA,GAAA,EAAA,EAAA,GAAA,GAAA,IAAA,KAAA,GA/BsE,CA+BtE;;;;;;;;AAEc;AAkGrB;;;;;;;;AAEgB;AAEf;;;;;;;;;;AAmBwC,iBA7HzB,SA6HyB,CAAA,gBAAA,SAAA,OAAA,EAAA,EAAA,OAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EA3HlC,gBA2HkC,EAAA,GAAA,CAAA,GAAA,MAAA,EA1HtB,OA0HsB,EAAA,GA1HV,OA0HU,GA1HA,WA0HA,CA1HY,OA0HZ,CAAA,CAAA,EAzHtC,kBAyHsC,CAzHnB,OAyHmB,EAzHV,OAyHU,CAAA;AACxB,iBAxBD,YAwBC,CAAA,OAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EAvBP,gBAuBO,EAAA,GAvBc,OAuBd,GAvBwB,WAuBxB,CAvBoC,OAuBpC,CAAA,CAAA,EAtBd,aAsBc,CAtBA,OAsBA,CAAA;;;;UAfP,gBAAA,CA4B6B;EAAC;;;;AAA1B;EAMT,CAAA,OAAA,CAAA,CAAA,KAAA,EA5Bc,WA4BI,CA5BQ,OA4BR,CAAA,CAAA,EA5BmB,OA4BnB,CA5B2B,OA4B3B,CA5BmC,OA4BnC,CAAA,CAAA;EAAA;;;;AAEL;EAEN,CAAA,OAAA,EAAA,gBAAa,SAAA,OAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,GAAA,MAAA,EAxBN,OAwBM,EAAA,GAxBM,OAwBN,GAxBgB,WAwBhB,CAxB4B,OAwB5B,CAAA,CAAA,EAAA,CAAA,GAAA,MAAA,EAvBR,OAuBQ,EAAA,GAvBI,OAuBJ,CAvBY,OAuBZ,CAAA;EAAA;;;AAAmB;;;;kDAXjC,MACJ,gCAAgC,IAAI,QAAQ,EAAE;;;;;KAMhD,8EACQ,YACR,cAAc;KAEP,yBAAyB;;QACjB"} |
+8
-1
@@ -70,2 +70,6 @@ //#region src/index.ts | ||
| }; | ||
| $.abort = () => { | ||
| control.abort(); | ||
| }; | ||
| $.all = (params$1) => Promise.all(params$1.map((p) => $(p))); | ||
| const runCleanup = () => { | ||
@@ -92,5 +96,8 @@ for (const fn$1 of cleanupFunctions.reverse()) try { | ||
| } | ||
| function runAbortable(fn) { | ||
| return abortable(($) => () => fn($))(); | ||
| } | ||
| //#endregion | ||
| export { AbortedError, abortable }; | ||
| export { AbortedError, abortable, runAbortable }; | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","names":["fn: (\n $: AbortableUtility,\n ) => (...params: TParams) => TReturn | PromiseLike<TReturn>","cleanupFunctions: (() => void)[]","g:\n | PromiseLike<UReturn>\n | UReturn\n | ((...params: UParams) => UReturn | PromiseLike<UReturn>)","params","fn: () => void","fn"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Error thrown when an operation is aborted.\n */\nexport class AbortedError extends Error {\n name = 'AbortedError';\n}\n\n/**\n * Utility type to exclude functions from a type.\n */\ntype NotFunction<T> = T extends (...params: readonly any[]) => any ? never : T;\n\n/**\n * Creates an abortable asynchronous operation.\n *\n * @template TParams - The parameters of the operation\n * @template TReturn - The return type of the operation\n * @param fn - A function that receives an abort-aware utility and returns an async operation\n * @returns A function that returns a promise with an additional `abort()` method\n *\n * @example\n * ```typescript\n * const operation = abortable($ => async (id: string) => {\n * const user = await $(fetchUser(id));\n * const posts = await $(fetchPosts(user.id));\n * return posts;\n * });\n *\n * const promise = operation('user123');\n * promise.abort(); // Cancel the operation\n *\n * const result = await promise;\n * if (result.ok) {\n * console.log('Success:', result.data);\n * } else {\n * console.log('Operation was aborted');\n * }\n * ```\n */\nexport function abortable<TParams extends readonly unknown[], TReturn>(\n fn: (\n $: AbortableUtility,\n ) => (...params: TParams) => TReturn | PromiseLike<TReturn>,\n): AbortableOperation<TParams, TReturn> {\n return (...params) => {\n const control = new AbortController();\n const cleanupFunctions: (() => void)[] = [];\n\n /**\n * Abort-aware utility for wrapping promises and functions.\n */\n function $<UReturn>(\n value: NotFunction<PromiseLike<UReturn> | UReturn>,\n ): Promise<UReturn>;\n function $<UReturn, UParams extends readonly unknown[]>(\n g: (...params: UParams) => UReturn | PromiseLike<UReturn>,\n ): (...params: UParams) => Promise<UReturn>;\n function $<UReturn, UParams extends readonly unknown[]>(\n g:\n | PromiseLike<UReturn>\n | UReturn\n | ((...params: UParams) => UReturn | PromiseLike<UReturn>),\n ): Promise<UReturn> | ((...params: UParams) => Promise<UReturn>) {\n if (typeof g === 'function') {\n return async (...params: UParams): Promise<UReturn> => {\n if (control.signal.aborted) throw new AbortedError();\n const result = await (\n g as unknown as (\n ...params: UParams\n ) => UReturn | PromiseLike<UReturn>\n )(...params);\n if (control.signal.aborted) throw new AbortedError();\n return result;\n };\n }\n return $<UReturn, []>(() => g)();\n }\n\n /**\n * Registers a cleanup function to be called when the operation completes or is aborted.\n * Cleanup functions are executed in reverse order of registration (LIFO).\n *\n * @param fn - The cleanup function to register\n *\n * @example\n * ```typescript\n * abortable($ => async (file: File) => {\n * const handle = await openFile(file);\n * $.cleanup(() => handle.close());\n * return processFile(handle);\n * });\n * ```\n */\n $.cleanup = (fn: () => void) => {\n if (control.signal.aborted) {\n fn();\n return;\n }\n cleanupFunctions.push(fn);\n };\n\n const runCleanup = () => {\n for (const fn of cleanupFunctions.reverse()) {\n try {\n fn();\n } catch (error) {\n // Ignore cleanup errors\n }\n }\n };\n\n return Object.assign(\n (async () => {\n try {\n const result = { ok: true, data: await fn($)(...params) } as const;\n runCleanup();\n return result;\n } catch (e) {\n runCleanup();\n if (e instanceof AbortedError) {\n return { ok: false } as const;\n }\n throw e;\n }\n })(),\n {\n abort: () => control.abort(),\n },\n );\n };\n}\n\n/**\n * Utility interface for abort-aware operations.\n */\ninterface AbortableUtility {\n /**\n * Wraps a promise or value to be abort-aware.\n * @param value - The promise or value to wrap\n * @returns A promise that can be aborted\n */\n <UReturn>(\n value: NotFunction<PromiseLike<UReturn> | UReturn>,\n ): Promise<UReturn>;\n\n /**\n * Wraps a function to make it abort-aware.\n * @param g - The function to wrap\n * @returns A wrapped function that checks for abortion\n */\n <UReturn, UParams extends readonly unknown[]>(\n g: (...params: UParams) => UReturn | PromiseLike<UReturn>,\n ): (...params: UParams) => Promise<UReturn>;\n\n /**\n * Registers a cleanup function to be called when the operation completes or is aborted.\n * Cleanup functions are executed in reverse order of registration (LIFO).\n * @param fn - The cleanup function to register\n */\n cleanup: (fn: () => void) => void;\n}\n\n/**\n * Type for an abortable operation.\n */\ntype AbortableOperation<TParams extends readonly unknown[], TReturn> = (\n ...params: TParams\n) => Promise<{ ok: true; data: TReturn } | { ok: false }> & {\n abort: () => void;\n};\n"],"mappings":";;;;AAGA,IAAa,eAAb,cAAkC,MAAM;CACtC,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCD,SAAgB,UACdA,IAGsC;AACtC,QAAO,CAAC,GAAG,WAAW;EACpB,MAAM,UAAU,IAAI;EACpB,MAAMC,mBAAmC,CAAE;EAW3C,SAAS,EACPC,GAI+D;AAC/D,cAAW,MAAM,WACf,QAAO,OAAO,GAAGC,aAAsC;AACrD,QAAI,QAAQ,OAAO,QAAS,OAAM,IAAI;IACtC,MAAM,SAAS,MAAM,AACnB,EAGA,GAAGA,SAAO;AACZ,QAAI,QAAQ,OAAO,QAAS,OAAM,IAAI;AACtC,WAAO;GACR;AAEH,UAAO,EAAe,MAAM,EAAE,EAAE;EACjC;;;;;;;;;;;;;;;;AAiBD,IAAE,UAAU,CAACC,SAAmB;AAC9B,OAAI,QAAQ,OAAO,SAAS;AAC1B,UAAI;AACJ;GACD;AACD,oBAAiB,KAAKC,KAAG;EAC1B;EAED,MAAM,aAAa,MAAM;AACvB,QAAK,MAAMA,QAAM,iBAAiB,SAAS,CACzC,KAAI;AACF,UAAI;GACL,SAAQ,OAAO,CAEf;EAEJ;AAED,SAAO,OAAO,OACZ,CAAC,YAAY;AACX,OAAI;IACF,MAAM,SAAS;KAAE,IAAI;KAAM,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,OAAO;IAAE;AACzD,gBAAY;AACZ,WAAO;GACR,SAAQ,GAAG;AACV,gBAAY;AACZ,QAAI,aAAa,aACf,QAAO,EAAE,IAAI,MAAO;AAEtB,UAAM;GACP;EACF,IAAG,EACJ,EACE,OAAO,MAAM,QAAQ,OAAO,CAC7B,EACF;CACF;AACF"} | ||
| {"version":3,"file":"index.js","names":["fn: (\n $: AbortableUtility,\n ) => (...params: TParams) => TReturn | PromiseLike<TReturn>","cleanupFunctions: (() => void)[]","g:\n | PromiseLike<UReturn>\n | UReturn\n | ((...params: UParams) => UReturn | PromiseLike<UReturn>)","params","fn: () => void","fn","params: T","fn: ($: AbortableUtility) => TReturn | PromiseLike<TReturn>"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Error thrown when an operation is aborted.\n */\nexport class AbortedError extends Error {\n name = 'AbortedError';\n}\n\n/**\n * Utility type to exclude functions from a type.\n */\ntype NotFunction<T> = T extends (...params: readonly any[]) => any ? never : T;\n\n/**\n * Creates an abortable asynchronous operation.\n *\n * @template TParams - The parameters of the operation\n * @template TReturn - The return type of the operation\n * @param fn - A function that receives an abort-aware utility and returns an async operation\n * @returns A function that returns a promise with an additional `abort()` method\n *\n * @example\n * ```typescript\n * const operation = abortable($ => async (id: string) => {\n * const user = await $(fetchUser(id));\n * const posts = await $(fetchPosts(user.id));\n * return posts;\n * });\n *\n * const promise = operation('user123');\n * promise.abort(); // Cancel the operation\n *\n * const result = await promise;\n * if (result.ok) {\n * console.log('Success:', result.data);\n * } else {\n * console.log('Operation was aborted');\n * }\n * ```\n */\nexport function abortable<TParams extends readonly unknown[], TReturn>(\n fn: (\n $: AbortableUtility,\n ) => (...params: TParams) => TReturn | PromiseLike<TReturn>,\n): AbortableOperation<TParams, TReturn> {\n return (...params) => {\n const control = new AbortController();\n const cleanupFunctions: (() => void)[] = [];\n\n /**\n * Abort-aware utility for wrapping promises and functions.\n */\n function $<const UReturn>(\n value: NotFunction<UReturn>,\n ): Promise<Awaited<UReturn>>;\n function $<const UReturn, UParams extends readonly unknown[]>(\n g: (...params: UParams) => UReturn | PromiseLike<UReturn>,\n ): (...params: UParams) => Promise<UReturn>;\n function $<UReturn, UParams extends readonly unknown[]>(\n g:\n | PromiseLike<UReturn>\n | UReturn\n | ((...params: UParams) => UReturn | PromiseLike<UReturn>),\n ): Promise<UReturn> | ((...params: UParams) => Promise<UReturn>) {\n if (typeof g === 'function') {\n return async (...params: UParams): Promise<UReturn> => {\n if (control.signal.aborted) throw new AbortedError();\n const result = await (\n g as unknown as (\n ...params: UParams\n ) => UReturn | PromiseLike<UReturn>\n )(...params);\n if (control.signal.aborted) throw new AbortedError();\n return result;\n };\n }\n return $<UReturn, []>(() => g)();\n }\n\n /**\n * Registers a cleanup function to be called when the operation completes or is aborted.\n * Cleanup functions are executed in reverse order of registration (LIFO).\n *\n * @param fn - The cleanup function to register\n *\n * @example\n * ```typescript\n * abortable($ => async (file: File) => {\n * const handle = await openFile(file);\n * $.cleanup(() => handle.close());\n * return processFile(handle);\n * });\n * ```\n */\n $.cleanup = (fn: () => void) => {\n if (control.signal.aborted) {\n fn();\n return;\n }\n cleanupFunctions.push(fn);\n };\n\n $.abort = () => {\n control.abort();\n };\n\n $.all = <T extends readonly unknown[] | []>(params: T) =>\n Promise.all<T>(params.map((p) => $(p))) as Promise<{\n -readonly [P in keyof T]: Awaited<T[P]>;\n }>;\n\n const runCleanup = () => {\n for (const fn of cleanupFunctions.reverse()) {\n try {\n fn();\n } catch (error) {\n // Ignore cleanup errors\n }\n }\n };\n\n return Object.assign(\n (async () => {\n try {\n const result = { ok: true, data: await fn($)(...params) } as const;\n runCleanup();\n return result;\n } catch (e) {\n runCleanup();\n if (e instanceof AbortedError) {\n return { ok: false } as const;\n }\n throw e;\n }\n })(),\n {\n abort: () => control.abort(),\n },\n );\n };\n}\n\nexport function runAbortable<TReturn>(\n fn: ($: AbortableUtility) => TReturn | PromiseLike<TReturn>,\n): AbortableTask<TReturn> {\n return abortable(($) => () => fn($))();\n}\n\n/**\n * Utility interface for abort-aware operations.\n */\ninterface AbortableUtility {\n /**\n * Wraps a promise or value to be abort-aware.\n * @param value - The promise or value to wrap\n * @returns A promise that can be aborted\n */\n <UReturn>(value: NotFunction<UReturn>): Promise<Awaited<UReturn>>;\n\n /**\n * Wraps a function to make it abort-aware.\n * @param g - The function to wrap\n * @returns A wrapped function that checks for abortion\n */\n <UReturn, UParams extends readonly unknown[]>(\n g: (...params: UParams) => UReturn | PromiseLike<UReturn>,\n ): (...params: UParams) => Promise<UReturn>;\n\n /**\n * Registers a cleanup function to be called when the operation completes or is aborted.\n * Cleanup functions are executed in reverse order of registration (LIFO).\n * @param fn - The cleanup function to register\n */\n cleanup: (fn: () => void) => void;\n\n abort: () => void;\n\n all: <T extends readonly unknown[] | []>(\n array: T,\n ) => Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>;\n}\n\n/**\n * Type for an abortable operation.\n */\ntype AbortableOperation<TParams extends readonly unknown[], TReturn> = (\n ...params: TParams\n) => AbortableTask<TReturn>;\n\nexport type AbortableTask<TReturn> = Promise<\n { ok: true; data: TReturn } | { ok: false }\n> & {\n abort: () => void;\n};\n"],"mappings":";;;;AAGA,IAAa,eAAb,cAAkC,MAAM;CACtC,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCD,SAAgB,UACdA,IAGsC;AACtC,QAAO,CAAC,GAAG,WAAW;EACpB,MAAM,UAAU,IAAI;EACpB,MAAMC,mBAAmC,CAAE;EAW3C,SAAS,EACPC,GAI+D;AAC/D,cAAW,MAAM,WACf,QAAO,OAAO,GAAGC,aAAsC;AACrD,QAAI,QAAQ,OAAO,QAAS,OAAM,IAAI;IACtC,MAAM,SAAS,MAAM,AACnB,EAGA,GAAGA,SAAO;AACZ,QAAI,QAAQ,OAAO,QAAS,OAAM,IAAI;AACtC,WAAO;GACR;AAEH,UAAO,EAAe,MAAM,EAAE,EAAE;EACjC;;;;;;;;;;;;;;;;AAiBD,IAAE,UAAU,CAACC,SAAmB;AAC9B,OAAI,QAAQ,OAAO,SAAS;AAC1B,UAAI;AACJ;GACD;AACD,oBAAiB,KAAKC,KAAG;EAC1B;AAED,IAAE,QAAQ,MAAM;AACd,WAAQ,OAAO;EAChB;AAED,IAAE,MAAM,CAAoCC,aAC1C,QAAQ,IAAO,SAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;EAIzC,MAAM,aAAa,MAAM;AACvB,QAAK,MAAMD,QAAM,iBAAiB,SAAS,CACzC,KAAI;AACF,UAAI;GACL,SAAQ,OAAO,CAEf;EAEJ;AAED,SAAO,OAAO,OACZ,CAAC,YAAY;AACX,OAAI;IACF,MAAM,SAAS;KAAE,IAAI;KAAM,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,OAAO;IAAE;AACzD,gBAAY;AACZ,WAAO;GACR,SAAQ,GAAG;AACV,gBAAY;AACZ,QAAI,aAAa,aACf,QAAO,EAAE,IAAI,MAAO;AAEtB,UAAM;GACP;EACF,IAAG,EACJ,EACE,OAAO,MAAM,QAAQ,OAAO,CAC7B,EACF;CACF;AACF;AAED,SAAgB,aACdE,IACwB;AACxB,QAAO,UAAU,CAAC,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE;AACvC"} |
+1
-1
| { | ||
| "name": "p-abort", | ||
| "version": "0.2.0", | ||
| "version": "0.2.1", | ||
| "description": "Abortable step-by-step operations", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+49
-12
@@ -113,2 +113,16 @@ # p-abort | ||
| ### Parallel Operations | ||
| Use `$.all()` to run multiple operations in parallel while maintaining abort capability: | ||
| ```typescript | ||
| const parallelFetch = abortable($ => async (ids: string[]) => { | ||
| // Fetch all data in parallel | ||
| const promises = ids.map(id => $(fetchData(id))); | ||
| const results = await $.all(promises); | ||
| return results; | ||
| }); | ||
| ``` | ||
| ## API | ||
@@ -147,20 +161,43 @@ | ||
| ## Error Handling | ||
| #### `$.all(array)` | ||
| Wraps multiple promises in a Promise.all-like operation. All promises become abort-aware and the entire operation can be cancelled. | ||
| When an operation is aborted, any in-progress steps are cancelled and the promise resolves to `{ ok: false }`. Other errors are propagated normally. | ||
| #### `$.abort()` | ||
| Manually aborts the current operation from within the operation function. | ||
| ### `runAbortable(fn)` | ||
| Creates and immediately runs an abortable operation without parameters. | ||
| #### Parameters | ||
| - `fn`: A function that receives the `$` utility and returns a value or promise | ||
| #### Returns | ||
| An `AbortableTask` that can be aborted and resolves to a result object. | ||
| ```typescript | ||
| const operation = abortable($ => async () => { | ||
| try { | ||
| const result = await $(someAsyncOperation()); | ||
| return result; | ||
| } catch (error) { | ||
| if (error instanceof AbortedError) { | ||
| console.log('Operation was cancelled'); | ||
| } | ||
| throw error; | ||
| } | ||
| import { runAbortable } from 'p-abort'; | ||
| const task = runAbortable(async $ => { | ||
| const data = await $(fetchData()); | ||
| return data; | ||
| }); | ||
| // Can abort the task | ||
| task.abort(); | ||
| const result = await task; | ||
| if (result.ok) { | ||
| console.log('Result:', result.data); | ||
| } else { | ||
| console.log('Task was aborted'); | ||
| } | ||
| ``` | ||
| ## Error Handling | ||
| When an operation is aborted, any in-progress steps are cancelled and the promise resolves to `{ ok: false }`. Other errors are propagated normally. You don't need to manually handle `AbortedError` as it's handled internally. | ||
| ## Advanced Usage | ||
@@ -167,0 +204,0 @@ |
+31
-8
@@ -52,6 +52,6 @@ /** | ||
| */ | ||
| function $<UReturn>( | ||
| value: NotFunction<PromiseLike<UReturn> | UReturn>, | ||
| ): Promise<UReturn>; | ||
| function $<UReturn, UParams extends readonly unknown[]>( | ||
| function $<const UReturn>( | ||
| value: NotFunction<UReturn>, | ||
| ): Promise<Awaited<UReturn>>; | ||
| function $<const UReturn, UParams extends readonly unknown[]>( | ||
| g: (...params: UParams) => UReturn | PromiseLike<UReturn>, | ||
@@ -103,2 +103,11 @@ ): (...params: UParams) => Promise<UReturn>; | ||
| $.abort = () => { | ||
| control.abort(); | ||
| }; | ||
| $.all = <T extends readonly unknown[] | []>(params: T) => | ||
| Promise.all<T>(params.map((p) => $(p))) as Promise<{ | ||
| -readonly [P in keyof T]: Awaited<T[P]>; | ||
| }>; | ||
| const runCleanup = () => { | ||
@@ -135,2 +144,8 @@ for (const fn of cleanupFunctions.reverse()) { | ||
| export function runAbortable<TReturn>( | ||
| fn: ($: AbortableUtility) => TReturn | PromiseLike<TReturn>, | ||
| ): AbortableTask<TReturn> { | ||
| return abortable(($) => () => fn($))(); | ||
| } | ||
| /** | ||
@@ -145,5 +160,3 @@ * Utility interface for abort-aware operations. | ||
| */ | ||
| <UReturn>( | ||
| value: NotFunction<PromiseLike<UReturn> | UReturn>, | ||
| ): Promise<UReturn>; | ||
| <UReturn>(value: NotFunction<UReturn>): Promise<Awaited<UReturn>>; | ||
@@ -165,2 +178,8 @@ /** | ||
| cleanup: (fn: () => void) => void; | ||
| abort: () => void; | ||
| all: <T extends readonly unknown[] | []>( | ||
| array: T, | ||
| ) => Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>; | ||
| } | ||
@@ -173,4 +192,8 @@ | ||
| ...params: TParams | ||
| ) => Promise<{ ok: true; data: TReturn } | { ok: false }> & { | ||
| ) => AbortableTask<TReturn>; | ||
| export type AbortableTask<TReturn> = Promise< | ||
| { ok: true; data: TReturn } | { ok: false } | ||
| > & { | ||
| abort: () => void; | ||
| }; |
33514
15.71%9
12.5%523
5.66%266
16.16%