Skip to content

Commit 9b4dd52

Browse files
authored
refactor(useAsyncIterMulti): base it on top of the shared logic of the internal useAsyncItersImperatively hook (#100)
1 parent 751630c commit 9b4dd52

File tree

1 file changed

+9
-124
lines changed

1 file changed

+9
-124
lines changed

src/useAsyncIterMulti/index.ts

Lines changed: 9 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
import { useEffect } from 'react';
21
import { useSimpleRerender } from '../common/hooks/useSimpleRerender.js';
3-
import { useRefWithInitialValue } from '../common/hooks/useRefWithInitialValue.js';
4-
import { isAsyncIter } from '../common/isAsyncIter.js';
52
import { type IterationResult } from '../useAsyncIter/index.js';
6-
import { type AsyncIterableSubject } from '../AsyncIterableSubject/index.js';
73
import { type MaybeFunction } from '../common/MaybeFunction.js';
8-
import { callOrReturn } from '../common/callOrReturn.js';
9-
import { asyncIterSyncMap } from '../common/asyncIterSyncMap.js';
10-
import { parseReactAsyncIterable } from '../common/ReactAsyncIterable.js';
11-
import { iterateAsyncIterWithCallbacks } from '../common/iterateAsyncIterWithCallbacks.js';
4+
import { useAsyncItersImperatively } from '../common/useAsyncItersImperatively/index.js';
125

136
export { useAsyncIterMulti, type IterationResult, type IterationResultSet };
147

@@ -211,126 +204,18 @@ function useAsyncIterMulti<
211204
): IterationResultSet<TValues, MaybeFunctions<TInitValues>, TDefaultInitValue> {
212205
const update = useSimpleRerender();
213206

214-
const ref = useRefWithInitialValue(() => ({
215-
currDiffCompId: 0,
216-
prevResults: [] as IterationResultSet<TValues, MaybeFunctions<TInitValues>, TDefaultInitValue>,
217-
activeItersMap: new Map<
218-
AsyncIterable<unknown>,
219-
{
220-
diffCompId: number;
221-
destroy: () => void;
222-
formatFn: (value: unknown, i: number) => unknown;
223-
currState: IterationResult<unknown, unknown>;
224-
}
225-
>(),
226-
}));
227-
228-
const { prevResults, activeItersMap } = ref.current;
229-
230-
useEffect(() => {
231-
return () => {
232-
for (const it of activeItersMap.values()) {
233-
it.destroy();
234-
}
235-
};
236-
}, []);
237-
238-
const optsNormed = {
207+
const currValues = useAsyncItersImperatively(inputs, () => update(), {
239208
initialValues: opts?.initialValues ?? [],
240209
defaultInitialValue: opts?.defaultInitialValue,
241-
};
242-
243-
const nextDiffCompId = (ref.current.currDiffCompId = ref.current.currDiffCompId === 0 ? 1 : 0);
244-
let numOfPrevRunItersPreserved = 0;
245-
const numOfPrevRunIters = activeItersMap.size;
246-
247-
const nextResults = inputs.map((input, i) => {
248-
if (!isAsyncIter(input)) {
249-
return {
250-
value: input,
251-
pendingFirst: false as const,
252-
done: false as const,
253-
error: undefined,
254-
};
255-
}
256-
257-
const { baseIter, formatFn } = parseReactAsyncIterable(input);
258-
259-
const existingIterState = activeItersMap.get(baseIter);
260-
261-
if (existingIterState) {
262-
numOfPrevRunItersPreserved++;
263-
existingIterState.diffCompId = nextDiffCompId;
264-
existingIterState.formatFn = formatFn;
265-
return existingIterState.currState;
266-
}
267-
268-
const formattedIter: AsyncIterable<unknown> = (() => {
269-
let iterationIdx = 0;
270-
return asyncIterSyncMap(baseIter, value => newIterState.formatFn(value, iterationIdx++));
271-
})();
272-
273-
const inputWithMaybeCurrentValue = input as typeof input & {
274-
value?: AsyncIterableSubject<unknown>['value'];
275-
};
210+
});
276211

277-
let startingValue;
278-
let pendingFirst;
279-
if (inputWithMaybeCurrentValue.value) {
280-
startingValue = inputWithMaybeCurrentValue.value.current;
281-
pendingFirst = false;
282-
} else {
283-
startingValue =
284-
i < prevResults.length
285-
? prevResults[i].value
286-
: callOrReturn(
287-
i < optsNormed.initialValues.length
288-
? optsNormed.initialValues[i]
289-
: optsNormed.defaultInitialValue
290-
);
291-
pendingFirst = true;
292-
}
293-
294-
const destroyFn = iterateAsyncIterWithCallbacks(formattedIter, startingValue, next => {
295-
newIterState.currState = { pendingFirst: false, ...next };
296-
update();
297-
});
298-
299-
const newIterState = {
300-
diffCompId: nextDiffCompId,
301-
destroy: destroyFn,
302-
formatFn,
303-
currState: {
304-
value: startingValue,
305-
pendingFirst,
306-
done: false as const,
307-
error: undefined,
308-
} as IterationResult<unknown, unknown>,
309-
};
310-
311-
activeItersMap.set(baseIter, newIterState);
312-
313-
return newIterState.currState;
314-
}) as IterationResultSet<TValues, MaybeFunctions<TInitValues>, TDefaultInitValue>;
315-
316-
const numOfPrevRunItersDisappeared = numOfPrevRunIters - numOfPrevRunItersPreserved;
317-
318-
if (numOfPrevRunItersDisappeared > 0) {
319-
let i = 0;
320-
for (const { 0: iter, 1: state } of activeItersMap) {
321-
if (state.diffCompId !== nextDiffCompId) {
322-
activeItersMap.delete(iter);
323-
state.destroy();
324-
if (++i === numOfPrevRunItersDisappeared) {
325-
break;
326-
}
327-
}
328-
}
329-
}
330-
331-
ref.current.prevResults = nextResults;
212+
const currValuesTypePatched = currValues as IterationResultSet<
213+
TValues,
214+
MaybeFunctions<TInitValues>,
215+
TDefaultInitValue
216+
>;
332217

333-
return nextResults;
218+
return currValuesTypePatched;
334219
}
335220

336221
type IterationResultSet<

0 commit comments

Comments
 (0)