1 | import { isAction, autorun, action, isObservableArray, runInAction } from "mobx";
|
2 | /**
|
3 | * `chunkProcessor` takes an observable array, observes it and calls `processor`
|
4 | * once for a chunk of items added to the observable array, optionally deboucing the action.
|
5 | * The maximum chunk size can be limited by number.
|
6 | * This allows both, splitting larger into smaller chunks or (when debounced) combining smaller
|
7 | * chunks and/or single items into reasonable chunks of work.
|
8 | *
|
9 | * @example
|
10 | * const trackedActions = observable([])
|
11 | * const stop = chunkProcessor(trackedActions, chunkOfMax10Items => {
|
12 | * sendTrackedActionsToServer(chunkOfMax10Items);
|
13 | * }, 100, 10)
|
14 | *
|
15 | * // usage:
|
16 | * trackedActions.push("scrolled")
|
17 | * trackedActions.push("hoveredButton")
|
18 | * // when both pushes happen within 100ms, there will be only one call to server
|
19 | *
|
20 | * @param {T[]} observableArray observable array instance to track
|
21 | * @param {(item: T[]) => void} processor action to call per item
|
22 | * @param {number} [debounce=0] optional debounce time in ms. With debounce 0 the processor will run synchronously
|
23 | * @param {number} [maxChunkSize=0] optionally do not call on full array but smaller chunks. With 0 it will process the full array.
|
24 | * @returns {IDisposer} stops the processor
|
25 | */
|
26 | export function chunkProcessor(observableArray, processor, debounce, maxChunkSize) {
|
27 | if (debounce === void 0) { debounce = 0; }
|
28 | if (maxChunkSize === void 0) { maxChunkSize = 0; }
|
29 | if (!isObservableArray(observableArray))
|
30 | throw new Error("Expected observable array as first argument");
|
31 | if (!isAction(processor))
|
32 | processor = action("chunkProcessor", processor);
|
33 | var runner = function () {
|
34 | var _loop_1 = function () {
|
35 | var chunkSize = maxChunkSize === 0
|
36 | ? observableArray.length
|
37 | : Math.min(observableArray.length, maxChunkSize);
|
38 | // construct a final set
|
39 | var items = observableArray.slice(0, chunkSize);
|
40 | // clear the slice for next iteration
|
41 | runInAction(function () { return observableArray.splice(0, chunkSize); });
|
42 | // fire processor
|
43 | processor(items);
|
44 | };
|
45 | while (observableArray.length > 0) {
|
46 | _loop_1();
|
47 | }
|
48 | };
|
49 | if (debounce > 0)
|
50 | return autorun(runner, { delay: debounce });
|
51 | else
|
52 | return autorun(runner);
|
53 | }
|