@daiso-tech/core 0.34.0 → 0.35.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 (149) hide show
  1. package/README.md +2 -4
  2. package/dist/async/_module-exports.d.ts +0 -1
  3. package/dist/async/_module-exports.js +0 -1
  4. package/dist/async/_module-exports.js.map +1 -1
  5. package/dist/async/async.errors.d.ts +19 -12
  6. package/dist/async/async.errors.js +27 -16
  7. package/dist/async/async.errors.js.map +1 -1
  8. package/dist/async/middlewares/_module.d.ts +3 -0
  9. package/dist/async/middlewares/_module.js +3 -0
  10. package/dist/async/middlewares/_module.js.map +1 -1
  11. package/dist/async/middlewares/_shared.d.ts +10 -0
  12. package/dist/async/middlewares/_shared.js +5 -0
  13. package/dist/async/middlewares/_shared.js.map +1 -0
  14. package/dist/async/middlewares/bulkhead/_module.d.ts +1 -0
  15. package/dist/async/middlewares/bulkhead/_module.js +2 -0
  16. package/dist/async/middlewares/bulkhead/_module.js.map +1 -0
  17. package/dist/async/middlewares/bulkhead/bulkhead.middleware.d.ts +80 -0
  18. package/dist/async/middlewares/bulkhead/bulkhead.middleware.js +46 -0
  19. package/dist/async/middlewares/bulkhead/bulkhead.middleware.js.map +1 -0
  20. package/dist/async/middlewares/dynamic/dynamic.middleware.d.ts +2 -2
  21. package/dist/async/middlewares/dynamic/dynamic.middleware.js +5 -5
  22. package/dist/async/middlewares/dynamic/dynamic.middleware.js.map +1 -1
  23. package/dist/async/middlewares/fallback/fallback.middleware.d.ts +10 -8
  24. package/dist/async/middlewares/fallback/fallback.middleware.js +1 -1
  25. package/dist/async/middlewares/fallback/fallback.middleware.js.map +1 -1
  26. package/dist/async/middlewares/hedging/_module.d.ts +2 -0
  27. package/dist/async/middlewares/hedging/_module.js +3 -0
  28. package/dist/async/middlewares/hedging/_module.js.map +1 -0
  29. package/dist/async/middlewares/hedging/_shared.d.ts +93 -0
  30. package/dist/async/middlewares/hedging/_shared.js +5 -0
  31. package/dist/async/middlewares/hedging/_shared.js.map +1 -0
  32. package/dist/async/middlewares/hedging/concurrent-hedging/_module.d.ts +1 -0
  33. package/dist/async/middlewares/hedging/concurrent-hedging/_module.js +2 -0
  34. package/dist/async/middlewares/hedging/concurrent-hedging/_module.js.map +1 -0
  35. package/dist/async/middlewares/hedging/concurrent-hedging/concurrent-hedging.middleware.d.ts +51 -0
  36. package/dist/async/middlewares/hedging/concurrent-hedging/concurrent-hedging.middleware.js +138 -0
  37. package/dist/async/middlewares/hedging/concurrent-hedging/concurrent-hedging.middleware.js.map +1 -0
  38. package/dist/async/middlewares/hedging/sequential-hedging/_module.d.ts +1 -0
  39. package/dist/async/middlewares/hedging/sequential-hedging/_module.js +2 -0
  40. package/dist/async/middlewares/hedging/sequential-hedging/_module.js.map +1 -0
  41. package/dist/async/middlewares/hedging/sequential-hedging/sequential-hedging.middleware.d.ts +51 -0
  42. package/dist/async/middlewares/hedging/sequential-hedging/sequential-hedging.middleware.js +104 -0
  43. package/dist/async/middlewares/hedging/sequential-hedging/sequential-hedging.middleware.js.map +1 -0
  44. package/dist/async/middlewares/observe/observe.middleware.d.ts +14 -16
  45. package/dist/async/middlewares/observe/observe.middleware.js +1 -1
  46. package/dist/async/middlewares/observe/observe.middleware.js.map +1 -1
  47. package/dist/async/middlewares/retry/retry.middleware.d.ts +41 -36
  48. package/dist/async/middlewares/retry/retry.middleware.js +31 -28
  49. package/dist/async/middlewares/retry/retry.middleware.js.map +1 -1
  50. package/dist/async/middlewares/timeout/timeout.middleware.d.ts +34 -39
  51. package/dist/async/middlewares/timeout/timeout.middleware.js +30 -47
  52. package/dist/async/middlewares/timeout/timeout.middleware.js.map +1 -1
  53. package/dist/async/utilities/_module.d.ts +2 -0
  54. package/dist/async/utilities/_module.js +2 -0
  55. package/dist/async/utilities/_module.js.map +1 -1
  56. package/dist/async/utilities/abort-and-fail/abort-and-fail.d.ts +3 -0
  57. package/dist/async/utilities/abort-and-fail/abort-and-fail.js +6 -7
  58. package/dist/async/utilities/abort-and-fail/abort-and-fail.js.map +1 -1
  59. package/dist/async/utilities/lazy-promise/lazy-promise.js +0 -1
  60. package/dist/async/utilities/lazy-promise/lazy-promise.js.map +1 -1
  61. package/dist/async/utilities/promise-queue/_module.d.ts +1 -0
  62. package/dist/async/utilities/promise-queue/_module.js +2 -0
  63. package/dist/async/utilities/promise-queue/_module.js.map +1 -0
  64. package/dist/async/utilities/promise-queue/promise-queue.d.ts +32 -0
  65. package/dist/async/utilities/promise-queue/promise-queue.js +107 -0
  66. package/dist/async/utilities/promise-queue/promise-queue.js.map +1 -0
  67. package/dist/async/utilities/timeout-and-fail/_module.d.ts +1 -0
  68. package/dist/async/utilities/timeout-and-fail/_module.js +2 -0
  69. package/dist/async/utilities/timeout-and-fail/_module.js.map +1 -0
  70. package/dist/async/utilities/timeout-and-fail/timeout-and-fail.d.ts +7 -0
  71. package/dist/async/utilities/timeout-and-fail/timeout-and-fail.js +19 -0
  72. package/dist/async/utilities/timeout-and-fail/timeout-and-fail.js.map +1 -0
  73. package/dist/cache/contracts/cache.contract.d.ts +2 -2
  74. package/dist/cache/contracts/cache.events.d.ts +43 -47
  75. package/dist/cache/contracts/cache.events.js +5 -103
  76. package/dist/cache/contracts/cache.events.js.map +1 -1
  77. package/dist/cache/implementations/derivables/cache/cache.d.ts +15 -15
  78. package/dist/cache/implementations/derivables/cache/cache.js +94 -79
  79. package/dist/cache/implementations/derivables/cache/cache.js.map +1 -1
  80. package/dist/cache/implementations/derivables/cache-factory/cache-factory.d.ts +1 -1
  81. package/dist/cache/implementations/derivables/cache-factory/cache-factory.js.map +1 -1
  82. package/dist/cache/implementations/test-utilities/cache.test-suite.js +138 -147
  83. package/dist/cache/implementations/test-utilities/cache.test-suite.js.map +1 -1
  84. package/dist/event-bus/contracts/_module-exports.d.ts +0 -1
  85. package/dist/event-bus/contracts/_module-exports.js +0 -1
  86. package/dist/event-bus/contracts/_module-exports.js.map +1 -1
  87. package/dist/event-bus/contracts/event-bus-adapter.contract.d.ts +6 -1
  88. package/dist/event-bus/contracts/event-bus-factory.contract.d.ts +2 -3
  89. package/dist/event-bus/contracts/event-bus-factory.contract.js.map +1 -1
  90. package/dist/event-bus/contracts/event-bus.contract.d.ts +12 -23
  91. package/dist/event-bus/implementations/derivables/event-bus/event-bus.d.ts +10 -10
  92. package/dist/event-bus/implementations/derivables/event-bus/event-bus.js +30 -30
  93. package/dist/event-bus/implementations/derivables/event-bus/event-bus.js.map +1 -1
  94. package/dist/event-bus/implementations/derivables/event-bus-factory/event-bus-factory.d.ts +13 -7
  95. package/dist/event-bus/implementations/derivables/event-bus-factory/event-bus-factory.js +11 -5
  96. package/dist/event-bus/implementations/derivables/event-bus-factory/event-bus-factory.js.map +1 -1
  97. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.d.ts +0 -2
  98. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js +13 -20
  99. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js.map +1 -1
  100. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.d.ts +0 -2
  101. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js +187 -207
  102. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js.map +1 -1
  103. package/dist/lock/contracts/lock-provider.contract.d.ts +2 -2
  104. package/dist/lock/contracts/lock.events.d.ts +35 -44
  105. package/dist/lock/contracts/lock.events.js +8 -90
  106. package/dist/lock/contracts/lock.events.js.map +1 -1
  107. package/dist/lock/implementations/derivables/lock-provider/lock-provider.d.ts +9 -9
  108. package/dist/lock/implementations/derivables/lock-provider/lock-provider.js +12 -12
  109. package/dist/lock/implementations/derivables/lock-provider/lock-provider.js.map +1 -1
  110. package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.d.ts +2 -2
  111. package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.js.map +1 -1
  112. package/dist/lock/implementations/derivables/lock-provider/lock.d.ts +2 -2
  113. package/dist/lock/implementations/derivables/lock-provider/lock.js +69 -50
  114. package/dist/lock/implementations/derivables/lock-provider/lock.js.map +1 -1
  115. package/dist/lock/implementations/derivables/lock-provider-factory/lock-provider-factory.d.ts +1 -1
  116. package/dist/lock/implementations/derivables/lock-provider-factory/lock-provider-factory.js.map +1 -1
  117. package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js +212 -212
  118. package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js.map +1 -1
  119. package/dist/serde/contracts/flexible-serde.contract.d.ts +0 -11
  120. package/dist/serde/implementations/derivables/serde.d.ts +1 -32
  121. package/dist/serde/implementations/derivables/serde.js +0 -45
  122. package/dist/serde/implementations/derivables/serde.js.map +1 -1
  123. package/dist/utilities/classes/hooks/async-hooks.d.ts +107 -20
  124. package/dist/utilities/classes/hooks/async-hooks.js +47 -18
  125. package/dist/utilities/classes/hooks/async-hooks.js.map +1 -1
  126. package/dist/utilities/classes/hooks/hooks.d.ts +39 -21
  127. package/dist/utilities/classes/hooks/hooks.js +19 -18
  128. package/dist/utilities/classes/hooks/hooks.js.map +1 -1
  129. package/dist/utilities/classes/key-prefixer/key-prefixer.js +2 -2
  130. package/dist/utilities/classes/key-prefixer/key-prefixer.js.map +1 -1
  131. package/dist/utilities/contracts/_module.d.ts +0 -1
  132. package/dist/utilities/contracts/_module.js +0 -1
  133. package/dist/utilities/contracts/_module.js.map +1 -1
  134. package/dist/utilities/functions/invokable.d.ts +9 -5
  135. package/dist/utilities/functions/invokable.js +10 -0
  136. package/dist/utilities/functions/invokable.js.map +1 -1
  137. package/package.json +22 -2
  138. package/dist/async/async.events.d.ts +0 -105
  139. package/dist/async/async.events.js +0 -82
  140. package/dist/async/async.events.js.map +0 -1
  141. package/dist/event-bus/contracts/_shared.d.ts +0 -12
  142. package/dist/event-bus/contracts/_shared.js +0 -15
  143. package/dist/event-bus/contracts/_shared.js.map +0 -1
  144. package/dist/test.d.ts +0 -1
  145. package/dist/test.js +0 -34
  146. package/dist/test.js.map +0 -1
  147. package/dist/utilities/contracts/sync-event-bus-listenable.d.ts +0 -13
  148. package/dist/utilities/contracts/sync-event-bus-listenable.js +0 -5
  149. package/dist/utilities/contracts/sync-event-bus-listenable.js.map +0 -1
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @module Async
3
+ */
4
+ import { type AsyncMiddlewareFn, type HookContext } from "../../../../utilities/_module-exports.js";
5
+ import type { HedgingSettings } from "../../../../async/middlewares/hedging/_shared.js";
6
+ /**
7
+ * The `concurrentHedging` middleware executes the primary function and all fallback functions concurrently.
8
+ * It returns the result of the first successful function and automatically aborts all remaining functions.
9
+ * If all function fail than error is thrown.
10
+ *
11
+ * IMPORT_PATH: `"@daiso-tech/core/async"`
12
+ * @group Middleware
13
+ * @throws {HedgingAsyncError} {@link HedgingAsyncError}
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { concurrentHedging } from "@daiso-tech/core/async";
18
+ * import { AsyncHooks } from "@daiso-tech/core/utilities";
19
+ *
20
+ * async function fn1(signal?: AbortSignal): Promise<unknown> {
21
+ * const response = await fetch("ENDPOINT-1", { signal });
22
+ * return await response.json();
23
+ * }
24
+ * async function fn2(signal?: AbortSignal): Promise<unknown> {
25
+ * const response = await fetch("ENDPOINT-2", { signal });
26
+ * return await response.json();
27
+ * }
28
+ * async function fn3(signal?: AbortSignal): Promise<unknown> {
29
+ * const response = await fetch("ENDPOINT-3", { signal });
30
+ * return await response.json();
31
+ * }
32
+ * const fetchData = new AsyncHooks(fn1, [
33
+ * concurrentHedging({
34
+ * fallbacks: [
35
+ * fn2,
36
+ * fn3
37
+ * ]
38
+ * })
39
+ * ], {
40
+ * signalBinder: {
41
+ * getSignal: (args) => args[0],
42
+ * forwardSignal: (args, signal) => {
43
+ * args[0] = signal;
44
+ * }
45
+ * }
46
+ * });
47
+ *
48
+ * console.log(await fetchData.invoke());
49
+ * ```
50
+ */
51
+ export declare function concurrentHedging<TParameters extends unknown[], TReturn, TContext extends HookContext>(settings: NoInfer<HedgingSettings<TParameters, TReturn, TContext>>): AsyncMiddlewareFn<TParameters, TReturn, TContext>;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @module Async
3
+ */
4
+ import { callInvokable, isInvokable, resolveOneOrMore, TimeSpan, } from "../../../../utilities/_module-exports.js";
5
+ import { HedgingAsyncError } from "../../../../async/async.errors.js";
6
+ import { timeoutAndFail } from "../../../../async/utilities/_module.js";
7
+ /**
8
+ * @internal
9
+ */
10
+ class ResolvedError extends Error {
11
+ constructor(message, cause) {
12
+ super(message, { cause });
13
+ this.name = ResolvedError.name;
14
+ }
15
+ }
16
+ /**
17
+ * The `concurrentHedging` middleware executes the primary function and all fallback functions concurrently.
18
+ * It returns the result of the first successful function and automatically aborts all remaining functions.
19
+ * If all function fail than error is thrown.
20
+ *
21
+ * IMPORT_PATH: `"@daiso-tech/core/async"`
22
+ * @group Middleware
23
+ * @throws {HedgingAsyncError} {@link HedgingAsyncError}
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { concurrentHedging } from "@daiso-tech/core/async";
28
+ * import { AsyncHooks } from "@daiso-tech/core/utilities";
29
+ *
30
+ * async function fn1(signal?: AbortSignal): Promise<unknown> {
31
+ * const response = await fetch("ENDPOINT-1", { signal });
32
+ * return await response.json();
33
+ * }
34
+ * async function fn2(signal?: AbortSignal): Promise<unknown> {
35
+ * const response = await fetch("ENDPOINT-2", { signal });
36
+ * return await response.json();
37
+ * }
38
+ * async function fn3(signal?: AbortSignal): Promise<unknown> {
39
+ * const response = await fetch("ENDPOINT-3", { signal });
40
+ * return await response.json();
41
+ * }
42
+ * const fetchData = new AsyncHooks(fn1, [
43
+ * concurrentHedging({
44
+ * fallbacks: [
45
+ * fn2,
46
+ * fn3
47
+ * ]
48
+ * })
49
+ * ], {
50
+ * signalBinder: {
51
+ * getSignal: (args) => args[0],
52
+ * forwardSignal: (args, signal) => {
53
+ * args[0] = signal;
54
+ * }
55
+ * }
56
+ * });
57
+ *
58
+ * console.log(await fetchData.invoke());
59
+ * ```
60
+ */
61
+ export function concurrentHedging(settings) {
62
+ const { waitTime = TimeSpan.fromSeconds(2), fallbacks, onHedgeAttempt = () => { }, onHedgeError = () => { }, } = settings;
63
+ const resolvedFallbacks = resolveOneOrMore(fallbacks).map((fallback, index) => {
64
+ if (isInvokable(fallback)) {
65
+ return {
66
+ name: `fallback-${String(index + 1)}`,
67
+ func: fallback,
68
+ };
69
+ }
70
+ return fallback;
71
+ });
72
+ return async (args, next, { context, abort, signal }) => {
73
+ function step1({ name, func }) {
74
+ return {
75
+ name,
76
+ promise: timeoutAndFail((async () => callInvokable(func, ...args))(), waitTime, (error) => {
77
+ abort(error);
78
+ }, signal),
79
+ };
80
+ }
81
+ async function step2({ name, promise }) {
82
+ try {
83
+ const value = await promise;
84
+ // We abort all other promises when on promise succeds.
85
+ abort(new ResolvedError("Already resolved"));
86
+ return {
87
+ type: "success",
88
+ value,
89
+ name,
90
+ };
91
+ }
92
+ catch (error) {
93
+ return {
94
+ type: "failure",
95
+ error,
96
+ name,
97
+ };
98
+ }
99
+ }
100
+ const funcs = [
101
+ {
102
+ name: "__initial",
103
+ func: next,
104
+ },
105
+ ...resolvedFallbacks,
106
+ ];
107
+ const promises = funcs.map(step1).map(step2);
108
+ const errors = [];
109
+ const promiseResults = await Promise.all(promises);
110
+ for (const promiseResult of promiseResults) {
111
+ callInvokable(onHedgeAttempt, {
112
+ args,
113
+ context,
114
+ name: promiseResult.name,
115
+ });
116
+ // We return the first fulfilled value
117
+ if (promiseResult.type === "success") {
118
+ return promiseResult.value;
119
+ }
120
+ else if (!(promiseResult.error instanceof ResolvedError)) {
121
+ callInvokable(onHedgeError, {
122
+ args,
123
+ context,
124
+ error: promiseResult.error,
125
+ name: promiseResult.name,
126
+ });
127
+ errors.push(promiseResult.error);
128
+ }
129
+ }
130
+ // If all promiseResults are rejected we will throw an error
131
+ const funcNames = funcs
132
+ .slice(1)
133
+ .map(({ name }) => `"${name}"`)
134
+ .join(", ");
135
+ throw new HedgingAsyncError(`The original function and fallback functions failed: ${funcNames}`, errors);
136
+ };
137
+ }
138
+ //# sourceMappingURL=concurrent-hedging.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrent-hedging.middleware.js","sourceRoot":"","sources":["../../../../../src/async/middlewares/hedging/concurrent-hedging/concurrent-hedging.middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from "../../../../async/middlewares/hedging/sequential-hedging/_module.js";
@@ -0,0 +1,2 @@
1
+ export * from "../../../../async/middlewares/hedging/sequential-hedging/_module.js";
2
+ //# sourceMappingURL=_module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_module.js","sourceRoot":"","sources":["../../../../../src/async/middlewares/hedging/sequential-hedging/_module.ts"],"names":[],"mappings":"AAAA,cAAc,2DAA2D,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @module Async
3
+ */
4
+ import { type AsyncMiddlewareFn, type HookContext } from "../../../../utilities/_module-exports.js";
5
+ import type { HedgingSettings } from "../../../../async/middlewares/hedging/_shared.js";
6
+ /**
7
+ * The `sequentialHedging` middleware executes the primary function and all fallback functions sequentially.
8
+ * It returns the result of the first successful function and automatically cancels all remaining functions.
9
+ * If all function fail than error is thrown.
10
+ *
11
+ * IMPORT_PATH: `"@daiso-tech/core/async"`
12
+ * @group Middleware
13
+ * @throws {HedgingAsyncError} {@link HedgingAsyncError}
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { sequentialHedging } from "@daiso-tech/core/async";
18
+ * import { AsyncHooks } from "@daiso-tech/core/utilities";
19
+ *
20
+ * async function fn1(signal?: AbortSignal): Promise<unknown> {
21
+ * const response = await fetch("ENDPOINT-1", { signal });
22
+ * return await response.json();
23
+ * }
24
+ * async function fn2(signal?: AbortSignal): Promise<unknown> {
25
+ * const response = await fetch("ENDPOINT-2", { signal });
26
+ * return await response.json();
27
+ * }
28
+ * async function fn3(signal?: AbortSignal): Promise<unknown> {
29
+ * const response = await fetch("ENDPOINT-3", { signal });
30
+ * return await response.json();
31
+ * }
32
+ * const fetchData = new AsyncHooks(fn1, [
33
+ * sequentialHedging({
34
+ * fallbacks: [
35
+ * fn2,
36
+ * fn3
37
+ * ]
38
+ * })
39
+ * ], {
40
+ * signalBinder: {
41
+ * getSignal: (args) => args[0],
42
+ * forwardSignal: (args, signal) => {
43
+ * args[0] = signal;
44
+ * }
45
+ * }
46
+ * });
47
+ *
48
+ * console.log(await fetchData.invoke());
49
+ * ```
50
+ */
51
+ export declare function sequentialHedging<TParameters extends unknown[], TReturn, TContext extends HookContext>(settings: NoInfer<HedgingSettings<TParameters, TReturn, TContext>>): AsyncMiddlewareFn<TParameters, TReturn, TContext>;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @module Async
3
+ */
4
+ import { callInvokable, isInvokable, resolveOneOrMore, TimeSpan, } from "../../../../utilities/_module-exports.js";
5
+ import { HedgingAsyncError } from "../../../../async/async.errors.js";
6
+ import { timeoutAndFail } from "../../../../async/utilities/_module.js";
7
+ /**
8
+ * The `sequentialHedging` middleware executes the primary function and all fallback functions sequentially.
9
+ * It returns the result of the first successful function and automatically cancels all remaining functions.
10
+ * If all function fail than error is thrown.
11
+ *
12
+ * IMPORT_PATH: `"@daiso-tech/core/async"`
13
+ * @group Middleware
14
+ * @throws {HedgingAsyncError} {@link HedgingAsyncError}
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { sequentialHedging } from "@daiso-tech/core/async";
19
+ * import { AsyncHooks } from "@daiso-tech/core/utilities";
20
+ *
21
+ * async function fn1(signal?: AbortSignal): Promise<unknown> {
22
+ * const response = await fetch("ENDPOINT-1", { signal });
23
+ * return await response.json();
24
+ * }
25
+ * async function fn2(signal?: AbortSignal): Promise<unknown> {
26
+ * const response = await fetch("ENDPOINT-2", { signal });
27
+ * return await response.json();
28
+ * }
29
+ * async function fn3(signal?: AbortSignal): Promise<unknown> {
30
+ * const response = await fetch("ENDPOINT-3", { signal });
31
+ * return await response.json();
32
+ * }
33
+ * const fetchData = new AsyncHooks(fn1, [
34
+ * sequentialHedging({
35
+ * fallbacks: [
36
+ * fn2,
37
+ * fn3
38
+ * ]
39
+ * })
40
+ * ], {
41
+ * signalBinder: {
42
+ * getSignal: (args) => args[0],
43
+ * forwardSignal: (args, signal) => {
44
+ * args[0] = signal;
45
+ * }
46
+ * }
47
+ * });
48
+ *
49
+ * console.log(await fetchData.invoke());
50
+ * ```
51
+ */
52
+ export function sequentialHedging(settings) {
53
+ const { waitTime = TimeSpan.fromSeconds(2), fallbacks, onHedgeAttempt = () => { }, onHedgeError = () => { }, } = settings;
54
+ const resolvedFallbacks = resolveOneOrMore(fallbacks).map((fallback, index) => {
55
+ if (isInvokable(fallback)) {
56
+ return {
57
+ name: `fallback-${String(index + 1)}`,
58
+ func: fallback,
59
+ };
60
+ }
61
+ return fallback;
62
+ });
63
+ return async (args, next, { context, signal, abort }) => {
64
+ const errors = [];
65
+ const funcs = [
66
+ {
67
+ name: "__initial",
68
+ func: next,
69
+ },
70
+ ...resolvedFallbacks,
71
+ ];
72
+ for (const { name, func } of funcs) {
73
+ try {
74
+ callInvokable(onHedgeAttempt, {
75
+ args,
76
+ context,
77
+ name,
78
+ });
79
+ return await timeoutAndFail((async () => callInvokable(func, ...args))(), waitTime, (error) => {
80
+ abort(error);
81
+ }, signal);
82
+ }
83
+ catch (error) {
84
+ if (signal.aborted) {
85
+ break;
86
+ }
87
+ callInvokable(onHedgeError, {
88
+ args,
89
+ context,
90
+ error,
91
+ name,
92
+ });
93
+ errors.push(error);
94
+ }
95
+ }
96
+ // If all promiseResults are rejected we will throw an error
97
+ const funcNames = funcs
98
+ .slice(1)
99
+ .map(({ name }) => `"${name}"`)
100
+ .join(", ");
101
+ throw new HedgingAsyncError(`The original function and fallback functions failed: ${funcNames}`, errors);
102
+ };
103
+ }
104
+ //# sourceMappingURL=sequential-hedging.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequential-hedging.middleware.js","sourceRoot":"","sources":["../../../../../src/async/middlewares/hedging/sequential-hedging/sequential-hedging.middleware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACH,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,QAAQ,GAGX,MAAM,gCAAgC,CAAC;AAKxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,iBAAiB,CAK7B,QAAkE;IAElE,MAAM,EACF,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAClC,SAAS,EACT,cAAc,GAAG,GAAG,EAAE,GAAE,CAAC,EACzB,YAAY,GAAG,GAAG,EAAE,GAAE,CAAC,GAC1B,GAAG,QAAQ,CAAC;IAEb,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,CAEvD,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;QAClB,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxB,OAAO;gBACH,IAAI,EAAE,YAAY,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE;gBACrC,IAAI,EAAE,QAAQ;aACjB,CAAC;QACN,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;QACpD,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG;YACV;gBACI,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,IAAI;aACb;YACD,GAAG,iBAAiB;SACvB,CAAC;QACF,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC;gBACD,aAAa,CAAC,cAAc,EAAE;oBAC1B,IAAI;oBACJ,OAAO;oBACP,IAAI;iBACP,CAAC,CAAC;gBACH,OAAO,MAAM,cAAc,CACvB,CAAC,KAAK,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,EAC5C,QAAQ,EACR,CAAC,KAAc,EAAE,EAAE;oBACf,KAAK,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC,EACD,MAAM,CACT,CAAC;YACN,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACtB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,MAAM;gBACV,CAAC;gBACD,aAAa,CAAC,YAAY,EAAE;oBACxB,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,IAAI;iBACP,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;QACL,CAAC;QAED,4DAA4D;QAC5D,MAAM,SAAS,GAAG,KAAK;aAClB,KAAK,CAAC,CAAC,CAAC;aACR,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC;aAC9B,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,MAAM,IAAI,iBAAiB,CACvB,wDAAwD,SAAS,EAAE,EACnE,MAAM,CACT,CAAC;IACN,CAAC,CAAC;AACN,CAAC"}
@@ -8,7 +8,7 @@ import { type AsyncMiddlewareFn, type Invokable } from "../../../utilities/_modu
8
8
  * IMPORT_PATH: `"@daiso-tech/core/async"`
9
9
  * @group Middleware
10
10
  */
11
- export type OnStartData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
11
+ export type OnObserveStartData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
12
12
  args: TParameters;
13
13
  context: TContext;
14
14
  };
@@ -17,13 +17,13 @@ export type OnStartData<TParameters extends unknown[] = unknown[], TContext exte
17
17
  * IMPORT_PATH: `"@daiso-tech/core/async"`
18
18
  * @group Middleware
19
19
  */
20
- export type OnStart<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnStartData<TParameters, TContext>]>;
20
+ export type OnObserveStart<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnObserveStartData<TParameters, TContext>]>;
21
21
  /**
22
22
  *
23
23
  * IMPORT_PATH: `"@daiso-tech/core/async"`
24
24
  * @group Middleware
25
25
  */
26
- export type OnSuccessData<TParameters extends unknown[] = unknown[], TReturn = unknown, TContext extends HookContext = HookContext> = {
26
+ export type OnObserveSuccessData<TParameters extends unknown[] = unknown[], TReturn = unknown, TContext extends HookContext = HookContext> = {
27
27
  returnValue: TReturn;
28
28
  args: TParameters;
29
29
  context: TContext;
@@ -33,13 +33,13 @@ export type OnSuccessData<TParameters extends unknown[] = unknown[], TReturn = u
33
33
  * IMPORT_PATH: `"@daiso-tech/core/async"`
34
34
  * @group Middleware
35
35
  */
36
- export type OnSuccess<TParameters extends unknown[] = unknown[], TReturn = unknown, TContext extends HookContext = HookContext> = Invokable<[data: OnSuccessData<TParameters, TReturn, TContext>]>;
36
+ export type OnObserveSuccess<TParameters extends unknown[] = unknown[], TReturn = unknown, TContext extends HookContext = HookContext> = Invokable<[data: OnObserveSuccessData<TParameters, TReturn, TContext>]>;
37
37
  /**
38
38
  *
39
39
  * IMPORT_PATH: `"@daiso-tech/core/async"`
40
40
  * @group Middleware
41
41
  */
42
- export type OnErrorData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
42
+ export type OnObserveErrorData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
43
43
  error: unknown;
44
44
  args: TParameters;
45
45
  context: TContext;
@@ -49,7 +49,7 @@ export type OnErrorData<TParameters extends unknown[] = unknown[], TContext exte
49
49
  * IMPORT_PATH: `"@daiso-tech/core/async"`
50
50
  * @group Middleware
51
51
  */
52
- export type OnFinallyData<TContext extends HookContext = HookContext> = {
52
+ export type OnObserveFinallyData<TContext extends HookContext = HookContext> = {
53
53
  executionTime: TimeSpan;
54
54
  context: TContext;
55
55
  };
@@ -58,37 +58,35 @@ export type OnFinallyData<TContext extends HookContext = HookContext> = {
58
58
  * IMPORT_PATH: `"@daiso-tech/core/async"`
59
59
  * @group Middleware
60
60
  */
61
- export type OnError<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnErrorData<TParameters, TContext>]>;
61
+ export type OnObserveError<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnObserveErrorData<TParameters, TContext>]>;
62
62
  /**
63
63
  *
64
64
  * IMPORT_PATH: `"@daiso-tech/core/async"`
65
65
  * @group Middleware
66
66
  */
67
- export type OnFinally<TContext extends HookContext = HookContext> = Invokable<[
68
- data: OnFinallyData<TContext>
69
- ]>;
67
+ export type OnObserveFinally<TContext extends HookContext = HookContext> = Invokable<[data: OnObserveFinallyData<TContext>]>;
70
68
  /**
71
69
  *
72
70
  * IMPORT_PATH: `"@daiso-tech/core/async"`
73
71
  * @group Middleware
74
72
  */
75
- export type ObserveSettings<TParameters extends unknown[] = unknown[], TReturn = unknown, TContext extends HookContext = HookContext> = {
73
+ export type ObserveCallbacks<TParameters extends unknown[] = unknown[], TReturn = unknown, TContext extends HookContext = HookContext> = {
76
74
  /**
77
75
  * Callback function that will be called when before the underlying {@link Invokable | `Invokable`} is called.
78
76
  */
79
- onStart?: OnStart<TParameters, TContext>;
77
+ onStart?: OnObserveStart<TParameters, TContext>;
80
78
  /**
81
79
  * Callback function that will be called when the underlying {@link Invokable | `Invokable`} is successfully called.
82
80
  */
83
- onSuccess?: OnSuccess<TParameters, TReturn, TContext>;
81
+ onSuccess?: OnObserveSuccess<TParameters, TReturn, TContext>;
84
82
  /**
85
83
  * Callback function that will be called when the underlying {@link Invokable | `Invokable`} throws an error.
86
84
  */
87
- onError?: OnError<TParameters, TContext>;
85
+ onError?: OnObserveError<TParameters, TContext>;
88
86
  /**
89
87
  * Callback function that will be called when the underlying {@link Invokable | `Invokable`} throws an error or is successfully called.
90
88
  */
91
- onFinally?: OnFinally<TContext>;
89
+ onFinally?: OnObserveFinally<TContext>;
92
90
  };
93
91
  /**
94
92
  * The `observe` middleware tracks an async function's state and runs callbacks when it fails with an error or succeeds.
@@ -129,4 +127,4 @@ export type ObserveSettings<TParameters extends unknown[] = unknown[], TReturn =
129
127
  * // Will log the execution time and arguments
130
128
  * ```
131
129
  */
132
- export declare function observe<TParameters extends unknown[], TReturn, TContext extends HookContext>(settings: NoInfer<ObserveSettings<TParameters, TReturn, TContext>>): AsyncMiddlewareFn<TParameters, TReturn, TContext>;
130
+ export declare function observe<TParameters extends unknown[], TReturn, TContext extends HookContext>(settings: NoInfer<ObserveCallbacks<TParameters, TReturn, TContext>>): AsyncMiddlewareFn<TParameters, TReturn, TContext>;
@@ -44,7 +44,7 @@ import { callInvokable, } from "../../../utilities/_module-exports.js";
44
44
  */
45
45
  export function observe(settings) {
46
46
  const { onStart = () => { }, onSuccess = () => { }, onError = () => { }, onFinally = () => { }, } = settings;
47
- return async (args, next, context) => {
47
+ return async (args, next, { context }) => {
48
48
  const start = performance.now();
49
49
  try {
50
50
  callInvokable(onStart, {
@@ -1 +1 @@
1
- {"version":3,"file":"observe.middleware.js","sourceRoot":"","sources":["../../../../src/async/middlewares/observe/observe.middleware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAoB,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EACH,aAAa,GAGhB,MAAM,gCAAgC,CAAC;AA6HxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,UAAU,OAAO,CAKnB,QAAkE;IAElE,MAAM,EACF,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,EAClB,SAAS,GAAG,GAAG,EAAE,GAAE,CAAC,EACpB,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,EAClB,SAAS,GAAG,GAAG,EAAE,GAAE,CAAC,GACvB,GAAG,QAAQ,CAAC;IACb,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC;YACD,aAAa,CAAC,OAAO,EAAE;gBACnB,IAAI;gBACJ,OAAO;aACV,CAAC,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACxC,aAAa,CAAC,SAAS,EAAE;gBACrB,IAAI;gBACJ,OAAO;gBACP,WAAW;aACd,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACvB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,aAAa,CAAC,OAAO,EAAE;gBACnB,IAAI;gBACJ,OAAO;gBACP,KAAK;aACR,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QAChB,CAAC;gBAAS,CAAC;YACP,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;YACzB,aAAa,CAAC,SAAS,EAAE;gBACrB,OAAO;gBACP,aAAa,EAAE,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC;aACjD,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"observe.middleware.js","sourceRoot":"","sources":["../../../../src/async/middlewares/observe/observe.middleware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAoB,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EACH,aAAa,GAGhB,MAAM,gCAAgC,CAAC;AA4HxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,UAAU,OAAO,CAKnB,QAAmE;IAEnE,MAAM,EACF,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,EAClB,SAAS,GAAG,GAAG,EAAE,GAAE,CAAC,EACpB,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,EAClB,SAAS,GAAG,GAAG,EAAE,GAAE,CAAC,GACvB,GAAG,QAAQ,CAAC;IACb,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC;YACD,aAAa,CAAC,OAAO,EAAE;gBACnB,IAAI;gBACJ,OAAO;aACV,CAAC,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACxC,aAAa,CAAC,SAAS,EAAE;gBACrB,IAAI;gBACJ,OAAO;gBACP,WAAW;aACd,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACvB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,aAAa,CAAC,OAAO,EAAE;gBACnB,IAAI;gBACJ,OAAO;gBACP,KAAK;aACR,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QAChB,CAAC;gBAAS,CAAC;YACP,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;YACzB,aAAa,CAAC,SAAS,EAAE;gBACrB,OAAO;gBACP,aAAa,EAAE,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC;aACjD,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC;AACN,CAAC"}
@@ -3,12 +3,13 @@
3
3
  */
4
4
  import { TimeSpan, type Invokable, type HookContext, type AsyncMiddlewareFn } from "../../../utilities/_module-exports.js";
5
5
  import { type BackoffPolicy } from "../../../async/backof-policies/_module.js";
6
+ import { type ErrorPolicy } from "../../../async/middlewares/_shared.js";
6
7
  /**
7
8
  *
8
9
  * IMPORT_PATH: `"@daiso-tech/core/async"`
9
- * @group Utilities
10
+ * @group Middlewares
10
11
  */
11
- export type OnExecutionAttemptData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
12
+ export type OnRetryAttemptData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
12
13
  attempt: number;
13
14
  args: TParameters;
14
15
  context: TContext;
@@ -16,15 +17,15 @@ export type OnExecutionAttemptData<TParameters extends unknown[] = unknown[], TC
16
17
  /**
17
18
  *
18
19
  * IMPORT_PATH: `"@daiso-tech/core/async"`
19
- * @group Utilities
20
+ * @group Middlewares
20
21
  */
21
- export type OnExecutionAttempt<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnExecutionAttemptData<TParameters, TContext>]>;
22
+ export type OnRetryAttempt<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnRetryAttemptData<TParameters, TContext>]>;
22
23
  /**
23
24
  *
24
25
  * IMPORT_PATH: `"@daiso-tech/core/async"`
25
- * @group Utilities
26
+ * @group Middlewares
26
27
  */
27
- export type OnRetryData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
28
+ export type OnRetryDelayData<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
28
29
  error: unknown;
29
30
  attempt: number;
30
31
  waitTime: TimeSpan;
@@ -34,21 +35,30 @@ export type OnRetryData<TParameters extends unknown[] = unknown[], TContext exte
34
35
  /**
35
36
  *
36
37
  * IMPORT_PATH: `"@daiso-tech/core/async"`
37
- * @group Utilities
38
+ * @group Middlewares
38
39
  */
39
- export type OnRetry<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnRetryData<TParameters, TContext>]>;
40
+ export type OnRetryDelay<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = Invokable<[data: OnRetryDelayData<TParameters, TContext>]>;
40
41
  /**
41
42
  *
42
43
  * IMPORT_PATH: `"@daiso-tech/core/async"`
43
- * @group Utilities
44
+ * @group Middlewares
44
45
  */
45
- export type RetryPolicy = Invokable<[error: unknown, attempt: number], boolean>;
46
+ export type RetryCallbacks<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
47
+ /**
48
+ * Callback function that will be called before execution attempt.
49
+ */
50
+ onExecutionAttempt?: OnRetryAttempt<TParameters, TContext>;
51
+ /**
52
+ * Callback function that will be called when the retry delay starts.
53
+ */
54
+ onRetryDelay?: OnRetryDelay<TParameters, TContext>;
55
+ };
46
56
  /**
47
57
  *
48
58
  * IMPORT_PATH: `"@daiso-tech/core/async"`
49
- * @group Utilities
59
+ * @group Middlewares
50
60
  */
51
- export type RetrySettings<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = {
61
+ export type RetrySettings<TParameters extends unknown[] = unknown[], TContext extends HookContext = HookContext> = RetryCallbacks<TParameters, TContext> & {
52
62
  /**
53
63
  * You can decide maximal times you can retry.
54
64
  * @default {4}
@@ -68,22 +78,10 @@ export type RetrySettings<TParameters extends unknown[] = unknown[], TContext ex
68
78
  *
69
79
  * @default
70
80
  * ```ts
71
- * () => true
81
+ * (_error: unknown) => true
72
82
  * ```
73
83
  */
74
- retryPolicy?: RetryPolicy;
75
- /**
76
- * Callback function that will be called before execution attempt.
77
- */
78
- onExecutionAttempt?: OnExecutionAttempt<TParameters, TContext>;
79
- /**
80
- * Callback function that will be called when the retry delay starts.
81
- */
82
- onRetryStart?: OnRetry<TParameters, TContext>;
83
- /**
84
- * Callback function that will be called when the retry delay ends and before the next execution attempt.
85
- */
86
- onRetryEnd?: OnRetry<TParameters, TContext>;
84
+ retryPolicy?: ErrorPolicy;
87
85
  };
88
86
  /**
89
87
  * The `retry` middleware enables automatic retries for all errors or specific errors, with configurable backoff policies.
@@ -91,22 +89,29 @@ export type RetrySettings<TParameters extends unknown[] = unknown[], TContext ex
91
89
  *
92
90
  * IMPORT_PATH: `"@daiso-tech/core/async"`
93
91
  * @group Middleware
94
- *
95
- * @throws {AbortAsyncError} {@link AbortAsyncError}
92
+ * @throws {RetryAsyncError} {@link RetryAsyncError}
96
93
  *
97
94
  * @example
98
95
  * ```ts
99
96
  * import { retry } from "@daiso-tech/core/async";
100
- * import { AsyncHooks } from "@daiso-tech/core/utilities";
97
+ * import { AsyncHooks, TimeSpan } from "@daiso-tech/core/utilities";
101
98
  *
102
- * await new AsyncHooks(async (url: string) => {
103
- * const response = await fetch(url);
104
- * const json = await response.json();
105
- * if (!response.ok) {
106
- * throw json
99
+ * const data = await new AsyncHooks(
100
+ * async (url: string, signal?: AbortSignal): Promise<unknown> => {
101
+ * const response = await fetch(url, { signal });
102
+ * return await response.json();
103
+ * },
104
+ * [retry()],
105
+ * {
106
+ * signalBinder: {
107
+ * getSignal: (args) => args[1],
108
+ * forwardSignal: (args, signal) => {
109
+ * args[1] = signal;
110
+ * }
111
+ * }
107
112
  * }
108
- * return json;
109
- * }, retry({ maxAttempts: 8 })).invoke("URL_ENDPOINT");
113
+ * )
114
+ * .invoke("URL");
110
115
  * ```
111
116
  */
112
117
  export declare function retry<TParameters extends unknown[], TReturn, TContext extends HookContext>(settings?: NoInfer<RetrySettings<TParameters, TContext>>): AsyncMiddlewareFn<TParameters, TReturn, TContext>;