@praxisjs/concurrent 1.2.13 → 1.3.0

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/__tests__/decorators.test.js +60 -3
  3. package/dist/__tests__/decorators.test.js.map +1 -1
  4. package/dist/__tests__/pool.test.js +103 -70
  5. package/dist/__tests__/pool.test.js.map +1 -1
  6. package/dist/__tests__/queue.test.js +86 -71
  7. package/dist/__tests__/queue.test.js.map +1 -1
  8. package/dist/__tests__/task.test.js +90 -68
  9. package/dist/__tests__/task.test.js.map +1 -1
  10. package/dist/__tests__/utils.test.d.ts +2 -0
  11. package/dist/__tests__/utils.test.d.ts.map +1 -0
  12. package/dist/__tests__/utils.test.js +32 -0
  13. package/dist/__tests__/utils.test.js.map +1 -0
  14. package/dist/decorators.d.ts +13 -3
  15. package/dist/decorators.d.ts.map +1 -1
  16. package/dist/decorators.js +8 -3
  17. package/dist/decorators.js.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/pool.d.ts +4 -1
  23. package/dist/pool.d.ts.map +1 -1
  24. package/dist/pool.js +29 -5
  25. package/dist/pool.js.map +1 -1
  26. package/dist/queue.d.ts +3 -1
  27. package/dist/queue.d.ts.map +1 -1
  28. package/dist/queue.js +35 -9
  29. package/dist/queue.js.map +1 -1
  30. package/dist/task.d.ts +3 -1
  31. package/dist/task.d.ts.map +1 -1
  32. package/dist/task.js +16 -3
  33. package/dist/task.js.map +1 -1
  34. package/dist/utils.d.ts +9 -0
  35. package/dist/utils.d.ts.map +1 -0
  36. package/dist/utils.js +26 -0
  37. package/dist/utils.js.map +1 -0
  38. package/package.json +4 -4
  39. package/src/__tests__/decorators.test.ts +78 -3
  40. package/src/__tests__/pool.test.ts +110 -102
  41. package/src/__tests__/queue.test.ts +103 -114
  42. package/src/__tests__/task.test.ts +96 -90
  43. package/src/__tests__/utils.test.ts +48 -0
  44. package/src/decorators.ts +23 -6
  45. package/src/index.ts +1 -0
  46. package/src/pool.ts +33 -4
  47. package/src/queue.ts +36 -8
  48. package/src/task.ts +18 -2
  49. package/src/utils.ts +24 -0
@@ -1,22 +1,32 @@
1
1
  import type { Computed } from "@praxisjs/shared";
2
2
  type AnyAsyncFn = (this: any, ...args: any[]) => Promise<any>;
3
- export type TaskDecorated<T extends AnyAsyncFn> = ((...args: Parameters<T>) => ReturnType<T>) & {
3
+ /**
4
+ * Strips the leading AbortSignal from a parameter tuple when present,
5
+ * so decorated fields expose only the user-visible arguments.
6
+ *
7
+ * Examples:
8
+ * [AbortSignal, number, string] → [number, string]
9
+ * [number, string] → [number, string] (unchanged)
10
+ */
11
+ type DropSignalIfPresent<T extends unknown[]> = T extends [AbortSignal, ...infer R] ? R : T;
12
+ export type TaskDecorated<T extends AnyAsyncFn> = ((...args: DropSignalIfPresent<Parameters<T>>) => ReturnType<T>) & {
4
13
  loading: Computed<boolean>;
5
14
  error: Computed<Error | null>;
6
15
  lastResult: Computed<Awaited<ReturnType<T>> | null>;
7
16
  cancelAll(): void;
8
17
  };
9
- export type QueueDecorated<T extends AnyAsyncFn> = ((...args: Parameters<T>) => ReturnType<T>) & {
18
+ export type QueueDecorated<T extends AnyAsyncFn> = ((...args: DropSignalIfPresent<Parameters<T>>) => ReturnType<T>) & {
10
19
  loading: Computed<boolean>;
11
20
  pending: Computed<number>;
12
21
  error: Computed<Error | null>;
13
22
  clear(): void;
14
23
  };
15
- export type PoolDecorated<T extends AnyAsyncFn> = ((...args: Parameters<T>) => ReturnType<T>) & {
24
+ export type PoolDecorated<T extends AnyAsyncFn> = ((...args: DropSignalIfPresent<Parameters<T>>) => ReturnType<T>) & {
16
25
  loading: Computed<boolean>;
17
26
  active: Computed<number>;
18
27
  pending: Computed<number>;
19
28
  error: Computed<Error | null>;
29
+ cancelAll(): void;
20
30
  };
21
31
  export type TaskOf<C, K extends keyof C> = C[K] extends AnyAsyncFn ? TaskDecorated<C[K]> : never;
22
32
  export type QueueOf<C, K extends keyof C> = C[K] extends AnyAsyncFn ? QueueDecorated<C[K]> : never;
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAOjD,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAI9D,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,UAAU,IAC5C,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IAC5C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpD,SAAS,IAAI,IAAI,CAAC;CACnB,CAAC;AAEJ,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,UAAU,IAC7C,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IAC5C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEJ,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,UAAU,IAC5C,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IAC5C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;CAC/B,CAAC;AAIJ,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACrC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACtC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AAEzD,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACrC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AAIxD,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,uHAYtC;AAID,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,uHAYvC;AAID,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,SAAI,uHAYvD"}
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQjD,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,KAAK,mBAAmB,CAAC,CAAC,SAAS,OAAO,EAAE,IAC1C,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAI9C,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,UAAU,IAC5C,CAAC,CAAC,GAAG,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACjE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpD,SAAS,IAAI,IAAI,CAAC;CACnB,CAAC;AAEJ,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,UAAU,IAC7C,CAAC,CAAC,GAAG,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACjE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEJ,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,UAAU,IAC5C,CAAC,CAAC,GAAG,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACjE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,SAAS,IAAI,IAAI,CAAC;CACnB,CAAC;AAIJ,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACrC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACtC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AAEzD,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACrC,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AAIxD,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,uHActC;AAID,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,uHAavC;AAID,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,SAAI,uHAavD"}
@@ -2,14 +2,17 @@ import { createFieldDecorator } from "@praxisjs/decorators";
2
2
  import { pool } from "./pool";
3
3
  import { queue } from "./queue";
4
4
  import { task } from "./task";
5
+ import { acceptsSignal } from "./utils";
5
6
  // ── @Task ──────────────────────────────────────────────────────────────────────
6
7
  export function Task(methodName) {
7
8
  return createFieldDecorator({
8
9
  bind(instance, _name) {
9
10
  const inst = instance;
11
+ // Detect signal on the unbound method — bound functions lose their source.
12
+ const wantsSignal = acceptsSignal(inst[methodName]);
10
13
  return {
11
14
  descriptor: {
12
- value: task(inst[methodName].bind(instance)),
15
+ value: task(inst[methodName].bind(instance), { signal: wantsSignal }),
13
16
  writable: true,
14
17
  },
15
18
  };
@@ -21,9 +24,10 @@ export function Queue(methodName) {
21
24
  return createFieldDecorator({
22
25
  bind(instance, _name) {
23
26
  const inst = instance;
27
+ const wantsSignal = acceptsSignal(inst[methodName]);
24
28
  return {
25
29
  descriptor: {
26
- value: queue(inst[methodName].bind(instance)),
30
+ value: queue(inst[methodName].bind(instance), { signal: wantsSignal }),
27
31
  writable: true,
28
32
  },
29
33
  };
@@ -35,9 +39,10 @@ export function Pool(methodName, concurrency = 1) {
35
39
  return createFieldDecorator({
36
40
  bind(instance, _name) {
37
41
  const inst = instance;
42
+ const wantsSignal = acceptsSignal(inst[methodName]);
38
43
  return {
39
44
  descriptor: {
40
- value: pool(concurrency, inst[methodName].bind(instance)),
45
+ value: pool(concurrency, inst[methodName].bind(instance), { signal: wantsSignal }),
41
46
  writable: true,
42
47
  },
43
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AA0C9B,kFAAkF;AAElF,MAAM,UAAU,IAAI,CAAC,UAAkB;IACrC,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAgB,EAAE,KAAa;YAClC,MAAM,IAAI,GAAG,QAAsC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE;oBACV,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAY;oBACvD,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,KAAK,CAAC,UAAkB;IACtC,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAgB,EAAE,KAAa;YAClC,MAAM,IAAI,GAAG,QAAsC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE;oBACV,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAY;oBACxD,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,IAAI,CAAC,UAAkB,EAAE,WAAW,GAAG,CAAC;IACtD,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAgB,EAAE,KAAa;YAClC,MAAM,IAAI,GAAG,QAAsC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE;oBACV,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAY;oBACpE,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAsDxC,kFAAkF;AAElF,MAAM,UAAU,IAAI,CAAC,UAAkB;IACrC,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAgB,EAAE,KAAa;YAClC,MAAM,IAAI,GAAG,QAAsC,CAAC;YACpD,2EAA2E;YAC3E,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE;oBACV,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAY;oBAChF,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,KAAK,CAAC,UAAkB;IACtC,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAgB,EAAE,KAAa;YAClC,MAAM,IAAI,GAAG,QAAsC,CAAC;YACpD,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE;oBACV,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAY;oBACjF,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,IAAI,CAAC,UAAkB,EAAE,WAAW,GAAG,CAAC;IACtD,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAgB,EAAE,KAAa;YAClC,MAAM,IAAI,GAAG,QAAsC,CAAC;YACpD,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE;oBACV,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAY;oBAC7F,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { Task, Queue, Pool } from "./decorators";
2
2
  export type { TaskDecorated, QueueDecorated, PoolDecorated, TaskOf, QueueOf, PoolOf } from "./decorators";
3
+ export { QueueClearedError } from "./queue";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { Task, Queue, Pool } from "./decorators";
2
+ export { QueueClearedError } from "./queue";
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
package/dist/pool.d.ts CHANGED
@@ -5,6 +5,9 @@ export interface PoolInstance<T> {
5
5
  active: Computed<number>;
6
6
  pending: Computed<number>;
7
7
  error: Computed<Error | null>;
8
+ cancelAll(): void;
8
9
  }
9
- export declare function pool<T>(concurrency: number, fn: (...args: unknown[]) => Promise<T>): PoolInstance<T>;
10
+ export declare function pool<T>(concurrency: number, fn: (...args: unknown[]) => Promise<T>, options?: {
11
+ signal?: boolean;
12
+ }): PoolInstance<T>;
10
13
  //# sourceMappingURL=pool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;CAC/B;AAED,wBAAgB,IAAI,CAAC,CAAC,EACpB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,YAAY,CAAC,CAAC,CAAC,CA2CjB"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,SAAS,IAAI,IAAI,CAAC;CACnB;AAMD,wBAAgB,IAAI,CAAC,CAAC,EACpB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,YAAY,CAAC,CAAC,CAAC,CAgEjB"}
package/dist/pool.js CHANGED
@@ -1,33 +1,45 @@
1
1
  import { signal, computed } from "@praxisjs/core/internal";
2
- export function pool(concurrency, fn) {
2
+ import { acceptsSignal } from "./utils";
3
+ function isAbortError(err) {
4
+ return err instanceof Error && err.name === "AbortError";
5
+ }
6
+ export function pool(concurrency, fn, options) {
3
7
  concurrency = Math.max(1, concurrency);
4
8
  const _active = signal(0);
5
9
  const _pending = signal(0);
6
10
  const _error = signal(null);
11
+ const _wantsSignal = options?.signal ?? acceptsSignal(fn);
7
12
  const _queue = [];
13
+ const _activeControllers = new Set();
8
14
  async function tryRun() {
9
15
  if (_active() >= concurrency || _queue.length === 0)
10
16
  return;
11
17
  const item = _queue[0];
12
18
  _queue.shift();
13
- const { args, resolve } = item;
19
+ const { args, resolve, controller } = item;
14
20
  _pending.update((n) => n - 1);
15
21
  _active.update((n) => n + 1);
22
+ _activeControllers.add(controller);
16
23
  try {
17
- resolve(await fn(...args));
24
+ const result = await (_wantsSignal ? fn(controller.signal, ...args) : fn(...args));
25
+ resolve(result);
18
26
  }
19
27
  catch (err) {
20
- _error.set(err instanceof Error ? err : new Error(String(err)));
28
+ if (!isAbortError(err)) {
29
+ _error.set(err instanceof Error ? err : new Error(String(err)));
30
+ }
21
31
  resolve(undefined);
22
32
  }
23
33
  finally {
34
+ _activeControllers.delete(controller);
24
35
  _active.update((n) => n - 1);
25
36
  void tryRun();
26
37
  }
27
38
  }
28
39
  function run(...args) {
40
+ const controller = new AbortController();
29
41
  return new Promise((resolve) => {
30
- _queue.push({ args, resolve });
42
+ _queue.push({ args, resolve, controller });
31
43
  _pending.update((n) => n + 1);
32
44
  void tryRun();
33
45
  });
@@ -36,6 +48,18 @@ export function pool(concurrency, fn) {
36
48
  run.active = computed(() => _active());
37
49
  run.pending = computed(() => _pending());
38
50
  run.error = computed(() => _error());
51
+ run.cancelAll = () => {
52
+ for (const c of _activeControllers) {
53
+ c.abort();
54
+ }
55
+ _activeControllers.clear();
56
+ while (_queue.length > 0) {
57
+ const item = _queue.shift();
58
+ item?.controller.abort();
59
+ item?.resolve(undefined);
60
+ }
61
+ _pending.set(0);
62
+ };
39
63
  return run;
40
64
  }
41
65
  //# sourceMappingURL=pool.js.map
package/dist/pool.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAW3D,MAAM,UAAU,IAAI,CAClB,WAAmB,EACnB,EAAsC;IAEtC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAe,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAGP,EAAE,CAAC;IAER,KAAK,UAAU,MAAM;QACnB,IAAI,OAAO,EAAE,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,KAAK,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,SAAS,GAAG,CAAC,GAAG,IAAe;QAC7B,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;YAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC/B,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,KAAK,MAAM,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC5C,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAErC,OAAO,GAAsB,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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"}
package/dist/queue.d.ts CHANGED
@@ -9,5 +9,7 @@ export interface QueueInstance<T> {
9
9
  error: Computed<Error | null>;
10
10
  clear(): void;
11
11
  }
12
- export declare function queue<T>(fn: (...args: unknown[]) => Promise<T>): QueueInstance<T>;
12
+ export declare function queue<T>(fn: (...args: unknown[]) => Promise<T>, options?: {
13
+ signal?: boolean;
14
+ }): QueueInstance<T>;
13
15
  //# sourceMappingURL=queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,qBAAa,iBAAkB,SAAQ,KAAK;;CAK3C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,KAAK,CAAC,CAAC,EACrB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,aAAa,CAAC,CAAC,CAAC,CA2DlB"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,qBAAa,iBAAkB,SAAQ,KAAK;;CAK3C;AAMD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,KAAK,CAAC,CAAC,EACrB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,aAAa,CAAC,CAAC,CAAC,CAgFlB"}
package/dist/queue.js CHANGED
@@ -1,17 +1,24 @@
1
1
  import { signal, computed } from "@praxisjs/core/internal";
2
+ import { acceptsSignal } from "./utils";
2
3
  export class QueueClearedError extends Error {
3
4
  constructor() {
4
5
  super("Queue cleared");
5
6
  this.name = "QueueClearedError";
6
7
  }
7
8
  }
8
- export function queue(fn) {
9
+ function isAbortError(err) {
10
+ return err instanceof Error && err.name === "AbortError";
11
+ }
12
+ export function queue(fn, options) {
9
13
  const _loading = signal(false);
10
14
  const _pending = signal(0);
11
15
  const _error = signal(null);
16
+ const _wantsSignal = options?.signal ?? acceptsSignal(fn);
12
17
  const _queue = [];
13
18
  let _running = false;
14
19
  let _cleared = false;
20
+ let _activeController = null;
21
+ let _activeAbortedByClear = false;
15
22
  async function drain() {
16
23
  if (_running || _queue.length === 0)
17
24
  return;
@@ -20,15 +27,28 @@ export function queue(fn) {
20
27
  while (_queue.length > 0) {
21
28
  const item = _queue[0];
22
29
  _queue.shift();
23
- const { args, resolve, reject } = item;
30
+ const { args, resolve, reject, controller } = item;
31
+ _activeController = controller;
32
+ _activeAbortedByClear = false;
24
33
  _pending.update((n) => n - 1);
25
34
  try {
26
- resolve(await fn(...args));
35
+ const result = await (_wantsSignal ? fn(controller.signal, ...args) : fn(...args));
36
+ resolve(result);
27
37
  }
28
38
  catch (err) {
29
- const e = err instanceof Error ? err : new Error(String(err));
30
- _error.set(e);
31
- reject(e);
39
+ // _activeAbortedByClear is set asynchronously by clear() between the await and this catch
40
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
41
+ if (isAbortError(err) && _activeAbortedByClear) {
42
+ reject(new QueueClearedError());
43
+ }
44
+ else {
45
+ const e = err instanceof Error ? err : new Error(String(err));
46
+ _error.set(e);
47
+ reject(e);
48
+ }
49
+ }
50
+ finally {
51
+ _activeController = null;
32
52
  }
33
53
  }
34
54
  _cleared = false;
@@ -39,8 +59,9 @@ export function queue(fn) {
39
59
  if (_cleared) {
40
60
  _cleared = false;
41
61
  }
62
+ const controller = new AbortController();
42
63
  return new Promise((resolve, reject) => {
43
- _queue.push({ args, resolve, reject });
64
+ _queue.push({ args, resolve, reject, controller });
44
65
  _pending.update((n) => n + 1);
45
66
  void drain();
46
67
  });
@@ -49,9 +70,14 @@ export function queue(fn) {
49
70
  enqueue.pending = computed(() => _pending());
50
71
  enqueue.error = computed(() => _error());
51
72
  enqueue.clear = () => {
52
- // Reject all currently queued (not-yet-started) items
73
+ if (_activeController) {
74
+ _activeAbortedByClear = true;
75
+ _activeController.abort();
76
+ }
53
77
  while (_queue.length > 0) {
54
- _queue.shift()?.reject(new QueueClearedError());
78
+ const item = _queue.shift();
79
+ item?.controller.abort();
80
+ item?.reject(new QueueClearedError());
55
81
  }
56
82
  _pending.set(0);
57
83
  _cleared = true;
package/dist/queue.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
package/dist/task.d.ts CHANGED
@@ -6,5 +6,7 @@ export interface TaskInstance<T> {
6
6
  lastResult: Computed<T | null>;
7
7
  cancelAll(): void;
8
8
  }
9
- export declare function task<T>(fn: (...args: unknown[]) => Promise<T>): TaskInstance<T>;
9
+ export declare function task<T>(fn: (...args: unknown[]) => Promise<T>, options?: {
10
+ signal?: boolean;
11
+ }): TaskInstance<T>;
10
12
  //# sourceMappingURL=task.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,UAAU,EAAE,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/B,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,wBAAgB,IAAI,CAAC,CAAC,EACpB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,YAAY,CAAC,CAAC,CAAC,CAiCjB"}
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,UAAU,EAAE,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/B,SAAS,IAAI,IAAI,CAAC;CACnB;AAMD,wBAAgB,IAAI,CAAC,CAAC,EACpB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,YAAY,CAAC,CAAC,CAAC,CA0CjB"}
package/dist/task.js CHANGED
@@ -1,15 +1,24 @@
1
1
  import { signal, computed } from "@praxisjs/core/internal";
2
- export function task(fn) {
2
+ import { acceptsSignal } from "./utils";
3
+ function isAbortError(err) {
4
+ return err instanceof Error && err.name === "AbortError";
5
+ }
6
+ export function task(fn, options) {
3
7
  const _loading = signal(false);
4
8
  const _error = signal(null);
5
9
  const _lastResult = signal(null);
6
10
  let _runId = 0;
11
+ let _controller = null;
12
+ const _wantsSignal = options?.signal ?? acceptsSignal(fn);
7
13
  async function run(...args) {
14
+ _controller?.abort();
15
+ const controller = new AbortController();
16
+ _controller = controller;
8
17
  const id = ++_runId;
9
18
  _loading.set(true);
10
19
  _error.set(null);
11
20
  try {
12
- const result = await fn(...args);
21
+ const result = await (_wantsSignal ? fn(controller.signal, ...args) : fn(...args));
13
22
  if (id !== _runId)
14
23
  return undefined;
15
24
  _lastResult.set(result);
@@ -19,7 +28,9 @@ export function task(fn) {
19
28
  catch (err) {
20
29
  if (id !== _runId)
21
30
  return undefined;
22
- _error.set(err instanceof Error ? err : new Error(String(err)));
31
+ if (!isAbortError(err)) {
32
+ _error.set(err instanceof Error ? err : new Error(String(err)));
33
+ }
23
34
  _loading.set(false);
24
35
  return undefined;
25
36
  }
@@ -28,6 +39,8 @@ export function task(fn) {
28
39
  run.error = computed(() => _error());
29
40
  run.lastResult = computed(() => _lastResult());
30
41
  run.cancelAll = () => {
42
+ _controller?.abort();
43
+ _controller = null;
31
44
  _runId++;
32
45
  _loading.set(false);
33
46
  };
package/dist/task.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAW3D,MAAM,UAAU,IAAI,CAClB,EAAsC;IAEtC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAe,IAAI,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,MAAM,CAAW,IAAI,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,UAAU,GAAG,CAAC,GAAG,IAAe;QACnC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YACjC,IAAI,EAAE,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACpC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,EAAE,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAChE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/C,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE;QACnB,MAAM,EAAE,CAAC;QACT,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,OAAO,GAAsB,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAUxC,SAAS,YAAY,CAAC,GAAY;IAChC,OAAO,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,EAAsC,EACtC,OAA8B;IAE9B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAe,IAAI,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,MAAM,CAAW,IAAI,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,WAAW,GAA2B,IAAI,CAAC;IAC/C,MAAM,YAAY,GAAG,OAAO,EAAE,MAAM,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC;IAE1D,KAAK,UAAU,GAAG,CAAC,GAAG,IAAe;QACnC,WAAW,EAAE,KAAK,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,WAAW,GAAG,UAAU,CAAC;QACzB,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YACnF,IAAI,EAAE,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACpC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,EAAE,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAClE,CAAC;YACD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/C,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE;QACnB,WAAW,EAAE,KAAK,EAAE,CAAC;QACrB,WAAW,GAAG,IAAI,CAAC;QACnB,MAAM,EAAE,CAAC;QACT,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,OAAO,GAAsB,CAAC;AAChC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns true if the function declares `signal` as its first parameter name.
3
+ * Used to decide whether to inject an AbortSignal at call time.
4
+ *
5
+ * Works on unminified source (class methods, arrow functions, async functions).
6
+ * Bound functions always return false — check the original method before binding.
7
+ */
8
+ export declare function acceptsSignal(fn: (...args: any[]) => any): boolean;
9
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,wBAAgB,aAAa,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,OAAO,CAelE"}
package/dist/utils.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Returns true if the function declares `signal` as its first parameter name.
3
+ * Used to decide whether to inject an AbortSignal at call time.
4
+ *
5
+ * Works on unminified source (class methods, arrow functions, async functions).
6
+ * Bound functions always return false — check the original method before binding.
7
+ */
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export function acceptsSignal(fn) {
10
+ try {
11
+ const src = fn.toString();
12
+ // Match the first character of the parameter list, e.g.:
13
+ // async loadUser(signal, id) → "signal"
14
+ // (signal: AbortSignal) => → "signal:" (TS annotation stripped below)
15
+ // (id: number) => → "id:"
16
+ // () => → ""
17
+ const m = /\(\s*([^),\s]*)/.exec(src);
18
+ const rawFirst = m?.[1] ?? "";
19
+ const firstName = rawFirst.split(/[:=]/)[0].trim();
20
+ return firstName === "signal";
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,8DAA8D;AAC9D,MAAM,UAAU,aAAa,CAAC,EAA2B;IACvD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QAC1B,yDAAyD;QACzD,4CAA4C;QAC5C,6EAA6E;QAC7E,yCAAyC;QACzC,sCAAsC;QACtC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,OAAO,SAAS,KAAK,QAAQ,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisjs/concurrent",
3
- "version": "1.2.13",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -14,9 +14,9 @@
14
14
  "typescript": "^5.9.3"
15
15
  },
16
16
  "dependencies": {
17
- "@praxisjs/core": "1.7.0",
18
- "@praxisjs/decorators": "1.2.0",
19
- "@praxisjs/shared": "0.2.0"
17
+ "@praxisjs/core": "1.8.0",
18
+ "@praxisjs/shared": "0.3.0",
19
+ "@praxisjs/decorators": "1.3.0"
20
20
  },
21
21
  "scripts": {
22
22
  "build": "tsc",
@@ -1,6 +1,7 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
3
  import { Task, Queue, Pool } from "../decorators";
4
+ import { QueueClearedError } from "../queue";
4
5
 
5
6
  function fieldCtx(name: string) {
6
7
  const initializers: Array<(this: unknown) => void> = [];
@@ -31,12 +32,14 @@ describe("Task decorator", () => {
31
32
  loading: () => boolean;
32
33
  error: () => Error | null;
33
34
  lastResult: () => number | null;
35
+ cancelAll: () => void;
34
36
  };
35
37
 
36
38
  expect(typeof taskLoad).toBe("function");
37
39
  expect(taskLoad.loading).toBeDefined();
38
40
  expect(taskLoad.error).toBeDefined();
39
41
  expect(taskLoad.lastResult).toBeDefined();
42
+ expect(taskLoad.cancelAll).toBeDefined();
40
43
 
41
44
  const result = await taskLoad(5);
42
45
  expect(result).toBe(10);
@@ -60,6 +63,29 @@ describe("Task decorator", () => {
60
63
  await p;
61
64
  expect(taskFetch.loading()).toBe(false);
62
65
  });
66
+
67
+ it("cancelAll() aborts the in-flight signal", async () => {
68
+ const { ctx, run } = fieldCtx("taskFetch");
69
+ Task("fetch")(undefined, ctx);
70
+
71
+ let capturedSignal!: AbortSignal;
72
+ let resolve!: () => void;
73
+ const instance: Record<string, unknown> = {
74
+ fetch: async (signal: AbortSignal) => {
75
+ capturedSignal = signal;
76
+ await new Promise<void>((r) => { resolve = r; });
77
+ },
78
+ };
79
+ run(instance);
80
+
81
+ const taskFetch = instance.taskFetch as { (): Promise<void>; cancelAll: () => void };
82
+ const p = taskFetch();
83
+ taskFetch.cancelAll();
84
+ resolve();
85
+ await p;
86
+
87
+ expect(capturedSignal.aborted).toBe(true);
88
+ });
63
89
  });
64
90
 
65
91
  // ── Queue ─────────────────────────────────────────────────────────────────────
@@ -98,10 +124,12 @@ describe("Queue decorator", () => {
98
124
 
99
125
  let resolveFirst!: () => void;
100
126
  const instance: Record<string, unknown> = {
101
- save: async (_: unknown, idx: unknown) =>
102
- idx === 0
127
+ save: async (signal: AbortSignal, _: unknown, idx: unknown) => {
128
+ void signal;
129
+ return idx === 0
103
130
  ? new Promise<void>((r) => { resolveFirst = r; })
104
- : Promise.resolve(),
131
+ : Promise.resolve();
132
+ },
105
133
  };
106
134
  run(instance);
107
135
 
@@ -133,6 +161,7 @@ describe("Pool decorator", () => {
133
161
  active: () => number;
134
162
  pending: () => number;
135
163
  error: () => Error | null;
164
+ cancelAll: () => void;
136
165
  };
137
166
 
138
167
  expect(typeof taskProcess).toBe("function");
@@ -140,6 +169,7 @@ describe("Pool decorator", () => {
140
169
  expect(taskProcess.active).toBeDefined();
141
170
  expect(taskProcess.pending).toBeDefined();
142
171
  expect(taskProcess.error).toBeDefined();
172
+ expect(taskProcess.cancelAll).toBeDefined();
143
173
 
144
174
  const result = await taskProcess(9);
145
175
  expect(result).toBe(10);
@@ -189,4 +219,49 @@ describe("Pool decorator", () => {
189
219
  resolvers[1]();
190
220
  await t2;
191
221
  });
222
+
223
+ it("cancelAll() cancels pending and active tasks", async () => {
224
+ const { ctx, run } = fieldCtx("taskWork");
225
+ Pool("work", 1)(undefined, ctx);
226
+
227
+ let resolveFirst!: () => void;
228
+ const instance: Record<string, unknown> = {
229
+ work: async (signal: AbortSignal, idx: unknown) => {
230
+ void signal;
231
+ if (idx === 0) await new Promise<void>((r) => { resolveFirst = r; });
232
+ },
233
+ };
234
+ run(instance);
235
+
236
+ const taskWork = instance.taskWork as {
237
+ (...args: unknown[]): Promise<void>;
238
+ active: () => number;
239
+ pending: () => number;
240
+ cancelAll: () => void;
241
+ };
242
+
243
+ const t1 = taskWork(0);
244
+ const t2 = taskWork(1);
245
+
246
+ await Promise.resolve();
247
+ taskWork.cancelAll();
248
+ resolveFirst();
249
+
250
+ await Promise.all([t1, t2]);
251
+
252
+ expect(taskWork.active()).toBe(0);
253
+ expect(taskWork.pending()).toBe(0);
254
+ });
255
+ });
256
+
257
+ // ── QueueClearedError re-export ────────────────────────────────────────────────
258
+
259
+ describe("QueueClearedError", () => {
260
+ it("is exported from the package", () => {
261
+ expect(QueueClearedError).toBeDefined();
262
+ const e = new QueueClearedError();
263
+ expect(e).toBeInstanceOf(Error);
264
+ expect(e.name).toBe("QueueClearedError");
265
+ expect(e.message).toBe("Queue cleared");
266
+ });
192
267
  });