cogsbox-state 0.5.315 → 0.5.316
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CogsState.jsx +579 -560
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +70 -24
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1820,10 +1820,23 @@ function createProxyHandler<T>(
|
|
|
1820
1820
|
// This state triggers a re-render when item heights change.
|
|
1821
1821
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
1822
1822
|
|
|
1823
|
+
// Track when we've attempted initial scroll
|
|
1824
|
+
const hasAttemptedScrollRef = useRef(false);
|
|
1825
|
+
const lastTotalCountRef = useRef(0);
|
|
1826
|
+
|
|
1827
|
+
// Subscribe to shadow state changes with limited logging
|
|
1823
1828
|
useEffect(() => {
|
|
1829
|
+
let updateCount = 0;
|
|
1824
1830
|
const unsubscribe = getGlobalStore
|
|
1825
1831
|
.getState()
|
|
1826
1832
|
.subscribeToShadowState(stateKey, () => {
|
|
1833
|
+
updateCount++;
|
|
1834
|
+
if (updateCount <= 5) {
|
|
1835
|
+
// Only log first 5 updates to avoid spam
|
|
1836
|
+
console.log(
|
|
1837
|
+
`[VirtualView] Shadow update #${updateCount}`
|
|
1838
|
+
);
|
|
1839
|
+
}
|
|
1827
1840
|
setShadowUpdateTrigger((prev) => prev + 1);
|
|
1828
1841
|
});
|
|
1829
1842
|
return unsubscribe;
|
|
@@ -1835,20 +1848,44 @@ function createProxyHandler<T>(
|
|
|
1835
1848
|
) as any[];
|
|
1836
1849
|
const totalCount = sourceArray.length;
|
|
1837
1850
|
|
|
1838
|
-
|
|
1839
|
-
|
|
1851
|
+
console.log(
|
|
1852
|
+
`[VirtualView] Initial setup - totalCount: ${totalCount}, itemHeight: ${itemHeight}, stickToBottom: ${stickToBottom}`
|
|
1853
|
+
);
|
|
1854
|
+
|
|
1855
|
+
// Reset scroll attempt when array size changes
|
|
1856
|
+
if (totalCount !== lastTotalCountRef.current) {
|
|
1857
|
+
console.log(
|
|
1858
|
+
`[VirtualView] Array size changed from ${lastTotalCountRef.current} to ${totalCount}`
|
|
1859
|
+
);
|
|
1860
|
+
hasAttemptedScrollRef.current = false;
|
|
1861
|
+
lastTotalCountRef.current = totalCount;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
// Calculate heights from shadow state and track if all measured
|
|
1865
|
+
const { totalHeight, positions, allMeasured } = useMemo(() => {
|
|
1840
1866
|
const shadowArray =
|
|
1841
1867
|
getGlobalStore.getState().getShadowMetadata(stateKey, path) ||
|
|
1842
1868
|
[];
|
|
1843
1869
|
let height = 0;
|
|
1844
1870
|
const pos: number[] = [];
|
|
1871
|
+
let measuredCount = 0;
|
|
1872
|
+
|
|
1845
1873
|
for (let i = 0; i < totalCount; i++) {
|
|
1846
1874
|
pos[i] = height;
|
|
1847
1875
|
const measuredHeight =
|
|
1848
1876
|
shadowArray[i]?.virtualizer?.itemHeight;
|
|
1877
|
+
if (measuredHeight) measuredCount++;
|
|
1849
1878
|
height += measuredHeight || itemHeight;
|
|
1850
1879
|
}
|
|
1851
|
-
|
|
1880
|
+
|
|
1881
|
+
const allMeasured =
|
|
1882
|
+
measuredCount === totalCount && totalCount > 0;
|
|
1883
|
+
|
|
1884
|
+
console.log(
|
|
1885
|
+
`[VirtualView] Heights calc - measured: ${measuredCount}/${totalCount}, allMeasured: ${allMeasured}, totalHeight: ${height}`
|
|
1886
|
+
);
|
|
1887
|
+
|
|
1888
|
+
return { totalHeight: height, positions: pos, allMeasured };
|
|
1852
1889
|
}, [
|
|
1853
1890
|
totalCount,
|
|
1854
1891
|
stateKey,
|
|
@@ -1861,6 +1898,11 @@ function createProxyHandler<T>(
|
|
|
1861
1898
|
const virtualState = useMemo(() => {
|
|
1862
1899
|
const start = Math.max(0, range.startIndex);
|
|
1863
1900
|
const end = Math.min(totalCount, range.endIndex);
|
|
1901
|
+
|
|
1902
|
+
console.log(
|
|
1903
|
+
`[VirtualView] Creating virtual slice - range: ${start}-${end} (${end - start} items)`
|
|
1904
|
+
);
|
|
1905
|
+
|
|
1864
1906
|
const validIndices = Array.from(
|
|
1865
1907
|
{ length: end - start },
|
|
1866
1908
|
(_, i) => start + i
|
|
@@ -1872,13 +1914,11 @@ function createProxyHandler<T>(
|
|
|
1872
1914
|
});
|
|
1873
1915
|
}, [range.startIndex, range.endIndex, sourceArray, totalCount]);
|
|
1874
1916
|
|
|
1875
|
-
//
|
|
1917
|
+
// Simplified layout effect that waits for all measurements
|
|
1876
1918
|
useLayoutEffect(() => {
|
|
1877
1919
|
const container = containerRef.current;
|
|
1878
1920
|
if (!container) return;
|
|
1879
1921
|
|
|
1880
|
-
let scrollTimeoutId: NodeJS.Timeout;
|
|
1881
|
-
|
|
1882
1922
|
// This function determines what's visible in the viewport.
|
|
1883
1923
|
const updateVirtualRange = () => {
|
|
1884
1924
|
if (!container) return;
|
|
@@ -1917,32 +1957,38 @@ function createProxyHandler<T>(
|
|
|
1917
1957
|
passive: true,
|
|
1918
1958
|
});
|
|
1919
1959
|
|
|
1920
|
-
//
|
|
1921
|
-
if (
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1960
|
+
// Scroll to bottom logic
|
|
1961
|
+
if (
|
|
1962
|
+
stickToBottom &&
|
|
1963
|
+
!hasAttemptedScrollRef.current &&
|
|
1964
|
+
totalCount > 0
|
|
1965
|
+
) {
|
|
1966
|
+
if (allMeasured) {
|
|
1967
|
+
// All items measured, safe to scroll
|
|
1968
|
+
console.log(
|
|
1969
|
+
`[VirtualView] All items measured, scrolling to bottom`
|
|
1970
|
+
);
|
|
1971
|
+
hasAttemptedScrollRef.current = true;
|
|
1972
|
+
container.scrollTo({
|
|
1973
|
+
top: container.scrollHeight,
|
|
1974
|
+
behavior: "auto",
|
|
1975
|
+
});
|
|
1976
|
+
} else {
|
|
1977
|
+
// Still waiting for measurements, try again next render
|
|
1978
|
+
console.log(
|
|
1979
|
+
`[VirtualView] Waiting for all measurements before scroll`
|
|
1980
|
+
);
|
|
1981
|
+
}
|
|
1934
1982
|
}
|
|
1935
1983
|
|
|
1936
1984
|
// Update the visible range on initial load.
|
|
1937
1985
|
updateVirtualRange();
|
|
1938
1986
|
|
|
1939
|
-
// Cleanup function
|
|
1987
|
+
// Cleanup function
|
|
1940
1988
|
return () => {
|
|
1941
|
-
clearTimeout(scrollTimeoutId);
|
|
1942
1989
|
container.removeEventListener("scroll", handleUserScroll);
|
|
1943
1990
|
};
|
|
1944
|
-
|
|
1945
|
-
}, [totalCount, positions, stickToBottom]);
|
|
1991
|
+
}, [totalCount, positions, stickToBottom, allMeasured]);
|
|
1946
1992
|
|
|
1947
1993
|
const scrollToBottom = useCallback(
|
|
1948
1994
|
(behavior: ScrollBehavior = "smooth") => {
|