@humanspeak/svelte-virtual-list 0.2.6-beta.3 → 0.2.6-beta.4

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.
@@ -253,12 +253,9 @@
253
253
  lastMeasuredIndex = result.newLastMeasuredIndex
254
254
  heightCache = result.updatedHeightCache
255
255
 
256
- // Update running totals for precise height calculation (only when significant changes)
257
- if (result.clearedDirtyItems.size > 10) {
258
- const heights = Object.values(heightCache)
259
- totalMeasuredHeight = heights.reduce((sum, h) => sum + h, 0)
260
- measuredCount = heights.length
261
- }
256
+ // Update running totals efficiently (O(1) instead of O(n)!)
257
+ totalMeasuredHeight = result.newTotalHeight
258
+ measuredCount = result.newValidCount
262
259
 
263
260
  // Clear processed dirty items
264
261
  result.clearedDirtyItems.forEach((index) => {
@@ -273,7 +270,9 @@
273
270
  }
274
271
  },
275
272
  100, // debounceTime
276
- dirtyItems // Pass dirty items for processing
273
+ dirtyItems, // Pass dirty items for processing
274
+ totalMeasuredHeight, // Current running total height
275
+ measuredCount // Current running total count
277
276
  )
278
277
  }
279
278
 
@@ -75,4 +75,6 @@ export declare const calculateAverageHeightDebounced: (isCalculatingHeight: bool
75
75
  newLastMeasuredIndex: number;
76
76
  updatedHeightCache: Record<number, number>;
77
77
  clearedDirtyItems: Set<number>;
78
- }) => void, debounceTime: number, dirtyItems: Set<number>) => NodeJS.Timeout | null;
78
+ newTotalHeight: number;
79
+ newValidCount: number;
80
+ }) => void, debounceTime: number, dirtyItems: Set<number>, currentTotalHeight?: number, currentValidCount?: number) => NodeJS.Timeout | null;
@@ -71,7 +71,7 @@ import { BROWSER } from 'esm-env';
71
71
  */
72
72
  export const calculateAverageHeightDebounced = (isCalculatingHeight, heightUpdateTimeout, visibleItemsGetter, itemElements, heightCache, lastMeasuredIndex, calculatedItemHeight,
73
73
  /* trunk-ignore(eslint/no-unused-vars) */
74
- onUpdate, debounceTime, dirtyItems) => {
74
+ onUpdate, debounceTime, dirtyItems, currentTotalHeight = 0, currentValidCount = 0) => {
75
75
  if (!BROWSER || isCalculatingHeight)
76
76
  return null;
77
77
  const visibleRange = visibleItemsGetter();
@@ -81,13 +81,15 @@ onUpdate, debounceTime, dirtyItems) => {
81
81
  if (heightUpdateTimeout)
82
82
  clearTimeout(heightUpdateTimeout);
83
83
  return setTimeout(() => {
84
- const { newHeight, newLastMeasuredIndex, updatedHeightCache, clearedDirtyItems } = calculateAverageHeight(itemElements, visibleRange, heightCache, calculatedItemHeight, dirtyItems);
84
+ const { newHeight, newLastMeasuredIndex, updatedHeightCache, clearedDirtyItems, newTotalHeight, newValidCount } = calculateAverageHeight(itemElements, visibleRange, heightCache, calculatedItemHeight, dirtyItems, currentTotalHeight, currentValidCount);
85
85
  if (Math.abs(newHeight - calculatedItemHeight) > 1 || dirtyItems.size > 0) {
86
86
  onUpdate({
87
87
  newHeight,
88
88
  newLastMeasuredIndex,
89
89
  updatedHeightCache,
90
- clearedDirtyItems
90
+ clearedDirtyItems,
91
+ newTotalHeight,
92
+ newValidCount
91
93
  });
92
94
  }
93
95
  }, debounceTime);
@@ -86,11 +86,13 @@ export declare const updateHeightAndScroll: (state: VirtualListState, setters: V
86
86
  */
87
87
  export declare const calculateAverageHeight: (itemElements: HTMLElement[], visibleRange: {
88
88
  start: number;
89
- }, heightCache: Record<number, number>, currentItemHeight: number, dirtyItems: Set<number>) => {
89
+ }, heightCache: Record<number, number>, currentItemHeight: number, dirtyItems: Set<number>, currentTotalHeight?: number, currentValidCount?: number) => {
90
90
  newHeight: number;
91
91
  newLastMeasuredIndex: number;
92
92
  updatedHeightCache: Record<number, number>;
93
93
  clearedDirtyItems: Set<number>;
94
+ newTotalHeight: number;
95
+ newValidCount: number;
94
96
  };
95
97
  /**
96
98
  * Processes large arrays in chunks to prevent UI blocking.
@@ -158,28 +158,23 @@ export const updateHeightAndScroll = (state, setters, immediate = false) => {
158
158
  * 40
159
159
  * )
160
160
  */
161
- export const calculateAverageHeight = (itemElements, visibleRange, heightCache, currentItemHeight, dirtyItems) => {
161
+ export const calculateAverageHeight = (itemElements, visibleRange, heightCache, currentItemHeight, dirtyItems, currentTotalHeight = 0, currentValidCount = 0) => {
162
162
  const validElements = itemElements.filter((el) => el);
163
163
  if (validElements.length === 0) {
164
164
  return {
165
165
  newHeight: currentItemHeight,
166
166
  newLastMeasuredIndex: visibleRange.start,
167
167
  updatedHeightCache: heightCache,
168
- clearedDirtyItems: new Set()
168
+ clearedDirtyItems: new Set(),
169
+ newTotalHeight: currentTotalHeight,
170
+ newValidCount: currentValidCount
169
171
  };
170
172
  }
171
173
  const newHeightCache = { ...heightCache };
172
174
  const clearedDirtyItems = new Set();
173
- // Initialize running totals for O(1) average calculation
174
- let totalValidHeight = 0;
175
- let validHeightCount = 0;
176
- // Calculate initial totals from existing cache
177
- for (const height of Object.values(heightCache)) {
178
- if (Number.isFinite(height) && height > 0) {
179
- totalValidHeight += height;
180
- validHeightCount++;
181
- }
182
- }
175
+ // Start with current running totals (O(1) instead of O(n))
176
+ let totalValidHeight = currentTotalHeight;
177
+ let validHeightCount = currentValidCount;
183
178
  // Process only dirty items if they exist, otherwise process all visible items
184
179
  if (dirtyItems.size > 0) {
185
180
  // Process only dirty items
@@ -240,7 +235,9 @@ export const calculateAverageHeight = (itemElements, visibleRange, heightCache,
240
235
  newHeight: validHeightCount > 0 ? totalValidHeight / validHeightCount : currentItemHeight,
241
236
  newLastMeasuredIndex: visibleRange.start,
242
237
  updatedHeightCache: newHeightCache,
243
- clearedDirtyItems
238
+ clearedDirtyItems,
239
+ newTotalHeight: totalValidHeight,
240
+ newValidCount: validHeightCount
244
241
  };
245
242
  };
246
243
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanspeak/svelte-virtual-list",
3
- "version": "0.2.6-beta.3",
3
+ "version": "0.2.6-beta.4",
4
4
  "description": "A lightweight, high-performance virtual list component for Svelte 5 that renders large datasets with minimal memory usage. Features include dynamic height support, smooth scrolling, TypeScript support, and efficient DOM recycling. Ideal for infinite scrolling lists, data tables, chat interfaces, and any application requiring the rendering of thousands of items without compromising performance. Zero dependencies and fully customizable.",
5
5
  "keywords": [
6
6
  "svelte",