tasuku 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  → [Try it out online](https://stackblitz.com/edit/tasuku-demo?file=index.js&devtoolsheight=50&view=editor)
14
14
 
15
- <sub>Support this project by starring and sharing it. [Follow me](https://github.com/privatenumber) to see what other cool projects I'm working on.</sub>
15
+ <sub>Found this package useful? Show your support & appreciation by [sponsoring](https://github.com/sponsors/privatenumber)! ❤️</sub>
16
16
 
17
17
  ## Install
18
18
  ```sh
@@ -25,7 +25,7 @@ npm i tasuku
25
25
  For example, here's a simple script that copies a file from path A to B.
26
26
 
27
27
  ```ts
28
- import { copyFile } from 'fs/promises'
28
+ import { copyFile } from 'node:fs/promises'
29
29
  import task from 'tasuku'
30
30
 
31
31
  task('Copying file from path A to B', async ({ setTitle }) => {
@@ -230,7 +230,7 @@ Returns a Promise that resolves with object:
230
230
  ```ts
231
231
  type TaskAPI = {
232
232
  // Result from taskFunction
233
- result: any
233
+ result: unknown
234
234
 
235
235
  // State of the task
236
236
  state: 'error' | 'warning' | 'success'
@@ -257,7 +257,7 @@ type TaskFunction = (taskInnerApi: {
257
257
  setOutput(output: string | { message: string }): void
258
258
  setWarning(warning: Error | string): void
259
259
  setError(error: Error | string): void
260
- }) => Promise<any>
260
+ }) => Promise<unknown>
261
261
  ```
262
262
 
263
263
  Required: true
@@ -292,7 +292,7 @@ Returns a Promise that resolves with object:
292
292
  // The results from the taskFunctions
293
293
  type TaskGroupAPI = {
294
294
  // Result from taskFunction
295
- result: any
295
+ result: unknown
296
296
 
297
297
  // State of the task
298
298
  state: 'error' | 'warning' | 'success'
@@ -339,11 +339,11 @@ _Tasuku_ or タスク is the phonetic Japanese pronounciation of the word "task
339
339
 
340
340
  ### Why did you make this?
341
341
 
342
- For writing scripts or CLI tools. _Tasuku_ is a great way to convey the state of the tasks that are running in your script without being imposing about the way you write your code.
342
+ I built _Tasuku_ as a lightweight task runner for scripts and CLI tools. It's designed to show task progress clearly without forcing a rigid structure on how you write your code.
343
343
 
344
- Major shoutout to [listr](https://github.com/SamVerschueren/listr) + [listr2](https://github.com/cenk1cenk2/listr2) for being the motivation and visual inspiration for _Tasuku_, and for being my go-to task runner for a long time. I made _Tasuku_ because I eventually found that they were too structured and declarative for my needs.
344
+ Big thanks to [listr](https://github.com/SamVerschueren/listr) and [listr2](https://github.com/cenk1cenk2/listr2), which inspired both the visuals and the idea—I've relied on them for years. But over time, I found their declarative approach too restrictive for my workflow, so I created something simpler and more flexible.
345
345
 
346
- Big thanks to [ink](https://github.com/vadimdemedes/ink) for doing all the heavy lifting for rendering interfaces in the terminal. Implementing a dynamic task list that doesn't interfere with `console.logs()` wouldn't have been so easy without it.
346
+ _Tasuku_ uses its own minimal ANSI-based renderer for terminal output, giving you smooth `console.log()` integration with zero runtime dependencies. The rendering model was originally inspired by [ink](https://github.com/vadimdemedes/ink)'s approach to terminal UIs.
347
347
 
348
348
  ### Doesn't the usage of nested `task` functions violate ESLint's [no-shadow](https://eslint.org/docs/rules/no-shadow)?
349
349
  Yes, but it should be fine as you don't need access to other `task` functions aside from the immediate one.
@@ -351,3 +351,11 @@ Yes, but it should be fine as you don't need access to other `task` functions as
351
351
  Put `task` in the allow list:
352
352
  - `"no-shadow": ["error", { "allow": ["task"] }]`
353
353
  - `"@typescript-eslint/no-shadow": ["error", { "allow": ["task"] }]`
354
+
355
+
356
+ ## Sponsors
357
+ <p align="center">
358
+ <a href="https://github.com/sponsors/privatenumber">
359
+ <img src="https://cdn.jsdelivr.net/gh/privatenumber/sponsors/sponsorkit/sponsors.svg">
360
+ </a>
361
+ </p>
package/dist/index.cjs ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";var Ye=Object.defineProperty;var s=(e,t)=>Ye(e,"name",{value:t,configurable:!0});var V=require("os"),K=require("stream"),W=require("process"),ze=require("tty");function He(e,t=1,r={}){const{indent:n=" ",includeEmptyLines:o=!1}=r;if(typeof e!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof e}\``);if(typeof t!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof t}\``);if(t<0)throw new RangeError(`Expected \`count\` to be at least 0, got \`${t}\``);if(typeof n!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof n}\``);if(t===0)return e;const a=o?/^/gm:/^(?!\s*$)/gm;return e.replace(a,n.repeat(t))}s(He,"indentString");function Ve(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}s(Ve,"escapeStringRegexp");const Q=/\s+at.*[(\s](.*)\)?/,Ke=/^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/,Qe=typeof V.homedir=="undefined"?"":V.homedir().replace(/\\/g,"/");function Je(e,{pretty:t=!1,basePath:r}={}){const n=r&&new RegExp(`(at | \\()${Ve(r.replace(/\\/g,"/"))}`,"g");if(typeof e=="string")return e.replace(/\\/g,"/").split(`
2
+ `).filter(o=>{const a=o.match(Q);if(a===null||!a[1])return!0;const l=a[1];return l.includes(".app/Contents/Resources/electron.asar")||l.includes(".app/Contents/Resources/default_app.asar")||l.includes("node_modules/electron/dist/resources/electron.asar")||l.includes("node_modules/electron/dist/resources/default_app.asar")?!1:!Ke.test(l)}).filter(o=>o.trim()!=="").map(o=>(n&&(o=o.replace(n,"$1")),t&&(o=o.replace(Q,(a,l)=>a.replace(l,l.replace(Qe,"~")))),o)).join(`
3
+ `)}s(Je,"cleanStack");var Xe=Object.defineProperty,J=s(e=>{throw TypeError(e)},"__typeError"),Ze=s((e,t,r)=>t in e?Xe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,"__defNormalProp"),et=s((e,t,r)=>Ze(e,t+"",r),"__publicField"),X=s((e,t,r)=>t.has(e)||J("Cannot "+r),"__accessCheck"),tt=s((e,t,r)=>(X(e,t,"read from private field"),r?r.call(e):t.get(e)),"__privateGet"),rt=s((e,t,r)=>t.has(e)?J("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),"__privateAdd"),nt=s((e,t,r,n)=>(X(e,t,"write to private field"),t.set(e,r),r),"__privateSet"),O;const ot=s(e=>e.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g,""),"cleanInternalStack"),z=class z extends Error{constructor(t){if(!Array.isArray(t))throw new TypeError(`Expected input to be an Array, got ${typeof t}`);t=t.map(n=>n instanceof Error?n:n!==null&&typeof n=="object"?Object.assign(new Error(n.message),n):new Error(n));let r=t.map(n=>typeof n.stack=="string"&&n.stack.length>0?ot(Je(n.stack)):String(n)).join(`
4
+ `);r=`
5
+ `+He(r,4),super(r),rt(this,O),et(this,"name","AggregateError"),nt(this,O,t)}get errors(){return tt(this,O).slice()}};s(z,"AggregateError");let F=z;O=new WeakMap;const H=class H extends Error{constructor(t){super(),this.name="AbortError",this.message=t}};s(H,"AbortError");let k=H;const Z=s(e=>globalThis.DOMException===void 0?new k(e):new DOMException(e),"getDOMException"),ee=s(e=>{const t=e.reason===void 0?Z("This operation was aborted."):e.reason;return t instanceof Error?t:Z(t)},"getAbortedReason");async function st(e,t,{concurrency:r=Number.POSITIVE_INFINITY,stopOnError:n=!0,signal:o}={}){return new Promise((a,l)=>{if(e[Symbol.iterator]===void 0&&e[Symbol.asyncIterator]===void 0)throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof e})`);if(typeof t!="function")throw new TypeError("Mapper function is required");if(!((Number.isSafeInteger(r)||r===Number.POSITIVE_INFINITY)&&r>=1))throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${r}\` (${typeof r})`);const p=[],f=[],v=new Map;let d=!1,_=!1,S=!1,T=0,R=0;const M=e[Symbol.iterator]===void 0?e[Symbol.asyncIterator]():e[Symbol.iterator](),h=s(i=>{d=!0,_=!0,l(i)},"reject");o&&(o.aborted&&h(ee(o)),o.addEventListener("abort",()=>{h(ee(o))}));const y=s(async()=>{if(_)return;const i=await M.next(),c=R;if(R++,i.done){if(S=!0,T===0&&!_){if(!n&&f.length>0){h(new F(f));return}if(_=!0,v.size===0){a(p);return}const u=[];for(const[g,P]of p.entries())v.get(g)!==te&&u.push(P);a(u)}return}T++,(async()=>{try{const u=await i.value;if(_)return;const g=await t(u,c);g===te&&v.set(c,g),p[c]=g,T--,await y()}catch(u){if(n)h(u);else{f.push(u),T--;try{await y()}catch(g){h(g)}}}})()},"next");(async()=>{for(let i=0;i<r;i++){try{await y()}catch(c){h(c);break}if(S||d)break}})()})}s(st,"pMap");const te=Symbol("skip"),re=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"];let G={};const it=s(e=>{const t=new K.PassThrough,r=new K.PassThrough;t.write=o=>{e("stdout",o)},r.write=o=>{e("stderr",o)};const n=new console.Console(t,r);for(const o of re)G[o]=console[o],console[o]=n[o];return()=>{for(const o of re)console[o]=G[o];G={}}},"patchConsole");var ne,oe,se,ie,le,ae,ce,ue,de,pe,fe,ge,ve,he,we,me,_e,Te,ye,be,xe,Ee,Ce,Ie,Se,Re,Oe,$e,Ae,Ne,Me;const B=((ne=globalThis.window)==null?void 0:ne.document)!==void 0;(se=(oe=globalThis.process)==null?void 0:oe.versions)==null||se.node,(le=(ie=globalThis.process)==null?void 0:ie.versions)==null||le.bun,(ce=(ae=globalThis.Deno)==null?void 0:ae.version)==null||ce.deno,(de=(ue=globalThis.process)==null?void 0:ue.versions)==null||de.electron,(fe=(pe=globalThis.navigator)==null?void 0:pe.userAgent)==null||fe.includes("jsdom"),typeof WorkerGlobalScope!="undefined"&&globalThis instanceof WorkerGlobalScope,typeof DedicatedWorkerGlobalScope!="undefined"&&globalThis instanceof DedicatedWorkerGlobalScope,typeof SharedWorkerGlobalScope!="undefined"&&globalThis instanceof SharedWorkerGlobalScope,typeof ServiceWorkerGlobalScope!="undefined"&&globalThis instanceof ServiceWorkerGlobalScope;const E=(ve=(ge=globalThis.navigator)==null?void 0:ge.userAgentData)==null?void 0:ve.platform;E==="macOS"||((he=globalThis.navigator)==null?void 0:he.platform)==="MacIntel"||((me=(we=globalThis.navigator)==null?void 0:we.userAgent)==null?void 0:me.includes(" Mac "))===!0||((_e=globalThis.process)==null||_e.platform),E==="Windows"||((Te=globalThis.navigator)==null?void 0:Te.platform)==="Win32"||((ye=globalThis.process)==null||ye.platform),E==="Linux"||((xe=(be=globalThis.navigator)==null?void 0:be.platform)==null?void 0:xe.startsWith("Linux"))===!0||((Ce=(Ee=globalThis.navigator)==null?void 0:Ee.userAgent)==null?void 0:Ce.includes(" Linux "))===!0||((Ie=globalThis.process)==null||Ie.platform),E==="iOS"||((Se=globalThis.navigator)==null?void 0:Se.platform)==="MacIntel"&&((Re=globalThis.navigator)==null?void 0:Re.maxTouchPoints)>1||/iPad|iPhone|iPod/.test((Oe=globalThis.navigator)==null?void 0:Oe.platform),E==="Android"||(($e=globalThis.navigator)==null?void 0:$e.platform)==="Android"||((Ne=(Ae=globalThis.navigator)==null?void 0:Ae.userAgent)==null?void 0:Ne.includes(" Android "))===!0||((Me=globalThis.process)==null||Me.platform);const $="\x1B[";!B&&W.env.TERM_PROGRAM,!B&&W.platform,B||W.cwd;const j=s((e=1)=>$+e+"A","cursorUp"),lt=$+"?25l",at=$+"?25h",C=$+"2K";var Pe,De,q,We,Fe;const ct=(Fe=(We=(q=(De=(Pe=ze)==null?void 0:Pe.WriteStream)==null?void 0:De.prototype)==null?void 0:q.hasColors)==null?void 0:We.call(q))!=null?Fe:!1,I=s((e,t)=>{if(!ct)return o=>o;const r=`\x1B[${e}m`,n=`\x1B[${t}m`;return o=>{const a=o+"";let l=a.indexOf(n);if(l===-1)return r+a+n;let p=r,f=0;const d=(t===22?n:"")+r;for(;l!==-1;)p+=a.slice(f,l)+d,f=l+n.length,l=a.indexOf(n,f);return p+=a.slice(f)+n,p}},"format"),ut=I(2,22),ke=I(31,39),dt=I(32,39),A=I(33,39),L=I(90,39),Ge=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],N=!!(process.env.CI||process.env.CONTINUOUS_INTEGRATION||process.env.BUILD_NUMBER),pt=s(e=>process.env.NO_COLOR||process.env.NODE_DISABLE_COLORS?!1:e.hasColors?e.hasColors():process.env.FORCE_COLOR!==void 0?process.env.FORCE_COLOR!=="0":e.isTTY!==!1,"detectColors"),w=s((e,t,r)=>e?t(r):r,"colorize"),Be=s(e=>{for(const t of e)if(t.state==="loading"||t.state==="pending"||t.children&&t.children.length>0&&!Be(t.children))return!1;return!0},"areAllTasksDone"),ft=s((e,t=process.stdout)=>{let r=0,n,o,a="",l=0,p,f=!1;const v=t.isTTY!==!1,d=pt(t),_=s((i,c)=>i==="pending"?w(d,L,"\u25FC"):i==="loading"?c?w(d,A,"\u276F"):w(d,A,Ge[r]):i==="success"?c?w(d,A,"\u276F"):w(d,dt,"\u2714"):i==="error"?c?w(d,ke,"\u276F"):w(d,ke,"\u2716"):i==="warning"?w(d,A,"\u26A0"):w(d,L,"\u25FC"),"getIcon"),S=s((i,c)=>{const u=" ".repeat(c),g=i.children&&i.children.length>0,P=_(i.state,g);let b=`${u}${P} ${i.title}`;if(i.status){const D=d?ut(`[${i.status}]`):`[${i.status}]`;b+=` ${D}`}if(b+=`
6
+ `,i.output){const D=`${u} `,Le=s(x=>d?L(x):x,"styleText");b+=`${i.output.split(`
7
+ `).map((x,Ue)=>`${D}${Le(Ue===0?`\u2192 ${x}`:x)}`).join(`
8
+ `)}
9
+ `}return g&&(b+=T(i.children,c+1)),b},"renderTask"),T=s((i,c=0)=>i.map(u=>S(u,c)).join(""),"renderTaskList"),R=s((i,c)=>{if(l>0){for(let u=0;u<l;u+=1)t.write(C),t.write(j());t.write(C),t.write("\x1B[G"),l=0}t.write(c),e.length>0&&(t.write(`
10
+ `),a=`
11
+ `,l=1)},"handleConsoleOutput"),M=s(()=>{const i=T(e),c=Be(e);if(c&&n&&(clearInterval(n),n=void 0),N){i!==a&&(t.write(i),a=i);return}if(!f&&v&&i!==""&&i!==`
12
+ `&&!c&&(t.write(lt),f=!0),l>0){for(let u=0;u<l;u+=1)t.write(C),t.write(j());t.write(C),t.write("\x1B[G")}t.write(i),a=i,l=i.split(`
13
+ `).length-1},"render"),h=s(()=>{o||(o=setTimeout(()=>{o=void 0,M()},33))},"scheduleRender"),y=s(()=>{if(n&&clearInterval(n),o&&clearTimeout(o),p&&p(),!N&&v&&l>0)for(let i=0;i<l;i+=1)t.write(C),t.write(j());!N&&v&&t.write(at)},"destroy");return N||(p=it(R),v&&(n=setInterval(()=>{r=(r+1)%Ge.length,h()},80))),{triggerRender:h,destroy:y}},"createRenderer");let U;const gt=s(e=>{U=e},"setRenderCallback"),vt=s(e=>new Proxy(e,{set(t,r,n){return Reflect.set(t,r,n),U&&U(),!0}}),"reactive"),Y=Symbol("run"),ht=s(e=>{const t={task:qe(e.children),setTitle(r){e.title=r},setStatus(r){e.status=r},setOutput(r){e.output=typeof r=="string"?r:"message"in r?r.message:""},setWarning(r){e.state="warning",r!==void 0&&t.setOutput(r)},setError(r){e.state="error",r!==void 0&&t.setOutput(r)}};return t},"createTaskInnerApi");let m;const je=s((e,t,r)=>{m||(m=ft(e),gt(()=>m.triggerRender()),e.isRoot=!0);const n=vt({title:t,state:"pending",children:[]});return e.push(n),{task:n,[Y]:async()=>{const o=ht(n);n.state="loading";let a;try{a=await r(o)}catch(l){throw o.setError(l),l}return n.state==="loading"&&(n.state="success"),a},clear:s(()=>{const o=e.indexOf(n);o!==-1&&e.splice(o,1),m&&m.triggerRender(),e.isRoot&&e.length===0&&m&&(m.destroy(),m=void 0)},"clear")}},"registerTask");function qe(e){const t=s(async(r,n)=>{const o=je(e,r,n);return{result:await o[Y](),get state(){return o.task.state},clear:o.clear}},"task");return t.group=(async(r,n)=>{const o=r((l,p)=>je(e,l,p)),a=await st(o,async l=>({result:await l[Y](),get state(){return l.task.state},clear:l.clear}),{concurrency:1,...n});return Object.assign(a,{clear:s(()=>{for(const l of o)l.clear()},"clear")})}),t}s(qe,"createTaskFunction");const wt=[];var mt=qe(wt);module.exports=mt;
@@ -18,17 +18,41 @@ interface Options {
18
18
  @default true
19
19
  */
20
20
  readonly stopOnError?: boolean;
21
+
22
+ /**
23
+ You can abort the promises using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
24
+
25
+ **Requires Node.js 16 or later.*
26
+
27
+ @example
28
+ ```
29
+ import pMap from 'p-map';
30
+ import delay from 'delay';
31
+
32
+ const abortController = new AbortController();
33
+
34
+ setTimeout(() => {
35
+ abortController.abort();
36
+ }, 500);
37
+
38
+ const mapper = async value => value;
39
+
40
+ await pMap([delay(1000), delay(1000)], mapper, {signal: abortController.signal});
41
+ // Throws AbortError (DOMException) after 500 ms.
42
+ ```
43
+ */
44
+ readonly signal?: AbortSignal;
21
45
  }
22
46
 
23
- declare type State = 'pending' | 'loading' | 'error' | 'warning' | 'success';
24
- declare type TaskObject = {
47
+ type State = 'pending' | 'loading' | 'error' | 'warning' | 'success';
48
+ type TaskObject = {
25
49
  title: string;
26
50
  state: State;
27
51
  children: TaskObject[];
28
52
  status?: string;
29
53
  output?: string;
30
54
  };
31
- declare type TaskInnerAPI = {
55
+ type TaskInnerAPI = {
32
56
  task: Task;
33
57
  setTitle(title: string): void;
34
58
  setStatus(status?: string): void;
@@ -38,19 +62,19 @@ declare type TaskInnerAPI = {
38
62
  message: string;
39
63
  }): void;
40
64
  };
41
- declare type TaskFunction<T> = (innerApi: TaskInnerAPI) => Promise<T>;
65
+ type TaskFunction<T> = (innerApi: TaskInnerAPI) => Promise<T>;
42
66
  declare const runSymbol: unique symbol;
43
- declare type RegisteredTask<T = any> = {
67
+ type RegisteredTask<T = unknown> = {
44
68
  [runSymbol]: () => Promise<T>;
45
69
  task: TaskObject;
46
70
  clear: () => void;
47
71
  };
48
- declare type TaskAPI<Result = any> = {
72
+ type TaskAPI<Result = unknown> = {
49
73
  result: Result;
50
74
  state: State;
51
75
  clear: () => void;
52
76
  };
53
- declare type Task = (<TaskReturnType>(
77
+ type Task = (<TaskReturnType>(
54
78
  /**
55
79
  * The task title
56
80
  */
@@ -61,13 +85,13 @@ title: string,
61
85
  taskFunction: TaskFunction<TaskReturnType>) => Promise<TaskAPI<TaskReturnType>>) & {
62
86
  group: TaskGroup;
63
87
  };
64
- declare type TaskGroupResults<RegisteredTasks extends RegisteredTask[]> = {
88
+ type TaskGroupResults<RegisteredTasks extends RegisteredTask[]> = {
65
89
  [Key in keyof RegisteredTasks]: (RegisteredTasks[Key] extends RegisteredTask<infer ReturnType> ? TaskAPI<ReturnType> : unknown);
66
90
  };
67
- declare type TaskGroupAPI<Results = any[]> = Results & {
91
+ type TaskGroupAPI<Results = unknown[]> = Results & {
68
92
  clear(): void;
69
93
  };
70
- declare type CreateTask = <ReturnType>(
94
+ type CreateTask = <ReturnType>(
71
95
  /**
72
96
  * The task title
73
97
  */
@@ -76,8 +100,9 @@ title: string,
76
100
  * The task function
77
101
  */
78
102
  taskFunction: TaskFunction<ReturnType>) => RegisteredTask<ReturnType>;
79
- declare type TaskGroup = <RegisteredTasks extends RegisteredTask[]>(createTasks: (taskCreator: CreateTask) => readonly [...RegisteredTasks], options?: Options) => Promise<TaskGroupAPI<TaskGroupResults<RegisteredTasks>>>;
103
+ type TaskGroup = <RegisteredTasks extends RegisteredTask[]>(createTasks: (taskCreator: CreateTask) => readonly [...RegisteredTasks], options?: Options) => Promise<TaskGroupAPI<TaskGroupResults<RegisteredTasks>>>;
80
104
 
81
105
  declare const _default: Task;
82
106
 
83
- export { Task, TaskAPI, TaskFunction, TaskGroupAPI, TaskInnerAPI, _default as default };
107
+ export { _default as default };
108
+ export type { Task, TaskAPI, TaskFunction, TaskGroupAPI, TaskInnerAPI };
@@ -0,0 +1,108 @@
1
+ interface Options {
2
+ /**
3
+ Number of concurrently pending promises returned by `mapper`.
4
+
5
+ Must be an integer from 1 and up or `Infinity`.
6
+
7
+ @default Infinity
8
+ */
9
+ readonly concurrency?: number;
10
+
11
+ /**
12
+ When `true`, the first mapper rejection will be rejected back to the consumer.
13
+
14
+ When `false`, instead of stopping when a promise rejects, it will wait for all the promises to settle and then reject with an [aggregated error](https://github.com/sindresorhus/aggregate-error) containing all the errors from the rejected promises.
15
+
16
+ Caveat: When `true`, any already-started async mappers will continue to run until they resolve or reject. In the case of infinite concurrency with sync iterables, *all* mappers are invoked on startup and will continue after the first rejection. [Issue #51](https://github.com/sindresorhus/p-map/issues/51) can be implemented for abort control.
17
+
18
+ @default true
19
+ */
20
+ readonly stopOnError?: boolean;
21
+
22
+ /**
23
+ You can abort the promises using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
24
+
25
+ **Requires Node.js 16 or later.*
26
+
27
+ @example
28
+ ```
29
+ import pMap from 'p-map';
30
+ import delay from 'delay';
31
+
32
+ const abortController = new AbortController();
33
+
34
+ setTimeout(() => {
35
+ abortController.abort();
36
+ }, 500);
37
+
38
+ const mapper = async value => value;
39
+
40
+ await pMap([delay(1000), delay(1000)], mapper, {signal: abortController.signal});
41
+ // Throws AbortError (DOMException) after 500 ms.
42
+ ```
43
+ */
44
+ readonly signal?: AbortSignal;
45
+ }
46
+
47
+ type State = 'pending' | 'loading' | 'error' | 'warning' | 'success';
48
+ type TaskObject = {
49
+ title: string;
50
+ state: State;
51
+ children: TaskObject[];
52
+ status?: string;
53
+ output?: string;
54
+ };
55
+ type TaskInnerAPI = {
56
+ task: Task;
57
+ setTitle(title: string): void;
58
+ setStatus(status?: string): void;
59
+ setWarning(warning?: Error | string): void;
60
+ setError(error?: Error | string): void;
61
+ setOutput(output: string | {
62
+ message: string;
63
+ }): void;
64
+ };
65
+ type TaskFunction<T> = (innerApi: TaskInnerAPI) => Promise<T>;
66
+ declare const runSymbol: unique symbol;
67
+ type RegisteredTask<T = unknown> = {
68
+ [runSymbol]: () => Promise<T>;
69
+ task: TaskObject;
70
+ clear: () => void;
71
+ };
72
+ type TaskAPI<Result = unknown> = {
73
+ result: Result;
74
+ state: State;
75
+ clear: () => void;
76
+ };
77
+ type Task = (<TaskReturnType>(
78
+ /**
79
+ * The task title
80
+ */
81
+ title: string,
82
+ /**
83
+ * The task function
84
+ */
85
+ taskFunction: TaskFunction<TaskReturnType>) => Promise<TaskAPI<TaskReturnType>>) & {
86
+ group: TaskGroup;
87
+ };
88
+ type TaskGroupResults<RegisteredTasks extends RegisteredTask[]> = {
89
+ [Key in keyof RegisteredTasks]: (RegisteredTasks[Key] extends RegisteredTask<infer ReturnType> ? TaskAPI<ReturnType> : unknown);
90
+ };
91
+ type TaskGroupAPI<Results = unknown[]> = Results & {
92
+ clear(): void;
93
+ };
94
+ type CreateTask = <ReturnType>(
95
+ /**
96
+ * The task title
97
+ */
98
+ title: string,
99
+ /**
100
+ * The task function
101
+ */
102
+ taskFunction: TaskFunction<ReturnType>) => RegisteredTask<ReturnType>;
103
+ type TaskGroup = <RegisteredTasks extends RegisteredTask[]>(createTasks: (taskCreator: CreateTask) => readonly [...RegisteredTasks], options?: Options) => Promise<TaskGroupAPI<TaskGroupResults<RegisteredTasks>>>;
104
+
105
+ declare const _default: Task;
106
+
107
+ export { _default as default };
108
+ export type { Task, TaskAPI, TaskFunction, TaskGroupAPI, TaskInnerAPI };