cogsbox-state 0.5.406 → 0.5.408
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 +330 -383
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +52 -120
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1803,9 +1803,7 @@ function createProxyHandler<T>(
|
|
|
1803
1803
|
return selectedIndex ?? -1;
|
|
1804
1804
|
};
|
|
1805
1805
|
}
|
|
1806
|
-
//
|
|
1807
|
-
// Optimal approach - replace the useVirtualView implementation
|
|
1808
|
-
// Complete useVirtualView implementation with comprehensive logging
|
|
1806
|
+
// Complete fixed useVirtualView implementation
|
|
1809
1807
|
if (prop === "useVirtualView") {
|
|
1810
1808
|
return (
|
|
1811
1809
|
options: VirtualViewOptions
|
|
@@ -1817,19 +1815,13 @@ function createProxyHandler<T>(
|
|
|
1817
1815
|
dependencies = [],
|
|
1818
1816
|
} = options;
|
|
1819
1817
|
|
|
1820
|
-
console.log("useVirtualView initialized with:", {
|
|
1821
|
-
itemHeight,
|
|
1822
|
-
overscan,
|
|
1823
|
-
stickToBottom,
|
|
1824
|
-
});
|
|
1825
|
-
|
|
1826
1818
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
1827
1819
|
const [range, setRange] = useState({
|
|
1828
1820
|
startIndex: 0,
|
|
1829
1821
|
endIndex: 10,
|
|
1830
1822
|
});
|
|
1831
1823
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
1832
|
-
const
|
|
1824
|
+
const isProgrammaticScrollRef = useRef(false); // Track if we're scrolling programmatically
|
|
1833
1825
|
const shouldStickToBottomRef = useRef(true);
|
|
1834
1826
|
const scrollToBottomIntervalRef = useRef<NodeJS.Timeout | null>(
|
|
1835
1827
|
null
|
|
@@ -1837,11 +1829,9 @@ function createProxyHandler<T>(
|
|
|
1837
1829
|
|
|
1838
1830
|
// Subscribe to shadow state updates
|
|
1839
1831
|
useEffect(() => {
|
|
1840
|
-
console.log("Setting up shadow state subscription");
|
|
1841
1832
|
const unsubscribe = getGlobalStore
|
|
1842
1833
|
.getState()
|
|
1843
1834
|
.subscribeToShadowState(stateKey, () => {
|
|
1844
|
-
console.log("Shadow state updated");
|
|
1845
1835
|
setShadowUpdateTrigger((prev) => prev + 1);
|
|
1846
1836
|
});
|
|
1847
1837
|
return unsubscribe;
|
|
@@ -1852,11 +1842,9 @@ function createProxyHandler<T>(
|
|
|
1852
1842
|
path
|
|
1853
1843
|
) as any[];
|
|
1854
1844
|
const totalCount = sourceArray.length;
|
|
1855
|
-
console.log("Source array length:", totalCount);
|
|
1856
1845
|
|
|
1857
1846
|
// Calculate heights and positions
|
|
1858
1847
|
const { totalHeight, positions } = useMemo(() => {
|
|
1859
|
-
console.log("Recalculating heights and positions");
|
|
1860
1848
|
const shadowArray =
|
|
1861
1849
|
getGlobalStore.getState().getShadowMetadata(stateKey, path) ||
|
|
1862
1850
|
[];
|
|
@@ -1868,7 +1856,6 @@ function createProxyHandler<T>(
|
|
|
1868
1856
|
shadowArray[i]?.virtualizer?.itemHeight;
|
|
1869
1857
|
height += measuredHeight || itemHeight;
|
|
1870
1858
|
}
|
|
1871
|
-
console.log("Total height calculated:", height);
|
|
1872
1859
|
return { totalHeight: height, positions: pos };
|
|
1873
1860
|
}, [
|
|
1874
1861
|
totalCount,
|
|
@@ -1882,10 +1869,6 @@ function createProxyHandler<T>(
|
|
|
1882
1869
|
const virtualState = useMemo(() => {
|
|
1883
1870
|
const start = Math.max(0, range.startIndex);
|
|
1884
1871
|
const end = Math.min(totalCount, range.endIndex);
|
|
1885
|
-
console.log("Creating virtual state for range:", {
|
|
1886
|
-
start,
|
|
1887
|
-
end,
|
|
1888
|
-
});
|
|
1889
1872
|
const validIndices = Array.from(
|
|
1890
1873
|
{ length: end - start },
|
|
1891
1874
|
(_, i) => start + i
|
|
@@ -1899,41 +1882,12 @@ function createProxyHandler<T>(
|
|
|
1899
1882
|
|
|
1900
1883
|
// Handle auto-scroll to bottom
|
|
1901
1884
|
useEffect(() => {
|
|
1902
|
-
|
|
1903
|
-
stickToBottom,
|
|
1904
|
-
hasContainer: !!containerRef.current,
|
|
1905
|
-
totalCount,
|
|
1906
|
-
shouldStickToBottom: shouldStickToBottomRef.current,
|
|
1907
|
-
range,
|
|
1908
|
-
});
|
|
1909
|
-
|
|
1910
|
-
if (!stickToBottom) {
|
|
1911
|
-
console.log("Stick to bottom is false, skipping");
|
|
1885
|
+
if (!stickToBottom || !containerRef.current || totalCount === 0)
|
|
1912
1886
|
return;
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
if (!containerRef.current) {
|
|
1916
|
-
console.log("No container ref, skipping");
|
|
1917
|
-
return;
|
|
1918
|
-
}
|
|
1919
|
-
|
|
1920
|
-
if (totalCount === 0) {
|
|
1921
|
-
console.log("No items, skipping");
|
|
1922
|
-
return;
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
if (!shouldStickToBottomRef.current) {
|
|
1926
|
-
console.log(
|
|
1927
|
-
"Should not stick to bottom (user scrolled), skipping"
|
|
1928
|
-
);
|
|
1929
|
-
return;
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
console.log("Proceeding with auto-scroll logic");
|
|
1887
|
+
if (!shouldStickToBottomRef.current) return;
|
|
1933
1888
|
|
|
1934
1889
|
// Clear any existing interval
|
|
1935
1890
|
if (scrollToBottomIntervalRef.current) {
|
|
1936
|
-
console.log("Clearing existing scroll interval");
|
|
1937
1891
|
clearInterval(scrollToBottomIntervalRef.current);
|
|
1938
1892
|
}
|
|
1939
1893
|
|
|
@@ -1942,68 +1896,61 @@ function createProxyHandler<T>(
|
|
|
1942
1896
|
const isInitialLoad = range.endIndex < jumpThreshold;
|
|
1943
1897
|
const isBigJump = totalCount > range.endIndex + jumpThreshold;
|
|
1944
1898
|
|
|
1945
|
-
console.log("Jump check:", {
|
|
1946
|
-
isInitialLoad,
|
|
1947
|
-
isBigJump,
|
|
1948
|
-
totalCount,
|
|
1949
|
-
currentEndIndex: range.endIndex,
|
|
1950
|
-
});
|
|
1951
|
-
|
|
1952
1899
|
if (isInitialLoad || isBigJump) {
|
|
1900
|
+
// Set programmatic scroll flag BEFORE changing range
|
|
1901
|
+
isProgrammaticScrollRef.current = true;
|
|
1902
|
+
|
|
1953
1903
|
const newRange = {
|
|
1954
1904
|
startIndex: Math.max(0, totalCount - 20),
|
|
1955
1905
|
endIndex: totalCount,
|
|
1956
1906
|
};
|
|
1957
|
-
console.log("Jumping to end range:", newRange);
|
|
1958
1907
|
setRange(newRange);
|
|
1908
|
+
|
|
1909
|
+
// Reset flag after a delay to ensure scroll events are ignored
|
|
1910
|
+
setTimeout(() => {
|
|
1911
|
+
isProgrammaticScrollRef.current = false;
|
|
1912
|
+
}, 100);
|
|
1959
1913
|
}
|
|
1960
1914
|
|
|
1961
1915
|
// Keep scrolling to bottom until we're actually there
|
|
1962
1916
|
let attempts = 0;
|
|
1963
1917
|
const maxAttempts = 50; // 5 seconds max
|
|
1964
1918
|
|
|
1965
|
-
console.log("Starting scroll-to-bottom interval");
|
|
1966
|
-
|
|
1967
1919
|
scrollToBottomIntervalRef.current = setInterval(() => {
|
|
1968
1920
|
const container = containerRef.current;
|
|
1969
|
-
if (!container)
|
|
1970
|
-
console.log("Container lost during interval");
|
|
1971
|
-
return;
|
|
1972
|
-
}
|
|
1921
|
+
if (!container) return;
|
|
1973
1922
|
|
|
1974
1923
|
attempts++;
|
|
1975
1924
|
|
|
1976
1925
|
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
1977
1926
|
const currentBottom = scrollTop + clientHeight;
|
|
1978
1927
|
const actualBottom = scrollHeight;
|
|
1979
|
-
const isAtBottom = actualBottom - currentBottom <
|
|
1980
|
-
|
|
1981
|
-
console.log(`Scroll attempt ${attempts}:`, {
|
|
1982
|
-
currentBottom,
|
|
1983
|
-
actualBottom,
|
|
1984
|
-
isAtBottom,
|
|
1985
|
-
scrollTop,
|
|
1986
|
-
scrollHeight,
|
|
1987
|
-
clientHeight,
|
|
1988
|
-
});
|
|
1928
|
+
const isAtBottom = actualBottom - currentBottom < 50; // Increased tolerance
|
|
1989
1929
|
|
|
1990
1930
|
if (isAtBottom || attempts >= maxAttempts) {
|
|
1991
|
-
console.log(
|
|
1992
|
-
isAtBottom
|
|
1993
|
-
? "Successfully reached bottom!"
|
|
1994
|
-
: "Timeout - giving up"
|
|
1995
|
-
);
|
|
1996
1931
|
clearInterval(scrollToBottomIntervalRef.current!);
|
|
1997
1932
|
scrollToBottomIntervalRef.current = null;
|
|
1933
|
+
|
|
1934
|
+
// Do one final scroll to ensure we're truly at bottom
|
|
1935
|
+
if (
|
|
1936
|
+
isAtBottom &&
|
|
1937
|
+
container.scrollTop <
|
|
1938
|
+
container.scrollHeight - container.clientHeight
|
|
1939
|
+
) {
|
|
1940
|
+
container.scrollTop = container.scrollHeight;
|
|
1941
|
+
}
|
|
1998
1942
|
} else {
|
|
1999
|
-
|
|
2000
|
-
|
|
1943
|
+
// Only scroll if we're not already scrolling there
|
|
1944
|
+
const targetScroll =
|
|
1945
|
+
container.scrollHeight - container.clientHeight;
|
|
1946
|
+
if (Math.abs(container.scrollTop - targetScroll) > 1) {
|
|
1947
|
+
container.scrollTop = container.scrollHeight;
|
|
1948
|
+
}
|
|
2001
1949
|
}
|
|
2002
1950
|
}, 100);
|
|
2003
1951
|
|
|
2004
1952
|
// Cleanup
|
|
2005
1953
|
return () => {
|
|
2006
|
-
console.log("Cleaning up scroll interval");
|
|
2007
1954
|
if (scrollToBottomIntervalRef.current) {
|
|
2008
1955
|
clearInterval(scrollToBottomIntervalRef.current);
|
|
2009
1956
|
scrollToBottomIntervalRef.current = null;
|
|
@@ -2014,37 +1961,28 @@ function createProxyHandler<T>(
|
|
|
2014
1961
|
// Handle user scroll
|
|
2015
1962
|
useEffect(() => {
|
|
2016
1963
|
const container = containerRef.current;
|
|
2017
|
-
if (!container)
|
|
2018
|
-
console.log("No container for scroll handler");
|
|
2019
|
-
return;
|
|
2020
|
-
}
|
|
1964
|
+
if (!container) return;
|
|
2021
1965
|
|
|
2022
|
-
|
|
1966
|
+
const handleScroll = () => {
|
|
1967
|
+
// Ignore programmatic scrolls
|
|
1968
|
+
if (isProgrammaticScrollRef.current) {
|
|
1969
|
+
return;
|
|
1970
|
+
}
|
|
2023
1971
|
|
|
2024
|
-
|
|
1972
|
+
// This is a real user scroll
|
|
1973
|
+
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
1974
|
+
const distanceFromBottom =
|
|
1975
|
+
scrollHeight - scrollTop - clientHeight;
|
|
1976
|
+
const isAtBottom = distanceFromBottom < 50; // Increased tolerance
|
|
2025
1977
|
|
|
2026
|
-
|
|
1978
|
+
// Stop any auto-scrolling if user scrolls
|
|
2027
1979
|
if (scrollToBottomIntervalRef.current) {
|
|
2028
|
-
console.log("User scrolled - stopping auto-scroll");
|
|
2029
1980
|
clearInterval(scrollToBottomIntervalRef.current);
|
|
2030
1981
|
scrollToBottomIntervalRef.current = null;
|
|
2031
1982
|
}
|
|
2032
1983
|
|
|
2033
|
-
|
|
2034
|
-
const isAtBottom =
|
|
2035
|
-
scrollHeight - scrollTop - clientHeight < 10;
|
|
2036
|
-
|
|
2037
|
-
// Update whether we should stick to bottom
|
|
1984
|
+
// Only update this for real user scrolls
|
|
2038
1985
|
shouldStickToBottomRef.current = isAtBottom;
|
|
2039
|
-
console.log("User scroll - at bottom:", isAtBottom);
|
|
2040
|
-
|
|
2041
|
-
// Mark as user scrolling
|
|
2042
|
-
clearTimeout(scrollTimeout);
|
|
2043
|
-
isUserScrollingRef.current = true;
|
|
2044
|
-
scrollTimeout = setTimeout(() => {
|
|
2045
|
-
isUserScrollingRef.current = false;
|
|
2046
|
-
console.log("User stopped scrolling");
|
|
2047
|
-
}, 150);
|
|
2048
1986
|
|
|
2049
1987
|
// Update visible range
|
|
2050
1988
|
let startIndex = 0;
|
|
@@ -2064,49 +2002,49 @@ function createProxyHandler<T>(
|
|
|
2064
2002
|
endIndex = i;
|
|
2065
2003
|
}
|
|
2066
2004
|
|
|
2067
|
-
|
|
2005
|
+
setRange({
|
|
2068
2006
|
startIndex: Math.max(0, startIndex),
|
|
2069
2007
|
endIndex: Math.min(totalCount, endIndex + 1 + overscan),
|
|
2070
|
-
};
|
|
2071
|
-
|
|
2072
|
-
console.log("Updating visible range:", newRange);
|
|
2073
|
-
setRange(newRange);
|
|
2008
|
+
});
|
|
2074
2009
|
};
|
|
2075
2010
|
|
|
2076
2011
|
container.addEventListener("scroll", handleScroll, {
|
|
2077
2012
|
passive: true,
|
|
2078
2013
|
});
|
|
2079
|
-
console.log("Initial scroll calculation");
|
|
2080
2014
|
handleScroll(); // Initial calculation
|
|
2081
2015
|
|
|
2082
2016
|
return () => {
|
|
2083
|
-
console.log("Removing scroll handler");
|
|
2084
2017
|
container.removeEventListener("scroll", handleScroll);
|
|
2085
|
-
clearTimeout(scrollTimeout);
|
|
2086
2018
|
};
|
|
2087
2019
|
}, [positions, totalCount, itemHeight, overscan]);
|
|
2088
2020
|
|
|
2089
2021
|
const scrollToBottom = useCallback(
|
|
2090
2022
|
(behavior: ScrollBehavior = "auto") => {
|
|
2091
|
-
console.log("Manual scrollToBottom called");
|
|
2092
2023
|
shouldStickToBottomRef.current = true;
|
|
2024
|
+
isProgrammaticScrollRef.current = true;
|
|
2093
2025
|
if (containerRef.current) {
|
|
2094
2026
|
containerRef.current.scrollTop =
|
|
2095
2027
|
containerRef.current.scrollHeight;
|
|
2096
2028
|
}
|
|
2029
|
+
setTimeout(() => {
|
|
2030
|
+
isProgrammaticScrollRef.current = false;
|
|
2031
|
+
}, 100);
|
|
2097
2032
|
},
|
|
2098
2033
|
[]
|
|
2099
2034
|
);
|
|
2100
2035
|
|
|
2101
2036
|
const scrollToIndex = useCallback(
|
|
2102
2037
|
(index: number, behavior: ScrollBehavior = "smooth") => {
|
|
2103
|
-
|
|
2038
|
+
isProgrammaticScrollRef.current = true;
|
|
2104
2039
|
if (containerRef.current && positions[index] !== undefined) {
|
|
2105
2040
|
containerRef.current.scrollTo({
|
|
2106
2041
|
top: positions[index],
|
|
2107
2042
|
behavior,
|
|
2108
2043
|
});
|
|
2109
2044
|
}
|
|
2045
|
+
setTimeout(() => {
|
|
2046
|
+
isProgrammaticScrollRef.current = false;
|
|
2047
|
+
}, 100);
|
|
2110
2048
|
},
|
|
2111
2049
|
[positions]
|
|
2112
2050
|
);
|
|
@@ -2129,12 +2067,6 @@ function createProxyHandler<T>(
|
|
|
2129
2067
|
},
|
|
2130
2068
|
};
|
|
2131
2069
|
|
|
2132
|
-
console.log("Returning virtualizer with props:", {
|
|
2133
|
-
range,
|
|
2134
|
-
totalHeight,
|
|
2135
|
-
startPosition: positions[range.startIndex] || 0,
|
|
2136
|
-
});
|
|
2137
|
-
|
|
2138
2070
|
return {
|
|
2139
2071
|
virtualState,
|
|
2140
2072
|
virtualizerProps,
|