@karmaniverous/entity-manager 6.1.0 → 6.1.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.
@@ -2,6 +2,7 @@
2
2
 
3
3
  var tslib = require('tslib');
4
4
  var radash = require('radash');
5
+ var promises = require('timers/promises');
5
6
  var conditionalize = require('./conditionalize.js');
6
7
 
7
8
  var _EntityManagerClient_options;
@@ -36,6 +37,47 @@ class EntityManagerClient {
36
37
  get options() {
37
38
  return tslib.__classPrivateFieldGet(this, _EntityManagerClient_options, "f");
38
39
  }
40
+ /**
41
+ * Executes a batch operation.
42
+ *
43
+ * @param items - Items to batch execute.
44
+ * @param executeBatch - Function to execute the batch.
45
+ * @param getUnprocessedItems - Function to get unprocessed items from the output.
46
+ * @param options - Batch options.
47
+ *
48
+ * @typeParam Item - Input item type.
49
+ * @typeParam Output - Output type.
50
+ *
51
+ * @returns Output array.
52
+ */
53
+ async batchExecute(items, executeBatch, getUnprocessedItems, { batchSize = this.options.batchSize, delayIncrement = this.options.delayIncrement, maxRetries = this.options.maxRetries, throttle = this.options.throttle, } = {}) {
54
+ const batches = radash.cluster(items, batchSize);
55
+ const outputs = [];
56
+ await radash.parallel(throttle, batches, async (batch) => {
57
+ let delay = 0;
58
+ let retry = 0;
59
+ while (batch.length) {
60
+ if (delay)
61
+ await promises.setTimeout(delay);
62
+ const output = await executeBatch(batch);
63
+ this.options.logger.debug('executed batch', {
64
+ batch,
65
+ delay,
66
+ retry,
67
+ output,
68
+ });
69
+ outputs.push(output);
70
+ batch = getUnprocessedItems?.(output) ?? [];
71
+ if (batch.length) {
72
+ if (retry === maxRetries)
73
+ throw new Error('max retries exceeded');
74
+ delay = delay ? delay * 2 : delayIncrement;
75
+ retry++;
76
+ }
77
+ }
78
+ });
79
+ return outputs;
80
+ }
39
81
  }
40
82
  _EntityManagerClient_options = new WeakMap();
41
83
 
package/dist/index.d.ts CHANGED
@@ -895,6 +895,20 @@ declare abstract class EntityManagerClient<O extends EntityManagerClientOptions>
895
895
  * Returns the options used to create the EntityManagerClient instance.
896
896
  */
897
897
  get options(): Required<O>;
898
+ /**
899
+ * Executes a batch operation.
900
+ *
901
+ * @param items - Items to batch execute.
902
+ * @param executeBatch - Function to execute the batch.
903
+ * @param getUnprocessedItems - Function to get unprocessed items from the output.
904
+ * @param options - Batch options.
905
+ *
906
+ * @typeParam Item - Input item type.
907
+ * @typeParam Output - Output type.
908
+ *
909
+ * @returns Output array.
910
+ */
911
+ protected batchExecute<Item, Output>(items: Item[], executeBatch: (items: Item[]) => Promise<Output>, getUnprocessedItems?: (output: Output) => Item[] | undefined, { batchSize, delayIncrement, maxRetries, throttle, }?: EntityManagerClientBatchOptions): Promise<Output[]>;
898
912
  }
899
913
 
900
914
  /**
@@ -1,5 +1,6 @@
1
1
  import { __classPrivateFieldSet, __classPrivateFieldGet } from 'tslib';
2
- import { isFunction } from 'radash';
2
+ import { isFunction, cluster, parallel } from 'radash';
3
+ import { setTimeout } from 'timers/promises';
3
4
  import { conditionalize } from './conditionalize.js';
4
5
 
5
6
  var _EntityManagerClient_options;
@@ -34,6 +35,47 @@ class EntityManagerClient {
34
35
  get options() {
35
36
  return __classPrivateFieldGet(this, _EntityManagerClient_options, "f");
36
37
  }
38
+ /**
39
+ * Executes a batch operation.
40
+ *
41
+ * @param items - Items to batch execute.
42
+ * @param executeBatch - Function to execute the batch.
43
+ * @param getUnprocessedItems - Function to get unprocessed items from the output.
44
+ * @param options - Batch options.
45
+ *
46
+ * @typeParam Item - Input item type.
47
+ * @typeParam Output - Output type.
48
+ *
49
+ * @returns Output array.
50
+ */
51
+ async batchExecute(items, executeBatch, getUnprocessedItems, { batchSize = this.options.batchSize, delayIncrement = this.options.delayIncrement, maxRetries = this.options.maxRetries, throttle = this.options.throttle, } = {}) {
52
+ const batches = cluster(items, batchSize);
53
+ const outputs = [];
54
+ await parallel(throttle, batches, async (batch) => {
55
+ let delay = 0;
56
+ let retry = 0;
57
+ while (batch.length) {
58
+ if (delay)
59
+ await setTimeout(delay);
60
+ const output = await executeBatch(batch);
61
+ this.options.logger.debug('executed batch', {
62
+ batch,
63
+ delay,
64
+ retry,
65
+ output,
66
+ });
67
+ outputs.push(output);
68
+ batch = getUnprocessedItems?.(output) ?? [];
69
+ if (batch.length) {
70
+ if (retry === maxRetries)
71
+ throw new Error('max retries exceeded');
72
+ delay = delay ? delay * 2 : delayIncrement;
73
+ retry++;
74
+ }
75
+ }
76
+ });
77
+ return outputs;
78
+ }
37
79
  }
38
80
  _EntityManagerClient_options = new WeakMap();
39
81
 
package/package.json CHANGED
@@ -132,5 +132,5 @@
132
132
  },
133
133
  "type": "module",
134
134
  "types": "dist/index.d.ts",
135
- "version": "6.1.0"
135
+ "version": "6.1.2"
136
136
  }