cogsbox-state 0.5.349 → 0.5.350

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-state",
3
- "version": "0.5.349",
3
+ "version": "0.5.350",
4
4
  "description": "React state management library with form controls and server sync",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/CogsState.tsx CHANGED
@@ -1813,12 +1813,8 @@ function createProxyHandler<T>(
1813
1813
  startIndex: 0,
1814
1814
  endIndex: 10,
1815
1815
  });
1816
- const sourceArray = getGlobalStore().getNestedState(
1817
- stateKey,
1818
- path
1819
- ) as any[];
1820
1816
  const isLockedToBottomRef = useRef(stickToBottom);
1821
- const prevTotalCountRef = useRef(sourceArray.length);
1817
+ const prevTotalCountRef = useRef(0);
1822
1818
 
1823
1819
  const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
1824
1820
 
@@ -1831,6 +1827,10 @@ function createProxyHandler<T>(
1831
1827
  return unsubscribe;
1832
1828
  }, [stateKey]);
1833
1829
 
1830
+ const sourceArray = getGlobalStore().getNestedState(
1831
+ stateKey,
1832
+ path
1833
+ ) as any[];
1834
1834
  const totalCount = sourceArray.length;
1835
1835
 
1836
1836
  const { totalHeight, positions } = useMemo(() => {
@@ -1868,14 +1868,55 @@ function createProxyHandler<T>(
1868
1868
  });
1869
1869
  }, [range.startIndex, range.endIndex, sourceArray, totalCount]);
1870
1870
 
1871
- // The one and only layout effect.
1871
+ // --- YOUR WORKING SCROLL ALGORITHM - UNTOUCHED ---
1872
1872
  useLayoutEffect(() => {
1873
1873
  const container = containerRef.current;
1874
- if (!container) return;
1875
-
1876
1874
  const hasNewItems = totalCount > prevTotalCountRef.current;
1877
1875
 
1878
- // This function is now ALWAYS fresh.
1876
+ if (
1877
+ !container ||
1878
+ !stickToBottom ||
1879
+ !isLockedToBottomRef.current ||
1880
+ !hasNewItems
1881
+ ) {
1882
+ return;
1883
+ }
1884
+
1885
+ // STEP 1: Set range to the end to render the items we need to measure.
1886
+ setRange({
1887
+ startIndex: Math.max(0, totalCount - 10 - overscan),
1888
+ endIndex: totalCount,
1889
+ });
1890
+
1891
+ // STEP 2: The LOOP.
1892
+ const intervalId = setInterval(() => {
1893
+ const lastItemIndex = totalCount - 1;
1894
+ const shadowArray =
1895
+ getGlobalStore
1896
+ .getState()
1897
+ .getShadowMetadata(stateKey, path) || [];
1898
+ const lastItemHeight =
1899
+ shadowArray[lastItemIndex]?.virtualizer?.itemHeight || 0;
1900
+
1901
+ if (lastItemHeight > 0) {
1902
+ clearInterval(intervalId);
1903
+ // STEP 3: Scroll.
1904
+ container.scrollTo({
1905
+ top: container.scrollHeight,
1906
+ behavior: "smooth",
1907
+ });
1908
+ }
1909
+ }, 100);
1910
+
1911
+ return () => clearInterval(intervalId);
1912
+ }, [totalCount]);
1913
+
1914
+ // --- THE FIX IS HERE ---
1915
+ // This effect now correctly updates when data changes.
1916
+ useEffect(() => {
1917
+ const container = containerRef.current;
1918
+ if (!container) return;
1919
+
1879
1920
  const updateVirtualRange = () => {
1880
1921
  const { scrollTop, clientHeight } = container;
1881
1922
  let low = 0,
@@ -1900,39 +1941,6 @@ function createProxyHandler<T>(
1900
1941
  });
1901
1942
  };
1902
1943
 
1903
- // --- YOUR SCROLLING LOGIC ---
1904
- // It only runs if we have new items and are locked to the bottom.
1905
- if (hasNewItems && isLockedToBottomRef.current) {
1906
- // STEP 1: Set range to the end to start measuring.
1907
- setRange({
1908
- startIndex: Math.max(0, totalCount - 10 - overscan),
1909
- endIndex: totalCount,
1910
- });
1911
-
1912
- // STEP 2: Start the LOOP.
1913
- const intervalId = setInterval(() => {
1914
- const lastItemIndex = totalCount - 1;
1915
- const shadowArray =
1916
- getGlobalStore
1917
- .getState()
1918
- .getShadowMetadata(stateKey, path) || [];
1919
- const lastItemHeight =
1920
- shadowArray[lastItemIndex]?.virtualizer?.itemHeight || 0;
1921
-
1922
- if (lastItemHeight > 0) {
1923
- clearInterval(intervalId);
1924
- container.scrollTo({
1925
- top: container.scrollHeight,
1926
- behavior: "smooth",
1927
- });
1928
- }
1929
- }, 100);
1930
-
1931
- // This return is the cleanup for the if-block.
1932
- return () => clearInterval(intervalId);
1933
- }
1934
-
1935
- // --- USER SCROLL HANDLING ---
1936
1944
  const handleUserScroll = () => {
1937
1945
  const isAtBottom =
1938
1946
  container.scrollHeight -
@@ -1948,14 +1956,13 @@ function createProxyHandler<T>(
1948
1956
  container.addEventListener("scroll", handleUserScroll, {
1949
1957
  passive: true,
1950
1958
  });
1951
- updateVirtualRange(); // Always update range for current view.
1959
+ updateVirtualRange(); // Always update range on render.
1952
1960
 
1953
- // This return is the cleanup for the whole effect.
1954
1961
  return () =>
1955
1962
  container.removeEventListener("scroll", handleUserScroll);
1956
- }, [totalCount, positions]); // Re-run when layout-related data changes.
1963
+ }, [totalCount, positions]); // FIX: This now has dependencies.
1957
1964
 
1958
- // This simple effect tracks the item count for the next render.
1965
+ // Simple effect to track previous item count for the scroll algorithm.
1959
1966
  useEffect(() => {
1960
1967
  prevTotalCountRef.current = totalCount;
1961
1968
  });
@@ -1963,6 +1970,8 @@ function createProxyHandler<T>(
1963
1970
  (behavior: ScrollBehavior = "smooth") => {
1964
1971
  if (containerRef.current) {
1965
1972
  isLockedToBottomRef.current = true;
1973
+ console.log("USER ACTION: Scroll lock ENABLED.");
1974
+ // This is a manual trigger, so we don't need the loop. Just scroll.
1966
1975
  containerRef.current.scrollTo({
1967
1976
  top: containerRef.current.scrollHeight,
1968
1977
  behavior,
@@ -1976,6 +1985,7 @@ function createProxyHandler<T>(
1976
1985
  (index: number, behavior: ScrollBehavior = "smooth") => {
1977
1986
  if (containerRef.current && positions[index] !== undefined) {
1978
1987
  isLockedToBottomRef.current = false;
1988
+ console.log("USER ACTION: Scroll lock DISABLED.");
1979
1989
  containerRef.current.scrollTo({
1980
1990
  top: positions[index],
1981
1991
  behavior,
@@ -2002,6 +2012,7 @@ function createProxyHandler<T>(
2002
2012
  },
2003
2013
  },
2004
2014
  };
2015
+
2005
2016
  return {
2006
2017
  virtualState,
2007
2018
  virtualizerProps,