UNPKG

@bigmi/react

Version:

React primitives for Bitcoin apps.

44 lines 1.79 kB
'use client'; import { deepEqual } from '@bigmi/core'; import { useMemo, useRef, useSyncExternalStore } from 'react'; const isPlainObject = (obj) => typeof obj === 'object' && !Array.isArray(obj); export function useSyncExternalStoreWithTracked(subscribe, getSnapshot, getServerSnapshot = getSnapshot, isEqual = deepEqual) { const trackedKeys = useRef(new Set()); const previousResult = useRef(undefined); const snapshotCache = useRef(getSnapshot()); const snapshot = useSyncExternalStore((onChange) => subscribe(() => { snapshotCache.current = getSnapshot(); onChange(); }), () => snapshotCache.current, getServerSnapshot); const result = useMemo(() => { if (!isPlainObject(snapshot)) { return snapshot; } const trackedResult = { ...snapshot }; Object.defineProperties(trackedResult, Object.fromEntries(Object.entries(trackedResult).map(([key, value]) => [ key, { configurable: false, enumerable: true, get: () => { trackedKeys.current.add(key); return value; }, }, ]))); return trackedResult; }, [snapshot]); return useMemo(() => { if (!trackedKeys.current.size || !previousResult.current) { previousResult.current = result; return result; } const hasChanged = Array.from(trackedKeys.current).some((key) => !isEqual(result[key], previousResult.current[key])); if (!hasChanged) { return previousResult.current; } previousResult.current = result; return result; }, [result, isEqual]); } //# sourceMappingURL=useSyncExternalStoreWithTracked.js.map