virtua 0.50.2 → 0.50.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.
Files changed (40) hide show
  1. package/lib/angular/VList.d.ts +7 -7
  2. package/lib/angular/Virtualizer.d.ts +11 -11
  3. package/lib/angular/WindowVirtualizer.d.ts +13 -9
  4. package/lib/angular/index.js +440 -434
  5. package/lib/angular/index.js.map +1 -1
  6. package/lib/core/index.cjs +342 -335
  7. package/lib/core/index.cjs.map +1 -1
  8. package/lib/core/index.d.ts +5 -2
  9. package/lib/core/index.js +326 -318
  10. package/lib/core/index.js.map +1 -1
  11. package/lib/core/layouts/types.d.ts +1 -0
  12. package/lib/core/observer.d.ts +1 -0
  13. package/lib/core/scroll-to.d.ts +1 -0
  14. package/lib/core/types.d.ts +1 -5
  15. package/lib/index.cjs +534 -532
  16. package/lib/index.cjs.map +1 -1
  17. package/lib/index.js +496 -494
  18. package/lib/index.js.map +1 -1
  19. package/lib/solid/VList.d.ts +1 -1
  20. package/lib/solid/Virtualizer.d.ts +4 -0
  21. package/lib/solid/WindowVirtualizer.d.ts +4 -0
  22. package/lib/solid/index.cjs +366 -378
  23. package/lib/solid/index.cjs.map +1 -1
  24. package/lib/solid/index.js +373 -386
  25. package/lib/solid/index.js.map +1 -1
  26. package/lib/solid/index.jsx +383 -368
  27. package/lib/solid/index.jsx.map +1 -1
  28. package/lib/svelte/ListItem.svelte +2 -2
  29. package/lib/svelte/Virtualizer.svelte +22 -32
  30. package/lib/svelte/WindowVirtualizer.svelte +22 -21
  31. package/lib/svelte/WindowVirtualizer.type.d.ts +4 -0
  32. package/lib/svelte/utils.js.map +1 -1
  33. package/lib/vue/WindowVirtualizer.d.ts +4 -0
  34. package/lib/vue/index.cjs +366 -385
  35. package/lib/vue/index.cjs.map +1 -1
  36. package/lib/vue/index.js +342 -361
  37. package/lib/vue/index.js.map +1 -1
  38. package/package.json +30 -29
  39. /package/lib/core/{resizer.d.ts → driver.d.ts} +0 -0
  40. /package/lib/core/{scroller.d.ts → layouts/list.d.ts} +0 -0
@@ -8,6 +8,7 @@ var clamp = (value, minValue, maxValue) => min(maxValue, max(minValue, value));
8
8
  var sort = (arr) => {
9
9
  return [...arr].sort((a, b) => a - b);
10
10
  };
11
+ var timeout = setTimeout;
11
12
  var microtask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
12
13
  Promise.resolve().then(fn);
13
14
  };
@@ -29,112 +30,6 @@ var once = (fn) => {
29
30
  };
30
31
  };
31
32
 
32
- //#endregion
33
- //#region src/core/cache.ts
34
- var UNCACHED = -1;
35
- var fill = (array, length, prepend) => {
36
- const key = prepend ? "unshift" : "push";
37
- for (let i = 0; i < length; i++) {
38
- array[key](-1);
39
- }
40
- return array;
41
- };
42
- var getItemSize = (cache, index) => {
43
- const size = cache._sizes[index];
44
- return size === -1 ? cache._defaultItemSize : size;
45
- };
46
- var setItemSize = (cache, index, size) => {
47
- const isInitialMeasurement = cache._sizes[index] === -1;
48
- cache._sizes[index] = size;
49
- cache._computedOffsetIndex = min(index, cache._computedOffsetIndex);
50
- return isInitialMeasurement;
51
- };
52
- var getItemOffset = (cache, index) => {
53
- if (!cache._length) return 0;
54
- if (cache._computedOffsetIndex >= index) {
55
- return cache._offsets[index];
56
- }
57
- if (cache._computedOffsetIndex < 0) {
58
- cache._offsets[0] = 0;
59
- cache._computedOffsetIndex = 0;
60
- }
61
- let i = cache._computedOffsetIndex;
62
- let top = cache._offsets[i];
63
- while (i < index) {
64
- top += getItemSize(cache, i);
65
- cache._offsets[++i] = top;
66
- }
67
- cache._computedOffsetIndex = index;
68
- return top;
69
- };
70
- var findIndex = (cache, offset, low = 0, high = cache._length - 1) => {
71
- let found = low;
72
- while (low <= high) {
73
- const mid = floor((low + high) / 2);
74
- if (getItemOffset(cache, mid) <= offset) {
75
- found = mid;
76
- low = mid + 1;
77
- } else {
78
- high = mid - 1;
79
- }
80
- }
81
- return clamp(found, 0, cache._length - 1);
82
- };
83
- var computeRange = (cache, startOffset, endOffset, prevStartIndex) => {
84
- prevStartIndex = min(prevStartIndex, cache._length - 1);
85
- if (getItemOffset(cache, prevStartIndex) <= startOffset) {
86
- const end = findIndex(cache, endOffset, prevStartIndex);
87
- return [findIndex(cache, startOffset, prevStartIndex, end), end];
88
- } else {
89
- const start = findIndex(cache, startOffset, undefined, prevStartIndex);
90
- return [start, findIndex(cache, endOffset, start)];
91
- }
92
- };
93
- var estimateDefaultItemSize = (cache, startIndex) => {
94
- let measuredCountBeforeStart = 0;
95
- const measuredSizes = [];
96
- cache._sizes.forEach((s, i) => {
97
- if (s !== -1) {
98
- measuredSizes.push(s);
99
- if (i < startIndex) {
100
- measuredCountBeforeStart++;
101
- }
102
- }
103
- });
104
- cache._computedOffsetIndex = -1;
105
- const sorted = sort(measuredSizes);
106
- const len = sorted.length;
107
- const mid = len / 2 | 0;
108
- const median = len % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
109
- const prevDefaultItemSize = cache._defaultItemSize;
110
- return ((cache._defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
111
- };
112
- var initCache = (length, itemSize, sizes) => {
113
- return {
114
- _defaultItemSize: itemSize,
115
- _sizes: sizes ? fill(sizes.slice(0, min(length, sizes.length)), max(0, length - sizes.length)) : fill([], length),
116
- _length: length,
117
- _computedOffsetIndex: -1,
118
- _offsets: fill([], length + 1)
119
- };
120
- };
121
- var takeCacheSnapshot = (cache) => {
122
- return [cache._sizes.slice(), cache._defaultItemSize];
123
- };
124
- var updateCacheLength = (cache, length, isShift) => {
125
- const diff = length - cache._length;
126
- cache._computedOffsetIndex = isShift ? -1 : min(length - 1, cache._computedOffsetIndex);
127
- cache._length = length;
128
- if (diff > 0) {
129
- fill(cache._offsets, diff);
130
- fill(cache._sizes, diff, isShift);
131
- return cache._defaultItemSize * diff;
132
- } else {
133
- cache._offsets.splice(diff);
134
- return (isShift ? cache._sizes.splice(0, -diff) : cache._sizes.splice(diff)).reduce((acc, removed) => acc - (removed === -1 ? cache._defaultItemSize : removed), 0);
135
- }
136
- };
137
-
138
33
  //#endregion
139
34
  //#region src/core/environment.ts
140
35
  var isBrowser = typeof window !== "undefined";
@@ -175,7 +70,8 @@ var UPDATE_SCROLL_END_EVENT = 8;
175
70
  var getScrollSize = (store) => {
176
71
  return max(store.$getTotalSize(), store.$getViewportSize());
177
72
  };
178
- var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnapshot, shouldAutoEstimateItemSize = false) => {
73
+ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItemOffset: getOffset, $getItemSize: getItemSize, $setItemSize: setItemSize, $isSizeEqual: isSizeEqual, $getTotalSize: getTotalSize, $getLength: getLength, $setLength: setLength, $estimateDefaultSize: estimateDefaultSize }, ssrCount = 0) => {
74
+ let shouldAutoEstimateItemSize = !!estimateDefaultSize;
179
75
  let isSSR = !!ssrCount;
180
76
  let stateVersion = 1;
181
77
  let viewportSize = 0;
@@ -190,27 +86,16 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
190
86
  let _prevRange = [0, isSSR ? max(ssrCount - 1, 0) : -1];
191
87
  let _totalMeasuredSize = 0;
192
88
  let _isViewportMeasured = false;
193
- const cache = initCache(elementsCount, cacheSnapshot ? cacheSnapshot[1] : itemSize, cacheSnapshot && cacheSnapshot[0]);
194
89
  const subscribers = new Set();
195
90
  const getRelativeScrollOffset = () => scrollOffset - startSpacerSize;
196
91
  const getVisibleOffset = () => getRelativeScrollOffset() + pendingJump + jump;
197
- const getRange = (startOffset, endOffset) => {
198
- return computeRange(cache, startOffset, endOffset, _prevRange[0]);
199
- };
200
- const getTotalSize = () => getItemOffset(cache, cache._length);
201
- const getItemOffset$1 = (index, fromEnd) => {
202
- const offset = getItemOffset(cache, index) - pendingJump;
92
+ const getItemOffset = (index, fromEnd) => {
93
+ const offset = getOffset(index) - pendingJump;
203
94
  if (fromEnd) {
204
- return getTotalSize() - offset - getItemSize$1(index);
95
+ return getTotalSize() - offset - getItemSize(index);
205
96
  }
206
97
  return offset;
207
98
  };
208
- const getItemSize$1 = (index) => {
209
- return getItemSize(cache, index);
210
- };
211
- const isSizeEqual = (index, value = -1) => {
212
- return cache._sizes[index] === value;
213
- };
214
99
  const applyJump = (j) => {
215
100
  if (j) {
216
101
  if (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE || _frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
@@ -225,9 +110,6 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
225
110
  subscribers.clear();
226
111
  },
227
112
  $getStateVersion: () => stateVersion,
228
- $getCacheSnapshot: () => {
229
- return takeCacheSnapshot(cache);
230
- },
231
113
  $getRange: (bufferSize = 200) => {
232
114
  if (!_isViewportMeasured || isSSR) {
233
115
  return _prevRange;
@@ -254,13 +136,13 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
254
136
  endIndex = max(endIndex, _frozenRange[1]);
255
137
  }
256
138
  }
257
- return [max(startIndex, 0), min(endIndex, cache._length - 1)];
139
+ return [max(startIndex, 0), min(endIndex, getLength() - 1)];
258
140
  },
259
- $findItemIndex: (offset) => findIndex(cache, offset - startSpacerSize),
141
+ $findItemIndex: (offset) => findIndex(offset - startSpacerSize),
260
142
  $isUnmeasuredItem: isSizeEqual,
261
- $getItemOffset: getItemOffset$1,
262
- $getItemSize: getItemSize$1,
263
- $getItemsLength: () => cache._length,
143
+ $getItemOffset: getItemOffset,
144
+ $getItemSize: getItemSize,
145
+ $getItemsLength: getLength,
264
146
  $getScrollOffset: () => scrollOffset,
265
147
  $isScrolling: () => _scrollDirection !== SCROLL_IDLE,
266
148
  $getViewportSize: () => viewportSize,
@@ -331,24 +213,24 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
331
213
  shouldKeep = index < _frozenRange[0];
332
214
  } else {
333
215
  const start = getRelativeScrollOffset();
334
- const itemOffset = getItemOffset$1(index);
335
- const itemSize = getItemSize$1(index);
216
+ const itemOffset = getItemOffset(index);
217
+ const itemSize = getItemSize(index);
336
218
  shouldKeep = _scrollDirection !== SCROLL_DOWN && _scrollMode === SCROLL_BY_NATIVE ? itemOffset + itemSize <= start : itemOffset < start && itemOffset + itemSize < start + viewportSize;
337
219
  }
338
220
  if (shouldKeep) {
339
- acc += size - getItemSize$1(index);
221
+ acc += size - getItemSize(index);
340
222
  }
341
223
  return acc;
342
224
  }, 0));
343
225
  for (const [index, size] of updated) {
344
- const prevSize = getItemSize$1(index);
345
- const isInitialMeasurement = setItemSize(cache, index, size);
226
+ const prevSize = getItemSize(index);
227
+ const isInitialMeasurement = setItemSize(index, size);
346
228
  if (shouldAutoEstimateItemSize) {
347
229
  _totalMeasuredSize += isInitialMeasurement ? size : size - prevSize;
348
230
  }
349
231
  }
350
232
  if (shouldAutoEstimateItemSize && viewportSize && _totalMeasuredSize > viewportSize) {
351
- applyJump(estimateDefaultItemSize(cache, findIndex(cache, getVisibleOffset())));
233
+ applyJump(estimateDefaultSize(findIndex(getVisibleOffset())));
352
234
  shouldAutoEstimateItemSize = false;
353
235
  }
354
236
  mutated = 1 + 2;
@@ -367,11 +249,11 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
367
249
  }
368
250
  case 5: {
369
251
  if (payload[1]) {
370
- applyJump(updateCacheLength(cache, payload[0], true));
252
+ applyJump(setLength(payload[0], true));
371
253
  _scrollMode = SCROLL_BY_SHIFT;
372
254
  mutated = 1;
373
255
  } else {
374
- updateCacheLength(cache, payload[0]);
256
+ setLength(payload[0]);
375
257
  mutated = 1;
376
258
  }
377
259
  break;
@@ -408,8 +290,139 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
408
290
  };
409
291
 
410
292
  //#endregion
411
- //#region src/core/scroller.ts
412
- var timeout = setTimeout;
293
+ //#region src/core/cache.ts
294
+ var UNCACHED = -1;
295
+ var findIndex = (getOffset, length, offset, low = 0, high = length - 1) => {
296
+ let found = low;
297
+ while (low <= high) {
298
+ const mid = floor((low + high) / 2);
299
+ if (getOffset(mid) <= offset) {
300
+ found = mid;
301
+ low = mid + 1;
302
+ } else {
303
+ high = mid - 1;
304
+ }
305
+ }
306
+ return clamp(found, 0, length - 1);
307
+ };
308
+
309
+ //#endregion
310
+ //#region src/core/layouts/list.ts
311
+ var fill = (array, length, prepend) => {
312
+ const key = prepend ? "unshift" : "push";
313
+ for (let i = 0; i < length; i++) {
314
+ array[key](-1);
315
+ }
316
+ return array;
317
+ };
318
+ var createListLayout = (length, itemSize, snapshot) => {
319
+ let defaultItemSize = snapshot && snapshot[1] || itemSize || 40;
320
+ let computedOffsetIndex = -1;
321
+ let prevStartIndex = 0;
322
+ const restoredSizes = snapshot && snapshot[0];
323
+ const sizes = restoredSizes ? fill(restoredSizes.slice(0, min(length, restoredSizes.length)), max(0, length - restoredSizes.length)) : fill([], length);
324
+ const offsets = fill([], length + 1);
325
+ const getSize = (index) => {
326
+ const size = sizes[index];
327
+ return size === -1 ? defaultItemSize : size;
328
+ };
329
+ const getOffset = (index) => {
330
+ if (!length) return 0;
331
+ if (computedOffsetIndex >= index) {
332
+ return offsets[index];
333
+ }
334
+ if (computedOffsetIndex < 0) {
335
+ offsets[0] = 0;
336
+ computedOffsetIndex = 0;
337
+ }
338
+ let i = computedOffsetIndex;
339
+ let top = offsets[i];
340
+ while (i < index) {
341
+ top += getSize(i);
342
+ offsets[++i] = top;
343
+ }
344
+ computedOffsetIndex = index;
345
+ return top;
346
+ };
347
+ return {
348
+ $getRange: (startOffset, endOffset) => {
349
+ prevStartIndex = min(prevStartIndex, length - 1);
350
+ let start;
351
+ let end;
352
+ if (getOffset(prevStartIndex) <= startOffset) {
353
+ end = findIndex(getOffset, length, endOffset, prevStartIndex);
354
+ start = findIndex(getOffset, length, startOffset, prevStartIndex, end);
355
+ } else {
356
+ start = findIndex(getOffset, length, startOffset, undefined, prevStartIndex);
357
+ end = findIndex(getOffset, length, endOffset, start);
358
+ }
359
+ prevStartIndex = start;
360
+ return [start, end];
361
+ },
362
+ $findIndex: (offset) => findIndex(getOffset, length, offset),
363
+ $getItemOffset: getOffset,
364
+ $getItemSize: getSize,
365
+ $setItemSize: (index, size) => {
366
+ const isInitialMeasurement = sizes[index] === -1;
367
+ sizes[index] = size;
368
+ computedOffsetIndex = min(index, computedOffsetIndex);
369
+ return isInitialMeasurement;
370
+ },
371
+ $isSizeEqual: (index, size = -1) => sizes[index] === size,
372
+ $getTotalSize: () => getOffset(length),
373
+ $getLength: () => length,
374
+ $setLength: (nextLength, isShift) => {
375
+ const diff = nextLength - length;
376
+ computedOffsetIndex = isShift ? -1 : min(nextLength - 1, computedOffsetIndex);
377
+ length = nextLength;
378
+ if (diff > 0) {
379
+ fill(offsets, diff);
380
+ fill(sizes, diff, isShift);
381
+ return defaultItemSize * diff;
382
+ } else {
383
+ offsets.splice(diff);
384
+ return (isShift ? sizes.splice(0, -diff) : sizes.splice(diff)).reduce((acc, removed) => acc - (removed === -1 ? defaultItemSize : removed), 0);
385
+ }
386
+ },
387
+ $estimateDefaultSize: itemSize ? undefined : (startIndex) => {
388
+ let measuredCountBeforeStart = 0;
389
+ const measuredSizes = [];
390
+ sizes.forEach((s, i) => {
391
+ if (s !== -1) {
392
+ measuredSizes.push(s);
393
+ if (i < startIndex) {
394
+ measuredCountBeforeStart++;
395
+ }
396
+ }
397
+ });
398
+ computedOffsetIndex = -1;
399
+ const sorted = sort(measuredSizes);
400
+ const len = sorted.length;
401
+ const mid = len / 2 | 0;
402
+ const median = len % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
403
+ const prevDefaultItemSize = defaultItemSize;
404
+ return ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
405
+ },
406
+ $snapshot: () => [sizes.slice(), defaultItemSize]
407
+ };
408
+ };
409
+
410
+ //#endregion
411
+ //#region src/core/observer.ts
412
+ var createResizeObserver = (cb) => {
413
+ let ro;
414
+ return {
415
+ _observe(e) {
416
+ (ro || (ro = new (getCurrentWindow(getCurrentDocument(e))).ResizeObserver(cb))).observe(e);
417
+ },
418
+ _unobserve(e) {
419
+ ro.unobserve(e);
420
+ },
421
+ _dispose() {
422
+ ro && ro.disconnect();
423
+ }
424
+ };
425
+ };
413
426
  var debounce = (fn, ms) => {
414
427
  let id;
415
428
  const cancel = () => {
@@ -499,6 +512,9 @@ var createScrollObserver = (store, viewport, isHorizontal, getScrollOffset, upda
499
512
  }
500
513
  };
501
514
  };
515
+
516
+ //#endregion
517
+ //#region src/core/driver.ts
502
518
  var createScrollScheduler = (store, initialized, scroll) => {
503
519
  let cancelScroll;
504
520
  return [async (getTargetOffset, smooth) => {
@@ -564,7 +580,7 @@ var createScrollScheduler = (store, initialized, scroll) => {
564
580
  cancelScroll && cancelScroll();
565
581
  }];
566
582
  };
567
- var createScroller = (store, isHorizontal) => {
583
+ var createContainerDriver = (store, isHorizontal) => {
568
584
  let viewportElement;
569
585
  let scrollObserver;
570
586
  let initialized = createPromise();
@@ -582,9 +598,28 @@ var createScroller = (store, isHorizontal) => {
582
598
  viewportElement[scrollOffsetKey] = offset;
583
599
  }
584
600
  });
601
+ const sizeKey = isHorizontal ? "width" : "height";
602
+ const mountedIndexes = new WeakMap();
603
+ const resizeObserver = createResizeObserver((entries) => {
604
+ const resizes = [];
605
+ for (const { target, contentRect } of entries) {
606
+ if (!target.offsetParent) continue;
607
+ if (target === viewportElement) {
608
+ store.$update(4, contentRect[sizeKey]);
609
+ } else {
610
+ const index = mountedIndexes.get(target);
611
+ if (index != null) {
612
+ resizes.push([index, contentRect[sizeKey]]);
613
+ }
614
+ }
615
+ }
616
+ if (resizes.length) {
617
+ store.$update(3, resizes);
618
+ }
619
+ });
585
620
  return {
586
- $observe(_, viewport) {
587
- viewportElement = viewport;
621
+ $observe(containerElement, viewport = containerElement.parentElement) {
622
+ resizeObserver._observe(viewportElement = viewport);
588
623
  if (isHorizontal) {
589
624
  isNegative = getComputedStyle(viewport).direction === "rtl";
590
625
  }
@@ -605,43 +640,32 @@ var createScroller = (store, isHorizontal) => {
605
640
  initialized[1](true);
606
641
  },
607
642
  $dispose() {
643
+ resizeObserver._dispose();
608
644
  scrollObserver && scrollObserver._dispose();
609
645
  initialized[1](false);
610
646
  initialized = createPromise();
611
647
  },
612
- $isNegative: () => isNegative,
613
- $scrollTo(offset) {
614
- scheduleScroll(() => offset);
615
- },
616
- $scrollBy(offset) {
617
- offset += store.$getScrollOffset();
618
- scheduleScroll(() => offset);
619
- },
620
- $scrollToIndex(index, { align, smooth, offset = 0 } = {}) {
621
- index = clamp(index, 0, store.$getItemsLength() - 1);
622
- if (align === "nearest") {
623
- const itemOffset = store.$getItemOffset(index);
624
- const scrollOffset = store.$getScrollOffset();
625
- if (itemOffset < scrollOffset) {
626
- align = "start";
627
- } else if (itemOffset + store.$getItemSize(index) > scrollOffset + store.$getViewportSize()) {
628
- align = "end";
629
- } else {
630
- return;
631
- }
632
- }
633
- scheduleScroll(() => {
634
- return offset + store.$getStartSpacerSize() + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - store.$getViewportSize() : align === "center" ? (store.$getItemSize(index) - store.$getViewportSize()) / 2 : 0);
635
- }, smooth);
648
+ $observeItem(el, index) {
649
+ mountedIndexes.set(el, index);
650
+ resizeObserver._observe(el);
651
+ return () => {
652
+ mountedIndexes.delete(el);
653
+ resizeObserver._unobserve(el);
654
+ };
636
655
  },
637
- $fixScrollJump: () => {
656
+ $isNegative: () => isNegative,
657
+ $scheduleScroll: scheduleScroll,
658
+ $fixScrollJump() {
638
659
  scrollObserver && scrollObserver._fixScrollJump();
639
- }
660
+ },
661
+ $getBaseOffset: store.$getStartSpacerSize,
662
+ $getScrollbarSize: () => 0
640
663
  };
641
664
  };
642
- var createWindowScroller = (store, isHorizontal) => {
665
+ var createWindowDriver = (store, isHorizontal) => {
643
666
  let containerElement;
644
667
  let scrollObserver;
668
+ let cleanupOnWindowResize;
645
669
  let initialized = createPromise();
646
670
  let isNegative = false;
647
671
  const scrollToKey = isHorizontal ? "left" : "top";
@@ -657,6 +681,21 @@ var createWindowScroller = (store, isHorizontal) => {
657
681
  window.scroll({ [scrollToKey]: offset });
658
682
  }
659
683
  });
684
+ const sizeKey = isHorizontal ? "width" : "height";
685
+ const mountedIndexes = new WeakMap();
686
+ const resizeObserver = createResizeObserver((entries) => {
687
+ const resizes = [];
688
+ for (const { target, contentRect } of entries) {
689
+ if (!target.offsetParent) continue;
690
+ const index = mountedIndexes.get(target);
691
+ if (index != null) {
692
+ resizes.push([index, contentRect[sizeKey]]);
693
+ }
694
+ }
695
+ if (resizes.length) {
696
+ store.$update(3, resizes);
697
+ }
698
+ });
660
699
  const calcOffsetToViewport = (node, viewport, window, isHorizontal, offset = 0) => {
661
700
  const offsetKey = isHorizontal ? "offsetLeft" : "offsetTop";
662
701
  const offsetSum = offset + (isHorizontal && isNegative ? window.innerWidth - node[offsetKey] - node.offsetWidth : node[offsetKey]);
@@ -672,6 +711,14 @@ var createWindowScroller = (store, isHorizontal) => {
672
711
  const scrollOffsetKey = isHorizontal ? "scrollX" : "scrollY";
673
712
  const document = getCurrentDocument(container);
674
713
  const window = getCurrentWindow(document);
714
+ const onWindowResize = () => {
715
+ store.$update(4, window[isHorizontal ? "innerWidth" : "innerHeight"]);
716
+ };
717
+ window.addEventListener("resize", onWindowResize);
718
+ microtask(onWindowResize);
719
+ cleanupOnWindowResize = () => {
720
+ window.removeEventListener("resize", onWindowResize);
721
+ };
675
722
  if (isHorizontal) {
676
723
  isNegative = getComputedStyle(getDocumentElement(document)).direction === "rtl";
677
724
  }
@@ -685,181 +732,56 @@ var createWindowScroller = (store, isHorizontal) => {
685
732
  initialized[1](true);
686
733
  },
687
734
  $dispose() {
735
+ cleanupOnWindowResize && cleanupOnWindowResize();
736
+ resizeObserver._dispose();
688
737
  scrollObserver && scrollObserver._dispose();
689
738
  containerElement = undefined;
690
739
  initialized[1](false);
691
740
  initialized = createPromise();
692
741
  },
742
+ $observeItem(el, index) {
743
+ mountedIndexes.set(el, index);
744
+ resizeObserver._observe(el);
745
+ return () => {
746
+ mountedIndexes.delete(el);
747
+ resizeObserver._unobserve(el);
748
+ };
749
+ },
693
750
  $isNegative: () => isNegative,
694
- $fixScrollJump: () => {
751
+ $scheduleScroll: scheduleScroll,
752
+ $fixScrollJump() {
695
753
  scrollObserver && scrollObserver._fixScrollJump();
696
754
  },
697
- $scrollToIndex(index, { align, smooth, offset = 0 } = {}) {
698
- if (!containerElement) return;
699
- index = clamp(index, 0, store.$getItemsLength() - 1);
700
- if (align === "nearest") {
701
- const itemOffset = store.$getItemOffset(index);
702
- const scrollOffset = store.$getScrollOffset();
703
- if (itemOffset < scrollOffset) {
704
- align = "start";
705
- } else if (itemOffset + store.$getItemSize(index) > scrollOffset + store.$getViewportSize()) {
706
- align = "end";
707
- } else {
708
- return;
709
- }
710
- }
755
+ $getBaseOffset() {
711
756
  const document = getCurrentDocument(containerElement);
712
- const window = getCurrentWindow(document);
713
- const html = getDocumentElement(document);
714
- const getScrollbarSize = () => store.$getViewportSize() - (isHorizontal ? html.clientWidth : html.clientHeight);
715
- scheduleScroll(() => {
716
- return offset + calcOffsetToViewport(containerElement, document.body, window, isHorizontal) + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - (store.$getViewportSize() - getScrollbarSize()) : align === "center" ? (store.$getItemSize(index) - (store.$getViewportSize() - getScrollbarSize())) / 2 : 0);
717
- }, smooth);
718
- }
719
- };
720
- };
721
- var createGridScroller = (rowStore, colStore) => {
722
- const rowScroller = createScroller(rowStore, false);
723
- const colScroller = createScroller(colStore, true);
724
- return {
725
- $observe(container, viewport) {
726
- rowScroller.$observe(container, viewport);
727
- colScroller.$observe(container, viewport);
728
- },
729
- $dispose() {
730
- rowScroller.$dispose();
731
- colScroller.$dispose();
732
- },
733
- $isNegative: colScroller.$isNegative,
734
- $scrollTo(row, col) {
735
- if (row != null) {
736
- rowScroller.$scrollTo(row);
737
- }
738
- if (col != null) {
739
- colScroller.$scrollTo(col);
740
- }
741
- },
742
- $scrollBy(row, col) {
743
- if (row != null) {
744
- rowScroller.$scrollBy(row);
745
- }
746
- if (col != null) {
747
- colScroller.$scrollBy(col);
748
- }
749
- },
750
- $scrollToIndex(row, col) {
751
- if (row != null) {
752
- rowScroller.$scrollToIndex(row);
753
- }
754
- if (col != null) {
755
- colScroller.$scrollToIndex(col);
756
- }
757
- },
758
- $fixScrollJump() {
759
- rowScroller.$fixScrollJump();
760
- colScroller.$fixScrollJump();
761
- }
762
- };
763
- };
764
-
765
- //#endregion
766
- //#region src/core/resizer.ts
767
- var createResizeObserver = (cb) => {
768
- let ro;
769
- return {
770
- _observe(e) {
771
- (ro || (ro = new (getCurrentWindow(getCurrentDocument(e))).ResizeObserver(cb))).observe(e);
757
+ return calcOffsetToViewport(containerElement, document.body, getCurrentWindow(document), isHorizontal);
772
758
  },
773
- _unobserve(e) {
774
- ro.unobserve(e);
775
- },
776
- _dispose() {
777
- ro && ro.disconnect();
759
+ $getScrollbarSize() {
760
+ const html = getDocumentElement(getCurrentDocument(containerElement));
761
+ return store.$getViewportSize() - (isHorizontal ? html.clientWidth : html.clientHeight);
778
762
  }
779
763
  };
780
764
  };
781
- var createResizer = (store, isHorizontal) => {
765
+ var createContainerGridDriver = (rowStore, colStore) => {
782
766
  let viewportElement;
783
- const sizeKey = isHorizontal ? "width" : "height";
784
- const mountedIndexes = new WeakMap();
785
- const resizeObserver = createResizeObserver((entries) => {
786
- const resizes = [];
787
- for (const { target, contentRect } of entries) {
788
- if (!target.offsetParent) continue;
789
- if (target === viewportElement) {
790
- store.$update(4, contentRect[sizeKey]);
791
- } else {
792
- const index = mountedIndexes.get(target);
793
- if (index != null) {
794
- resizes.push([index, contentRect[sizeKey]]);
795
- }
796
- }
797
- }
798
- if (resizes.length) {
799
- store.$update(3, resizes);
767
+ let rowScrollObserver;
768
+ let colScrollObserver;
769
+ let initialized = createPromise();
770
+ let isNegative = false;
771
+ const [scheduleScrollX, cancelScrollX] = createScrollScheduler(colStore, () => initialized[0], (offset, smooth) => {
772
+ const opts = { left: normalizeScrollOffset(offset, isNegative) };
773
+ if (smooth) {
774
+ opts.behavior = "smooth";
800
775
  }
776
+ viewportElement.scrollTo(opts);
801
777
  });
802
- return {
803
- $observeRoot(viewport) {
804
- resizeObserver._observe(viewportElement = viewport);
805
- },
806
- $observeItem: (el, i) => {
807
- mountedIndexes.set(el, i);
808
- resizeObserver._observe(el);
809
- return () => {
810
- mountedIndexes.delete(el);
811
- resizeObserver._unobserve(el);
812
- };
813
- },
814
- $dispose: resizeObserver._dispose
815
- };
816
- };
817
- var createWindowResizer = (store, isHorizontal) => {
818
- const sizeKey = isHorizontal ? "width" : "height";
819
- const windowSizeKey = isHorizontal ? "innerWidth" : "innerHeight";
820
- const mountedIndexes = new WeakMap();
821
- const resizeObserver = createResizeObserver((entries) => {
822
- const resizes = [];
823
- for (const { target, contentRect } of entries) {
824
- if (!target.offsetParent) continue;
825
- const index = mountedIndexes.get(target);
826
- if (index != null) {
827
- resizes.push([index, contentRect[sizeKey]]);
828
- }
829
- }
830
- if (resizes.length) {
831
- store.$update(3, resizes);
778
+ const [scheduleScrollY, cancelScrollY] = createScrollScheduler(rowStore, () => initialized[0], (offset, smooth) => {
779
+ const opts = { top: offset };
780
+ if (smooth) {
781
+ opts.behavior = "smooth";
832
782
  }
783
+ viewportElement.scrollTo(opts);
833
784
  });
834
- let cleanupOnWindowResize;
835
- return {
836
- $observeRoot(container) {
837
- const window = getCurrentWindow(getCurrentDocument(container));
838
- const onWindowResize = () => {
839
- store.$update(4, window[windowSizeKey]);
840
- };
841
- window.addEventListener("resize", onWindowResize);
842
- microtask(onWindowResize);
843
- cleanupOnWindowResize = () => {
844
- window.removeEventListener("resize", onWindowResize);
845
- };
846
- },
847
- $observeItem: (el, i) => {
848
- mountedIndexes.set(el, i);
849
- resizeObserver._observe(el);
850
- return () => {
851
- mountedIndexes.delete(el);
852
- resizeObserver._unobserve(el);
853
- };
854
- },
855
- $dispose() {
856
- cleanupOnWindowResize && cleanupOnWindowResize();
857
- resizeObserver._dispose();
858
- }
859
- };
860
- };
861
- var createGridResizer = (rowStore, colStore) => {
862
- let viewportElement;
863
785
  const mountedIndexes = new WeakMap();
864
786
  const maybeCachedRowIndexes = new Set();
865
787
  const maybeCachedColIndexes = new Set();
@@ -936,9 +858,40 @@ var createGridResizer = (rowStore, colStore) => {
936
858
  colStore.$update(3, widthResizes);
937
859
  }
938
860
  });
861
+ const observeAxisScroll = (store, isHorizontal, cancelScroll) => {
862
+ const viewport = viewportElement;
863
+ const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
864
+ const overflowKey = isHorizontal ? "overflowX" : "overflowY";
865
+ const negative = isHorizontal && isNegative;
866
+ return createScrollObserver(store, viewport, isHorizontal, () => normalizeScrollOffset(viewport[scrollOffsetKey], negative), (jump, shift, isMomentumScrolling) => {
867
+ if (isMomentumScrolling) {
868
+ const style = viewport.style;
869
+ const prev = style[overflowKey];
870
+ style[overflowKey] = "hidden";
871
+ timeout(() => {
872
+ style[overflowKey] = prev;
873
+ });
874
+ }
875
+ viewport[scrollOffsetKey] = normalizeScrollOffset(store.$getScrollOffset() + jump, negative);
876
+ if (shift) {
877
+ cancelScroll();
878
+ }
879
+ });
880
+ };
939
881
  return {
940
- $observeRoot(viewport) {
882
+ $observe(containerElement, viewport = containerElement.parentElement) {
941
883
  resizeObserver._observe(viewportElement = viewport);
884
+ isNegative = getComputedStyle(viewport).direction === "rtl";
885
+ rowScrollObserver = observeAxisScroll(rowStore, false, cancelScrollY);
886
+ colScrollObserver = observeAxisScroll(colStore, true, cancelScrollX);
887
+ initialized[1](true);
888
+ },
889
+ $dispose() {
890
+ resizeObserver._dispose();
891
+ rowScrollObserver && rowScrollObserver._dispose();
892
+ colScrollObserver && colScrollObserver._dispose();
893
+ initialized[1](false);
894
+ initialized = createPromise();
942
895
  },
943
896
  $observeItem(el, rowIndex, colIndex) {
944
897
  mountedIndexes.set(el, [rowIndex, colIndex]);
@@ -950,6 +903,14 @@ var createGridResizer = (rowStore, colStore) => {
950
903
  resizeObserver._unobserve(el);
951
904
  };
952
905
  },
906
+ $resizeRows(rows) {
907
+ for (const [r] of rows) {
908
+ for (let c = 0; c < colStore.$getItemsLength(); c++) {
909
+ sizeCache.delete(getKey(r, c));
910
+ }
911
+ }
912
+ rowStore.$update(3, rows);
913
+ },
953
914
  $resizeCols(cols) {
954
915
  for (const [c] of cols) {
955
916
  for (let r = 0; r < rowStore.$getItemsLength(); r++) {
@@ -958,18 +919,71 @@ var createGridResizer = (rowStore, colStore) => {
958
919
  }
959
920
  colStore.$update(3, cols);
960
921
  },
961
- $resizeRows(rows) {
962
- for (const [r] of rows) {
963
- for (let c = 0; c < colStore.$getItemsLength(); c++) {
964
- sizeCache.delete(getKey(r, c));
965
- }
966
- }
967
- rowStore.$update(3, rows);
922
+ $isNegative: () => isNegative,
923
+ $scheduleScrollX: scheduleScrollX,
924
+ $scheduleScrollY: scheduleScrollY,
925
+ $fixScrollJump() {
926
+ rowScrollObserver && rowScrollObserver._fixScrollJump();
927
+ colScrollObserver && colScrollObserver._fixScrollJump();
968
928
  },
969
- $dispose: resizeObserver._dispose
929
+ $getBaseOffset: (isHorizontal) => (isHorizontal ? colStore : rowStore).$getStartSpacerSize()
970
930
  };
971
931
  };
972
932
 
933
+ //#endregion
934
+ //#region src/core/scroll-to.ts
935
+ var scrollTo = (driver, offset) => {
936
+ driver.$scheduleScroll(() => offset);
937
+ };
938
+ var scrollBy = (driver, store, offset) => {
939
+ scrollTo(driver, offset + store.$getScrollOffset());
940
+ };
941
+ var scrollToIndex = (driver, store, index, { align, smooth, offset = 0 } = {}) => {
942
+ index = clamp(index, 0, store.$getItemsLength() - 1);
943
+ if (align === "nearest") {
944
+ const itemOffset = store.$getItemOffset(index);
945
+ const scrollOffset = store.$getScrollOffset();
946
+ if (itemOffset < scrollOffset) {
947
+ align = "start";
948
+ } else if (itemOffset + store.$getItemSize(index) > scrollOffset + store.$getViewportSize()) {
949
+ align = "end";
950
+ } else {
951
+ return;
952
+ }
953
+ }
954
+ driver.$scheduleScroll(() => {
955
+ return offset + driver.$getBaseOffset() + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - (store.$getViewportSize() - driver.$getScrollbarSize()) : align === "center" ? (store.$getItemSize(index) - (store.$getViewportSize() - driver.$getScrollbarSize())) / 2 : 0);
956
+ }, smooth);
957
+ };
958
+ var gridScrollTo = (driver, row, col) => {
959
+ if (row != null) {
960
+ driver.$scheduleScrollY(() => row);
961
+ }
962
+ if (col != null) {
963
+ driver.$scheduleScrollX(() => col);
964
+ }
965
+ };
966
+ var gridScrollBy = (driver, rowStore, colStore, row, col) => {
967
+ if (row != null) {
968
+ const target = row + rowStore.$getScrollOffset();
969
+ driver.$scheduleScrollY(() => target);
970
+ }
971
+ if (col != null) {
972
+ const target = col + colStore.$getScrollOffset();
973
+ driver.$scheduleScrollX(() => target);
974
+ }
975
+ };
976
+ var gridScrollToIndex = (driver, rowStore, colStore, row, col) => {
977
+ if (row != null) {
978
+ const index = clamp(row, 0, rowStore.$getItemsLength() - 1);
979
+ driver.$scheduleScrollY(() => driver.$getBaseOffset(false) + rowStore.$getItemOffset(index));
980
+ }
981
+ if (col != null) {
982
+ const index = clamp(col, 0, colStore.$getItemsLength() - 1);
983
+ driver.$scheduleScrollX(() => driver.$getBaseOffset(true) + colStore.$getItemOffset(index));
984
+ }
985
+ };
986
+
973
987
  //#endregion
974
988
  //#region src/solid/ListItem.tsx
975
989
  var ListItem = (props) => {
@@ -981,13 +995,15 @@ var ListItem = (props) => {
981
995
  });
982
996
  const style = createMemo(() => {
983
997
  const isHorizontal = props._isHorizontal;
998
+ const hide = props._hide;
999
+ const isSSR = props._isSSR;
984
1000
  const style = {
985
1001
  contain: "layout style",
986
- position: "absolute",
1002
+ position: hide && isSSR ? undefined : "absolute",
987
1003
  [isHorizontal ? "height" : "width"]: "100%",
988
1004
  [isHorizontal ? "top" : "left"]: "0px",
989
1005
  [isHorizontal ? "left" : "top"]: props._offset + "px",
990
- visibility: props._hide ? "hidden" : undefined
1006
+ visibility: !hide || isSSR ? undefined : "hidden"
991
1007
  };
992
1008
  if (isHorizontal) {
993
1009
  style.display = "inline-flex";
@@ -1009,11 +1025,12 @@ var isSameRange = (prev, next) => {
1009
1025
  //#region src/solid/Virtualizer.tsx
1010
1026
  var Virtualizer = (props) => {
1011
1027
  let containerRef;
1012
- const { itemSize, horizontal = false, cache } = props;
1028
+ const { itemSize, horizontal = false, cache, ssrCount } = props;
1013
1029
  props = mergeProps({ as: "div" }, props);
1014
- const store = createVirtualStore(props.data.length, itemSize, undefined, cache, !itemSize);
1015
- const resizer = createResizer(store, horizontal);
1016
- const scroller = createScroller(store, horizontal);
1030
+ const [isSSR, setIsSSR] = createSignal(!!ssrCount);
1031
+ const layout = createListLayout(props.data.length, itemSize, cache);
1032
+ const store = createVirtualStore(layout, ssrCount);
1033
+ const driver = createContainerDriver(store, horizontal);
1017
1034
  const [stateVersion, setRerender] = createSignal(store.$getStateVersion());
1018
1035
  store.$subscribe(1, () => {
1019
1036
  setRerender(store.$getStateVersion());
@@ -1034,12 +1051,13 @@ var Virtualizer = (props) => {
1034
1051
  });
1035
1052
  const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
1036
1053
  const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
1037
- const isNegative = createMemo(() => stateVersion() && scroller.$isNegative());
1054
+ const isNegative = createMemo(() => stateVersion() && driver.$isNegative());
1038
1055
  onMount(() => {
1056
+ setIsSSR(false);
1039
1057
  if (props.ref) {
1040
1058
  props.ref({
1041
1059
  get cache() {
1042
- return store.$getCacheSnapshot();
1060
+ return layout.$snapshot();
1043
1061
  },
1044
1062
  get scrollOffset() {
1045
1063
  return store.$getScrollOffset();
@@ -1053,22 +1071,18 @@ var Virtualizer = (props) => {
1053
1071
  findItemIndex: store.$findItemIndex,
1054
1072
  getItemOffset: store.$getItemOffset,
1055
1073
  getItemSize: store.$getItemSize,
1056
- scrollToIndex: scroller.$scrollToIndex,
1057
- scrollTo: scroller.$scrollTo,
1058
- scrollBy: scroller.$scrollBy
1074
+ scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts),
1075
+ scrollTo: (offset) => scrollTo(driver, offset),
1076
+ scrollBy: (offset) => scrollBy(driver, store, offset)
1059
1077
  });
1060
1078
  }
1061
- const container = containerRef;
1062
- const scrollable = props.scrollRef || container.parentElement;
1063
- resizer.$observeRoot(scrollable);
1064
- scroller.$observe(container, scrollable);
1079
+ driver.$observe(containerRef, props.scrollRef);
1065
1080
  onCleanup(() => {
1066
1081
  if (props.ref) {
1067
1082
  props.ref();
1068
1083
  }
1069
1084
  store.$dispose();
1070
- resizer.$dispose();
1071
- scroller.$dispose();
1085
+ driver.$dispose();
1072
1086
  });
1073
1087
  });
1074
1088
  createComputed(on(() => props.startMargin || 0, (value) => {
@@ -1077,7 +1091,7 @@ var Virtualizer = (props) => {
1077
1091
  }
1078
1092
  }));
1079
1093
  createEffect(on(stateVersion, () => {
1080
- scroller.$fixScrollJump();
1094
+ driver.$fixScrollJump();
1081
1095
  }));
1082
1096
  const dataSlice = createMemo(() => {
1083
1097
  const count = props.data.length;
@@ -1120,7 +1134,7 @@ var Virtualizer = (props) => {
1120
1134
  const children = createMemo(() => {
1121
1135
  return untrack(() => props.children(data, index));
1122
1136
  });
1123
- return <ListItem _as={props.item} _index={index()} _resizer={resizer.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} />;
1137
+ return <ListItem _as={props.item} _index={index()} _resizer={driver.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} _isSSR={isSSR()} />;
1124
1138
  };
1125
1139
  return <Dynamic component={props.as} ref={containerRef} style={{
1126
1140
  contain: "size style",
@@ -1149,6 +1163,7 @@ var VList = (props) => {
1149
1163
  "children",
1150
1164
  "bufferSize",
1151
1165
  "itemSize",
1166
+ "ssrCount",
1152
1167
  "shift",
1153
1168
  "horizontal",
1154
1169
  "keepMounted",
@@ -1166,7 +1181,7 @@ var VList = (props) => {
1166
1181
  height: "100%",
1167
1182
  ...local.style
1168
1183
  }}>
1169
- <Virtualizer ref={local.ref} data={local.data} bufferSize={local.bufferSize} itemSize={local.itemSize} shift={local.shift} horizontal={local.horizontal} keepMounted={local.keepMounted} cache={local.cache} item={local.item} onScroll={local.onScroll} onScrollEnd={local.onScrollEnd}>
1184
+ <Virtualizer ref={local.ref} data={local.data} bufferSize={local.bufferSize} itemSize={local.itemSize} ssrCount={local.ssrCount} shift={local.shift} horizontal={local.horizontal} keepMounted={local.keepMounted} cache={local.cache} item={local.item} onScroll={local.onScroll} onScrollEnd={local.onScrollEnd}>
1170
1185
  {local.children}
1171
1186
  </Virtualizer>
1172
1187
  </div>;
@@ -1176,10 +1191,11 @@ var VList = (props) => {
1176
1191
  //#region src/solid/WindowVirtualizer.tsx
1177
1192
  var WindowVirtualizer = (props) => {
1178
1193
  let containerRef;
1179
- const { ref: _ref, data: _data, children: _children, itemSize, shift: _shift, horizontal = false, cache, onScrollEnd: _onScrollEnd } = props;
1180
- const store = createVirtualStore(props.data.length, itemSize, undefined, cache, !itemSize);
1181
- const resizer = createWindowResizer(store, horizontal);
1182
- const scroller = createWindowScroller(store, horizontal);
1194
+ const { ref: _ref, data: _data, children: _children, itemSize, ssrCount, shift: _shift, horizontal = false, cache, onScrollEnd: _onScrollEnd } = props;
1195
+ const [isSSR, setIsSSR] = createSignal(!!ssrCount);
1196
+ const layout = createListLayout(props.data.length, itemSize, cache);
1197
+ const store = createVirtualStore(layout, ssrCount);
1198
+ const driver = createWindowDriver(store, horizontal);
1183
1199
  const [stateVersion, setRerender] = createSignal(store.$getStateVersion());
1184
1200
  store.$subscribe(1, () => {
1185
1201
  setRerender(store.$getStateVersion());
@@ -1200,12 +1216,13 @@ var WindowVirtualizer = (props) => {
1200
1216
  });
1201
1217
  const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
1202
1218
  const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
1203
- const isNegative = createMemo(() => stateVersion() && scroller.$isNegative());
1219
+ const isNegative = createMemo(() => stateVersion() && driver.$isNegative());
1204
1220
  onMount(() => {
1221
+ setIsSSR(false);
1205
1222
  if (props.ref) {
1206
1223
  props.ref({
1207
1224
  get cache() {
1208
- return store.$getCacheSnapshot();
1225
+ return layout.$snapshot();
1209
1226
  },
1210
1227
  get scrollOffset() {
1211
1228
  return store.$getScrollOffset();
@@ -1216,22 +1233,20 @@ var WindowVirtualizer = (props) => {
1216
1233
  findItemIndex: store.$findItemIndex,
1217
1234
  getItemOffset: store.$getItemOffset,
1218
1235
  getItemSize: store.$getItemSize,
1219
- scrollToIndex: scroller.$scrollToIndex
1236
+ scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts)
1220
1237
  });
1221
1238
  }
1222
- resizer.$observeRoot(containerRef);
1223
- scroller.$observe(containerRef);
1239
+ driver.$observe(containerRef);
1224
1240
  onCleanup(() => {
1225
1241
  if (props.ref) {
1226
1242
  props.ref();
1227
1243
  }
1228
1244
  store.$dispose();
1229
- resizer.$dispose();
1230
- scroller.$dispose();
1245
+ driver.$dispose();
1231
1246
  });
1232
1247
  });
1233
1248
  createEffect(on(stateVersion, () => {
1234
- scroller.$fixScrollJump();
1249
+ driver.$fixScrollJump();
1235
1250
  }));
1236
1251
  const dataSlice = createMemo(() => {
1237
1252
  const count = props.data.length;
@@ -1269,7 +1284,7 @@ var WindowVirtualizer = (props) => {
1269
1284
  const children = createMemo(() => {
1270
1285
  return untrack(() => props.children(data, itemIndex));
1271
1286
  });
1272
- return <ListItem _index={itemIndex()} _resizer={resizer.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} />;
1287
+ return <ListItem _index={itemIndex()} _resizer={driver.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} _isSSR={isSSR()} />;
1273
1288
  }}
1274
1289
  </For>
1275
1290
  </div>;