From d8bca1100df5cc8a14a23d235788809ef16b1d03 Mon Sep 17 00:00:00 2001 From: Petyo Ivanov Date: Sun, 27 Oct 2024 10:59:23 +0200 Subject: [PATCH] fix: make useCellValues reliable --- src/hooks.ts | 32 +++----------------------------- src/realm.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/hooks.ts b/src/hooks.ts index 725d0f5..c839f7e 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -40,12 +40,7 @@ export function useCellValue(cell: NodeRef) { const realm = useRealm() realm.register(cell) - const cb = React.useCallback( - (c: () => void) => { - return realm.sub(cell, c) - }, - [realm, cell] - ) + const cb = React.useCallback((c: () => void) => realm.sub(cell, c), [realm, cell]) return React.useSyncExternalStore( cb, @@ -85,29 +80,8 @@ export function useCellValues export function useCellValues(...cells: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]; // prettier-ignore export function useCellValues(...cells: Array>): unknown[] { const realm = useRealm() - const initial = React.useMemo( - () => realm.getValues(cells), - // eslint-disable-next-line react-hooks/exhaustive-deps - [] - ) - const currentRef = React.useRef(initial) - - const cb = React.useCallback( - (c: () => void) => { - const sub = (values: unknown[]) => { - currentRef.current = values - c() - } - return realm.subMultiple(cells, sub) - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [realm, ...cells] - ) - return React.useSyncExternalStore( - cb, - () => currentRef.current, - () => currentRef.current - ) + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + return useCellValue(realm.combineCells.apply(realm, cells as any)) } /** diff --git a/src/realm.ts b/src/realm.ts index d311ffc..c4667c7 100644 --- a/src/realm.ts +++ b/src/realm.ts @@ -494,6 +494,50 @@ export class Realm { }) } + /** + * Combines the values from multiple nodes into a cell that's an array of the latest values of the nodes. + */ + combineCells (...nodes: [NodeRef]): NodeRef<[T1]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef]): NodeRef<[T1, T2]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]> // prettier-ignore + combineCells (...nodes: [NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef]): NodeRef<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]> // prettier-ignore + combineCells(...sources: Array>): NodeRef { + return tap( + this.cellInstance( + sources.map((source) => this.getValue(source)), + true + ), + (sink) => { + this.connect({ + map: + (done) => + (...args) => { + done(args) + }, + sink, + sources, + }) + } + ) + } + /** * Gets the current value of a node. The node must be stateful. * @remark if possible, use {@link withLatestFrom} or {@link combine}, as getValue will not create a dependency to the passed node,