@bigmi/react
Version:
React primitives for Bitcoin apps.
40 lines (39 loc) • 1.58 kB
JavaScript
"use client";
import { useMemo, useRef, useSyncExternalStore } from "react";
import { deepEqual } from "@bigmi/core";
//#region src/hooks/useSyncExternalStoreWithTracked.ts
const isPlainObject = (obj) => typeof obj === "object" && !Array.isArray(obj);
function useSyncExternalStoreWithTracked(subscribe, getSnapshot, getServerSnapshot = getSnapshot, isEqual = deepEqual) {
const trackedKeys = useRef(/* @__PURE__ */ new Set());
const previousResult = useRef(void 0);
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;
}
if (!Array.from(trackedKeys.current).some((key) => !isEqual(result[key], previousResult.current[key]))) return previousResult.current;
previousResult.current = result;
return result;
}, [result, isEqual]);
}
//#endregion
export { useSyncExternalStoreWithTracked };
//# sourceMappingURL=useSyncExternalStoreWithTracked.js.map