From 720d6fc32fd0c3f42085914ac1b00ebbac03c948 Mon Sep 17 00:00:00 2001 From: Julien Saguet <49377434+jsaguet@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:52:45 +0200 Subject: [PATCH 01/10] fix(angular-virtual): capture _didMount cleanup to remove scroll/resize listeners on destroy (#1159) --- .changeset/fix-angular-virtual-cleanup.md | 5 +++++ packages/angular-virtual/src/index.ts | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .changeset/fix-angular-virtual-cleanup.md diff --git a/.changeset/fix-angular-virtual-cleanup.md b/.changeset/fix-angular-virtual-cleanup.md new file mode 100644 index 000000000..c60d757ed --- /dev/null +++ b/.changeset/fix-angular-virtual-cleanup.md @@ -0,0 +1,5 @@ +--- +'@tanstack/angular-virtual': patch +--- + +fix: capture \_didMount cleanup to remove scroll/resize listeners on destroy diff --git a/packages/angular-virtual/src/index.ts b/packages/angular-virtual/src/index.ts index 55532654a..79aa266b2 100644 --- a/packages/angular-virtual/src/index.ts +++ b/packages/angular-virtual/src/index.ts @@ -70,8 +70,12 @@ function createVirtualizerBase< { allowSignalWrites: true }, ) - let cleanup: () => void | undefined - afterNextRender({ read: () => (virtualizer ?? lazyInit())._didMount() }) + let cleanup: (() => void) | undefined + afterNextRender({ + read: () => { + cleanup = (virtualizer ?? lazyInit())._didMount() + }, + }) inject(DestroyRef).onDestroy(() => cleanup?.()) From 3113d3d988cd16f3a78d66c50209b85180fa69ea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:03:09 +0200 Subject: [PATCH 02/10] ci: Version Packages (#1161) --- .changeset/fix-angular-virtual-cleanup.md | 5 ----- examples/angular/dynamic/package.json | 2 +- examples/angular/fixed/package.json | 2 +- examples/angular/infinite-scroll/package.json | 2 +- examples/angular/padding/package.json | 2 +- examples/angular/smooth-scroll/package.json | 2 +- examples/angular/sticky/package.json | 2 +- examples/angular/table/package.json | 2 +- examples/angular/variable/package.json | 2 +- examples/angular/window/package.json | 2 +- packages/angular-virtual/CHANGELOG.md | 6 ++++++ packages/angular-virtual/package.json | 2 +- pnpm-lock.yaml | 18 +++++++++--------- 13 files changed, 25 insertions(+), 24 deletions(-) delete mode 100644 .changeset/fix-angular-virtual-cleanup.md diff --git a/.changeset/fix-angular-virtual-cleanup.md b/.changeset/fix-angular-virtual-cleanup.md deleted file mode 100644 index c60d757ed..000000000 --- a/.changeset/fix-angular-virtual-cleanup.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/angular-virtual': patch ---- - -fix: capture \_didMount cleanup to remove scroll/resize listeners on destroy diff --git a/examples/angular/dynamic/package.json b/examples/angular/dynamic/package.json index 668010cad..5392f148b 100644 --- a/examples/angular/dynamic/package.json +++ b/examples/angular/dynamic/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/fixed/package.json b/examples/angular/fixed/package.json index ea3f21414..f21e3ccb3 100644 --- a/examples/angular/fixed/package.json +++ b/examples/angular/fixed/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/infinite-scroll/package.json b/examples/angular/infinite-scroll/package.json index e815aba52..55c6aed80 100644 --- a/examples/angular/infinite-scroll/package.json +++ b/examples/angular/infinite-scroll/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", "@tanstack/angular-query-experimental": "5.80.7", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/padding/package.json b/examples/angular/padding/package.json index 130bc01de..e05c1ec26 100644 --- a/examples/angular/padding/package.json +++ b/examples/angular/padding/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/smooth-scroll/package.json b/examples/angular/smooth-scroll/package.json index 67abe9ea3..596066cd3 100644 --- a/examples/angular/smooth-scroll/package.json +++ b/examples/angular/smooth-scroll/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/sticky/package.json b/examples/angular/sticky/package.json index d3b40e868..e1cc96980 100644 --- a/examples/angular/sticky/package.json +++ b/examples/angular/sticky/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/table/package.json b/examples/angular/table/package.json index 7116cfb67..42f7673eb 100644 --- a/examples/angular/table/package.json +++ b/examples/angular/table/package.json @@ -19,7 +19,7 @@ "@angular/router": "^18.1.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-table": "8.21.3", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/variable/package.json b/examples/angular/variable/package.json index b0f8d6ca6..daf4f9719 100644 --- a/examples/angular/variable/package.json +++ b/examples/angular/variable/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/window/package.json b/examples/angular/window/package.json index ad0a41c3e..b25108301 100644 --- a/examples/angular/window/package.json +++ b/examples/angular/window/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.12", + "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/packages/angular-virtual/CHANGELOG.md b/packages/angular-virtual/CHANGELOG.md index a7e0fef09..83ec12e89 100644 --- a/packages/angular-virtual/CHANGELOG.md +++ b/packages/angular-virtual/CHANGELOG.md @@ -1,5 +1,11 @@ # @tanstack/angular-virtual +## 4.0.13 + +### Patch Changes + +- fix: capture \_didMount cleanup to remove scroll/resize listeners on destroy ([#1159](https://github.com/TanStack/virtual/pull/1159)) + ## 4.0.12 ### Patch Changes diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index c3ce97a9a..91a9c6980 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/angular-virtual", - "version": "4.0.12", + "version": "4.0.13", "description": "Headless UI for virtualizing scrollable elements in Angular", "author": "Garrett Darnell", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ccc5c50a6..2400fdc7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,7 +102,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -154,7 +154,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -209,7 +209,7 @@ importers: specifier: 5.80.7 version: 5.80.7(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -261,7 +261,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -313,7 +313,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -368,7 +368,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -426,7 +426,7 @@ importers: specifier: 8.21.3 version: 8.21.3(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -478,7 +478,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -530,7 +530,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.12 + specifier: ^4.0.13 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 From 3374977c623cd95eb4cdb44ad44eb94677d65c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjam=C3=ADn=20Vicente?= <62021328+benjavicente@users.noreply.github.com> Date: Sun, 26 Apr 2026 07:00:50 -0400 Subject: [PATCH 03/10] chore(angular-virtual)!: upgrade Angular to v19 (#1158) --- .changeset/gold-days-greet.md | 5 + docs/framework/angular/angular-virtual.md | 14 + examples/angular/dynamic/package.json | 24 +- examples/angular/fixed/package.json | 24 +- examples/angular/infinite-scroll/package.json | 24 +- examples/angular/padding/package.json | 24 +- examples/angular/smooth-scroll/package.json | 24 +- examples/angular/sticky/package.json | 24 +- examples/angular/table/package.json | 24 +- examples/angular/variable/package.json | 24 +- examples/angular/window/package.json | 24 +- examples/lit/dynamic/package.json | 4 +- examples/lit/fixed/package.json | 4 +- examples/react/dynamic/package.json | 4 +- examples/react/fixed/package.json | 4 +- examples/react/infinite-scroll/package.json | 2 +- examples/react/padding/package.json | 2 +- examples/react/scroll-padding/package.json | 2 +- examples/react/smooth-scroll/package.json | 2 +- examples/react/sticky/package.json | 2 +- examples/react/table/package.json | 2 +- examples/react/variable/package.json | 2 +- examples/react/window/package.json | 4 +- examples/svelte/dynamic/package.json | 4 +- examples/svelte/fixed/package.json | 4 +- examples/svelte/infinite-scroll/package.json | 4 +- examples/svelte/smooth-scroll/package.json | 4 +- examples/svelte/sticky/package.json | 4 +- examples/svelte/table/package.json | 4 +- examples/vue/dynamic/package.json | 4 +- examples/vue/fixed/package.json | 4 +- examples/vue/infinite-scroll/package.json | 4 +- examples/vue/padding/package.json | 4 +- examples/vue/scroll-padding/package.json | 4 +- examples/vue/smooth-scroll/package.json | 4 +- examples/vue/sticky/package.json | 4 +- examples/vue/table/package.json | 4 +- examples/vue/variable/package.json | 4 +- knip.json | 4 +- package.json | 8 +- packages/angular-virtual/README.md | 2 +- packages/angular-virtual/angular.json | 56 + packages/angular-virtual/e2e/app/angular.json | 56 + .../e2e/app/src/app/app.component.ts | 25 + .../e2e/app/src/app/app.config.ts | 7 + .../e2e/app/src/app/app.routes.ts | 29 + .../app/src/app/measure-element.component.ts | 115 + .../e2e/app/src/app/scroll.component.ts | 113 + .../app/src/app/smooth-scroll.component.ts | 119 + .../e2e/app/src/app/stale-index.component.ts | 102 + .../angular-virtual/e2e/app/src/index.html | 12 + packages/angular-virtual/e2e/app/src/main.ts | 5 + .../angular-virtual/e2e/app/src/styles.css | 14 + .../e2e/app/test/measure-element.spec.ts | 42 + .../e2e/app/test/scroll.spec.ts | 133 + .../e2e/app/test/smooth-scroll.spec.ts | 143 + .../e2e/app/test/stale-index.spec.ts | 38 + .../angular-virtual/e2e/app/tsconfig.app.json | 9 + .../angular-virtual/e2e/app/tsconfig.json | 33 + packages/angular-virtual/ng-package.json | 9 - packages/angular-virtual/package.json | 53 +- packages/angular-virtual/playwright.config.ts | 17 + packages/angular-virtual/src/index.ts | 216 +- packages/angular-virtual/src/proxy.ts | 173 +- packages/angular-virtual/src/types.ts | 5 + packages/angular-virtual/tsconfig.build.json | 15 - packages/angular-virtual/tsconfig.json | 8 +- packages/angular-virtual/vite.config.ts | 20 + .../react-virtual/e2e/app/test/scroll.spec.ts | 4 +- packages/virtual-core/tests/index.test.ts | 28 +- pnpm-lock.yaml | 4527 ++++++++--------- 71 files changed, 3731 insertions(+), 2738 deletions(-) create mode 100644 .changeset/gold-days-greet.md create mode 100644 packages/angular-virtual/angular.json create mode 100644 packages/angular-virtual/e2e/app/angular.json create mode 100644 packages/angular-virtual/e2e/app/src/app/app.component.ts create mode 100644 packages/angular-virtual/e2e/app/src/app/app.config.ts create mode 100644 packages/angular-virtual/e2e/app/src/app/app.routes.ts create mode 100644 packages/angular-virtual/e2e/app/src/app/measure-element.component.ts create mode 100644 packages/angular-virtual/e2e/app/src/app/scroll.component.ts create mode 100644 packages/angular-virtual/e2e/app/src/app/smooth-scroll.component.ts create mode 100644 packages/angular-virtual/e2e/app/src/app/stale-index.component.ts create mode 100644 packages/angular-virtual/e2e/app/src/index.html create mode 100644 packages/angular-virtual/e2e/app/src/main.ts create mode 100644 packages/angular-virtual/e2e/app/src/styles.css create mode 100644 packages/angular-virtual/e2e/app/test/measure-element.spec.ts create mode 100644 packages/angular-virtual/e2e/app/test/scroll.spec.ts create mode 100644 packages/angular-virtual/e2e/app/test/smooth-scroll.spec.ts create mode 100644 packages/angular-virtual/e2e/app/test/stale-index.spec.ts create mode 100644 packages/angular-virtual/e2e/app/tsconfig.app.json create mode 100644 packages/angular-virtual/e2e/app/tsconfig.json delete mode 100644 packages/angular-virtual/ng-package.json create mode 100644 packages/angular-virtual/playwright.config.ts delete mode 100644 packages/angular-virtual/tsconfig.build.json create mode 100644 packages/angular-virtual/vite.config.ts diff --git a/.changeset/gold-days-greet.md b/.changeset/gold-days-greet.md new file mode 100644 index 000000000..e606fd23f --- /dev/null +++ b/.changeset/gold-days-greet.md @@ -0,0 +1,5 @@ +--- +'@tanstack/angular-virtual': major +--- + +Angular +19 with proper lazy init diff --git a/docs/framework/angular/angular-virtual.md b/docs/framework/angular/angular-virtual.md index f02fdda95..5ed696a34 100644 --- a/docs/framework/angular/angular-virtual.md +++ b/docs/framework/angular/angular-virtual.md @@ -4,6 +4,8 @@ title: Angular Virtual The `@tanstack/angular-virtual` adapter is a wrapper around the core virtual logic. +Angular Virtual supports Angular 19 and newer. In practice, the adapter is intended to support Angular LTS releases and newer. + ## `injectVirtualizer` ```ts @@ -16,6 +18,18 @@ function injectVirtualizer( ``` This function returns an `AngularVirtualizer` instance configured to work with an HTML element as the scrollElement. +The returned `AngularVirtualizer` mirrors the core `Virtualizer`, but adapter-managed state is exposed through Angular signals. This includes: + +- `getTotalSize` +- `getVirtualItems` +- `isScrolling` +- `options` +- `range` +- `scrollDirection` +- `scrollElement` +- `scrollOffset` +- `scrollRect` +- `measurementsCache` ## `injectWindowVirtualizer` diff --git a/examples/angular/dynamic/package.json b/examples/angular/dynamic/package.json index 5392f148b..a863663aa 100644 --- a/examples/angular/dynamic/package.json +++ b/examples/angular/dynamic/package.json @@ -9,14 +9,14 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", @@ -24,9 +24,9 @@ "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/fixed/package.json b/examples/angular/fixed/package.json index f21e3ccb3..ebc8abedd 100644 --- a/examples/angular/fixed/package.json +++ b/examples/angular/fixed/package.json @@ -9,23 +9,23 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/infinite-scroll/package.json b/examples/angular/infinite-scroll/package.json index 55c6aed80..a55857eff 100644 --- a/examples/angular/infinite-scroll/package.json +++ b/examples/angular/infinite-scroll/package.json @@ -9,14 +9,14 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@tanstack/angular-query-experimental": "5.80.7", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", @@ -24,9 +24,9 @@ "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/padding/package.json b/examples/angular/padding/package.json index e05c1ec26..981673126 100644 --- a/examples/angular/padding/package.json +++ b/examples/angular/padding/package.json @@ -9,23 +9,23 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/smooth-scroll/package.json b/examples/angular/smooth-scroll/package.json index 596066cd3..eefc31796 100644 --- a/examples/angular/smooth-scroll/package.json +++ b/examples/angular/smooth-scroll/package.json @@ -9,23 +9,23 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/sticky/package.json b/examples/angular/sticky/package.json index e1cc96980..1d5213bb1 100644 --- a/examples/angular/sticky/package.json +++ b/examples/angular/sticky/package.json @@ -9,14 +9,14 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", @@ -24,9 +24,9 @@ "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/table/package.json b/examples/angular/table/package.json index 42f7673eb..b0a19837c 100644 --- a/examples/angular/table/package.json +++ b/examples/angular/table/package.json @@ -9,14 +9,14 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-table": "8.21.3", "@tanstack/angular-virtual": "^4.0.13", @@ -25,9 +25,9 @@ "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/variable/package.json b/examples/angular/variable/package.json index daf4f9719..fed28f9d2 100644 --- a/examples/angular/variable/package.json +++ b/examples/angular/variable/package.json @@ -9,23 +9,23 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/angular/window/package.json b/examples/angular/window/package.json index b25108301..b8be6a829 100644 --- a/examples/angular/window/package.json +++ b/examples/angular/window/package.json @@ -9,23 +9,23 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "^18.1.0", - "@angular/common": "^18.1.0", - "@angular/compiler": "^18.1.0", - "@angular/core": "^18.1.0", - "@angular/forms": "^18.1.0", - "@angular/platform-browser": "^18.1.0", - "@angular/platform-browser-dynamic": "^18.1.0", - "@angular/router": "^18.1.0", + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", "@tanstack/angular-virtual": "^4.0.13", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.1.0", - "@angular/cli": "^18.1.0", - "@angular/compiler-cli": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "typescript": "5.6.3" } } diff --git a/examples/lit/dynamic/package.json b/examples/lit/dynamic/package.json index 6dd9f9bd7..26e226a79 100644 --- a/examples/lit/dynamic/package.json +++ b/examples/lit/dynamic/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "@types/node": "^24.5.2", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/lit/fixed/package.json b/examples/lit/fixed/package.json index 1547fae2f..3dea50249 100644 --- a/examples/lit/fixed/package.json +++ b/examples/lit/fixed/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "@types/node": "^24.5.2", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/react/dynamic/package.json b/examples/react/dynamic/package.json index a409cc002..c2f8ab1bc 100644 --- a/examples/react/dynamic/package.json +++ b/examples/react/dynamic/package.json @@ -18,7 +18,7 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/react/fixed/package.json b/examples/react/fixed/package.json index 1f1932b0b..652871821 100644 --- a/examples/react/fixed/package.json +++ b/examples/react/fixed/package.json @@ -17,7 +17,7 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/react/infinite-scroll/package.json b/examples/react/infinite-scroll/package.json index 0b89b8b6a..2f541b45e 100644 --- a/examples/react/infinite-scroll/package.json +++ b/examples/react/infinite-scroll/package.json @@ -18,6 +18,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/padding/package.json b/examples/react/padding/package.json index b4fdb8b84..a9e4b904e 100644 --- a/examples/react/padding/package.json +++ b/examples/react/padding/package.json @@ -17,6 +17,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/scroll-padding/package.json b/examples/react/scroll-padding/package.json index 48201c79c..cfa93d193 100644 --- a/examples/react/scroll-padding/package.json +++ b/examples/react/scroll-padding/package.json @@ -18,6 +18,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/smooth-scroll/package.json b/examples/react/smooth-scroll/package.json index c9aac6b59..eb9ca3218 100644 --- a/examples/react/smooth-scroll/package.json +++ b/examples/react/smooth-scroll/package.json @@ -17,6 +17,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/sticky/package.json b/examples/react/sticky/package.json index c1e7a1517..b8c14583e 100644 --- a/examples/react/sticky/package.json +++ b/examples/react/sticky/package.json @@ -20,6 +20,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/table/package.json b/examples/react/table/package.json index c39fdc372..7a451f38c 100644 --- a/examples/react/table/package.json +++ b/examples/react/table/package.json @@ -19,6 +19,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/variable/package.json b/examples/react/variable/package.json index 27f8cea64..78feb0406 100644 --- a/examples/react/variable/package.json +++ b/examples/react/variable/package.json @@ -17,6 +17,6 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "vite": "^5.4.19" + "vite": "^6.4.2" } } diff --git a/examples/react/window/package.json b/examples/react/window/package.json index d4958456a..e74ee5187 100644 --- a/examples/react/window/package.json +++ b/examples/react/window/package.json @@ -17,7 +17,7 @@ "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", "@vitejs/plugin-react": "^4.5.2", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/svelte/dynamic/package.json b/examples/svelte/dynamic/package.json index cf2a4ad46..9e2c27e78 100644 --- a/examples/svelte/dynamic/package.json +++ b/examples/svelte/dynamic/package.json @@ -18,7 +18,7 @@ "svelte": "^4.2.20", "svelte-check": "^4.2.1", "tslib": "^2.8.1", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/svelte/fixed/package.json b/examples/svelte/fixed/package.json index 7841f9940..59fe40d8c 100644 --- a/examples/svelte/fixed/package.json +++ b/examples/svelte/fixed/package.json @@ -17,7 +17,7 @@ "svelte": "^4.2.20", "svelte-check": "^4.2.1", "tslib": "^2.8.1", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/svelte/infinite-scroll/package.json b/examples/svelte/infinite-scroll/package.json index 612b5c986..8970550f8 100644 --- a/examples/svelte/infinite-scroll/package.json +++ b/examples/svelte/infinite-scroll/package.json @@ -18,7 +18,7 @@ "svelte": "^4.2.20", "svelte-check": "^4.2.1", "tslib": "^2.8.1", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/svelte/smooth-scroll/package.json b/examples/svelte/smooth-scroll/package.json index c3c82c566..2b4689b3e 100644 --- a/examples/svelte/smooth-scroll/package.json +++ b/examples/svelte/smooth-scroll/package.json @@ -18,7 +18,7 @@ "svelte": "^4.2.20", "svelte-check": "^4.2.1", "tslib": "^2.8.1", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/svelte/sticky/package.json b/examples/svelte/sticky/package.json index 488913754..742c8c9e9 100644 --- a/examples/svelte/sticky/package.json +++ b/examples/svelte/sticky/package.json @@ -19,7 +19,7 @@ "svelte": "^4.2.20", "svelte-check": "^4.2.1", "tslib": "^2.8.1", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/svelte/table/package.json b/examples/svelte/table/package.json index f23c3b325..ce43eb5e1 100644 --- a/examples/svelte/table/package.json +++ b/examples/svelte/table/package.json @@ -19,7 +19,7 @@ "svelte": "^4.2.20", "svelte-check": "^4.2.1", "tslib": "^2.8.1", - "typescript": "5.4.5", - "vite": "^5.4.19" + "typescript": "5.6.3", + "vite": "^6.4.2" } } diff --git a/examples/vue/dynamic/package.json b/examples/vue/dynamic/package.json index 192ef6859..b208d1fd1 100644 --- a/examples/vue/dynamic/package.json +++ b/examples/vue/dynamic/package.json @@ -15,8 +15,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/fixed/package.json b/examples/vue/fixed/package.json index 18a1c4c00..98116db25 100644 --- a/examples/vue/fixed/package.json +++ b/examples/vue/fixed/package.json @@ -14,8 +14,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/infinite-scroll/package.json b/examples/vue/infinite-scroll/package.json index 331389714..1c799f0bd 100644 --- a/examples/vue/infinite-scroll/package.json +++ b/examples/vue/infinite-scroll/package.json @@ -15,8 +15,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/padding/package.json b/examples/vue/padding/package.json index 194a00ac6..44c968273 100644 --- a/examples/vue/padding/package.json +++ b/examples/vue/padding/package.json @@ -14,8 +14,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/scroll-padding/package.json b/examples/vue/scroll-padding/package.json index f2977210e..828113304 100644 --- a/examples/vue/scroll-padding/package.json +++ b/examples/vue/scroll-padding/package.json @@ -15,8 +15,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/smooth-scroll/package.json b/examples/vue/smooth-scroll/package.json index fe1919490..2d9e16c1b 100644 --- a/examples/vue/smooth-scroll/package.json +++ b/examples/vue/smooth-scroll/package.json @@ -14,8 +14,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/sticky/package.json b/examples/vue/sticky/package.json index 1b53ee4ef..37a46bf12 100644 --- a/examples/vue/sticky/package.json +++ b/examples/vue/sticky/package.json @@ -17,8 +17,8 @@ "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@types/lodash": "^4.17.17", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/table/package.json b/examples/vue/table/package.json index 2202ac4c7..1b097983d 100644 --- a/examples/vue/table/package.json +++ b/examples/vue/table/package.json @@ -16,8 +16,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/examples/vue/variable/package.json b/examples/vue/variable/package.json index b451870b9..3539f7c9e 100644 --- a/examples/vue/variable/package.json +++ b/examples/vue/variable/package.json @@ -14,8 +14,8 @@ "devDependencies": { "@codesandbox/vue-preview": "^0.1.1-alpha.16", "@vitejs/plugin-vue": "^5.2.4", - "typescript": "5.4.5", - "vite": "^5.4.19", + "typescript": "5.6.3", + "vite": "^6.4.2", "vue-tsc": "^2.2.10" } } diff --git a/knip.json b/knip.json index f3a69e7a2..490dfd010 100644 --- a/knip.json +++ b/knip.json @@ -1,4 +1,6 @@ { "$schema": "https://unpkg.com/knip@5/schema.json", - "ignoreWorkspaces": ["examples/**", "packages/react-virtual/e2e/**"] + "ignoreWorkspaces": ["examples/**"], + "ignoreDependencies": ["@angular/cli"], + "ignore": ["packages/react-virtual/e2e/app/**"] } diff --git a/package.json b/package.json index 57a6cea18..ae31b4eda 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@playwright/test": "^1.53.1", "@svitejs/changesets-changelog-github-compact": "^1.2.0", "@tanstack/eslint-config": "0.3.4", - "@tanstack/vite-config": "0.3.0", + "@tanstack/vite-config": "0.4.3", "@testing-library/jest-dom": "^6.6.3", "@types/node": "^24.5.2", "eslint": "^9.36.0", @@ -56,8 +56,8 @@ "publint": "^0.3.15", "sherif": "^1.9.0", "tinyglobby": "^0.2.15", - "typescript": "5.4.5", - "vite": "^5.4.19", - "vitest": "^2.1.9" + "typescript": "5.6.3", + "vite": "^6.4.2", + "vitest": "^4.1.4" } } diff --git a/packages/angular-virtual/README.md b/packages/angular-virtual/README.md index c3c262a89..a479bced6 100644 --- a/packages/angular-virtual/README.md +++ b/packages/angular-virtual/README.md @@ -4,7 +4,7 @@ Efficiently virtualize only the visible DOM nodes within massive scrollable elem # Quick Start -> NOTE: Angular Virtual requires Angular 17. +> NOTE: Angular Virtual requires Angular 19. 1. Install `@tanstack/angular-virtual` diff --git a/packages/angular-virtual/angular.json b/packages/angular-virtual/angular.json new file mode 100644 index 000000000..62d3df20a --- /dev/null +++ b/packages/angular-virtual/angular.json @@ -0,0 +1,56 @@ +{ + "$schema": "../../node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "pnpm", + "analytics": false, + "cache": { + "enabled": false + } + }, + "projects": { + "angular-virtual-e2e": { + "projectType": "application", + "root": "e2e/app", + "sourceRoot": "e2e/app/src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "e2e/app/dist/angular-virtual-e2e", + "index": "e2e/app/src/index.html", + "browser": "e2e/app/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "e2e/app/tsconfig.app.json", + "styles": ["e2e/app/src/styles.css"], + "scripts": [] + }, + "configurations": { + "production": { + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-virtual-e2e:build:production" + }, + "development": { + "buildTarget": "angular-virtual-e2e:build:development" + } + }, + "defaultConfiguration": "development" + } + } + } + } +} diff --git a/packages/angular-virtual/e2e/app/angular.json b/packages/angular-virtual/e2e/app/angular.json new file mode 100644 index 000000000..6436fe9a4 --- /dev/null +++ b/packages/angular-virtual/e2e/app/angular.json @@ -0,0 +1,56 @@ +{ + "$schema": "../../../node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "pnpm", + "analytics": false, + "cache": { + "enabled": false + } + }, + "projects": { + "angular-virtual-e2e": { + "projectType": "application", + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/angular-virtual-e2e", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "styles": ["src/styles.css"], + "scripts": [] + }, + "configurations": { + "production": { + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-virtual-e2e:build:production" + }, + "development": { + "buildTarget": "angular-virtual-e2e:build:development" + } + }, + "defaultConfiguration": "development" + } + } + } + } +} diff --git a/packages/angular-virtual/e2e/app/src/app/app.component.ts b/packages/angular-virtual/e2e/app/src/app/app.component.ts new file mode 100644 index 000000000..00b89cf0e --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/app.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core' +import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router' + +@Component({ + selector: 'app-root', + standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [RouterLink, RouterLinkActive, RouterOutlet], + template: ` + + + + `, +}) +export class AppComponent {} diff --git a/packages/angular-virtual/e2e/app/src/app/app.config.ts b/packages/angular-virtual/e2e/app/src/app/app.config.ts new file mode 100644 index 000000000..043337582 --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/app.config.ts @@ -0,0 +1,7 @@ +import type { ApplicationConfig } from '@angular/core' +import { provideRouter } from '@angular/router' +import { routes } from './app.routes' + +export const appConfig: ApplicationConfig = { + providers: [provideRouter(routes)], +} diff --git a/packages/angular-virtual/e2e/app/src/app/app.routes.ts b/packages/angular-virtual/e2e/app/src/app/app.routes.ts new file mode 100644 index 000000000..b82c9497f --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/app.routes.ts @@ -0,0 +1,29 @@ +import type { Routes } from '@angular/router' +import { MeasureElementComponent } from './measure-element.component' +import { SmoothScrollComponent } from './smooth-scroll.component' +import { ScrollComponent } from './scroll.component' +import { StaleIndexComponent } from './stale-index.component' + +export const routes: Routes = [ + { + path: '', + pathMatch: 'full', + redirectTo: 'scroll', + }, + { + path: 'scroll', + component: ScrollComponent, + }, + { + path: 'smooth-scroll', + component: SmoothScrollComponent, + }, + { + path: 'measure-element', + component: MeasureElementComponent, + }, + { + path: 'stale-index', + component: StaleIndexComponent, + }, +] diff --git a/packages/angular-virtual/e2e/app/src/app/measure-element.component.ts b/packages/angular-virtual/e2e/app/src/app/measure-element.component.ts new file mode 100644 index 000000000..16a8f74b4 --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/measure-element.component.ts @@ -0,0 +1,115 @@ +import { + ChangeDetectionStrategy, + Component, + afterRenderEffect, + signal, + viewChild, + viewChildren, +} from '@angular/core' +import type { ElementRef } from '@angular/core' +import { injectVirtualizer } from '@tanstack/angular-virtual' + +interface Item { + id: string + label: string +} + +const initialItems: Array = [ + { id: 'item-a', label: 'A' }, + { id: 'item-b', label: 'B' }, + { id: 'item-c', label: 'C' }, +] + +@Component({ + standalone: true, + selector: 'app-measure-element', + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+
+ @for (row of virtualizer.getVirtualItems(); track row.key) { + @let item = this.items()[row.index]!; +
+
+ Row {{ item.label }} + + +
+ @if (expandedId() === item.id) { +
+ Expanded content for {{ item.label }} +
+ } +
+ } +
+
+
{{ virtualizer.getTotalSize() }}
+ `, +}) +export class MeasureElementComponent { + scrollElement = viewChild>('scrollElement') + + virtualItems = viewChildren>('virtualItem') + + items = signal(initialItems) + + expandedId = signal(null) + + #measureItems = afterRenderEffect({ + read: () => { + this.virtualItems().forEach((el) => { + this.virtualizer.measureElement(el.nativeElement) + }) + }, + }) + + virtualizer = injectVirtualizer(() => ({ + scrollElement: this.scrollElement(), + count: this.items().length, + estimateSize: () => 36, + getItemKey: (index) => this.items()[index]!.id, + })) + + toggleExpand(id: string) { + this.expandedId.update((current) => (current === id ? null : id)) + } + + deleteItem(id: string) { + this.items.update((items) => items.filter((item) => item.id !== id)) + + if (this.expandedId() === id) { + this.expandedId.set(null) + } + } +} diff --git a/packages/angular-virtual/e2e/app/src/app/scroll.component.ts b/packages/angular-virtual/e2e/app/src/app/scroll.component.ts new file mode 100644 index 000000000..707c396fe --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/scroll.component.ts @@ -0,0 +1,113 @@ +import { + ChangeDetectionStrategy, + Component, + afterRenderEffect, + viewChild, + viewChildren, +} from '@angular/core' +import type { ElementRef } from '@angular/core' +import { injectVirtualizer } from '@tanstack/angular-virtual' + +function getRandomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min +} + +const randomHeightForKey = (() => { + const cache = new Map() + return (id: string) => { + const value = cache.get(id) + if (value !== undefined) { + return value + } + const v = getRandomInt(25, 100) + cache.set(id, v) + return v + } +})() + +@Component({ + standalone: true, + selector: 'app-scroll', + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ + + + +
+
+ @for (row of virtualizer.getVirtualItems(); track row.key) { +
+
+ Row {{ row.index }} +
+
+ } +
+
+
+ `, +}) +export class ScrollComponent { + scrollElement = viewChild>('scrollElement') + + virtualItems = viewChildren>('virtualItem') + + count = 1002 + + initialOffset = Number( + new URLSearchParams(window.location.search).get('initialOffset') ?? 0, + ) + + #measureItems = afterRenderEffect({ + read: () => { + this.virtualItems().forEach((el) => { + this.virtualizer.measureElement(el.nativeElement) + }) + }, + }) + + virtualizer = injectVirtualizer(() => ({ + scrollElement: this.scrollElement(), + count: this.count, + estimateSize: () => 50, + initialOffset: this.initialOffset, + debug: true, + })) + + randomHeight(key: string | number | bigint): number { + return randomHeightForKey(String(key)) + } +} diff --git a/packages/angular-virtual/e2e/app/src/app/smooth-scroll.component.ts b/packages/angular-virtual/e2e/app/src/app/smooth-scroll.component.ts new file mode 100644 index 000000000..faaab3bc1 --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/smooth-scroll.component.ts @@ -0,0 +1,119 @@ +import { + ChangeDetectionStrategy, + Component, + afterRenderEffect, + viewChild, + viewChildren, +} from '@angular/core' +import type { ElementRef } from '@angular/core' +import { injectVirtualizer } from '@tanstack/angular-virtual' + +function getRandomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min +} + +const randomHeightForKey = (() => { + const cache = new Map() + return (id: string) => { + const value = cache.get(id) + if (value !== undefined) { + return value + } + const v = getRandomInt(25, 100) + cache.set(id, v) + return v + } +})() + +@Component({ + standalone: true, + selector: 'app-smooth-scroll', + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ + + + + + +
+ +
+
+ @for (row of virtualizer.getVirtualItems(); track row.key) { +
+
+ Row {{ row.index }} +
+
+ } +
+
+ `, +}) +export class SmoothScrollComponent { + scrollElement = viewChild>('scrollElement') + + virtualItems = viewChildren>('virtualItem') + + count = 1002 + + #measureItems = afterRenderEffect({ + read: () => { + this.virtualItems().forEach((el) => { + this.virtualizer.measureElement(el.nativeElement) + }) + }, + }) + + virtualizer = injectVirtualizer(() => ({ + scrollElement: this.scrollElement(), + count: this.count, + estimateSize: () => 50, + })) + + scrollToIndex(index: number, align?: 'auto' | 'start' | 'center' | 'end') { + this.virtualizer.scrollToIndex(index, { + behavior: 'smooth', + align, + }) + } + + randomHeight(key: string | number | bigint): number { + return randomHeightForKey(String(key)) + } +} diff --git a/packages/angular-virtual/e2e/app/src/app/stale-index.component.ts b/packages/angular-virtual/e2e/app/src/app/stale-index.component.ts new file mode 100644 index 000000000..8d9746599 --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/app/stale-index.component.ts @@ -0,0 +1,102 @@ +import { + ChangeDetectionStrategy, + Component, + afterRenderEffect, + signal, + viewChild, + viewChildren, +} from '@angular/core' +import type { ElementRef } from '@angular/core' +import { injectVirtualizer } from '@tanstack/angular-virtual' + +interface Item { + id: string + label: string +} + +function makeItems(count: number): Array { + return Array.from({ length: count }, (_, index) => ({ + id: `item-${index}`, + label: `Row ${index}`, + })) +} + +@Component({ + standalone: true, + selector: 'app-stale-index', + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ +
Count: {{ items().length }}
+ @if (error()) { +
{{ error() }}
+ } + +
+
+ @for (row of virtualizer.getVirtualItems(); track row.index) { +
+ {{ items()[row.index].label }} +
+ } +
+
+
+ `, +}) +export class StaleIndexComponent { + scrollElement = viewChild>('scrollElement') + + virtualItems = viewChildren>('virtualItem') + + items = signal(makeItems(20)) + + error = signal(null) + + #measureItems = afterRenderEffect({ + read: () => { + this.virtualItems().forEach((el) => { + this.virtualizer.measureElement(el.nativeElement) + }) + }, + }) + + virtualizer = injectVirtualizer(() => ({ + scrollElement: this.scrollElement(), + count: this.items().length, + estimateSize: () => 50, + getItemKey: (index) => { + const items = this.items() + if (index < 0 || index >= items.length) { + const message = `getItemKey called with stale index ${index} (count=${items.length})` + this.error.set(message) + throw new Error(message) + } + return items[index]!.id + }, + })) + + removeLastFive() { + this.items.update((items) => items.slice(0, Math.max(0, items.length - 5))) + } +} diff --git a/packages/angular-virtual/e2e/app/src/index.html b/packages/angular-virtual/e2e/app/src/index.html new file mode 100644 index 000000000..ef4f004aa --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/index.html @@ -0,0 +1,12 @@ + + + + + Angular Virtual E2E + + + + + + + diff --git a/packages/angular-virtual/e2e/app/src/main.ts b/packages/angular-virtual/e2e/app/src/main.ts new file mode 100644 index 000000000..c3d8f9af9 --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/main.ts @@ -0,0 +1,5 @@ +import { bootstrapApplication } from '@angular/platform-browser' +import { appConfig } from './app/app.config' +import { AppComponent } from './app/app.component' + +bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)) diff --git a/packages/angular-virtual/e2e/app/src/styles.css b/packages/angular-virtual/e2e/app/src/styles.css new file mode 100644 index 000000000..bc166c773 --- /dev/null +++ b/packages/angular-virtual/e2e/app/src/styles.css @@ -0,0 +1,14 @@ +html, +body { + margin: 0; + font-family: sans-serif; +} + +body { + padding: 16px; +} + +button { + margin-right: 8px; + margin-bottom: 8px; +} diff --git a/packages/angular-virtual/e2e/app/test/measure-element.spec.ts b/packages/angular-virtual/e2e/app/test/measure-element.spec.ts new file mode 100644 index 000000000..6973fdbb5 --- /dev/null +++ b/packages/angular-virtual/e2e/app/test/measure-element.spec.ts @@ -0,0 +1,42 @@ +import { expect, test } from '@playwright/test' + +test('positions items correctly after expand → collapse → delete → expand', async ({ + page, +}) => { + await page.goto('/measure-element/') + + // All 3 items visible at ~36px each + await expect(page.locator('[data-testid="item-a"]')).toBeVisible() + await expect(page.locator('[data-testid="item-b"]')).toBeVisible() + await expect(page.locator('[data-testid="item-c"]')).toBeVisible() + + // Step 1: Expand A → should grow to ~160px + await page.click('[data-testid="expand-item-a"]') + await expect(page.locator('[data-testid="content-item-a"]')).toBeVisible() + + // Step 2: Collapse A → back to ~36px + await page.click('[data-testid="expand-item-a"]') + await expect(page.locator('[data-testid="content-item-a"]')).not.toBeVisible() + + // Step 3: Delete A + await page.click('[data-testid="delete-item-a"]') + await expect(page.locator('[data-testid="item-a"]')).not.toBeVisible() + + // Step 4: Expand B → should grow to ~160px + await page.click('[data-testid="expand-item-b"]') + await expect(page.locator('[data-testid="content-item-b"]')).toBeVisible() + + // Wait for ResizeObserver to measure the expanded B + await page.waitForTimeout(200) + + // C should be positioned after the expanded B, not overlapping it + const bBox = await page.locator('[data-testid="item-b"]').boundingBox() + const cBox = await page.locator('[data-testid="item-c"]').boundingBox() + + expect(bBox).not.toBeNull() + expect(cBox).not.toBeNull() + + // C's top should be at or after B's bottom (with no overlap) + const bBottom = bBox!.y + bBox!.height + expect(cBox!.y).toBeGreaterThanOrEqual(bBottom - 1) // 1px tolerance +}) diff --git a/packages/angular-virtual/e2e/app/test/scroll.spec.ts b/packages/angular-virtual/e2e/app/test/scroll.spec.ts new file mode 100644 index 000000000..9e2f5f014 --- /dev/null +++ b/packages/angular-virtual/e2e/app/test/scroll.spec.ts @@ -0,0 +1,133 @@ +import { expect, test } from '@playwright/test' + +const check = () => { + const item = document.querySelector('[data-testid="item-1000"]') + const container = document.querySelector('#scroll-container') + + if (!item || !container) throw new Error('Elements not found') + + const itemRect = item.getBoundingClientRect() + const containerRect = container.getBoundingClientRect() + const scrollTop = container.scrollTop + + const top = itemRect.top + scrollTop - containerRect.top + const bottom = top + itemRect.height + + const containerBottom = scrollTop + container.clientHeight + + return Math.abs(bottom - containerBottom) +} + +test('scrolls to index 1000', async ({ page }) => { + await page.goto('/scroll/') + await page.click('#scroll-to-1000') + + // Wait for scroll effect (including retries) + await page.waitForTimeout(1000) + + await expect(page.locator('[data-testid="item-1000"]')).toBeVisible() + + const delta = await page.evaluate(check) + // Angular layout/scroll alignment needs a slightly higher tolerance than React. + expect(delta).toBeLessThan(4.5) +}) + +test('scrolls to last item', async ({ page }) => { + await page.goto('/scroll/') + await page.click('#scroll-to-last') + + await page.waitForTimeout(1000) + + // Last item (index 1001) should be visible + await expect(page.locator('[data-testid="item-1001"]')).toBeVisible() + + // Container should be scrolled to the very bottom + const atBottom = await page.evaluate(() => { + const container = document.querySelector('#scroll-container') + if (!container) throw new Error('Container not found') + return Math.abs( + container.scrollTop + container.clientHeight - container.scrollHeight, + ) + }) + expect(atBottom).toBeLessThan(1.01) +}) + +test('renders correctly with initialOffset and user scroll up', async ({ + page, +}) => { + // Start at offset 5000 (no programmatic scrollToIndex) + await page.goto('/scroll/?initialOffset=5000') + await page.waitForTimeout(500) + + // Items around offset 5000 should be visible + const visibleIndex = await page.evaluate(() => { + const container = document.querySelector('#scroll-container') + if (!container) throw new Error('Container not found') + const items = container.querySelectorAll('[data-index]') + const indices = Array.from(items).map((el) => + Number(el.getAttribute('data-index')), + ) + return Math.min(...indices) + }) + expect(visibleIndex).toBeGreaterThan(0) + + // Scroll up by 2000px (user scroll, not programmatic) + await page.evaluate(() => { + const container = document.querySelector('#scroll-container') + if (!container) throw new Error('Container not found') + container.scrollTop -= 2000 + }) + await page.waitForTimeout(500) + + // After scroll up, items should be properly measured and positioned + // (no gaps, no overlaps) — verify consecutive items are contiguous + const layout = await page.evaluate(() => { + const container = document.querySelector('#scroll-container') + if (!container) throw new Error('Container not found') + const items = Array.from(container.querySelectorAll('[data-index]')) + .map((el) => { + const rect = el.getBoundingClientRect() + return { + index: Number(el.getAttribute('data-index')), + top: rect.top, + bottom: rect.bottom, + height: rect.height, + } + }) + .sort((a, b) => a.index - b.index) + + // Check that each item's top matches the previous item's bottom (within tolerance) + let maxGap = 0 + for (let i = 1; i < items.length; i++) { + const gap = Math.abs(items[i].top - items[i - 1].bottom) + maxGap = Math.max(maxGap, gap) + } + + return { items, maxGap } + }) + + expect(layout.items.length > 0).toBe(true) + expect(layout.items.length).toBeGreaterThan(3) + // Items should be contiguous — no gaps between consecutive items + expect(layout.maxGap).toBeLessThan(2) +}) + +test('scrolls to index 0', async ({ page }) => { + await page.goto('/scroll/') + + // First scroll down + await page.click('#scroll-to-1000') + await page.waitForTimeout(1000) + + // Then scroll to first item + await page.click('#scroll-to-0') + await page.waitForTimeout(1000) + + await expect(page.locator('[data-testid="item-0"]')).toBeVisible() + + const scrollTop = await page.evaluate(() => { + const container = document.querySelector('#scroll-container') + return container?.scrollTop ?? -1 + }) + expect(scrollTop).toBeLessThan(1.01) +}) diff --git a/packages/angular-virtual/e2e/app/test/smooth-scroll.spec.ts b/packages/angular-virtual/e2e/app/test/smooth-scroll.spec.ts new file mode 100644 index 000000000..d8650db91 --- /dev/null +++ b/packages/angular-virtual/e2e/app/test/smooth-scroll.spec.ts @@ -0,0 +1,143 @@ +import { expect, test } from '@playwright/test' + +test('smooth scrolls to index 1000', async ({ page }) => { + await page.goto('/smooth-scroll/') + await page.click('#scroll-to-1000') + + // Smooth scroll animation is 500ms + reconciliation time + await page.waitForTimeout(2000) + + await expect(page.locator('[data-testid="item-1000"]')).toBeVisible() + + const delta = await page.evaluate(() => { + const item = document.querySelector('[data-testid="item-1000"]') + const container = document.querySelector('#scroll-container') + if (!item || !container) throw new Error('Elements not found') + + const itemRect = item.getBoundingClientRect() + const containerRect = container.getBoundingClientRect() + const scrollTop = container.scrollTop + const top = itemRect.top + scrollTop - containerRect.top + const bottom = top + itemRect.height + const containerBottom = scrollTop + container.clientHeight + return Math.abs(bottom - containerBottom) + }) + expect(delta).toBeLessThan(1.01) +}) + +test('smooth scrolls to index 100', async ({ page }) => { + await page.goto('/smooth-scroll/') + await page.click('#scroll-to-100') + + await page.waitForTimeout(2000) + + await expect(page.locator('[data-testid="item-100"]')).toBeVisible() +}) + +test('smooth scrolls to index 0 after scrolling away', async ({ page }) => { + await page.goto('/smooth-scroll/') + + // First scroll down + await page.click('#scroll-to-500') + await page.waitForTimeout(2000) + await expect(page.locator('[data-testid="item-500"]')).toBeVisible() + + // Then smooth scroll back to top + await page.click('#scroll-to-0') + await page.waitForTimeout(2000) + + await expect(page.locator('[data-testid="item-0"]')).toBeVisible() + + const scrollTop = await page.evaluate(() => { + const container = document.querySelector('#scroll-container') + return container?.scrollTop ?? -1 + }) + expect(scrollTop).toBeLessThan(1.01) +}) + +test('smooth scrolls to index 500 with start alignment', async ({ page }) => { + await page.goto('/smooth-scroll/') + await page.click('#scroll-to-500-start') + + await page.waitForTimeout(2000) + + await expect(page.locator('[data-testid="item-500"]')).toBeVisible() + + const delta = await page.evaluate( + ([idx, align]) => { + const item = document.querySelector(`[data-testid="item-${idx}"]`) + const container = document.querySelector('#scroll-container') + if (!item || !container) throw new Error('Elements not found') + const itemRect = item.getBoundingClientRect() + const containerRect = container.getBoundingClientRect() + if (align === 'start') { + return Math.abs(itemRect.top - containerRect.top) + } + return 0 + }, + [500, 'start'] as const, + ) + expect(delta).toBeLessThan(1.01) +}) + +test('smooth scrolls to index 500 with center alignment', async ({ page }) => { + await page.goto('/smooth-scroll/') + await page.click('#scroll-to-500-center') + + await page.waitForTimeout(2000) + + await expect(page.locator('[data-testid="item-500"]')).toBeVisible() + + const delta = await page.evaluate( + ([idx]) => { + const item = document.querySelector(`[data-testid="item-${idx}"]`) + const container = document.querySelector('#scroll-container') + if (!item || !container) throw new Error('Elements not found') + const itemRect = item.getBoundingClientRect() + const containerRect = container.getBoundingClientRect() + const containerCenter = containerRect.top + containerRect.height / 2 + const itemCenter = itemRect.top + itemRect.height / 2 + return Math.abs(itemCenter - containerCenter) + }, + [500] as const, + ) + // Center alignment has slightly more tolerance due to rounding + expect(delta).toBeLessThan(50) +}) + +test('smooth scrolls sequentially to multiple targets', async ({ page }) => { + await page.goto('/smooth-scroll/') + + // Scroll to 100 first + await page.click('#scroll-to-100') + await page.waitForTimeout(2000) + await expect(page.locator('[data-testid="item-100"]')).toBeVisible() + + // Then scroll to 500 + await page.click('#scroll-to-500') + await page.waitForTimeout(2000) + await expect(page.locator('[data-testid="item-500"]')).toBeVisible() + + // Then scroll to 1000 + await page.click('#scroll-to-1000') + await page.waitForTimeout(2000) + await expect(page.locator('[data-testid="item-1000"]')).toBeVisible() +}) + +test('interrupting smooth scroll with another smooth scroll', async ({ + page, +}) => { + await page.goto('/smooth-scroll/') + + // Start scrolling to 1000 + await page.click('#scroll-to-1000') + // Interrupt mid-animation (before the 500ms animation completes) + await page.waitForTimeout(200) + await page.click('#scroll-to-100') + + // Wait for the second scroll to complete + await page.waitForTimeout(2000) + + // Should have ended at 100, not 1000 + await expect(page.locator('[data-testid="item-100"]')).toBeVisible() +}) diff --git a/packages/angular-virtual/e2e/app/test/stale-index.spec.ts b/packages/angular-virtual/e2e/app/test/stale-index.spec.ts new file mode 100644 index 000000000..fcf7d93e8 --- /dev/null +++ b/packages/angular-virtual/e2e/app/test/stale-index.spec.ts @@ -0,0 +1,38 @@ +import { expect, test } from '@playwright/test' + +test('does not call getItemKey with stale index after removing items', async ({ + page, +}) => { + await page.goto('/stale-index/') + + // Verify initial state + await expect(page.locator('[data-testid="item-count"]')).toHaveText( + 'Count: 20', + ) + + // Scroll to the bottom so the last items are rendered and observed by ResizeObserver + const container = page.locator('[data-testid="scroll-container"]') + await container.evaluate((el) => (el.scrollTop = el.scrollHeight)) + await page.waitForTimeout(100) + + // Remove 5 items from the end — the RO may still fire for the now-disconnected nodes + await page.click('[data-testid="remove-items"]') + await expect(page.locator('[data-testid="item-count"]')).toHaveText( + 'Count: 15', + ) + + // Wait for any pending ResizeObserver callbacks + await page.waitForTimeout(200) + + // No error should have been thrown + await expect(page.locator('[data-testid="error"]')).not.toBeVisible() + + // Remove 5 more to stress it + await page.click('[data-testid="remove-items"]') + await expect(page.locator('[data-testid="item-count"]')).toHaveText( + 'Count: 10', + ) + await page.waitForTimeout(200) + + await expect(page.locator('[data-testid="error"]')).not.toBeVisible() +}) diff --git a/packages/angular-virtual/e2e/app/tsconfig.app.json b/packages/angular-virtual/e2e/app/tsconfig.app.json new file mode 100644 index 000000000..c3317bcd2 --- /dev/null +++ b/packages/angular-virtual/e2e/app/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": ["node"] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/packages/angular-virtual/e2e/app/tsconfig.json b/packages/angular-virtual/e2e/app/tsconfig.json new file mode 100644 index 000000000..fab69658a --- /dev/null +++ b/packages/angular-virtual/e2e/app/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "esModuleInterop": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "lib": ["ES2022", "dom"], + "baseUrl": ".", + "paths": { + "@tanstack/angular-virtual": ["../../src/index.ts"], + "@tanstack/virtual-core": ["../../../virtual-core/src/index.ts"] + } + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/angular-virtual/ng-package.json b/packages/angular-virtual/ng-package.json deleted file mode 100644 index b12a231c1..000000000 --- a/packages/angular-virtual/ng-package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "./node_modules/ng-packagr/ng-package.schema.json", - "lib": { - "entryFile": "src/index.ts" - }, - "allowedNonPeerDependencies": ["@tanstack/virtual-core"], - "dest": "build", - "deleteDestPath": false -} diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index 91a9c6980..e8e892ade 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -20,42 +20,51 @@ "virtual-core" ], "type": "module", - "module": "build/fesm2022/tanstack-angular-virtual.mjs", - "types": "build/index.d.ts", + "types": "dist/esm/index.d.ts", + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", "exports": { ".": { - "types": "./build/index.d.ts", - "esm2022": "./build/esm2022/tanstack-angular-virtual.mjs", - "esm": "./build/esm2022/tanstack-angular-virtual.mjs", - "default": "./build/fesm2022/tanstack-angular-virtual.mjs" + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } }, - "./package.json": { - "default": "./package.json" - } - }, - "engines": { - "node": ">=12" + "./package.json": "./package.json" }, "files": [ - "build" + "dist", + "src" ], "scripts": { - "clean": "premove ./build", - "test:types": "tsc --noEmit", + "clean": "premove ./dist ./build ./coverage", "test:eslint": "eslint ./src", - "build": "ng-packagr -p ng-package.json -c tsconfig.build.json" + "test:build": "publint --strict", + "test:types": "tsc", + "build": "vite build", + "test:e2e": "../../node_modules/.bin/playwright test" }, "dependencies": { - "@tanstack/virtual-core": "workspace:*", - "tslib": "^2.8.1" + "@tanstack/virtual-core": "workspace:*" }, "devDependencies": { - "@angular/core": "^18.1.0", - "ng-packagr": "^18.1.0", - "typescript": "5.4.5" + "@angular-devkit/build-angular": "^19.0.0", + "@angular/cli": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/router": "^19.0.0", + "tslib": "^2.8.1", + "typescript": "5.6.3", + "zone.js": "0.15.1" }, "peerDependencies": { - "@angular/core": ">=18.1.0" + "@angular/core": ">=19.0.0" }, "sideEffects": false } diff --git a/packages/angular-virtual/playwright.config.ts b/packages/angular-virtual/playwright.config.ts new file mode 100644 index 000000000..617f10405 --- /dev/null +++ b/packages/angular-virtual/playwright.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from '@playwright/test' + +const PORT = 4201 +const baseURL = `http://127.0.0.1:${PORT}` + +export default defineConfig({ + testDir: './e2e/app/test', + use: { + baseURL, + }, + webServer: { + command: `pnpm exec ng serve --host 127.0.0.1 --port ${PORT} --configuration development`, + url: `${baseURL}/scroll`, + reuseExistingServer: !process.env.CI, + stdout: 'pipe', + }, +}) diff --git a/packages/angular-virtual/src/index.ts b/packages/angular-virtual/src/index.ts index 79aa266b2..453377fa3 100644 --- a/packages/angular-virtual/src/index.ts +++ b/packages/angular-virtual/src/index.ts @@ -1,10 +1,13 @@ import { + ApplicationRef, DestroyRef, - afterNextRender, + Injector, + afterRenderEffect, + assertInInjectionContext, computed, - effect, inject, - signal, + linkedSignal, + runInInjectionContext, untracked, } from '@angular/core' import { @@ -16,70 +19,152 @@ import { observeWindowRect, windowScroll, } from '@tanstack/virtual-core' -import { proxyVirtualizer } from './proxy' -import type { ElementRef, Signal } from '@angular/core' +import { signalProxy } from './proxy' +import type { ElementRef } from '@angular/core' import type { PartialKeys, VirtualizerOptions } from '@tanstack/virtual-core' import type { AngularVirtualizer } from './types' export * from '@tanstack/virtual-core' export * from './types' -function createVirtualizerBase< +export type AngularVirtualizerOptions< + TScrollElement extends Element | Window, + TItemElement extends Element, +> = VirtualizerOptions & { + /** + * Whether to flush the DOM using `ApplicationRef.tick()` + * @default true + * */ + useApplicationRefTick?: boolean +} + +export type AngularExtensionOptions = { + /** + * The injector to use for the virtualizer. + * @default inject(Injector) + */ + injector?: Injector +} + +// Flush CD after virtual-core updates so template bindings hit the DOM +// before the next frame's scroll reconciliation reads `scrollHeight`. +function injectScheduleDomFlushViaAppRefTick() { + const appRef = inject(ApplicationRef) + const destroyRef = inject(DestroyRef) + let hostDestroyed = false + destroyRef.onDestroy(() => { + hostDestroyed = true + }) + let domFlushQueued = false + + return () => { + if (domFlushQueued) return + domFlushQueued = true + queueMicrotask(() => { + domFlushQueued = false + if (hostDestroyed) return + appRef.tick() + }) + } +} + +function injectVirtualizerBase< TScrollElement extends Element | Window, TItemElement extends Element, >( - options: Signal>, -): AngularVirtualizer { - let virtualizer: Virtualizer - function lazyInit() { - virtualizer ??= new Virtualizer(options()) - return virtualizer + options: () => AngularVirtualizerOptions, + extensions: AngularExtensionOptions = {}, +) { + let injector = extensions.injector + if (!injector) { + assertInInjectionContext(injectVirtualizerBase) + injector = inject(Injector) } - const virtualizerSignal = signal(virtualizer!, { equal: () => false }) + return runInInjectionContext(injector, () => { + const scheduleDomFlush = injectScheduleDomFlushViaAppRefTick() - // two-way sync options - effect( - () => { - const _options = options() - lazyInit() - virtualizerSignal.set(virtualizer) - virtualizer.setOptions({ + const resolvedOptions = computed< + VirtualizerOptions + >(() => { + const { useApplicationRefTick = true, ..._options } = options() + return { ..._options, onChange: (instance, sync) => { - // update virtualizerSignal so that dependent computeds recompute. - virtualizerSignal.set(instance) + reactiveVirtualizer.set(instance) + if (useApplicationRefTick) { + scheduleDomFlush() + } _options.onChange?.(instance, sync) }, - }) - // update virtualizerSignal so that dependent computeds recompute. - virtualizerSignal.set(virtualizer) - }, - { allowSignalWrites: true }, - ) - - const scrollElement = computed(() => options().getScrollElement()) - // let the virtualizer know when the scroll element is changed - effect( - () => { - const el = scrollElement() - if (el) { - untracked(virtualizerSignal)._willUpdate() } - }, - { allowSignalWrites: true }, - ) - - let cleanup: (() => void) | undefined - afterNextRender({ - read: () => { - cleanup = (virtualizer ?? lazyInit())._didMount() - }, - }) + }) + + // Computed here is used to lazily initialize the Virtualizer instance, + // allowing it to be created after input/model signals are initialized. + // Options are untracked to maintain a single instance of the Virtualizer. + const lazyVirtualizer = computed( + () => new Virtualizer(untracked(resolvedOptions)), + ) + + // The reference in onChange is safe since computed signals are not evaluated eagerly. + const reactiveVirtualizer = linkedSignal( + () => { + const virtualizer = lazyVirtualizer() + // If setOptions does not call onChange, it's safe to call it here + virtualizer.setOptions(resolvedOptions()) + return virtualizer + }, + { equal: () => false }, + ) - inject(DestroyRef).onDestroy(() => cleanup?.()) + afterRenderEffect((cleanup) => { + cleanup(lazyVirtualizer()._didMount()) + }) - return proxyVirtualizer(virtualizerSignal, lazyInit) + afterRenderEffect(() => { + reactiveVirtualizer()._willUpdate() + }) + + return signalProxy( + reactiveVirtualizer, + // Methods that pass through: call on the instance without tracking the signal read + [ + '_didMount', + '_willUpdate', + 'calculateRange', + 'getVirtualIndexes', + 'measure', + 'measureElement', + 'resizeItem', + 'scrollBy', + 'scrollToIndex', + 'scrollToOffset', + 'setOptions', + ], + // Attributes that will be transformed to signals + [ + 'isScrolling', + 'measurementsCache', + 'options', + 'range', + 'scrollDirection', + 'scrollElement', + 'scrollOffset', + 'scrollRect', + ], + // Methods that will be tracked to the virtualizer signal + [ + 'getOffsetForAlignment', + 'getOffsetForIndex', + 'getVirtualItemForOffset', + 'indexFromElement', + ], + // Zero-arg methods exposed as computed signals + ['getTotalSize', 'getVirtualItems'], + // The rest is passed as is, and can be accessed or called before initialization + ) as unknown as AngularVirtualizer + }) } export function injectVirtualizer< @@ -87,29 +172,32 @@ export function injectVirtualizer< TItemElement extends Element, >( options: () => PartialKeys< - Omit, 'getScrollElement'>, + Omit< + AngularVirtualizerOptions, + 'getScrollElement' + >, 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' > & { scrollElement: ElementRef | TScrollElement | undefined }, ): AngularVirtualizer { - const resolvedOptions = computed(() => { + return injectVirtualizerBase(() => { + const _options = options() return { observeElementRect: observeElementRect, observeElementOffset: observeElementOffset, scrollToFn: elementScroll, getScrollElement: () => { - const elementOrRef = options().scrollElement + const elementOrRef = _options.scrollElement return ( (isElementRef(elementOrRef) ? elementOrRef.nativeElement : elementOrRef) ?? null ) }, - ...options(), + ..._options, } }) - return createVirtualizerBase(resolvedOptions) } function isElementRef( @@ -120,23 +208,19 @@ function isElementRef( export function injectWindowVirtualizer( options: () => PartialKeys< - VirtualizerOptions, + AngularVirtualizerOptions, | 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' >, ): AngularVirtualizer { - const resolvedOptions = computed(() => { - return { - getScrollElement: () => (typeof document !== 'undefined' ? window : null), - observeElementRect: observeWindowRect, - observeElementOffset: observeWindowOffset, - scrollToFn: windowScroll, - initialOffset: () => - typeof document !== 'undefined' ? window.scrollY : 0, - ...options(), - } - }) - return createVirtualizerBase(resolvedOptions) + return injectVirtualizerBase(() => ({ + getScrollElement: () => (typeof document !== 'undefined' ? window : null), + observeElementRect: observeWindowRect, + observeElementOffset: observeWindowOffset, + scrollToFn: windowScroll, + initialOffset: () => (typeof document !== 'undefined' ? window.scrollY : 0), + ...options(), + })) } diff --git a/packages/angular-virtual/src/proxy.ts b/packages/angular-virtual/src/proxy.ts index 1664b58ea..0a9749d45 100644 --- a/packages/angular-virtual/src/proxy.ts +++ b/packages/angular-virtual/src/proxy.ts @@ -1,84 +1,98 @@ import { computed, untracked } from '@angular/core' -import type { Signal, WritableSignal } from '@angular/core' -import type { Virtualizer } from '@tanstack/virtual-core' -import type { AngularVirtualizer } from './types' +import type { Signal } from '@angular/core' -export function proxyVirtualizer< - V extends Virtualizer, - S extends Element | Window = V extends Virtualizer ? U : never, - I extends Element = V extends Virtualizer ? U : never, +type SignalProxy< + TInput extends Record, + TMethodsToPassThrough extends keyof TInput, + TAttributesToTransformToSignals extends keyof TInput, + TMethodsToTrack extends keyof TInput, + TMethodsToTransformToSignals extends keyof TInput, +> = { + [K in TMethodsToPassThrough]: TInput[K] +} & { + [K in TAttributesToTransformToSignals]: Signal +} & { + [K in TMethodsToTrack]: TInput[K] +} & { + [K in TMethodsToTransformToSignals]: Signal> +} + +export function signalProxy< + TInput extends Record, + TMethodsToPassThrough extends keyof TInput, + TAttributesToTransformToSignals extends keyof TInput, + TMethodsToTrack extends keyof TInput, + TMethodsToTransformToSignals extends keyof TInput, >( - virtualizerSignal: WritableSignal, - lazyInit: () => V, -): AngularVirtualizer { - return new Proxy(virtualizerSignal, { + inputSignal: Signal, + methodsToPassThrough: Array, + attributesToTransformToSignals: Array, + methodsToTrack: Array, + methodsToTransformToSignals: Array, +): SignalProxy< + TInput, + TMethodsToPassThrough, + TAttributesToTransformToSignals, + TMethodsToTrack, + TMethodsToTransformToSignals +> { + // Type needed to proxy with the apply handler + const callableTarget = (() => inputSignal()) as (() => TInput) & + Record + + return new Proxy(callableTarget, { apply() { - return virtualizerSignal() + return inputSignal() }, get(target, property) { - const untypedTarget = target as any - if (untypedTarget[property]) { - return untypedTarget[property] - } - let virtualizer = untracked(virtualizerSignal) - if (virtualizer == null) { - virtualizer = lazyInit() - untracked(() => virtualizerSignal.set(virtualizer)) + const fieldValue = target[property as keyof typeof callableTarget] + if (fieldValue !== undefined) return fieldValue + + // Methods that pass through: call on the instance without tracking the signal read + if (methodsToPassThrough.includes(property as TMethodsToPassThrough)) { + return (target[property] = ( + ...args: Parameters + ) => untracked(inputSignal)[property as keyof TInput](...args)) } - // Create computed signals for each property that represents a reactive value + // Zero-arg methods exposed as computed signals if ( - typeof property === 'string' && - [ - 'getTotalSize', - 'getVirtualItems', - 'isScrolling', - 'options', - 'range', - 'scrollDirection', - 'scrollElement', - 'scrollOffset', - 'scrollRect', - 'measureElementCache', - 'measurementsCache', - ].includes(property) + methodsToTransformToSignals.includes( + property as TMethodsToTransformToSignals, + ) ) { - const isFunction = - typeof virtualizer[property as keyof V] === 'function' - Object.defineProperty(untypedTarget, property, { - value: isFunction - ? computed(() => (target()[property as keyof V] as Function)()) - : computed(() => target()[property as keyof V]), - configurable: true, - enumerable: true, - }) + return (target[property] = computed(() => + (inputSignal()[property as keyof TInput] as () => unknown)(), + )) + } + + // Methods that need to be tracked, track instance changes and call the method + if (methodsToTrack.includes(property as TMethodsToTrack)) { + return (target[property] = ( + ...args: Parameters + ) => inputSignal()[property as keyof TInput](...args)) } - // Create plain signals for functions that accept arguments and return reactive values + // Other values that are tracked as signals if ( - typeof property === 'string' && - [ - 'getOffsetForAlignment', - 'getOffsetForIndex', - 'getVirtualItemForOffset', - 'indexFromElement', - ].includes(property) + attributesToTransformToSignals.includes( + property as TAttributesToTransformToSignals, + ) ) { - const fn = virtualizer[property as keyof V] as Function - Object.defineProperty(untypedTarget, property, { - value: toComputed(virtualizerSignal, fn), - configurable: true, - enumerable: true, - }) + return (target[property] = computed( + () => inputSignal()[property as keyof TInput], + )) } - return untypedTarget[property] || virtualizer[property as keyof V] + // All other fields. Any field that is not handled above will fail if the signal includes + // input or model signals from a component and this is accessed before initialization. + return untracked(inputSignal)[property as keyof TInput] }, - has(_, property: string) { - return !!untracked(virtualizerSignal)[property as keyof V] + has(_, property: PropertyKey) { + return property in untracked(inputSignal) }, ownKeys() { - return Reflect.ownKeys(untracked(virtualizerSignal)) + return Reflect.ownKeys(untracked(inputSignal)) }, getOwnPropertyDescriptor() { return { @@ -86,32 +100,11 @@ export function proxyVirtualizer< configurable: true, } }, - }) as unknown as AngularVirtualizer -} - -function toComputed>( - signal: Signal, - fn: Function, -) { - const computedCache: Record> = {} - - return (...args: Array) => { - // Cache computeds by their arguments to avoid re-creating the computed on each call - const serializedArgs = serializeArgs(...args) - if (computedCache.hasOwnProperty(serializedArgs)) { - return computedCache[serializedArgs]?.() - } - const computedSignal = computed(() => { - void signal() - return fn(...args) - }) - - computedCache[serializedArgs] = computedSignal - - return computedSignal() - } -} - -function serializeArgs(...args: Array) { - return JSON.stringify(args) + }) as SignalProxy< + TInput, + TMethodsToPassThrough, + TAttributesToTransformToSignals, + TMethodsToTrack, + TMethodsToTransformToSignals + > } diff --git a/packages/angular-virtual/src/types.ts b/packages/angular-virtual/src/types.ts index 08c536cf7..2ffbd7268 100644 --- a/packages/angular-virtual/src/types.ts +++ b/packages/angular-virtual/src/types.ts @@ -15,7 +15,9 @@ export type AngularVirtualizer< | 'scrollElement' | 'scrollOffset' | 'scrollRect' + | 'measurementsCache' > & { + (): Virtualizer getTotalSize: Signal< ReturnType['getTotalSize']> > @@ -23,6 +25,9 @@ export type AngularVirtualizer< ReturnType['getVirtualItems']> > isScrolling: Signal['isScrolling']> + measurementsCache: Signal< + Virtualizer['measurementsCache'] + > options: Signal['options']> range: Signal['range']> scrollDirection: Signal< diff --git a/packages/angular-virtual/tsconfig.build.json b/packages/angular-virtual/tsconfig.build.json deleted file mode 100644 index 667ba09d2..000000000 --- a/packages/angular-virtual/tsconfig.build.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./node_modules/ng-packagr/lib/ts/conf/tsconfig.ngc.json", - "compilerOptions": { - "moduleResolution": "bundler", - "allowJs": true, - "moduleDetection": "force", - "module": "ESNext" - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true - }, - "include": ["src/**/*.ts"] -} diff --git a/packages/angular-virtual/tsconfig.json b/packages/angular-virtual/tsconfig.json index 3c5a067c2..d5844eca6 100644 --- a/packages/angular-virtual/tsconfig.json +++ b/packages/angular-virtual/tsconfig.json @@ -1,11 +1,5 @@ { "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "./build/lib" - }, - "angularCompilerOptions": { - "compilationMode": "partial" - }, - "include": ["src", "eslint.config.js"], + "include": ["src", "eslint.config.js", "vite.config.ts"], "exclude": ["**/*.spec.ts"] } diff --git a/packages/angular-virtual/vite.config.ts b/packages/angular-virtual/vite.config.ts new file mode 100644 index 000000000..cd9bdf7a8 --- /dev/null +++ b/packages/angular-virtual/vite.config.ts @@ -0,0 +1,20 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackViteConfig } from '@tanstack/vite-config' +import packageJson from './package.json' + +const config = defineConfig({ + test: { + name: packageJson.name, + dir: './tests', + watch: false, + environment: 'jsdom', + }, +}) + +export default mergeConfig( + config, + tanstackViteConfig({ + entry: './src/index.ts', + srcDir: './src', + }), +) diff --git a/packages/react-virtual/e2e/app/test/scroll.spec.ts b/packages/react-virtual/e2e/app/test/scroll.spec.ts index d7d1710ea..4e0506c4d 100644 --- a/packages/react-virtual/e2e/app/test/scroll.spec.ts +++ b/packages/react-virtual/e2e/app/test/scroll.spec.ts @@ -11,11 +11,11 @@ const check = () => { const scrollTop = container.scrollTop const top = itemRect.top + scrollTop - containerRect.top - const botttom = top + itemRect.height + const bottom = top + itemRect.height const containerBottom = scrollTop + container.clientHeight - return Math.abs(botttom - containerBottom) + return Math.abs(bottom - containerBottom) } test('scrolls to index 1000', async ({ page }) => { diff --git a/packages/virtual-core/tests/index.test.ts b/packages/virtual-core/tests/index.test.ts index 3134298f7..0d9495845 100644 --- a/packages/virtual-core/tests/index.test.ts +++ b/packages/virtual-core/tests/index.test.ts @@ -167,14 +167,18 @@ test('should not throw when component unmounts during scrollToIndex rAF loop', ( return rafCallbacks.length }) - const mockWindow = { - requestAnimationFrame: mockRaf, - cancelAnimationFrame: vi.fn(), - ResizeObserver: vi.fn(() => ({ + const MockResizeObserver = vi.fn(function () { + return { observe: vi.fn(), unobserve: vi.fn(), disconnect: vi.fn(), - })), + } + }) + + const mockWindow = { + requestAnimationFrame: mockRaf, + cancelAnimationFrame: vi.fn(), + ResizeObserver: MockResizeObserver, } const mockScrollElement = { @@ -333,15 +337,19 @@ function createMockEnvironment() { }) const mockCancelRaf = vi.fn() + const MockResizeObserver = vi.fn(function () { + return { + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn(), + } + }) + const mockWindow = { requestAnimationFrame: mockRaf, cancelAnimationFrame: mockCancelRaf, performance: { now: () => Date.now() }, - ResizeObserver: vi.fn(() => ({ - observe: vi.fn(), - unobserve: vi.fn(), - disconnect: vi.fn(), - })), + ResizeObserver: MockResizeObserver, } const mockScrollElement = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2400fdc7d..0aae59636 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,10 +19,10 @@ importers: version: 1.2.0(encoding@0.1.13) '@tanstack/eslint-config': specifier: 0.3.4 - version: 0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + version: 0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) '@tanstack/vite-config': - specifier: 0.3.0 - version: 0.3.0(@types/node@24.9.2)(rollup@4.52.5)(typescript@5.4.5)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + specifier: 0.4.3 + version: 0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.9.1 @@ -37,7 +37,7 @@ importers: version: 27.1.0 knip: specifier: ^5.63.1 - version: 5.66.4(@types/node@24.9.2)(typescript@5.4.5) + version: 5.66.4(@types/node@24.9.2)(typescript@5.6.3) markdown-link-extractor: specifier: ^4.0.2 version: 4.0.2 @@ -63,41 +63,41 @@ importers: specifier: ^0.2.15 version: 0.2.15 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vitest: - specifier: ^2.1.9 - version: 2.1.9(@types/node@24.9.2)(jsdom@27.1.0)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^4.1.4 + version: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) examples/angular/dynamic: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@faker-js/faker': specifier: ^8.4.1 version: 8.4.1 @@ -115,44 +115,44 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/fixed: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -167,47 +167,47 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/infinite-scroll: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-query-experimental': specifier: 5.80.7 - version: 5.80.7(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + version: 5.80.7(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -222,44 +222,44 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/padding: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -274,44 +274,44 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/smooth-scroll: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -326,44 +326,44 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/sticky: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@faker-js/faker': specifier: ^8.4.1 version: 8.4.1 @@ -381,50 +381,50 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/table: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@faker-js/faker': specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-table': specifier: 8.21.3 - version: 8.21.3(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + version: 8.21.3(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -439,44 +439,44 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/variable: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -491,44 +491,44 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/angular/window: dependencies: '@angular/animations': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/common': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: ^18.1.0 - version: 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20 '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^18.1.0 - version: 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-browser-dynamic': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))) '@angular/router': - specifier: ^18.1.0 - version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': specifier: ^4.0.13 version: link:../../../packages/angular-virtual @@ -543,17 +543,17 @@ importers: version: 0.15.1 devDependencies: '@angular-devkit/build-angular': - specifier: ^18.1.0 - version: 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': - specifier: ^18.1.0 - version: 18.2.21(chokidar@3.6.0) + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) '@angular/compiler-cli': - specifier: ^18.1.0 - version: 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 examples/lit/dynamic: dependencies: @@ -574,11 +574,11 @@ importers: specifier: ^24.5.2 version: 24.9.2 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/lit/fixed: dependencies: @@ -599,11 +599,11 @@ importers: specifier: ^24.5.2 version: 24.9.2 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/dynamic: dependencies: @@ -631,13 +631,13 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/fixed: dependencies: @@ -662,13 +662,13 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/infinite-scroll: dependencies: @@ -693,10 +693,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/padding: dependencies: @@ -718,10 +718,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/scroll-padding: dependencies: @@ -746,10 +746,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/smooth-scroll: dependencies: @@ -771,10 +771,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/sticky: dependencies: @@ -805,10 +805,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/table: dependencies: @@ -836,10 +836,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/variable: dependencies: @@ -861,10 +861,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/react/window: dependencies: @@ -889,13 +889,13 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/svelte/dynamic: dependencies: @@ -908,7 +908,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -917,16 +917,16 @@ importers: version: 4.2.20 svelte-check: specifier: ^4.2.1 - version: 4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5) + version: 4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3) tslib: specifier: ^2.8.1 version: 2.8.1 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/svelte/fixed: dependencies: @@ -936,7 +936,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -945,16 +945,16 @@ importers: version: 4.2.20 svelte-check: specifier: ^4.2.1 - version: 4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5) + version: 4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3) tslib: specifier: ^2.8.1 version: 2.8.1 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/svelte/infinite-scroll: dependencies: @@ -967,7 +967,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -976,16 +976,16 @@ importers: version: 4.2.20 svelte-check: specifier: ^4.2.1 - version: 4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5) + version: 4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3) tslib: specifier: ^2.8.1 version: 2.8.1 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/svelte/smooth-scroll: dependencies: @@ -998,7 +998,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -1007,16 +1007,16 @@ importers: version: 4.2.20 svelte-check: specifier: ^4.2.1 - version: 4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5) + version: 4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3) tslib: specifier: ^2.8.1 version: 2.8.1 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/svelte/sticky: dependencies: @@ -1032,7 +1032,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -1041,16 +1041,16 @@ importers: version: 4.2.20 svelte-check: specifier: ^4.2.1 - version: 4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5) + version: 4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3) tslib: specifier: ^2.8.1 version: 2.8.1 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/svelte/table: dependencies: @@ -1066,7 +1066,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -1075,16 +1075,16 @@ importers: version: 4.2.20 svelte-check: specifier: ^4.2.1 - version: 4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5) + version: 4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3) tslib: specifier: ^2.8.1 version: 2.8.1 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) examples/vue/dynamic: dependencies: @@ -1096,23 +1096,23 @@ importers: version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/fixed: dependencies: @@ -1121,51 +1121,51 @@ importers: version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/infinite-scroll: dependencies: '@tanstack/vue-query': specifier: ^5.80.7 - version: 5.90.5(vue@3.5.22(typescript@5.4.5)) + version: 5.90.5(vue@3.5.22(typescript@5.6.3)) '@tanstack/vue-virtual': specifier: ^3.13.24 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/padding: dependencies: @@ -1174,23 +1174,23 @@ importers: version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/scroll-padding: dependencies: @@ -1199,26 +1199,26 @@ importers: version: link:../../../packages/vue-virtual '@vueuse/core': specifier: ^12.8.2 - version: 12.8.2(typescript@5.4.5) + version: 12.8.2(typescript@5.6.3) vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/smooth-scroll: dependencies: @@ -1227,23 +1227,23 @@ importers: version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/sticky: dependencies: @@ -1258,7 +1258,7 @@ importers: version: 4.17.21 vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 @@ -1268,16 +1268,16 @@ importers: version: 4.17.20 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/table: dependencies: @@ -1286,29 +1286,29 @@ importers: version: 8.4.1 '@tanstack/vue-table': specifier: ^8.21.3 - version: 8.21.3(vue@3.5.22(typescript@5.4.5)) + version: 8.21.3(vue@3.5.22(typescript@5.6.3)) '@tanstack/vue-virtual': specifier: ^3.13.24 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) examples/vue/variable: dependencies: @@ -1317,42 +1317,60 @@ importers: version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) devDependencies: '@codesandbox/vue-preview': specifier: ^0.1.1-alpha.16 version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 vite: - specifier: ^5.4.19 - version: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 - version: 2.2.12(typescript@5.4.5) + version: 2.2.12(typescript@5.6.3) packages/angular-virtual: dependencies: '@tanstack/virtual-core': specifier: workspace:* version: link:../virtual-core + devDependencies: + '@angular-devkit/build-angular': + specifier: ^19.0.0 + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + '@angular/cli': + specifier: ^19.0.0 + version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) + '@angular/common': + specifier: ^19.0.0 + version: 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/compiler-cli': + specifier: ^19.0.0 + version: 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) + '@angular/core': + specifier: ^19.0.0 + version: 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': + specifier: ^19.0.0 + version: 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/router': + specifier: ^19.0.0 + version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) tslib: specifier: ^2.8.1 version: 2.8.1 - devDependencies: - '@angular/core': - specifier: ^18.1.0 - version: 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) - ng-packagr: - specifier: ^18.1.0 - version: 18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.6.3 + version: 5.6.3 + zone.js: + specifier: 0.15.1 + version: 0.15.1 packages/lit-virtual: dependencies: @@ -1384,7 +1402,7 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) react: specifier: ^18.3.1 version: 18.3.1 @@ -1406,7 +1424,7 @@ importers: version: 1.9.10 vite-plugin-solid: specifier: ^2.11.6 - version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) packages/svelte-virtual: dependencies: @@ -1416,10 +1434,10 @@ importers: devDependencies: '@sveltejs/package': specifier: ^2.3.11 - version: 2.5.4(svelte@4.2.20)(typescript@5.4.5) + version: 2.5.4(svelte@4.2.20)(typescript@5.6.3) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) svelte: specifier: ^4.2.20 version: 4.2.20 @@ -1434,10 +1452,10 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) vue: specifier: ^3.5.16 - version: 3.5.22(typescript@5.4.5) + version: 3.5.22(typescript@5.6.3) packages: @@ -1451,27 +1469,28 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular-devkit/architect@0.1802.21': - resolution: {integrity: sha512-+Ll+xtpKwZ3iLWN/YypvnCZV/F0MVbP+/7ZpMR+Xv/uB0OmribhBVj9WGaCd9I/bGgoYBw8wBV/NFNCKkf0k3Q==} + '@angular-devkit/architect@0.1902.24': + resolution: {integrity: sha512-G63tV2EW15xCWfDhFYwLc1MWu2UbY6M+JaRfDr8NxwP9PZJyIkGHA9YUhnx+35x7aNb52sTPDW0uY4ukhOvYFg==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular-devkit/build-angular@18.2.21': - resolution: {integrity: sha512-0pJfURFpEUV2USgZ2TL3nNAaJmF9bICx9OVddBoC+F9FeOpVKxkcVIb+c8Km5zHFo1iyVtPZ6Rb25vFk9Zm/ug==} + '@angular-devkit/build-angular@19.2.24': + resolution: {integrity: sha512-foSat36hPfGyrQnKSlvynTWY2HBVc2nEF/Tx3C0Yv+aVmMePBzrONiHs67yXB7C6rrYvrJtQuy+nAPvEOBV/0A==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: - '@angular/compiler-cli': ^18.0.0 - '@angular/localize': ^18.0.0 - '@angular/platform-server': ^18.0.0 - '@angular/service-worker': ^18.0.0 - '@web/test-runner': ^0.18.0 + '@angular/compiler-cli': ^19.0.0 || ^19.2.0-next.0 + '@angular/localize': ^19.0.0 || ^19.2.0-next.0 + '@angular/platform-server': ^19.0.0 || ^19.2.0-next.0 + '@angular/service-worker': ^19.0.0 || ^19.2.0-next.0 + '@angular/ssr': ^19.2.24 + '@web/test-runner': ^0.20.0 browser-sync: ^3.0.2 jest: ^29.5.0 jest-environment-jsdom: ^29.5.0 karma: ^6.3.0 - ng-packagr: ^18.0.0 + ng-packagr: ^19.0.0 || ^19.2.0-next.0 protractor: ^7.0.0 - tailwindcss: ^2.0.0 || ^3.0.0 - typescript: '>=5.4 <5.6' + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + typescript: '>=5.5 <5.9' peerDependenciesMeta: '@angular/localize': optional: true @@ -1479,6 +1498,8 @@ packages: optional: true '@angular/service-worker': optional: true + '@angular/ssr': + optional: true '@web/test-runner': optional: true browser-sync: @@ -1496,44 +1517,49 @@ packages: tailwindcss: optional: true - '@angular-devkit/build-webpack@0.1802.21': - resolution: {integrity: sha512-2jSVRhA3N4Elg8OLcBktgi+CMSjlAm/bBQJE6TQYbdQWnniuT7JAWUHA/iPf7MYlQE5qj4rnAni1CI/c1Bk4HQ==} + '@angular-devkit/build-webpack@0.1902.24': + resolution: {integrity: sha512-txDA1cbmsD5+mcw74JCh0UiSZQKQzcDalkqPYpSA+9/uFGUSULSonlyCmg5UpyrpiOzM5ACI/++qJ1g52TqWWA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: webpack: ^5.30.0 webpack-dev-server: ^5.0.2 - '@angular-devkit/core@18.2.21': - resolution: {integrity: sha512-Lno6GNbJME85wpc/uqn+wamBxvfZJZFYSH8+oAkkyjU/hk8r5+X8DuyqsKAa0m8t46zSTUsonHsQhVe5vgrZeQ==} + '@angular-devkit/core@19.2.24': + resolution: {integrity: sha512-Kd49warf6U/EyWe5BszF/eebN3zQ3bk7tgfEljAw8q/rX95UUtriJubWvp6pgzHfzBA4jwq8f+QiNZB8eBEXPA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: - chokidar: ^3.5.2 + chokidar: ^4.0.0 peerDependenciesMeta: chokidar: optional: true - '@angular-devkit/schematics@18.2.21': - resolution: {integrity: sha512-yuC2vN4VL48JhnsaOa9J/o0Jl+cxOklRNQp5J2/ypMuRROaVCrZAPiX+ChSHh++kHYMpj8+ggNrrUwRNfMKACQ==} + '@angular-devkit/schematics@19.2.24': + resolution: {integrity: sha512-lnw+ZM1Io+cJAkReC0NPDjqObL8NtKzKIkdgEEKC8CUmkhurYhedbicN8Y8NYHgG1uLd2GozW3+/QqPRZaN+Lw==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular/animations@18.2.14': - resolution: {integrity: sha512-Kp/MWShoYYO+R3lrrZbZgszbbLGVXHB+39mdJZwnIuZMDkeL3JsIBlSOzyJRTnpS1vITc+9jgHvP/6uKbMrW1Q==} + '@angular/animations@19.2.20': + resolution: {integrity: sha512-TQ4OCazTRAge45FIp3bzO/chImObmasPzprgEzKSDckjGbshAWlYXeCe3U8YaGNaWnkzByyIRNV4P4aHe63M0w==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: - '@angular/core': 18.2.14 + '@angular/common': 19.2.20 + '@angular/core': 19.2.20 - '@angular/build@18.2.21': - resolution: {integrity: sha512-uvq3qP4cByJrUkV1ri0v3x6LxOFt4fDKiQdNwbQAqdxtfRs3ssEIoCGns4t89sTWXv6VZWBNDcDIKK9/Fa9mmg==} + '@angular/build@19.2.24': + resolution: {integrity: sha512-/Z6Ka0+xpmSXz5KHP94iRO5R1ZwbcJfj7Q7k/d6QH5Wk8rVFIoI/3a9nmLewjR/CxW8QaiziPYQpG1ezRgj9hQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: - '@angular/compiler-cli': ^18.0.0 - '@angular/localize': ^18.0.0 - '@angular/platform-server': ^18.0.0 - '@angular/service-worker': ^18.0.0 + '@angular/compiler': ^19.0.0 || ^19.2.0-next.0 + '@angular/compiler-cli': ^19.0.0 || ^19.2.0-next.0 + '@angular/localize': ^19.0.0 || ^19.2.0-next.0 + '@angular/platform-server': ^19.0.0 || ^19.2.0-next.0 + '@angular/service-worker': ^19.0.0 || ^19.2.0-next.0 + '@angular/ssr': ^19.2.24 + karma: ^6.4.0 less: ^4.2.0 + ng-packagr: ^19.0.0 || ^19.2.0-next.0 postcss: ^8.4.0 - tailwindcss: ^2.0.0 || ^3.0.0 - typescript: '>=5.4 <5.6' + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + typescript: '>=5.5 <5.9' peerDependenciesMeta: '@angular/localize': optional: true @@ -1541,85 +1567,86 @@ packages: optional: true '@angular/service-worker': optional: true + '@angular/ssr': + optional: true + karma: + optional: true less: optional: true + ng-packagr: + optional: true postcss: optional: true tailwindcss: optional: true - '@angular/cli@18.2.21': - resolution: {integrity: sha512-efweY4p8awRTbHs+HKdg6s44hl7Y0gdVlXYi3HeY8Z5JDC0abbka0K6sA/MrV9AXvn/5ovxYbxiL3AsOApjTpg==} + '@angular/cli@19.2.24': + resolution: {integrity: sha512-HjU4r/Va9w868fKVeUNOgkHBVDQc2VFHWxj0I3WekGhYN3dlfTVNn0/3dNutkBBuCxxTb9Xl6E6wf6KrlA9wcQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular/common@18.2.14': - resolution: {integrity: sha512-ZPRswzaVRiqcfZoowuAM22Hr2/z10ajWOUoFDoQ9tWqz/fH/773kJv2F9VvePIekgNPCzaizqv9gF6tGNqaAwg==} + '@angular/common@19.2.20': + resolution: {integrity: sha512-1M3W3FjUUbVKXDMs+yQpBhnkD/pCe0Jn79rPE5W+EGWWxFoLSyGX+fhnRO5m4c9k66p3nvYrikWQ0ZzMv3M5tw==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: - '@angular/core': 18.2.14 + '@angular/core': 19.2.20 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@18.2.14': - resolution: {integrity: sha512-BmmjyrFSBSYkm0tBSqpu4cwnJX/b/XvhM36mj2k8jah3tNS5zLDDx5w6tyHmaPJa/1D95MlXx2h6u7K9D+Mhew==} + '@angular/compiler-cli@19.2.20': + resolution: {integrity: sha512-tYYQk8AUz2sEkVl0a3uebduDUXPuKiGEKl2Jryrbn0xh9i1EsxoCjt1VvHnGnksGp3mz4DQihFVEnte0KeVQ5g==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} hasBin: true peerDependencies: - '@angular/compiler': 18.2.14 - typescript: '>=5.4 <5.6' + '@angular/compiler': 19.2.20 + typescript: '>=5.5 <5.9' - '@angular/compiler@18.2.14': - resolution: {integrity: sha512-Mpq3v/mztQzGAQAAFV+wAI1hlXxZ0m8eDBgaN2kD3Ue+r4S6bLm1Vlryw0iyUnt05PcFIdxPT6xkcphq5pl6lw==} + '@angular/compiler@19.2.20': + resolution: {integrity: sha512-LvjE8W58EACgTFaAoqmNe7FRsbvoQ0GvCB/rmm6AEMWx/0W/JBvWkQTrOQlwpoeYOHcMZRGdmPcZoUDwU3JySQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} - peerDependencies: - '@angular/core': 18.2.14 - peerDependenciesMeta: - '@angular/core': - optional: true - '@angular/core@18.2.14': - resolution: {integrity: sha512-BIPrCs93ZZTY9ym7yfoTgAQ5rs706yoYeAdrgc8kh/bDbM9DawxKlgeKBx2FLt09Y0YQ1bFhKVp0cV4gDEaMxQ==} + '@angular/core@19.2.20': + resolution: {integrity: sha512-pxzQh8ouqfE57lJlXjIzXFuRETwkfMVwS+NFCfv2yh01Qtx+vymO8ZClcJMgLPfBYinhBYX+hrRYVSa1nzlkRQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: rxjs: ^6.5.3 || ^7.4.0 - zone.js: ~0.14.10 + zone.js: ~0.15.0 - '@angular/forms@18.2.14': - resolution: {integrity: sha512-fZVwXctmBJa5VdopJae/T9MYKPXNd04+6j4k/6X819y+9fiyWLJt2QicSc5Rc+YD9mmhXag3xaljlrnotf9VGA==} + '@angular/forms@19.2.20': + resolution: {integrity: sha512-agi7InbMzop1jrud6L7SlNwnZk3iNolORcFIwBQMvKxLkcJ+ttbSYuM0KAw56IundWHf4dL9GP4cSygm4kUeFA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: - '@angular/common': 18.2.14 - '@angular/core': 18.2.14 - '@angular/platform-browser': 18.2.14 + '@angular/common': 19.2.20 + '@angular/core': 19.2.20 + '@angular/platform-browser': 19.2.20 rxjs: ^6.5.3 || ^7.4.0 - '@angular/platform-browser-dynamic@18.2.14': - resolution: {integrity: sha512-QOv+o89u8HLN0LG8faTIVHKBxfkOBHVDB0UuXy19+HJofWZGGvho+vGjV0/IAkhZnMC4Sxdoy/mOHP2ytALX3A==} + '@angular/platform-browser-dynamic@19.2.20': + resolution: {integrity: sha512-bNuykQy/MrDeARqvDPf6bqx+m1Qqanep7FhDy9QYWxfqz7D++/phqT9l8Ubj88juFCSDfR5ktUWdpnDz3/BCfA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: - '@angular/common': 18.2.14 - '@angular/compiler': 18.2.14 - '@angular/core': 18.2.14 - '@angular/platform-browser': 18.2.14 + '@angular/common': 19.2.20 + '@angular/compiler': 19.2.20 + '@angular/core': 19.2.20 + '@angular/platform-browser': 19.2.20 - '@angular/platform-browser@18.2.14': - resolution: {integrity: sha512-W+JTxI25su3RiZVZT3Yrw6KNUCmOIy7OZIZ+612skPgYK2f2qil7VclnW1oCwG896h50cMJU/lnAfxZxefQgyQ==} + '@angular/platform-browser@19.2.20': + resolution: {integrity: sha512-O9ZoQKILPC1T2c64OASS75XlOLBxY81m5AAgsBKhwiFWq+V28RsO0cnwpi1YSh/z4ryH8Fe7IUFz8jGrsJi3hQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: - '@angular/animations': 18.2.14 - '@angular/common': 18.2.14 - '@angular/core': 18.2.14 + '@angular/animations': 19.2.20 + '@angular/common': 19.2.20 + '@angular/core': 19.2.20 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/router@18.2.14': - resolution: {integrity: sha512-v/gweh8MBjjDfh1QssuyjISa+6SVVIvIZox7MaMs81RkaoVHwS9grDtPud1pTKHzms2KxSVpvwwyvkRJQplueg==} + '@angular/router@19.2.20': + resolution: {integrity: sha512-y0fyKycxJHr82kxXKE50Vac5hPn5Kx3gw9CfqyEuwJ9VQzEixDljU+chrQK4Wods14jJn9Tt2ncNPGH1rLya3Q==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} peerDependencies: - '@angular/common': 18.2.14 - '@angular/core': 18.2.14 - '@angular/platform-browser': 18.2.14 + '@angular/common': 19.2.20 + '@angular/core': 19.2.20 + '@angular/platform-browser': 19.2.20 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@4.0.5': @@ -1639,14 +1666,14 @@ packages: resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} - '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} - engines: {node: '>=6.9.0'} - '@babel/core@7.26.10': resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} + '@babel/core@7.26.9': + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} @@ -1659,10 +1686,6 @@ packages: resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.24.7': - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} - engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} @@ -1809,8 +1832,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2276,8 +2299,8 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@discoveryjs/json-ext@0.6.1': - resolution: {integrity: sha512-boghen8F0Q8D+0/Q1/1r6DUEieUJ8w2a1gIknExMSHBsJFOr2+0KUfHiVYBvucPwl3+RU5PFBK833FjFCh3BhA==} + '@discoveryjs/json-ext@0.6.3': + resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} '@emnapi/core@1.6.0': @@ -2289,428 +2312,308 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.23.1': - resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.23.1': - resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.23.1': - resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.23.1': - resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.23.1': - resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.23.1': - resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.23.1': - resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.23.1': - resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.23.1': - resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.23.1': - resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.23.1': - resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.23.1': - resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.23.1': - resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.23.1': - resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.23.1': - resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.23.1': - resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.23.1': - resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} engines: {node: '>=18'} - cpu: [x64] - os: [linux] + cpu: [arm64] + os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.23.1': - resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.23.1': - resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.23.1': - resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] - '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.23.1': - resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.23.1': - resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.23.1': - resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.23.1': - resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -2779,29 +2682,63 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/checkbox@2.5.0': - resolution: {integrity: sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==} + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} - '@inquirer/confirm@3.1.22': - resolution: {integrity: sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==} + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/confirm@3.2.0': - resolution: {integrity: sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==} + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@5.1.6': + resolution: {integrity: sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/core@9.2.1': - resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==} + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/editor@2.2.0': - resolution: {integrity: sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw==} + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/expand@2.3.0': - resolution: {integrity: sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw==} + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true '@inquirer/external-editor@1.0.2': resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} @@ -2812,45 +2749,94 @@ packages: '@types/node': optional: true - '@inquirer/figures@1.0.14': - resolution: {integrity: sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/input@2.3.0': - resolution: {integrity: sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw==} + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} - '@inquirer/number@1.1.0': - resolution: {integrity: sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA==} + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/password@2.2.0': - resolution: {integrity: sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg==} + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/prompts@5.3.8': - resolution: {integrity: sha512-b2BudQY/Si4Y2a0PdZZL6BeJtl8llgeZa7U2j47aaJSCeAl1e4UI7y8a9bSkO3o/ZbZrgT5muy/34JbsjfIWxA==} + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/rawlist@2.3.0': - resolution: {integrity: sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ==} + '@inquirer/prompts@7.3.2': + resolution: {integrity: sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/search@1.1.0': - resolution: {integrity: sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ==} + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/select@2.5.0': - resolution: {integrity: sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==} + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true '@inquirer/type@1.5.5': resolution: {integrity: sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==} engines: {node: '>=18'} - '@inquirer/type@2.0.0': - resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} @@ -2864,6 +2850,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} @@ -2938,11 +2928,11 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@listr2/prompt-adapter-inquirer@2.0.15': - resolution: {integrity: sha512-MZrGem/Ujjd4cPTLYDfCZK2iKKeiO/8OX13S6jqxldLs0Prf2aGqVlJ77nMBqMv7fzqgXEgjrNHLXcKR8l9lOg==} + '@listr2/prompt-adapter-inquirer@2.0.18': + resolution: {integrity: sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==} engines: {node: '>=18.0.0'} peerDependencies: - '@inquirer/prompts': '>= 3 < 6' + '@inquirer/prompts': '>= 3 < 8' '@lit-labs/ssr-dom-shim@1.4.0': resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} @@ -2950,33 +2940,33 @@ packages: '@lit/reactive-element@2.1.1': resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} - '@lmdb/lmdb-darwin-arm64@3.0.13': - resolution: {integrity: sha512-uiKPB0Fv6WEEOZjruu9a6wnW/8jrjzlZbxXscMB8kuCJ1k6kHpcBnuvaAWcqhbI7rqX5GKziwWEdD+wi2gNLfA==} + '@lmdb/lmdb-darwin-arm64@3.2.6': + resolution: {integrity: sha512-yF/ih9EJJZc72psFQbwnn8mExIWfTnzWJg+N02hnpXtDPETYLmQswIMBn7+V88lfCaFrMozJsUvcEQIkEPU0Gg==} cpu: [arm64] os: [darwin] - '@lmdb/lmdb-darwin-x64@3.0.13': - resolution: {integrity: sha512-bEVIIfK5mSQoG1R19qA+fJOvCB+0wVGGnXHT3smchBVahYBdlPn2OsZZKzlHWfb1E+PhLBmYfqB5zQXFP7hJig==} + '@lmdb/lmdb-darwin-x64@3.2.6': + resolution: {integrity: sha512-5BbCumsFLbCi586Bb1lTWQFkekdQUw8/t8cy++Uq251cl3hbDIGEwD9HAwh8H6IS2F6QA9KdKmO136LmipRNkg==} cpu: [x64] os: [darwin] - '@lmdb/lmdb-linux-arm64@3.0.13': - resolution: {integrity: sha512-afbVrsMgZ9dUTNUchFpj5VkmJRxvht/u335jUJ7o23YTbNbnpmXif3VKQGCtnjSh+CZaqm6N3CPG8KO3zwyZ1Q==} + '@lmdb/lmdb-linux-arm64@3.2.6': + resolution: {integrity: sha512-l5VmJamJ3nyMmeD1ANBQCQqy7do1ESaJQfKPSm2IG9/ADZryptTyCj8N6QaYgIWewqNUrcbdMkJajRQAt5Qjfg==} cpu: [arm64] os: [linux] - '@lmdb/lmdb-linux-arm@3.0.13': - resolution: {integrity: sha512-Yml1KlMzOnXj/tnW7yX8U78iAzTk39aILYvCPbqeewAq1kSzl+w59k/fiVkTBfvDi/oW/5YRxL+Fq+Y1Fr1r2Q==} + '@lmdb/lmdb-linux-arm@3.2.6': + resolution: {integrity: sha512-+6XgLpMb7HBoWxXj+bLbiiB4s0mRRcDPElnRS3LpWRzdYSe+gFk5MT/4RrVNqd2MESUDmb53NUXw1+BP69bjiQ==} cpu: [arm] os: [linux] - '@lmdb/lmdb-linux-x64@3.0.13': - resolution: {integrity: sha512-vOtxu0xC0SLdQ2WRXg8Qgd8T32ak4SPqk5zjItRszrJk2BdeXqfGxBJbP7o4aOvSPSmSSv46Lr1EP4HXU8v7Kg==} + '@lmdb/lmdb-linux-x64@3.2.6': + resolution: {integrity: sha512-nDYT8qN9si5+onHYYaI4DiauDMx24OAiuZAUsEqrDy+ja/3EbpXPX/VAkMV8AEaQhy3xc4dRC+KcYIvOFefJ4Q==} cpu: [x64] os: [linux] - '@lmdb/lmdb-win32-x64@3.0.13': - resolution: {integrity: sha512-UCrMJQY/gJnOl3XgbWRZZUvGGBuKy6i0YNSptgMzHBjs+QYDYR1Mt/RLTOPy4fzzves65O1EDmlL//OzEqoLlA==} + '@lmdb/lmdb-win32-x64@3.2.6': + resolution: {integrity: sha512-XlqVtILonQnG+9fH2N3Aytria7P/1fwDgDhl29rde96uH2sLB8CHORIf2PfuLVzFQJ7Uqp8py9AYwr3ZUCFfWg==} cpu: [x64] os: [win32] @@ -3144,12 +3134,12 @@ packages: '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} - '@ngtools/webpack@18.2.21': - resolution: {integrity: sha512-mfLT7lXbyJRlsazuPyuF5AGsMcgzRJRwsDlgxFbiy1DBlaF1chRFsXrKYj1gQ/WXQWNcEd11aedU0Rt+iCNDVw==} + '@ngtools/webpack@19.2.24': + resolution: {integrity: sha512-lDWjW4lFwT0vbniJG7ziaDC2bX7rj8e4Fa59TpSLNHEjuPvK5chOTgT0+L63fEdfTfHoTy+ohAK1158UBXWt7g==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: - '@angular/compiler-cli': ^18.0.0 - typescript: '>=5.4 <5.6' + '@angular/compiler-cli': ^19.0.0 || ^19.2.0-next.0 + typescript: '>=5.5 <5.9' webpack: ^5.54.0 '@nodelib/fs.scandir@2.1.5': @@ -3164,42 +3154,42 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@2.2.2': - resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/agent@3.0.0': + resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/fs@3.1.1': - resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@npmcli/fs@4.0.0': + resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/git@5.0.8': - resolution: {integrity: sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/git@6.0.3': + resolution: {integrity: sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/installed-package-contents@2.1.0': - resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@npmcli/installed-package-contents@3.0.0': + resolution: {integrity: sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true - '@npmcli/node-gyp@3.0.0': - resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@npmcli/node-gyp@4.0.0': + resolution: {integrity: sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/package-json@5.2.1': - resolution: {integrity: sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/package-json@6.2.0': + resolution: {integrity: sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/promise-spawn@7.0.2': - resolution: {integrity: sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/promise-spawn@8.0.3': + resolution: {integrity: sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/redact@2.0.1': - resolution: {integrity: sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/redact@3.2.2': + resolution: {integrity: sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/run-script@8.1.0': - resolution: {integrity: sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/run-script@9.1.0': + resolution: {integrity: sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==} + engines: {node: ^18.17.0 || >=20.5.0} '@nx/nx-darwin-arm64@22.1.3': resolution: {integrity: sha512-4D/jXGsr3jcQ0vBo8aXXZMdfmC3n4OsZ1zjFaOXlF62Ujug+RqI/IvKxycT9r7Lr09PmW2OqBC01NfIWKoBLhg==} @@ -3479,15 +3469,6 @@ packages: rollup: optional: true - '@rollup/plugin-node-resolve@15.3.1': - resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -3497,193 +3478,128 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.22.4': - resolution: {integrity: sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.52.5': - resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.22.4': - resolution: {integrity: sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-android-arm64@4.52.5': - resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.22.4': - resolution: {integrity: sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-arm64@4.52.5': - resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.22.4': - resolution: {integrity: sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.52.5': - resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.5': - resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.5': - resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.22.4': - resolution: {integrity: sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-gnueabihf@4.52.5': - resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.22.4': - resolution: {integrity: sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==} + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.5': - resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.22.4': - resolution: {integrity: sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.52.5': - resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.22.4': - resolution: {integrity: sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==} + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.5': - resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} - cpu: [arm64] + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.5': - resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.22.4': - resolution: {integrity: sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==} + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.5': - resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.22.4': - resolution: {integrity: sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.52.5': - resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.5': - resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.22.4': - resolution: {integrity: sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.5': - resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.22.4': - resolution: {integrity: sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.52.5': - resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.22.4': - resolution: {integrity: sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==} + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.5': - resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} cpu: [x64] - os: [linux] + os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.52.5': - resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.22.4': - resolution: {integrity: sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==} + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.52.5': - resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.22.4': - resolution: {integrity: sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.52.5': - resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.5': - resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.22.4': - resolution: {integrity: sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.52.5': - resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] @@ -3714,33 +3630,33 @@ packages: '@rushstack/ts-command-line@4.22.6': resolution: {integrity: sha512-QSRqHT/IfoC5nk9zn6+fgyqOPXHME0BfchII9EUPR19pocsNp/xSbeBCbD3PIR2Lg+Q5qk7OFqk1VhWPMdKHJg==} - '@schematics/angular@18.2.21': - resolution: {integrity: sha512-5Ai+NEflQZi67y4NsQ3o04iEp7zT0/BUFVCrJ3CueU3uYQGs8jrN1Lk6tvQ9c5HzGcTDrMXuTrCswyR9o6ecpA==} + '@schematics/angular@19.2.24': + resolution: {integrity: sha512-RGHb7ebUQTOxtWfNcBXCzDog8LwJzvVp3/BptEI+78M+tCaBJM6BAS2vrDphJRjVbjV3DTwZcmlNRqCHJeSknA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@sigstore/bundle@2.3.2': - resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} - engines: {node: ^16.14.0 || >=18.0.0} + '@sigstore/bundle@3.1.0': + resolution: {integrity: sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==} + engines: {node: ^18.17.0 || >=20.5.0} - '@sigstore/core@1.1.0': - resolution: {integrity: sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==} - engines: {node: ^16.14.0 || >=18.0.0} + '@sigstore/core@2.0.0': + resolution: {integrity: sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==} + engines: {node: ^18.17.0 || >=20.5.0} - '@sigstore/protobuf-specs@0.3.3': - resolution: {integrity: sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==} + '@sigstore/protobuf-specs@0.4.3': + resolution: {integrity: sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==} engines: {node: ^18.17.0 || >=20.5.0} - '@sigstore/sign@2.3.2': - resolution: {integrity: sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==} - engines: {node: ^16.14.0 || >=18.0.0} + '@sigstore/sign@3.1.0': + resolution: {integrity: sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==} + engines: {node: ^18.17.0 || >=20.5.0} - '@sigstore/tuf@2.3.4': - resolution: {integrity: sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==} - engines: {node: ^16.14.0 || >=18.0.0} + '@sigstore/tuf@3.1.1': + resolution: {integrity: sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==} + engines: {node: ^18.17.0 || >=20.5.0} - '@sigstore/verify@1.2.1': - resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==} - engines: {node: ^16.14.0 || >=18.0.0} + '@sigstore/verify@2.1.1': + resolution: {integrity: sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==} + engines: {node: ^18.17.0 || >=20.5.0} '@sinclair/typebox@0.34.41': resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} @@ -3749,6 +3665,9 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@stylistic/eslint-plugin@5.5.0': resolution: {integrity: sha512-IeZF+8H0ns6prg4VrkhgL+yrvDXWDH2cKchrbh80ejG9dQgZWp10epHMbgRuQvgchLII/lfh6Xn3lu6+6L86Hw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3842,9 +3761,11 @@ packages: resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} engines: {node: '>=12'} - '@tanstack/vite-config@0.3.0': - resolution: {integrity: sha512-p1HuuSD3OUoVMYHfjkzUJqVBUurp1BDrGwT3302GRpSjpBHiJvZex3+NzRIXdG9NdjeJ0mT7DYpNMoii7GVROQ==} + '@tanstack/vite-config@0.4.3': + resolution: {integrity: sha512-bqXfdPmD6DuAZdE08ih5bSqpcge9Im9nEym3CKcQ9OsPo0jmGW7WrJarLaoVB6qWEysh3FIwWQN1gtfeC7q8UQ==} engines: {node: '>=18'} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 '@tanstack/vue-query@5.90.5': resolution: {integrity: sha512-bTEmgIb6o5BqkoJPNV7ZKKsDHjiVnNydORw1n6S/x0dppb3lTT5KFOotQ5PqZG3OQY+9AwA6RJJN3pEx+9j1Pg==} @@ -3891,9 +3812,9 @@ packages: resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} engines: {node: ^16.14.0 || >=18.0.0} - '@tufjs/models@2.0.1': - resolution: {integrity: sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==} - engines: {node: ^16.14.0 || >=18.0.0} + '@tufjs/models@3.0.1': + resolution: {integrity: sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==} + engines: {node: ^18.17.0 || >=20.5.0} '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -3964,8 +3885,11 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -4018,18 +3942,12 @@ packages: '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/mute-stream@0.0.4': - resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} - '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@22.18.13': - resolution: {integrity: sha512-Bo45YKIjnmFtv6I1TuC8AaHBbqXtIo+Om5fE4QiU1Tj8QR/qt+8O3BAtOimG5IFmwaWiPmB3Mv3jtYzBA4Us2A==} - '@types/node@24.9.2': resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==} @@ -4053,9 +3971,6 @@ packages: '@types/react@18.3.26': resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} @@ -4089,9 +4004,6 @@ packages: '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} - '@types/wrap-ansi@3.0.0': - resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} - '@types/ws@7.4.7': resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} @@ -4256,11 +4168,11 @@ packages: resolution: {integrity: sha512-XKIlF1i6UJiyTL52mDrSDDgRX7Qr5yJ7ts9zn2liZEmhiAEum4XKrJRAWmHdFwCQeGBU+rb+/b0ldw/9V8lOWw==} engines: {node: '>=18'} - '@vitejs/plugin-basic-ssl@1.1.0': - resolution: {integrity: sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==} - engines: {node: '>=14.6.0'} + '@vitejs/plugin-basic-ssl@1.2.0': + resolution: {integrity: sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==} + engines: {node: '>=14.21.3'} peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} @@ -4275,34 +4187,34 @@ packages: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 - '@vitest/expect@2.1.9': - resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + '@vitest/expect@4.1.4': + resolution: {integrity: sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==} - '@vitest/mocker@2.1.9': - resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + '@vitest/mocker@4.1.4': + resolution: {integrity: sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + '@vitest/pretty-format@4.1.4': + resolution: {integrity: sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==} - '@vitest/runner@2.1.9': - resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + '@vitest/runner@4.1.4': + resolution: {integrity: sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==} - '@vitest/snapshot@2.1.9': - resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + '@vitest/snapshot@4.1.4': + resolution: {integrity: sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==} - '@vitest/spy@2.1.9': - resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + '@vitest/spy@4.1.4': + resolution: {integrity: sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==} - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + '@vitest/utils@4.1.4': + resolution: {integrity: sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==} '@volar/language-core@2.4.15': resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==} @@ -4464,18 +4376,19 @@ packages: resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true - abbrev@2.0.0: - resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - acorn-import-attributes@1.9.5: - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} peerDependencies: - acorn: ^8 + acorn: ^8.14.0 acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -4495,10 +4408,6 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - ajv-draft-04@1.0.0: resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} peerDependencies: @@ -4523,11 +4432,6 @@ packages: ajv: optional: true - ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - ajv-keywords@5.1.0: resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: @@ -4545,6 +4449,9 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + alien-signals@1.0.13: resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} @@ -4638,8 +4545,8 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - babel-loader@9.1.3: - resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==} + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} engines: {node: '>= 14.15.0'} peerDependencies: '@babel/core': ^7.12.0 @@ -4680,6 +4587,11 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.10.18: + resolution: {integrity: sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==} + engines: {node: '>=6.0.0'} + hasBin: true + baseline-browser-mapping@2.8.22: resolution: {integrity: sha512-/tk9kky/d8T8CTXIQYASLyhAxR5VwL3zct1oAoVTaOUHwrmsGnfbRwNdEq+vOl2BN8i3PcDdP0o4Q+jjKQoFbQ==} hasBin: true @@ -4687,6 +4599,10 @@ packages: batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + beasties@0.3.2: + resolution: {integrity: sha512-p4AF8uYzm9Fwu8m/hSVTCPXrRBPmB34hQpHsec2KOaR9CZmgoU8IOv4Cvwq4hgz2p4hLMNbsdNl5XeA6XbAQwA==} + engines: {node: '>=14.0.0'} + better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -4729,6 +4645,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -4743,13 +4664,9 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - cacache@18.0.4: - resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==} - engines: {node: ^16.14.0 || >=18.0.0} + cacache@19.0.1: + resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} + engines: {node: ^18.17.0 || >=20.5.0} cache-content-type@1.0.1: resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} @@ -4770,27 +4687,23 @@ packages: caniuse-lite@1.0.30001752: resolution: {integrity: sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g==} + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + chai-a11y-axe@1.5.0: resolution: {integrity: sha512-V/Vg/zJDr9aIkaHJ2KQu7lGTQQm5ZOH4u1k5iTMvIXuSVlSuUo0jcSpSqf9wUn9zl6oQXa4e4E0cqH18KOgKlQ==} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -4810,14 +4723,14 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -4883,8 +4796,8 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} commander@2.20.3: @@ -4973,10 +4886,6 @@ packages: typescript: optional: true - critters@0.0.24: - resolution: {integrity: sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==} - deprecated: Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -5067,10 +4976,6 @@ packages: dedent-js@1.0.1: resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - deep-equal@1.0.1: resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==} @@ -5203,6 +5108,9 @@ packages: electron-to-chromium@1.5.244: resolution: {integrity: sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==} + electron-to-chromium@1.5.336: + resolution: {integrity: sha512-AbH9q9J455r/nLmdNZes0G0ZKcRX73FicwowalLs6ijwOmCJSRRrLX63lcAlzy9ux3dWK1w1+1nsBJEWN11hcQ==} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5237,6 +5145,10 @@ packages: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} @@ -5285,6 +5197,9 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -5293,23 +5208,18 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - esbuild-wasm@0.23.0: - resolution: {integrity: sha512-6jP8UmWy6R6TUUV8bMuC3ZyZ6lZKI56x0tkxyCIqWwRRJ/DgeQKneh/Oid5EoGoPFLrGNkz47ZEtWAYuiY/u9g==} + esbuild-wasm@0.25.4: + resolution: {integrity: sha512-2HlCS6rNvKWaSKhWaG/YIyRsTsL3gUrMP2ToZMBIjw9LM7vVcIs+rz8kE2vExvTJgvM8OKPqNpcHawY/BQc/qQ==} engines: {node: '>=18'} hasBin: true - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.23.0: - resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} engines: {node: '>=18'} hasBin: true - esbuild@0.23.1: - resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} engines: {node: '>=18'} hasBin: true @@ -5447,8 +5357,8 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} exponential-backoff@3.1.3: @@ -5461,17 +5371,9 @@ packages: extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -5669,6 +5571,7 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@14.0.0: @@ -5727,9 +5630,9 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} + hosted-git-info@8.1.0: + resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} + engines: {node: ^18.17.0 || >=20.5.0} hpack.js@2.1.6: resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} @@ -5750,9 +5653,6 @@ packages: htmlparser2@10.0.0: resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - http-assert@1.5.0: resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} engines: {node: '>= 0.8'} @@ -5799,10 +5699,6 @@ packages: resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} engines: {node: '>=8.0.0'} - https-proxy-agent@7.0.5: - resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} - engines: {node: '>= 14'} - https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -5840,9 +5736,9 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore-walk@6.0.5: - resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ignore-walk@7.0.0: + resolution: {integrity: sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==} + engines: {node: ^18.17.0 || >=20.5.0} ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} @@ -5857,9 +5753,6 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - immutable@4.3.7: - resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} - immutable@5.1.4: resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} @@ -5889,9 +5782,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@4.1.3: - resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ini@5.0.0: + resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==} + engines: {node: ^18.17.0 || >=20.5.0} injection-js@2.6.1: resolution: {integrity: sha512-dbR5bdhi7TWDoCye9cByZqeg/gAfamm8Vu3G1KZOTYkOif8WkuM8CD0oeDPtZYMzT5YH76JAFB7bkmyY9OJi2A==} @@ -5974,12 +5867,6 @@ packages: resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==} engines: {node: '>=8'} - is-lambda@1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-network-error@1.3.0: resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} engines: {node: '>=16'} @@ -6128,9 +6015,9 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-parse-even-better-errors@3.0.2: - resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-parse-even-better-errors@4.0.0: + resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} + engines: {node: ^18.17.0 || >=20.5.0} json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -6227,8 +6114,8 @@ packages: webpack: optional: true - less@4.2.0: - resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==} + less@4.2.2: + resolution: {integrity: sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==} engines: {node: '>=6'} hasBin: true @@ -6256,8 +6143,8 @@ packages: resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - listr2@8.2.4: - resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==} + listr2@8.2.5: + resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} engines: {node: '>=18.0.0'} lit-element@4.2.1: @@ -6269,8 +6156,8 @@ packages: lit@3.3.1: resolution: {integrity: sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==} - lmdb@3.0.13: - resolution: {integrity: sha512-UGe+BbaSUQtAMZobTb4nHvFMrmvuAQKSeaqAX2meTEQjfsbpl5sxdHD8T72OnwD4GU9uwNhYXIVe4QGs8N9Zyw==} + lmdb@3.2.6: + resolution: {integrity: sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==} hasBin: true loader-runner@4.3.1: @@ -6332,9 +6219,6 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -6357,8 +6241,8 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.11: - resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -6375,9 +6259,9 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-fetch-happen@13.0.1: - resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} - engines: {node: ^16.14.0 || >=18.0.0} + make-fetch-happen@14.0.3: + resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} + engines: {node: ^18.17.0 || >=20.5.0} markdown-link-extractor@4.0.2: resolution: {integrity: sha512-5cUOu4Vwx1wenJgxaudsJ8xwLUMN7747yDJX3V/L7+gi3e4MsCm7w5nbrDQQy8nEfnl4r5NV3pDXMAjhGXYXAw==} @@ -6455,8 +6339,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - mini-css-extract-plugin@2.9.0: - resolution: {integrity: sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==} + mini-css-extract-plugin@2.9.2: + resolution: {integrity: sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 @@ -6489,9 +6373,9 @@ packages: resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} engines: {node: '>=16 || 14 >=14.17'} - minipass-fetch@3.0.5: - resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + minipass-fetch@4.0.1: + resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} + engines: {node: ^18.17.0 || >=20.5.0} minipass-flush@1.0.5: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} @@ -6521,6 +6405,10 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -6533,8 +6421,8 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} - mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} ms@2.0.0: @@ -6561,6 +6449,10 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + nanocolors@0.2.13: resolution: {integrity: sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==} @@ -6590,29 +6482,26 @@ packages: resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} engines: {node: '>= 0.6'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@18.2.1: - resolution: {integrity: sha512-dy9ZDpZb3QpAz+Y/m8VAu7ctr2VrnRU3gmQwJagnNybVJtCsKn3lZA3IW7Z7GTLoG5IALSPouiCgiB/C8ozv7w==} + ng-packagr@19.2.2: + resolution: {integrity: sha512-dFuwFsDJMBSd1YtmLLcX5bNNUCQUlRqgf34aXA+79PmkOP+0eF8GP2949wq3+jMjmFTNm80Oo8IUYiSLwklKCQ==} engines: {node: ^18.19.1 || >=20.11.1} hasBin: true peerDependencies: - '@angular/compiler-cli': ^18.0.0 || ^18.2.0-next.0 - tailwindcss: ^2.0.0 || ^3.0.0 + '@angular/compiler-cli': ^19.0.0 || ^19.1.0-next.0 || ^19.2.0-next.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 - typescript: '>=5.4 <5.6' + typescript: '>=5.5 <5.9' peerDependenciesMeta: tailwindcss: optional: true - nice-napi@1.0.2: - resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==} - os: ['!win32'] - - node-addon-api@3.2.1: - resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -6636,13 +6525,9 @@ packages: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true - - node-gyp@10.3.1: - resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} - engines: {node: ^16.14.0 || >=18.0.0} + node-gyp@11.5.0: + resolution: {integrity: sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true node-machine-id@1.1.12: @@ -6651,14 +6536,13 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - nopt@7.2.1: - resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} - normalize-package-data@6.0.2: - resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} - engines: {node: ^16.14.0 || >=18.0.0} + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -6668,33 +6552,33 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} - npm-bundled@3.0.1: - resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-bundled@4.0.0: + resolution: {integrity: sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==} + engines: {node: ^18.17.0 || >=20.5.0} - npm-install-checks@6.3.0: - resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-install-checks@7.1.2: + resolution: {integrity: sha512-z9HJBCYw9Zr8BqXcllKIs5nI+QggAImbBdHphOzVYrz2CB4iQ6FzWyKmlqDZua+51nAu7FcemlbTc9VgQN5XDQ==} + engines: {node: ^18.17.0 || >=20.5.0} - npm-normalize-package-bin@3.0.1: - resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-normalize-package-bin@4.0.0: + resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} + engines: {node: ^18.17.0 || >=20.5.0} - npm-package-arg@11.0.3: - resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==} - engines: {node: ^16.14.0 || >=18.0.0} + npm-package-arg@12.0.2: + resolution: {integrity: sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==} + engines: {node: ^18.17.0 || >=20.5.0} - npm-packlist@8.0.2: - resolution: {integrity: sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-packlist@9.0.0: + resolution: {integrity: sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==} + engines: {node: ^18.17.0 || >=20.5.0} - npm-pick-manifest@9.1.0: - resolution: {integrity: sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==} - engines: {node: ^16.14.0 || >=18.0.0} + npm-pick-manifest@10.0.0: + resolution: {integrity: sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==} + engines: {node: ^18.17.0 || >=20.5.0} - npm-registry-fetch@17.1.0: - resolution: {integrity: sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==} - engines: {node: ^16.14.0 || >=18.0.0} + npm-registry-fetch@18.0.2: + resolution: {integrity: sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==} + engines: {node: ^18.17.0 || >=20.5.0} npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} @@ -6722,6 +6606,9 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -6767,10 +6654,6 @@ packages: ordered-binary@1.6.0: resolution: {integrity: sha512-IQh2aMfMIDbPjI/8a3Edr+PiOpcsB7yo8NdW7aHWVaoR/pcDldunMvnnwbk/auPGqmKeAdxtZl7MHX/QmPwhvQ==} - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} @@ -6817,9 +6700,9 @@ packages: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} p-retry@6.2.1: resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} @@ -6842,9 +6725,9 @@ packages: package-manager-detector@1.5.0: resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} - pacote@18.0.6: - resolution: {integrity: sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==} - engines: {node: ^16.14.0 || >=18.0.0} + pacote@20.0.0: + resolution: {integrity: sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true parent-module@1.0.1: @@ -6921,16 +6804,9 @@ packages: resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} engines: {node: '>=18'} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} @@ -6941,20 +6817,20 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - piscina@4.6.1: - resolution: {integrity: sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==} + piscina@4.8.0: + resolution: {integrity: sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==} piscina@4.9.2: resolution: {integrity: sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==} @@ -7027,8 +6903,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.41: - resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + postcss@8.5.2: + resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} engines: {node: ^10 || ^12 || >=14} postcss@8.5.6: @@ -7068,21 +6944,13 @@ packages: resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - proc-log@4.2.0: - resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + proc-log@5.0.0: + resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} + engines: {node: ^18.17.0 || >=20.5.0} process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - promise-inflight@1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - promise-retry@2.0.1: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} @@ -7240,13 +7108,14 @@ packages: resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} hasBin: true - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} hasBin: true restore-cursor@3.1.0: @@ -7277,13 +7146,8 @@ packages: peerDependencies: rollup: 2.x || 3.x || 4.x - rollup@4.22.4: - resolution: {integrity: sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rollup@4.52.5: - resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7317,8 +7181,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass-loader@16.0.0: - resolution: {integrity: sha512-n13Z+3rU9A177dk4888czcVFiC8CL9dii4qpXWUg3YIIgZEvi9TCFKjOQcbK0kJM7DJu9VucrZFddvNfYCPwtw==} + sass-loader@16.0.5: + resolution: {integrity: sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==} engines: {node: '>= 18.12.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -7338,8 +7202,8 @@ packages: webpack: optional: true - sass@1.77.6: - resolution: {integrity: sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==} + sass@1.85.0: + resolution: {integrity: sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==} engines: {node: '>=14.0.0'} hasBin: true @@ -7358,10 +7222,6 @@ packages: scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} - schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} - schema-utils@4.3.3: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} @@ -7389,8 +7249,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} engines: {node: '>=10'} hasBin: true @@ -7516,9 +7376,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - sigstore@2.3.1: - resolution: {integrity: sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==} - engines: {node: ^16.14.0 || >=18.0.0} + sigstore@3.1.0: + resolution: {integrity: sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==} + engines: {node: ^18.17.0 || >=20.5.0} slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -7617,9 +7477,9 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - ssri@10.0.6: - resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ssri@12.0.0: + resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} + engines: {node: ^18.17.0 || >=20.5.0} stable-hash-x@0.2.0: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} @@ -7636,8 +7496,8 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} @@ -7743,13 +7603,18 @@ packages: tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + tar@7.5.13: + resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} + engines: {node: '>=18'} term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - terser-webpack-plugin@5.3.14: - resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + terser-webpack-plugin@5.4.0: + resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -7764,8 +7629,8 @@ packages: uglify-js: optional: true - terser@5.31.6: - resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==} + terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} engines: {node: '>=10'} hasBin: true @@ -7781,23 +7646,16 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} - engines: {node: '>=14.0.0'} - - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tldts-core@7.0.17: @@ -7807,10 +7665,6 @@ packages: resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==} hasBin: true - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - tmp@0.2.5: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} @@ -7869,9 +7723,6 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} - tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -7879,9 +7730,9 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - tuf-js@2.2.1: - resolution: {integrity: sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==} - engines: {node: ^16.14.0 || >=18.0.0} + tuf-js@3.1.0: + resolution: {integrity: sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==} + engines: {node: ^18.17.0 || >=20.5.0} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -7910,17 +7761,14 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} @@ -7948,13 +7796,13 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} - unique-filename@3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-filename@4.0.0: + resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} + engines: {node: ^18.17.0 || >=20.5.0} - unique-slug@4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-slug@5.0.0: + resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} + engines: {node: ^18.17.0 || >=20.5.0} universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -7973,6 +7821,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -7990,19 +7844,14 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validate-npm-package-name@5.0.1: - resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + validate-npm-package-name@6.0.2: + resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==} + engines: {node: ^18.17.0 || >=20.5.0} vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite-node@2.1.9: - resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - vite-plugin-dts@4.2.3: resolution: {integrity: sha512-O5NalzHANQRwVw1xj8KQun3Bv8OSDAlNJXrnqoAz10BOuW8FVvY5g4ygj+DlJZL5mtSPuMu9vd3OfrdW5d4k6w==} engines: {node: ^14.18.0 || >=16.0.0} @@ -8013,10 +7862,10 @@ packages: vite: optional: true - vite-plugin-externalize-deps@0.9.0: - resolution: {integrity: sha512-wg3qb5gCy2d1KpPKyD9wkXMcYJ84yjgziHrStq9/8R7chhUC73mhQz+tVtvhFiICQHsBn1pnkY4IBbPqF9JHNw==} + vite-plugin-externalize-deps@0.10.0: + resolution: {integrity: sha512-eQrtpT/Do7AvDn76l1yL6ZHyXJ+UWH2LaHVqhAes9go54qaAnPZuMbgxcroQ/7WY3ZyetZzYW2quQnDF0DV5qg==} peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 vite-plugin-solid@2.11.10: resolution: {integrity: sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw==} @@ -8036,22 +7885,27 @@ packages: vite: optional: true - vite@5.4.21: - resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@6.4.2: + resolution: {integrity: sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' less: '*' lightningcss: ^1.21.0 sass: '*' sass-embedded: '*' stylus: '*' sugarss: '*' - terser: ^5.4.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + jiti: + optional: true less: optional: true lightningcss: @@ -8066,6 +7920,10 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true vitefu@0.2.5: resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} @@ -8083,23 +7941,39 @@ packages: vite: optional: true - vitest@2.1.9: - resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} - engines: {node: ^18.0.0 || >=20.0.0} + vitest@4.1.4: + resolution: {integrity: sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.9 - '@vitest/ui': 2.1.9 + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.4 + '@vitest/browser-preview': 4.1.4 + '@vitest/browser-webdriverio': 4.1.4 + '@vitest/coverage-istanbul': 4.1.4 + '@vitest/coverage-v8': 4.1.4 + '@vitest/ui': 4.1.4 happy-dom: '*' jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@opentelemetry/api': + optional: true '@types/node': optional: true - '@vitest/browser': + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': optional: true '@vitest/ui': optional: true @@ -8150,8 +8024,12 @@ packages: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} - watchpack@2.4.1: - resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} wbuf@1.7.3: @@ -8210,8 +8088,8 @@ packages: html-webpack-plugin: optional: true - webpack@5.94.0: - resolution: {integrity: sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==} + webpack@5.105.0: + resolution: {integrity: sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -8231,6 +8109,7 @@ packages: whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} @@ -8248,9 +8127,9 @@ packages: engines: {node: '>= 8'} hasBin: true - which@4.0.0: - resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} - engines: {node: ^16.13.0 || >=18.0.0} + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true why-is-node-running@2.3.0: @@ -8325,6 +8204,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml@2.8.1: resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} engines: {node: '>= 14.6'} @@ -8371,21 +8254,21 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular-devkit/architect@0.1802.21(chokidar@3.6.0)': + '@angular-devkit/architect@0.1902.24(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 18.2.21(chokidar@3.6.0) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) rxjs: 7.8.1 transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5))(typescript@5.4.5)': + '@angular-devkit/build-angular@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.1802.21(chokidar@3.6.0) - '@angular-devkit/build-webpack': 0.1802.21(chokidar@3.6.0)(webpack-dev-server@5.2.2(webpack@5.94.0(esbuild@0.23.0)))(webpack@5.94.0(esbuild@0.23.0)) - '@angular-devkit/core': 18.2.21(chokidar@3.6.0) - '@angular/build': 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(less@4.2.0)(postcss@8.4.41)(terser@5.31.6)(typescript@5.4.5) - '@angular/compiler-cli': 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) + '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) + '@angular-devkit/build-webpack': 0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)))(webpack@5.105.0(esbuild@0.25.4)) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular/build': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1) + '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) '@babel/core': 7.26.10 '@babel/generator': 7.26.10 '@babel/helper-annotate-as-pure': 7.25.9 @@ -8395,57 +8278,138 @@ snapshots: '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.26.10) '@babel/preset-env': 7.26.9(@babel/core@7.26.10) '@babel/runtime': 7.26.10 - '@discoveryjs/json-ext': 0.6.1 - '@ngtools/webpack': 18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(typescript@5.4.5)(webpack@5.94.0(esbuild@0.23.0)) + '@discoveryjs/json-ext': 0.6.3 + '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) ansi-colors: 4.1.3 - autoprefixer: 10.4.20(postcss@8.4.41) - babel-loader: 9.1.3(@babel/core@7.26.10)(webpack@5.94.0) + autoprefixer: 10.4.20(postcss@8.5.2) + babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)) browserslist: 4.27.0 - copy-webpack-plugin: 12.0.2(webpack@5.94.0) - critters: 0.0.24 - css-loader: 7.1.2(webpack@5.94.0) - esbuild-wasm: 0.23.0 - fast-glob: 3.3.2 + copy-webpack-plugin: 12.0.2(webpack@5.105.0(esbuild@0.25.4)) + css-loader: 7.1.2(webpack@5.105.0(esbuild@0.25.4)) + esbuild-wasm: 0.25.4 + fast-glob: 3.3.3 http-proxy-middleware: 3.0.5 - https-proxy-agent: 7.0.5 istanbul-lib-instrument: 6.0.3 jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 - less: 4.2.0 - less-loader: 12.2.0(less@4.2.0)(webpack@5.94.0) - license-webpack-plugin: 4.0.2(webpack@5.94.0) + less: 4.2.2 + less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)) + license-webpack-plugin: 4.0.2(webpack@5.105.0(esbuild@0.25.4)) loader-utils: 3.3.1 - magic-string: 0.30.11 - mini-css-extract-plugin: 2.9.0(webpack@5.94.0) - mrmime: 2.0.0 + mini-css-extract-plugin: 2.9.2(webpack@5.105.0(esbuild@0.25.4)) open: 10.1.0 ora: 5.4.1 - parse5-html-rewriting-stream: 7.0.0 - picomatch: 4.0.2 - piscina: 4.6.1 - postcss: 8.4.41 - postcss-loader: 8.1.1(postcss@8.4.41)(typescript@5.4.5)(webpack@5.94.0) + picomatch: 4.0.4 + piscina: 4.8.0 + postcss: 8.5.2 + postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + resolve-url-loader: 5.0.0 + rxjs: 7.8.1 + sass: 1.85.0 + sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)) + semver: 7.7.1 + source-map-loader: 5.0.0(webpack@5.105.0(esbuild@0.25.4)) + source-map-support: 0.5.21 + terser: 5.39.0 + tree-kill: 1.2.2 + tslib: 2.8.1 + typescript: 5.6.3 + webpack: 5.105.0(esbuild@0.25.4) + webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) + webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) + webpack-merge: 6.0.1 + webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.25.4)) + optionalDependencies: + esbuild: 0.25.4 + ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) + transitivePeerDependencies: + - '@angular/compiler' + - '@rspack/core' + - '@swc/core' + - '@types/node' + - bufferutil + - chokidar + - debug + - html-webpack-plugin + - jiti + - lightningcss + - node-sass + - sass-embedded + - stylus + - sugarss + - supports-color + - tsx + - uglify-js + - utf-8-validate + - vite + - webpack-cli + - yaml + + '@angular-devkit/build-angular@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) + '@angular-devkit/build-webpack': 0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)))(webpack@5.105.0(esbuild@0.25.4)) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular/build': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1) + '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) + '@babel/core': 7.26.10 + '@babel/generator': 7.26.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/plugin-transform-async-generator-functions': 7.26.8(@babel/core@7.26.10) + '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.10) + '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.26.10) + '@babel/preset-env': 7.26.9(@babel/core@7.26.10) + '@babel/runtime': 7.26.10 + '@discoveryjs/json-ext': 0.6.3 + '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + ansi-colors: 4.1.3 + autoprefixer: 10.4.20(postcss@8.5.2) + babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)) + browserslist: 4.27.0 + copy-webpack-plugin: 12.0.2(webpack@5.105.0(esbuild@0.25.4)) + css-loader: 7.1.2(webpack@5.105.0(esbuild@0.25.4)) + esbuild-wasm: 0.25.4 + fast-glob: 3.3.3 + http-proxy-middleware: 3.0.5 + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + karma-source-map-support: 1.4.0 + less: 4.2.2 + less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)) + license-webpack-plugin: 4.0.2(webpack@5.105.0(esbuild@0.25.4)) + loader-utils: 3.3.1 + mini-css-extract-plugin: 2.9.2(webpack@5.105.0(esbuild@0.25.4)) + open: 10.1.0 + ora: 5.4.1 + picomatch: 4.0.4 + piscina: 4.8.0 + postcss: 8.5.2 + postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) resolve-url-loader: 5.0.0 rxjs: 7.8.1 - sass: 1.77.6 - sass-loader: 16.0.0(sass@1.77.6)(webpack@5.94.0) - semver: 7.6.3 - source-map-loader: 5.0.0(webpack@5.94.0) + sass: 1.85.0 + sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)) + semver: 7.7.1 + source-map-loader: 5.0.0(webpack@5.105.0(esbuild@0.25.4)) source-map-support: 0.5.21 - terser: 5.31.6 + terser: 5.39.0 tree-kill: 1.2.2 - tslib: 2.6.3 - typescript: 5.4.5 - watchpack: 2.4.1 - webpack: 5.94.0(esbuild@0.23.0) - webpack-dev-middleware: 7.4.2(webpack@5.94.0(esbuild@0.23.0)) - webpack-dev-server: 5.2.2(webpack@5.94.0(esbuild@0.23.0)) + tslib: 2.8.1 + typescript: 5.6.3 + webpack: 5.105.0(esbuild@0.25.4) + webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) + webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.94.0) + webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.25.4)) optionalDependencies: - esbuild: 0.23.0 - ng-packagr: 18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5) + esbuild: 0.25.4 + ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) transitivePeerDependencies: + - '@angular/compiler' - '@rspack/core' - '@swc/core' - '@types/node' @@ -8453,179 +8417,189 @@ snapshots: - chokidar - debug - html-webpack-plugin + - jiti - lightningcss - node-sass - sass-embedded - stylus - sugarss - supports-color + - tsx - uglify-js - utf-8-validate + - vite - webpack-cli + - yaml - '@angular-devkit/build-webpack@0.1802.21(chokidar@3.6.0)(webpack-dev-server@5.2.2(webpack@5.94.0(esbuild@0.23.0)))(webpack@5.94.0(esbuild@0.23.0))': + '@angular-devkit/build-webpack@0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)))(webpack@5.105.0(esbuild@0.25.4))': dependencies: - '@angular-devkit/architect': 0.1802.21(chokidar@3.6.0) + '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) rxjs: 7.8.1 - webpack: 5.94.0(esbuild@0.23.0) - webpack-dev-server: 5.2.2(webpack@5.94.0(esbuild@0.23.0)) + webpack: 5.105.0(esbuild@0.25.4) + webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) transitivePeerDependencies: - chokidar - '@angular-devkit/core@18.2.21(chokidar@3.6.0)': + '@angular-devkit/core@19.2.24(chokidar@4.0.3)': dependencies: - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) jsonc-parser: 3.3.1 - picomatch: 4.0.2 + picomatch: 4.0.4 rxjs: 7.8.1 source-map: 0.7.4 optionalDependencies: - chokidar: 3.6.0 + chokidar: 4.0.3 - '@angular-devkit/schematics@18.2.21(chokidar@3.6.0)': + '@angular-devkit/schematics@19.2.24(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 18.2.21(chokidar@3.6.0) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) jsonc-parser: 3.3.1 - magic-string: 0.30.11 + magic-string: 0.30.17 ora: 5.4.1 rxjs: 7.8.1 transitivePeerDependencies: - chokidar - '@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))': + '@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/common': 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 - '@angular/build@18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(@types/node@24.9.2)(chokidar@3.6.0)(less@4.2.0)(postcss@8.4.41)(terser@5.31.6)(typescript@5.4.5)': + '@angular/build@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.1802.21(chokidar@3.6.0) - '@angular/compiler-cli': 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 + '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) + '@angular/compiler': 19.2.20 + '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) + '@babel/core': 7.26.10 + '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-split-export-declaration': 7.24.7 - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) - '@inquirer/confirm': 3.1.22 - '@vitejs/plugin-basic-ssl': 1.1.0(vite@5.4.21(@types/node@24.9.2)(less@4.2.0)(sass@1.77.6)(terser@5.31.6)) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.10) + '@inquirer/confirm': 5.1.6(@types/node@24.9.2) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) + beasties: 0.3.2 browserslist: 4.27.0 - critters: 0.0.24 - esbuild: 0.23.0 - fast-glob: 3.3.2 - https-proxy-agent: 7.0.5 - listr2: 8.2.4 - lmdb: 3.0.13 - magic-string: 0.30.11 - mrmime: 2.0.0 + esbuild: 0.25.4 + fast-glob: 3.3.3 + https-proxy-agent: 7.0.6 + istanbul-lib-instrument: 6.0.3 + listr2: 8.2.5 + magic-string: 0.30.17 + mrmime: 2.0.1 parse5-html-rewriting-stream: 7.0.0 - picomatch: 4.0.2 - piscina: 4.6.1 - rollup: 4.22.4 - sass: 1.77.6 - semver: 7.6.3 - typescript: 5.4.5 - vite: 5.4.21(@types/node@24.9.2)(less@4.2.0)(sass@1.77.6)(terser@5.31.6) - watchpack: 2.4.1 + picomatch: 4.0.4 + piscina: 4.8.0 + rollup: 4.59.0 + sass: 1.85.0 + semver: 7.7.1 + source-map-support: 0.5.21 + typescript: 5.6.3 + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) + watchpack: 2.4.2 optionalDependencies: - less: 4.2.0 - postcss: 8.4.41 + less: 4.2.2 + lmdb: 3.2.6 + ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) + postcss: 8.5.2 transitivePeerDependencies: - '@types/node' - chokidar + - jiti - lightningcss - sass-embedded - stylus - sugarss - supports-color - terser + - tsx + - yaml - '@angular/cli@18.2.21(chokidar@3.6.0)': + '@angular/cli@19.2.24(@types/node@24.9.2)(chokidar@4.0.3)': dependencies: - '@angular-devkit/architect': 0.1802.21(chokidar@3.6.0) - '@angular-devkit/core': 18.2.21(chokidar@3.6.0) - '@angular-devkit/schematics': 18.2.21(chokidar@3.6.0) - '@inquirer/prompts': 5.3.8 - '@listr2/prompt-adapter-inquirer': 2.0.15(@inquirer/prompts@5.3.8) - '@schematics/angular': 18.2.21(chokidar@3.6.0) + '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) + '@inquirer/prompts': 7.3.2(@types/node@24.9.2) + '@listr2/prompt-adapter-inquirer': 2.0.18(@inquirer/prompts@7.3.2(@types/node@24.9.2)) + '@schematics/angular': 19.2.24(chokidar@4.0.3) '@yarnpkg/lockfile': 1.1.0 - ini: 4.1.3 + ini: 5.0.0 jsonc-parser: 3.3.1 - listr2: 8.2.4 - npm-package-arg: 11.0.3 - npm-pick-manifest: 9.1.0 - pacote: 18.0.6 - resolve: 1.22.8 - semver: 7.6.3 + listr2: 8.2.5 + npm-package-arg: 12.0.2 + npm-pick-manifest: 10.0.0 + pacote: 20.0.0 + resolve: 1.22.10 + semver: 7.7.1 symbol-observable: 4.0.0 yargs: 17.7.2 transitivePeerDependencies: - - bluebird + - '@types/node' - chokidar - supports-color - '@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': + '@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5)': + '@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3)': dependencies: - '@angular/compiler': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) - '@babel/core': 7.25.2 + '@angular/compiler': 19.2.20 + '@babel/core': 7.26.9 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 4.0.3 convert-source-map: 1.9.0 reflect-metadata: 0.2.2 semver: 7.7.3 tslib: 2.8.1 - typescript: 5.4.5 + typescript: 5.6.3 yargs: 17.7.2 transitivePeerDependencies: - supports-color - '@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))': + '@angular/compiler@19.2.20': dependencies: tslib: 2.8.1 - optionalDependencies: - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)': + '@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 zone.js: 0.15.1 - '@angular/forms@18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': + '@angular/forms@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/common': 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/platform-browser-dynamic@18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))': + '@angular/platform-browser-dynamic@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.20)(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))': dependencies: - '@angular/common': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/compiler': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/common': 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/compiler': 19.2.20 + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) tslib: 2.8.1 - '@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))': + '@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@angular/common': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/common': 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/animations': 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) - '@angular/router@18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': + '@angular/router@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/common': 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) rxjs: 7.8.2 tslib: 2.8.1 @@ -8655,13 +8629,13 @@ snapshots: '@babel/compat-data@7.28.5': {} - '@babel/core@7.25.2': + '@babel/core@7.26.10': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.5 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.25.2) + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.26.10) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 '@babel/template': 7.27.2 @@ -8675,13 +8649,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@7.26.10': + '@babel/core@7.26.9': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.5 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.26.10) + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.26.9) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 '@babel/template': 7.27.2 @@ -8731,10 +8705,6 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.24.7': - dependencies: - '@babel/types': 7.28.5 - '@babel/helper-annotate-as-pure@7.25.9': dependencies: '@babel/types': 7.28.5 @@ -8802,18 +8772,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.25.2)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.10 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 '@babel/traverse': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.26.10)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.26.9)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.26.9 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 '@babel/traverse': 7.28.5 @@ -8931,9 +8901,9 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.10)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.26.10)': @@ -9589,7 +9559,7 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@discoveryjs/json-ext@0.6.1': {} + '@discoveryjs/json-ext@0.6.3': {} '@emnapi/core@1.6.0': dependencies: @@ -9604,217 +9574,157 @@ snapshots: dependencies: tslib: 2.8.1 - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.23.0': - optional: true - - '@esbuild/aix-ppc64@0.23.1': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.23.0': - optional: true - - '@esbuild/android-arm64@0.23.1': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-arm@0.23.0': - optional: true - - '@esbuild/android-arm@0.23.1': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/android-x64@0.23.0': - optional: true - - '@esbuild/android-x64@0.23.1': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.23.0': - optional: true - - '@esbuild/darwin-arm64@0.23.1': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.23.0': - optional: true - - '@esbuild/darwin-x64@0.23.1': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.23.0': - optional: true - - '@esbuild/freebsd-arm64@0.23.1': + '@esbuild/aix-ppc64@0.25.12': optional: true - '@esbuild/freebsd-x64@0.21.5': + '@esbuild/aix-ppc64@0.25.4': optional: true - '@esbuild/freebsd-x64@0.23.0': + '@esbuild/android-arm64@0.25.12': optional: true - '@esbuild/freebsd-x64@0.23.1': + '@esbuild/android-arm64@0.25.4': optional: true - '@esbuild/linux-arm64@0.21.5': + '@esbuild/android-arm@0.25.12': optional: true - '@esbuild/linux-arm64@0.23.0': + '@esbuild/android-arm@0.25.4': optional: true - '@esbuild/linux-arm64@0.23.1': + '@esbuild/android-x64@0.25.12': optional: true - '@esbuild/linux-arm@0.21.5': + '@esbuild/android-x64@0.25.4': optional: true - '@esbuild/linux-arm@0.23.0': + '@esbuild/darwin-arm64@0.25.12': optional: true - '@esbuild/linux-arm@0.23.1': + '@esbuild/darwin-arm64@0.25.4': optional: true - '@esbuild/linux-ia32@0.21.5': + '@esbuild/darwin-x64@0.25.12': optional: true - '@esbuild/linux-ia32@0.23.0': + '@esbuild/darwin-x64@0.25.4': optional: true - '@esbuild/linux-ia32@0.23.1': + '@esbuild/freebsd-arm64@0.25.12': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/freebsd-arm64@0.25.4': optional: true - '@esbuild/linux-loong64@0.23.0': + '@esbuild/freebsd-x64@0.25.12': optional: true - '@esbuild/linux-loong64@0.23.1': + '@esbuild/freebsd-x64@0.25.4': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/linux-arm64@0.25.12': optional: true - '@esbuild/linux-mips64el@0.23.0': + '@esbuild/linux-arm64@0.25.4': optional: true - '@esbuild/linux-mips64el@0.23.1': + '@esbuild/linux-arm@0.25.12': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/linux-arm@0.25.4': optional: true - '@esbuild/linux-ppc64@0.23.0': + '@esbuild/linux-ia32@0.25.12': optional: true - '@esbuild/linux-ppc64@0.23.1': + '@esbuild/linux-ia32@0.25.4': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/linux-loong64@0.25.12': optional: true - '@esbuild/linux-riscv64@0.23.0': + '@esbuild/linux-loong64@0.25.4': optional: true - '@esbuild/linux-riscv64@0.23.1': + '@esbuild/linux-mips64el@0.25.12': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/linux-mips64el@0.25.4': optional: true - '@esbuild/linux-s390x@0.23.0': + '@esbuild/linux-ppc64@0.25.12': optional: true - '@esbuild/linux-s390x@0.23.1': + '@esbuild/linux-ppc64@0.25.4': optional: true - '@esbuild/linux-x64@0.21.5': + '@esbuild/linux-riscv64@0.25.12': optional: true - '@esbuild/linux-x64@0.23.0': + '@esbuild/linux-riscv64@0.25.4': optional: true - '@esbuild/linux-x64@0.23.1': + '@esbuild/linux-s390x@0.25.12': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@esbuild/linux-s390x@0.25.4': optional: true - '@esbuild/netbsd-x64@0.23.0': + '@esbuild/linux-x64@0.25.12': optional: true - '@esbuild/netbsd-x64@0.23.1': + '@esbuild/linux-x64@0.25.4': optional: true - '@esbuild/openbsd-arm64@0.23.0': + '@esbuild/netbsd-arm64@0.25.12': optional: true - '@esbuild/openbsd-arm64@0.23.1': + '@esbuild/netbsd-arm64@0.25.4': optional: true - '@esbuild/openbsd-x64@0.21.5': + '@esbuild/netbsd-x64@0.25.12': optional: true - '@esbuild/openbsd-x64@0.23.0': + '@esbuild/netbsd-x64@0.25.4': optional: true - '@esbuild/openbsd-x64@0.23.1': + '@esbuild/openbsd-arm64@0.25.12': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/openbsd-arm64@0.25.4': optional: true - '@esbuild/sunos-x64@0.23.0': + '@esbuild/openbsd-x64@0.25.12': optional: true - '@esbuild/sunos-x64@0.23.1': + '@esbuild/openbsd-x64@0.25.4': optional: true - '@esbuild/win32-arm64@0.21.5': + '@esbuild/openharmony-arm64@0.25.12': optional: true - '@esbuild/win32-arm64@0.23.0': + '@esbuild/sunos-x64@0.25.12': optional: true - '@esbuild/win32-arm64@0.23.1': + '@esbuild/sunos-x64@0.25.4': optional: true - '@esbuild/win32-ia32@0.21.5': + '@esbuild/win32-arm64@0.25.12': optional: true - '@esbuild/win32-ia32@0.23.0': + '@esbuild/win32-arm64@0.25.4': optional: true - '@esbuild/win32-ia32@0.23.1': + '@esbuild/win32-ia32@0.25.12': optional: true - '@esbuild/win32-x64@0.21.5': + '@esbuild/win32-ia32@0.25.4': optional: true - '@esbuild/win32-x64@0.23.0': + '@esbuild/win32-x64@0.25.12': optional: true - '@esbuild/win32-x64@0.23.1': + '@esbuild/win32-x64@0.25.4': optional: true '@eslint-community/eslint-utils@4.9.0(eslint@9.39.0(jiti@2.6.1))': @@ -9882,50 +9792,60 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/checkbox@2.5.0': + '@inquirer/ansi@1.0.2': {} + + '@inquirer/checkbox@4.3.2(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/figures': 1.0.14 - '@inquirer/type': 1.5.5 - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.9.2) yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/confirm@3.1.22': + '@inquirer/confirm@5.1.21(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/confirm@3.2.0': + '@inquirer/confirm@5.1.6(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/core@9.2.1': + '@inquirer/core@10.3.2(@types/node@24.9.2)': dependencies: - '@inquirer/figures': 1.0.14 - '@inquirer/type': 2.0.0 - '@types/mute-stream': 0.0.4 - '@types/node': 22.18.13 - '@types/wrap-ansi': 3.0.0 - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.9.2) cli-width: 4.1.0 - mute-stream: 1.0.0 + mute-stream: 2.0.0 signal-exit: 4.1.0 - strip-ansi: 6.0.1 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/editor@2.2.0': + '@inquirer/editor@4.2.23(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 - external-editor: 3.1.0 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/external-editor': 1.0.3(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/expand@2.3.0': + '@inquirer/expand@4.0.23(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.9.2 '@inquirer/external-editor@1.0.2(@types/node@24.9.2)': dependencies: @@ -9934,65 +9854,86 @@ snapshots: optionalDependencies: '@types/node': 24.9.2 - '@inquirer/figures@1.0.14': {} - - '@inquirer/input@2.3.0': + '@inquirer/external-editor@1.0.3(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 + chardet: 2.1.1 + iconv-lite: 0.7.0 + optionalDependencies: + '@types/node': 24.9.2 + + '@inquirer/figures@1.0.15': {} - '@inquirer/number@1.1.0': + '@inquirer/input@4.3.1(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/password@2.2.0': + '@inquirer/number@3.0.23(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 - ansi-escapes: 4.3.2 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/prompts@5.3.8': + '@inquirer/password@4.0.23(@types/node@24.9.2)': dependencies: - '@inquirer/checkbox': 2.5.0 - '@inquirer/confirm': 3.2.0 - '@inquirer/editor': 2.2.0 - '@inquirer/expand': 2.3.0 - '@inquirer/input': 2.3.0 - '@inquirer/number': 1.1.0 - '@inquirer/password': 2.2.0 - '@inquirer/rawlist': 2.3.0 - '@inquirer/search': 1.1.0 - '@inquirer/select': 2.5.0 + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 + + '@inquirer/prompts@7.3.2(@types/node@24.9.2)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@24.9.2) + '@inquirer/confirm': 5.1.21(@types/node@24.9.2) + '@inquirer/editor': 4.2.23(@types/node@24.9.2) + '@inquirer/expand': 4.0.23(@types/node@24.9.2) + '@inquirer/input': 4.3.1(@types/node@24.9.2) + '@inquirer/number': 3.0.23(@types/node@24.9.2) + '@inquirer/password': 4.0.23(@types/node@24.9.2) + '@inquirer/rawlist': 4.1.11(@types/node@24.9.2) + '@inquirer/search': 3.2.2(@types/node@24.9.2) + '@inquirer/select': 4.4.2(@types/node@24.9.2) + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/rawlist@2.3.0': + '@inquirer/rawlist@4.1.11(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/type': 1.5.5 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/type': 3.0.10(@types/node@24.9.2) yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/search@1.1.0': + '@inquirer/search@3.2.2(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/figures': 1.0.14 - '@inquirer/type': 1.5.5 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.9.2) yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.9.2 - '@inquirer/select@2.5.0': + '@inquirer/select@4.4.2(@types/node@24.9.2)': dependencies: - '@inquirer/core': 9.2.1 - '@inquirer/figures': 1.0.14 - '@inquirer/type': 1.5.5 - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.9.2) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.9.2) yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.9.2 '@inquirer/type@1.5.5': dependencies: mute-stream: 1.0.0 - '@inquirer/type@2.0.0': - dependencies: - mute-stream: 1.0.0 + '@inquirer/type@3.0.10(@types/node@24.9.2)': + optionalDependencies: + '@types/node': 24.9.2 '@isaacs/balanced-match@4.0.1': {} @@ -10009,6 +9950,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@istanbuljs/schema@0.1.3': {} '@jest/diff-sequences@30.0.1': {} @@ -10081,9 +10026,9 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@2.0.15(@inquirer/prompts@5.3.8)': + '@listr2/prompt-adapter-inquirer@2.0.18(@inquirer/prompts@7.3.2(@types/node@24.9.2))': dependencies: - '@inquirer/prompts': 5.3.8 + '@inquirer/prompts': 7.3.2(@types/node@24.9.2) '@inquirer/type': 1.5.5 '@lit-labs/ssr-dom-shim@1.4.0': {} @@ -10092,22 +10037,22 @@ snapshots: dependencies: '@lit-labs/ssr-dom-shim': 1.4.0 - '@lmdb/lmdb-darwin-arm64@3.0.13': + '@lmdb/lmdb-darwin-arm64@3.2.6': optional: true - '@lmdb/lmdb-darwin-x64@3.0.13': + '@lmdb/lmdb-darwin-x64@3.2.6': optional: true - '@lmdb/lmdb-linux-arm64@3.0.13': + '@lmdb/lmdb-linux-arm64@3.2.6': optional: true - '@lmdb/lmdb-linux-arm@3.0.13': + '@lmdb/lmdb-linux-arm@3.2.6': optional: true - '@lmdb/lmdb-linux-x64@3.0.13': + '@lmdb/lmdb-linux-x64@3.2.6': optional: true - '@lmdb/lmdb-win32-x64@3.0.13': + '@lmdb/lmdb-win32-x64@3.2.6': optional: true '@manypkg/find-root@1.1.0': @@ -10271,11 +10216,11 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@ngtools/webpack@18.2.21(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(typescript@5.4.5)(webpack@5.94.0(esbuild@0.23.0))': + '@ngtools/webpack@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4))': dependencies: - '@angular/compiler-cli': 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) - typescript: 5.4.5 - webpack: 5.94.0(esbuild@0.23.0) + '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) + typescript: 5.6.3 + webpack: 5.105.0(esbuild@0.25.4) '@nodelib/fs.scandir@2.1.5': dependencies: @@ -10289,7 +10234,7 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@npmcli/agent@2.2.2': + '@npmcli/agent@3.0.0': dependencies: agent-base: 7.1.4 http-proxy-agent: 7.0.2 @@ -10299,59 +10244,53 @@ snapshots: transitivePeerDependencies: - supports-color - '@npmcli/fs@3.1.1': + '@npmcli/fs@4.0.0': dependencies: semver: 7.7.3 - '@npmcli/git@5.0.8': + '@npmcli/git@6.0.3': dependencies: - '@npmcli/promise-spawn': 7.0.2 - ini: 4.1.3 + '@npmcli/promise-spawn': 8.0.3 + ini: 5.0.0 lru-cache: 10.4.3 - npm-pick-manifest: 9.1.0 - proc-log: 4.2.0 - promise-inflight: 1.0.1 + npm-pick-manifest: 10.0.0 + proc-log: 5.0.0 promise-retry: 2.0.1 semver: 7.7.3 - which: 4.0.0 - transitivePeerDependencies: - - bluebird + which: 5.0.0 - '@npmcli/installed-package-contents@2.1.0': + '@npmcli/installed-package-contents@3.0.0': dependencies: - npm-bundled: 3.0.1 - npm-normalize-package-bin: 3.0.1 + npm-bundled: 4.0.0 + npm-normalize-package-bin: 4.0.0 - '@npmcli/node-gyp@3.0.0': {} + '@npmcli/node-gyp@4.0.0': {} - '@npmcli/package-json@5.2.1': + '@npmcli/package-json@6.2.0': dependencies: - '@npmcli/git': 5.0.8 + '@npmcli/git': 6.0.3 glob: 10.4.5 - hosted-git-info: 7.0.2 - json-parse-even-better-errors: 3.0.2 - normalize-package-data: 6.0.2 - proc-log: 4.2.0 + hosted-git-info: 8.1.0 + json-parse-even-better-errors: 4.0.0 + proc-log: 5.0.0 semver: 7.7.3 - transitivePeerDependencies: - - bluebird + validate-npm-package-license: 3.0.4 - '@npmcli/promise-spawn@7.0.2': + '@npmcli/promise-spawn@8.0.3': dependencies: - which: 4.0.0 + which: 5.0.0 - '@npmcli/redact@2.0.1': {} + '@npmcli/redact@3.2.2': {} - '@npmcli/run-script@8.1.0': + '@npmcli/run-script@9.1.0': dependencies: - '@npmcli/node-gyp': 3.0.0 - '@npmcli/package-json': 5.2.1 - '@npmcli/promise-spawn': 7.0.2 - node-gyp: 10.3.1 - proc-log: 4.2.0 - which: 4.0.0 + '@npmcli/node-gyp': 4.0.0 + '@npmcli/package-json': 6.2.0 + '@npmcli/promise-spawn': 8.0.3 + node-gyp: 11.5.0 + proc-log: 5.0.0 + which: 5.0.0 transitivePeerDependencies: - - bluebird - supports-color '@nx/nx-darwin-arm64@22.1.3': @@ -10556,142 +10495,94 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/plugin-json@6.1.0(rollup@4.52.5)': + '@rollup/plugin-json@6.1.0(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - optionalDependencies: - rollup: 4.52.5 - - '@rollup/plugin-node-resolve@15.3.1(rollup@4.52.5)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.11 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) optionalDependencies: - rollup: 4.52.5 + rollup: 4.59.0 + optional: true - '@rollup/pluginutils@5.3.0(rollup@4.52.5)': + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: - rollup: 4.52.5 - - '@rollup/rollup-android-arm-eabi@4.22.4': - optional: true - - '@rollup/rollup-android-arm-eabi@4.52.5': - optional: true - - '@rollup/rollup-android-arm64@4.22.4': - optional: true - - '@rollup/rollup-android-arm64@4.52.5': - optional: true - - '@rollup/rollup-darwin-arm64@4.22.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.52.5': - optional: true - - '@rollup/rollup-darwin-x64@4.22.4': - optional: true - - '@rollup/rollup-darwin-x64@4.52.5': - optional: true - - '@rollup/rollup-freebsd-arm64@4.52.5': - optional: true - - '@rollup/rollup-freebsd-x64@4.52.5': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.22.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.52.5': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.22.4': - optional: true + rollup: 4.59.0 - '@rollup/rollup-linux-arm-musleabihf@4.52.5': + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.22.4': + '@rollup/rollup-android-arm64@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.5': + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.22.4': + '@rollup/rollup-darwin-x64@4.59.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.5': + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.5': + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.22.4': + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.5': + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.22.4': + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.5': + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.5': + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.22.4': + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.5': + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.22.4': + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.5': + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-musl@4.22.4': + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - '@rollup/rollup-linux-x64-musl@4.52.5': + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - '@rollup/rollup-openharmony-arm64@4.52.5': + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.22.4': + '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.5': + '@rollup/rollup-openbsd-x64@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.22.4': + '@rollup/rollup-openharmony-arm64@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.5': + '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.5': + '@rollup/rollup-win32-ia32-msvc@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.22.4': + '@rollup/rollup-win32-x64-gnu@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.5': + '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true '@rollup/wasm-node@4.52.5': @@ -10699,6 +10590,7 @@ snapshots: '@types/estree': 1.0.8 optionalDependencies: fsevents: 2.3.3 + optional: true '@rushstack/node-core-library@5.7.0(@types/node@24.9.2)': dependencies: @@ -10734,50 +10626,52 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@schematics/angular@18.2.21(chokidar@3.6.0)': + '@schematics/angular@19.2.24(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 18.2.21(chokidar@3.6.0) - '@angular-devkit/schematics': 18.2.21(chokidar@3.6.0) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) jsonc-parser: 3.3.1 transitivePeerDependencies: - chokidar - '@sigstore/bundle@2.3.2': + '@sigstore/bundle@3.1.0': dependencies: - '@sigstore/protobuf-specs': 0.3.3 + '@sigstore/protobuf-specs': 0.4.3 - '@sigstore/core@1.1.0': {} + '@sigstore/core@2.0.0': {} - '@sigstore/protobuf-specs@0.3.3': {} + '@sigstore/protobuf-specs@0.4.3': {} - '@sigstore/sign@2.3.2': + '@sigstore/sign@3.1.0': dependencies: - '@sigstore/bundle': 2.3.2 - '@sigstore/core': 1.1.0 - '@sigstore/protobuf-specs': 0.3.3 - make-fetch-happen: 13.0.1 - proc-log: 4.2.0 + '@sigstore/bundle': 3.1.0 + '@sigstore/core': 2.0.0 + '@sigstore/protobuf-specs': 0.4.3 + make-fetch-happen: 14.0.3 + proc-log: 5.0.0 promise-retry: 2.0.1 transitivePeerDependencies: - supports-color - '@sigstore/tuf@2.3.4': + '@sigstore/tuf@3.1.1': dependencies: - '@sigstore/protobuf-specs': 0.3.3 - tuf-js: 2.2.1 + '@sigstore/protobuf-specs': 0.4.3 + tuf-js: 3.1.0 transitivePeerDependencies: - supports-color - '@sigstore/verify@1.2.1': + '@sigstore/verify@2.1.1': dependencies: - '@sigstore/bundle': 2.3.2 - '@sigstore/core': 1.1.0 - '@sigstore/protobuf-specs': 0.3.3 + '@sigstore/bundle': 3.1.0 + '@sigstore/core': 2.0.0 + '@sigstore/protobuf-specs': 0.4.3 '@sinclair/typebox@0.34.41': {} '@sindresorhus/merge-streams@2.3.0': {} + '@standard-schema/spec@1.1.0': {} + '@stylistic/eslint-plugin@5.5.0(eslint@9.39.0(jiti@2.6.1))': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) @@ -10786,39 +10680,39 @@ snapshots: eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.3 + picomatch: 4.0.4 - '@sveltejs/package@2.5.4(svelte@4.2.20)(typescript@5.4.5)': + '@sveltejs/package@2.5.4(svelte@4.2.20)(typescript@5.6.3)': dependencies: chokidar: 4.0.3 kleur: 4.1.5 sade: 1.8.1 semver: 7.7.3 svelte: 4.2.20 - svelte2tsx: 0.7.45(svelte@4.2.20)(typescript@5.4.5) + svelte2tsx: 0.7.45(svelte@4.2.20)(typescript@5.6.3) transitivePeerDependencies: - typescript - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)))(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) debug: 4.4.3 svelte: 4.2.20 - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)))(svelte@4.2.20)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) debug: 4.4.3 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.21 svelte: 4.2.20 svelte-hmr: 0.16.0(svelte@4.2.20) - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) - vitefu: 0.2.5(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vitefu: 0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) transitivePeerDependencies: - supports-color @@ -10829,28 +10723,28 @@ snapshots: transitivePeerDependencies: - encoding - '@tanstack/angular-query-experimental@5.80.7(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))': + '@tanstack/angular-query-experimental@5.80.7(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@angular/common': 18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/common': 19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@tanstack/query-core': 5.80.7 '@tanstack/query-devtools': 5.80.0 - '@tanstack/angular-table@8.21.3(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))': + '@tanstack/angular-table@8.21.3(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@angular/core': 18.2.14(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) '@tanstack/table-core': 8.21.3 tslib: 2.8.1 - '@tanstack/eslint-config@0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5)': + '@tanstack/eslint-config@0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3)': dependencies: '@eslint/js': 9.39.0 '@stylistic/eslint-plugin': 5.5.0(eslint@9.39.0(jiti@2.6.1)) eslint: 9.39.0(jiti@2.6.1) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.39.0(jiti@2.6.1)) - eslint-plugin-n: 17.23.1(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1)) + eslint-plugin-n: 17.23.1(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) globals: 16.5.0 - typescript-eslint: 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + typescript-eslint: 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) vue-eslint-parser: 10.2.0(eslint@9.39.0(jiti@2.6.1)) transitivePeerDependencies: - '@typescript-eslint/utils' @@ -10893,31 +10787,31 @@ snapshots: '@tanstack/table-core@8.21.3': {} - '@tanstack/vite-config@0.3.0(@types/node@24.9.2)(rollup@4.52.5)(typescript@5.4.5)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))': + '@tanstack/vite-config@0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': dependencies: - rollup-plugin-preserve-directives: 0.4.0(rollup@4.52.5) - vite-plugin-dts: 4.2.3(@types/node@24.9.2)(rollup@4.52.5)(typescript@5.4.5)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) - vite-plugin-externalize-deps: 0.9.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) - vite-tsconfig-paths: 5.1.4(typescript@5.4.5)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + rollup-plugin-preserve-directives: 0.4.0(rollup@4.59.0) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite-plugin-dts: 4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + vite-plugin-externalize-deps: 0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + vite-tsconfig-paths: 5.1.4(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) transitivePeerDependencies: - '@types/node' - rollup - supports-color - typescript - - vite - '@tanstack/vue-query@5.90.5(vue@3.5.22(typescript@5.4.5))': + '@tanstack/vue-query@5.90.5(vue@3.5.22(typescript@5.6.3))': dependencies: '@tanstack/match-sorter-utils': 8.19.4 '@tanstack/query-core': 5.90.5 '@vue/devtools-api': 6.6.4 - vue: 3.5.22(typescript@5.4.5) - vue-demi: 0.14.10(vue@3.5.22(typescript@5.4.5)) + vue: 3.5.22(typescript@5.6.3) + vue-demi: 0.14.10(vue@3.5.22(typescript@5.6.3)) - '@tanstack/vue-table@8.21.3(vue@3.5.22(typescript@5.4.5))': + '@tanstack/vue-table@8.21.3(vue@3.5.22(typescript@5.6.3))': dependencies: '@tanstack/table-core': 8.21.3 - vue: 3.5.22(typescript@5.4.5) + vue: 3.5.22(typescript@5.6.3) '@testing-library/dom@10.4.1': dependencies: @@ -10953,7 +10847,7 @@ snapshots: '@tufjs/canonical-json@2.0.0': {} - '@tufjs/models@2.0.1': + '@tufjs/models@3.0.1': dependencies: '@tufjs/canonical-json': 2.0.0 minimatch: 9.0.5 @@ -11047,7 +10941,15 @@ snapshots: '@types/deep-eql@4.0.2': {} - '@types/estree@1.0.5': {} + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 '@types/estree@1.0.8': {} @@ -11119,20 +11021,12 @@ snapshots: '@types/mime@1.3.5': {} - '@types/mute-stream@0.0.4': - dependencies: - '@types/node': 24.9.2 - '@types/node-forge@1.3.14': dependencies: '@types/node': 24.9.2 '@types/node@12.20.55': {} - '@types/node@22.18.13': - dependencies: - undici-types: 6.21.0 - '@types/node@24.9.2': dependencies: undici-types: 7.16.0 @@ -11154,8 +11048,6 @@ snapshots: '@types/prop-types': 15.7.15 csstype: 3.1.3 - '@types/resolve@1.20.2': {} - '@types/retry@0.12.2': {} '@types/send@0.17.6': @@ -11196,8 +11088,6 @@ snapshots: '@types/web-bluetooth@0.0.21': {} - '@types/wrap-ansi@3.0.0': {} - '@types/ws@7.4.7': dependencies: '@types/node': 24.9.2 @@ -11206,41 +11096,41 @@ snapshots: dependencies: '@types/node': 24.9.2 - '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) '@typescript-eslint/scope-manager': 8.46.2 - '@typescript-eslint/type-utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/type-utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.46.2 eslint: 9.39.0(jiti@2.6.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.4.5) - typescript: 5.4.5 + ts-api-utils: 2.1.0(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3)': dependencies: '@typescript-eslint/scope-manager': 8.46.2 '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.46.2 debug: 4.4.3 eslint: 9.39.0(jiti@2.6.1) - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.46.2(typescript@5.4.5)': + '@typescript-eslint/project-service@8.46.2(typescript@5.6.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.4.5) + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.6.3) '@typescript-eslint/types': 8.46.2 debug: 4.4.3 - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -11249,28 +11139,28 @@ snapshots: '@typescript-eslint/types': 8.46.2 '@typescript-eslint/visitor-keys': 8.46.2 - '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.4.5)': + '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.6.3)': dependencies: - typescript: 5.4.5 + typescript: 5.6.3 - '@typescript-eslint/type-utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/type-utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3)': dependencies: '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.4.5) - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.6.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) debug: 4.4.3 eslint: 9.39.0(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.4.5) - typescript: 5.4.5 + ts-api-utils: 2.1.0(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.46.2': {} - '@typescript-eslint/typescript-estree@8.46.2(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@8.46.2(typescript@5.6.3)': dependencies: - '@typescript-eslint/project-service': 8.46.2(typescript@5.4.5) - '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.4.5) + '@typescript-eslint/project-service': 8.46.2(typescript@5.6.3) + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.6.3) '@typescript-eslint/types': 8.46.2 '@typescript-eslint/visitor-keys': 8.46.2 debug: 4.4.3 @@ -11278,19 +11168,19 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.4.5) - typescript: 5.4.5 + ts-api-utils: 2.1.0(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.46.2 '@typescript-eslint/types': 8.46.2 - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.6.3) eslint: 9.39.0(jiti@2.6.1) - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -11360,11 +11250,15 @@ snapshots: '@ver0/deep-equal@1.0.0': {} - '@vitejs/plugin-basic-ssl@1.1.0(vite@5.4.21(@types/node@24.9.2)(less@4.2.0)(sass@1.77.6)(terser@5.31.6))': + '@vitejs/plugin-basic-ssl@1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))': + dependencies: + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) + + '@vitejs/plugin-basic-ssl@1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': dependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.2.0)(sass@1.77.6)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))': + '@vitejs/plugin-react@4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -11372,54 +11266,55 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))(vue@3.5.22(typescript@5.4.5))': + '@vitejs/plugin-vue@5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3))': dependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) - vue: 3.5.22(typescript@5.4.5) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vue: 3.5.22(typescript@5.6.3) - '@vitest/expect@2.1.9': + '@vitest/expect@4.1.4': dependencies: - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - tinyrainbow: 1.2.0 + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.4 + '@vitest/utils': 4.1.4 + chai: 6.2.2 + tinyrainbow: 3.1.0 - '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6))': + '@vitest/mocker@4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': dependencies: - '@vitest/spy': 2.1.9 + '@vitest/spy': 4.1.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - '@vitest/pretty-format@2.1.9': + '@vitest/pretty-format@4.1.4': dependencies: - tinyrainbow: 1.2.0 + tinyrainbow: 3.1.0 - '@vitest/runner@2.1.9': + '@vitest/runner@4.1.4': dependencies: - '@vitest/utils': 2.1.9 - pathe: 1.1.2 + '@vitest/utils': 4.1.4 + pathe: 2.0.3 - '@vitest/snapshot@2.1.9': + '@vitest/snapshot@4.1.4': dependencies: - '@vitest/pretty-format': 2.1.9 + '@vitest/pretty-format': 4.1.4 + '@vitest/utils': 4.1.4 magic-string: 0.30.21 - pathe: 1.1.2 + pathe: 2.0.3 - '@vitest/spy@2.1.9': - dependencies: - tinyspy: 3.0.2 + '@vitest/spy@4.1.4': {} - '@vitest/utils@2.1.9': + '@vitest/utils@4.1.4': dependencies: - '@vitest/pretty-format': 2.1.9 - loupe: 3.2.1 - tinyrainbow: 1.2.0 + '@vitest/pretty-format': 4.1.4 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 '@volar/language-core@2.4.15': dependencies: @@ -11482,7 +11377,7 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/language-core@2.1.6(typescript@5.4.5)': + '@vue/language-core@2.1.6(typescript@5.6.3)': dependencies: '@volar/language-core': 2.4.23 '@vue/compiler-dom': 3.5.22 @@ -11493,9 +11388,9 @@ snapshots: muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 - '@vue/language-core@2.2.12(typescript@5.4.5)': + '@vue/language-core@2.2.12(typescript@5.6.3)': dependencies: '@volar/language-core': 2.4.15 '@vue/compiler-dom': 3.5.22 @@ -11506,7 +11401,7 @@ snapshots: muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 '@vue/reactivity@3.5.22': dependencies: @@ -11524,28 +11419,28 @@ snapshots: '@vue/shared': 3.5.22 csstype: 3.1.3 - '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.4.5))': + '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.6.3))': dependencies: '@vue/compiler-ssr': 3.5.22 '@vue/shared': 3.5.22 - vue: 3.5.22(typescript@5.4.5) + vue: 3.5.22(typescript@5.6.3) '@vue/shared@3.5.22': {} - '@vueuse/core@12.8.2(typescript@5.4.5)': + '@vueuse/core@12.8.2(typescript@5.6.3)': dependencies: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 12.8.2 - '@vueuse/shared': 12.8.2(typescript@5.4.5) - vue: 3.5.22(typescript@5.4.5) + '@vueuse/shared': 12.8.2(typescript@5.6.3) + vue: 3.5.22(typescript@5.6.3) transitivePeerDependencies: - typescript '@vueuse/metadata@12.8.2': {} - '@vueuse/shared@12.8.2(typescript@5.4.5)': + '@vueuse/shared@12.8.2(typescript@5.6.3)': dependencies: - vue: 3.5.22(typescript@5.4.5) + vue: 3.5.22(typescript@5.6.3) transitivePeerDependencies: - typescript @@ -11716,14 +11611,14 @@ snapshots: dependencies: argparse: 2.0.1 - abbrev@2.0.0: {} + abbrev@3.0.1: {} accepts@1.3.8: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-attributes@1.9.5(acorn@8.15.0): + acorn-import-phases@1.0.4(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -11740,11 +11635,6 @@ snapshots: agent-base@7.1.4: {} - aggregate-error@3.1.0: - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - ajv-draft-04@1.0.0(ajv@8.13.0): optionalDependencies: ajv: 8.13.0 @@ -11757,13 +11647,9 @@ snapshots: optionalDependencies: ajv: 8.13.0 - ajv-formats@3.0.1(ajv@8.17.1): + ajv-formats@3.0.1(ajv@8.18.0): optionalDependencies: - ajv: 8.17.1 - - ajv-keywords@3.5.2(ajv@6.12.6): - dependencies: - ajv: 6.12.6 + ajv: 8.18.0 ajv-keywords@5.1.0(ajv@8.17.1): dependencies: @@ -11798,6 +11684,13 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + alien-signals@1.0.13: {} ansi-colors@4.1.3: {} @@ -11851,14 +11744,14 @@ snapshots: asynckit@0.4.0: {} - autoprefixer@10.4.20(postcss@8.4.41): + autoprefixer@10.4.20(postcss@8.5.2): dependencies: browserslist: 4.27.0 caniuse-lite: 1.0.30001752 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.4.41 + postcss: 8.5.2 postcss-value-parser: 4.2.0 axe-core@4.11.0: {} @@ -11873,12 +11766,12 @@ snapshots: axobject-query@4.1.0: {} - babel-loader@9.1.3(@babel/core@7.26.10)(webpack@5.94.0): + babel-loader@9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)): dependencies: '@babel/core': 7.26.10 find-cache-dir: 4.0.0 schema-utils: 4.3.3 - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.28.5): dependencies: @@ -11924,10 +11817,23 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.10.18: {} + baseline-browser-mapping@2.8.22: {} batch@0.6.1: {} + beasties@0.3.2: + dependencies: + css-select: 5.2.2 + css-what: 6.2.2 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + htmlparser2: 10.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-media-query-parser: 0.2.3 + better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 @@ -11991,6 +11897,14 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.27.0) + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.18 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.336 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + buffer-from@1.1.2: {} buffer@5.7.1: @@ -12004,11 +11918,9 @@ snapshots: bytes@3.1.2: {} - cac@6.7.14: {} - - cacache@18.0.4: + cacache@19.0.1: dependencies: - '@npmcli/fs': 3.1.1 + '@npmcli/fs': 4.0.0 fs-minipass: 3.0.3 glob: 10.4.5 lru-cache: 10.4.3 @@ -12016,10 +11928,10 @@ snapshots: minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 - p-map: 4.0.0 - ssri: 10.0.6 - tar: 6.2.1 - unique-filename: 3.0.0 + p-map: 7.0.4 + ssri: 12.0.0 + tar: 7.5.13 + unique-filename: 4.0.0 cache-content-type@1.0.1: dependencies: @@ -12040,29 +11952,21 @@ snapshots: caniuse-lite@1.0.30001752: {} + caniuse-lite@1.0.30001787: {} + chai-a11y-axe@1.5.0: dependencies: axe-core: 4.11.0 - chai@5.3.3: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + chai@6.2.2: {} chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - chardet@0.7.0: {} - chardet@2.1.1: {} - check-error@2.1.1: {} - cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -12104,9 +12008,9 @@ snapshots: chownr@2.0.0: {} - chrome-trace-event@1.0.4: {} + chownr@3.0.0: {} - clean-stack@2.2.0: {} + chrome-trace-event@1.0.4: {} cli-cursor@3.1.0: dependencies: @@ -12173,7 +12077,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@12.1.0: {} + commander@13.1.0: + optional: true commander@2.20.3: {} @@ -12181,7 +12086,8 @@ snapshots: common-path-prefix@3.0.0: {} - commondir@1.0.1: {} + commondir@1.0.1: + optional: true compare-versions@6.1.1: {} @@ -12232,7 +12138,7 @@ snapshots: dependencies: is-what: 3.14.1 - copy-webpack-plugin@12.0.2(webpack@5.94.0): + copy-webpack-plugin@12.0.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -12240,7 +12146,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) core-js-compat@3.46.0: dependencies: @@ -12248,24 +12154,14 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig@9.0.0(typescript@5.4.5): + cosmiconfig@9.0.0(typescript@5.6.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: - typescript: 5.4.5 - - critters@0.0.24: - dependencies: - chalk: 4.1.2 - css-select: 5.2.2 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - htmlparser2: 8.0.2 - postcss: 8.5.6 - postcss-media-query-parser: 0.2.3 + typescript: 5.6.3 cross-spawn@7.0.6: dependencies: @@ -12273,7 +12169,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.2(webpack@5.94.0): + css-loader@7.1.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -12284,7 +12180,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.3 optionalDependencies: - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) css-select@5.2.2: dependencies: @@ -12345,8 +12241,6 @@ snapshots: dedent-js@1.0.1: {} - deep-eql@5.0.2: {} - deep-equal@1.0.1: {} deep-is@0.1.4: {} @@ -12382,7 +12276,8 @@ snapshots: dependency-graph@0.11.0: {} - dependency-graph@1.0.0: {} + dependency-graph@1.0.0: + optional: true dequal@2.0.3: {} @@ -12393,7 +12288,8 @@ snapshots: detect-libc@1.0.3: optional: true - detect-libc@2.1.2: {} + detect-libc@2.1.2: + optional: true detect-node@2.1.0: {} @@ -12447,6 +12343,8 @@ snapshots: electron-to-chromium@1.5.244: {} + electron-to-chromium@1.5.336: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -12478,6 +12376,11 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.0 + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + enquirer@2.3.6: dependencies: ansi-colors: 4.1.3 @@ -12514,6 +12417,8 @@ snapshots: es-module-lexer@1.7.0: {} + es-module-lexer@2.0.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -12525,87 +12430,64 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - esbuild-wasm@0.23.0: {} + esbuild-wasm@0.25.4: {} - esbuild@0.21.5: + esbuild@0.25.12: optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - esbuild@0.23.0: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esbuild@0.25.4: optionalDependencies: - '@esbuild/aix-ppc64': 0.23.0 - '@esbuild/android-arm': 0.23.0 - '@esbuild/android-arm64': 0.23.0 - '@esbuild/android-x64': 0.23.0 - '@esbuild/darwin-arm64': 0.23.0 - '@esbuild/darwin-x64': 0.23.0 - '@esbuild/freebsd-arm64': 0.23.0 - '@esbuild/freebsd-x64': 0.23.0 - '@esbuild/linux-arm': 0.23.0 - '@esbuild/linux-arm64': 0.23.0 - '@esbuild/linux-ia32': 0.23.0 - '@esbuild/linux-loong64': 0.23.0 - '@esbuild/linux-mips64el': 0.23.0 - '@esbuild/linux-ppc64': 0.23.0 - '@esbuild/linux-riscv64': 0.23.0 - '@esbuild/linux-s390x': 0.23.0 - '@esbuild/linux-x64': 0.23.0 - '@esbuild/netbsd-x64': 0.23.0 - '@esbuild/openbsd-arm64': 0.23.0 - '@esbuild/openbsd-x64': 0.23.0 - '@esbuild/sunos-x64': 0.23.0 - '@esbuild/win32-arm64': 0.23.0 - '@esbuild/win32-ia32': 0.23.0 - '@esbuild/win32-x64': 0.23.0 - - esbuild@0.23.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.23.1 - '@esbuild/android-arm': 0.23.1 - '@esbuild/android-arm64': 0.23.1 - '@esbuild/android-x64': 0.23.1 - '@esbuild/darwin-arm64': 0.23.1 - '@esbuild/darwin-x64': 0.23.1 - '@esbuild/freebsd-arm64': 0.23.1 - '@esbuild/freebsd-x64': 0.23.1 - '@esbuild/linux-arm': 0.23.1 - '@esbuild/linux-arm64': 0.23.1 - '@esbuild/linux-ia32': 0.23.1 - '@esbuild/linux-loong64': 0.23.1 - '@esbuild/linux-mips64el': 0.23.1 - '@esbuild/linux-ppc64': 0.23.1 - '@esbuild/linux-riscv64': 0.23.1 - '@esbuild/linux-s390x': 0.23.1 - '@esbuild/linux-x64': 0.23.1 - '@esbuild/netbsd-x64': 0.23.1 - '@esbuild/openbsd-arm64': 0.23.1 - '@esbuild/openbsd-x64': 0.23.1 - '@esbuild/sunos-x64': 0.23.1 - '@esbuild/win32-arm64': 0.23.1 - '@esbuild/win32-ia32': 0.23.1 - '@esbuild/win32-x64': 0.23.1 + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 escalade@3.2.0: {} @@ -12634,7 +12516,7 @@ snapshots: eslint: 9.39.0(jiti@2.6.1) eslint-compat-utils: 0.5.1(eslint@9.39.0(jiti@2.6.1)) - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.39.0(jiti@2.6.1)): + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1)): dependencies: '@typescript-eslint/types': 8.46.2 comment-parser: 1.4.1 @@ -12647,11 +12529,11 @@ snapshots: stable-hash-x: 0.2.0 unrs-resolver: 1.11.1 optionalDependencies: - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) transitivePeerDependencies: - supports-color - eslint-plugin-n@17.23.1(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5): + eslint-plugin-n@17.23.1(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3): dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.0(jiti@2.6.1)) enhanced-resolve: 5.18.3 @@ -12662,7 +12544,7 @@ snapshots: globrex: 0.1.2 ignore: 5.3.2 semver: 7.7.3 - ts-declaration-location: 1.0.7(typescript@5.4.5) + ts-declaration-location: 1.0.7(typescript@5.6.3) transitivePeerDependencies: - typescript @@ -12769,7 +12651,7 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - expect-type@1.2.2: {} + expect-type@1.3.0: {} exponential-backoff@3.1.3: {} @@ -12811,22 +12693,8 @@ snapshots: extendable-error@0.1.7: {} - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - fast-deep-equal@3.1.3: {} - fast-glob@3.3.2: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -12857,6 +12725,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -12886,6 +12758,7 @@ snapshots: commondir: 1.0.1 make-dir: 3.1.0 pkg-dir: 4.2.0 + optional: true find-cache-dir@4.0.0: dependencies: @@ -13080,7 +12953,7 @@ snapshots: he@1.2.0: {} - hosted-git-info@7.0.2: + hosted-git-info@8.1.0: dependencies: lru-cache: 10.4.3 @@ -13110,13 +12983,6 @@ snapshots: domutils: 3.2.2 entities: 6.0.1 - htmlparser2@8.0.2: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 4.5.0 - http-assert@1.5.0: dependencies: deep-equal: 1.0.1 @@ -13189,13 +13055,6 @@ snapshots: transitivePeerDependencies: - debug - https-proxy-agent@7.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -13227,7 +13086,7 @@ snapshots: ieee754@1.2.1: {} - ignore-walk@6.0.5: + ignore-walk@7.0.0: dependencies: minimatch: 9.0.5 @@ -13238,8 +13097,6 @@ snapshots: image-size@0.5.5: optional: true - immutable@4.3.7: {} - immutable@5.1.4: {} import-fresh@3.3.1: @@ -13259,11 +13116,12 @@ snapshots: inherits@2.0.4: {} - ini@4.1.3: {} + ini@5.0.0: {} injection-js@2.6.1: dependencies: tslib: 2.8.1 + optional: true internal-ip@6.2.0: dependencies: @@ -13326,10 +13184,6 @@ snapshots: dependencies: ip-regex: 4.3.0 - is-lambda@1.0.1: {} - - is-module@1.0.0: {} - is-network-error@1.3.0: {} is-number@7.0.0: {} @@ -13479,7 +13333,7 @@ snapshots: json-parse-even-better-errors@2.3.1: {} - json-parse-even-better-errors@3.0.2: {} + json-parse-even-better-errors@4.0.0: {} json-schema-traverse@0.4.1: {} @@ -13515,7 +13369,7 @@ snapshots: kleur@4.1.5: {} - knip@5.66.4(@types/node@24.9.2)(typescript@5.4.5): + knip@5.66.4(@types/node@24.9.2)(typescript@5.6.3): dependencies: '@nodelib/fs.walk': 1.2.8 '@types/node': 24.9.2 @@ -13529,7 +13383,7 @@ snapshots: picomatch: 4.0.3 smol-toml: 1.4.2 strip-json-comments: 5.0.2 - typescript: 5.4.5 + typescript: 5.6.3 zod: 4.1.12 koa-compose@4.1.0: {} @@ -13593,13 +13447,13 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.8.3 - less-loader@12.2.0(less@4.2.0)(webpack@5.94.0): + less-loader@12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)): dependencies: - less: 4.2.0 + less: 4.2.2 optionalDependencies: - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) - less@4.2.0: + less@4.2.2: dependencies: copy-anything: 2.0.6 parse-node-version: 1.0.1 @@ -13626,23 +13480,24 @@ snapshots: mime: 1.6.0 needle: 3.3.1 source-map: 0.6.1 + optional: true levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.94.0): + license-webpack-plugin@4.0.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: webpack-sources: 3.3.3 optionalDependencies: - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) lines-and-columns@1.2.4: {} lines-and-columns@2.0.3: {} - listr2@8.2.4: + listr2@8.2.5: dependencies: cli-truncate: 4.0.0 colorette: 2.0.20 @@ -13667,7 +13522,7 @@ snapshots: lit-element: 4.2.1 lit-html: 3.3.1 - lmdb@3.0.13: + lmdb@3.2.6: dependencies: msgpackr: 1.11.5 node-addon-api: 6.1.0 @@ -13675,12 +13530,13 @@ snapshots: ordered-binary: 1.6.0 weak-lru-cache: 1.2.2 optionalDependencies: - '@lmdb/lmdb-darwin-arm64': 3.0.13 - '@lmdb/lmdb-darwin-x64': 3.0.13 - '@lmdb/lmdb-linux-arm': 3.0.13 - '@lmdb/lmdb-linux-arm64': 3.0.13 - '@lmdb/lmdb-linux-x64': 3.0.13 - '@lmdb/lmdb-win32-x64': 3.0.13 + '@lmdb/lmdb-darwin-arm64': 3.2.6 + '@lmdb/lmdb-darwin-x64': 3.2.6 + '@lmdb/lmdb-linux-arm': 3.2.6 + '@lmdb/lmdb-linux-arm64': 3.2.6 + '@lmdb/lmdb-linux-x64': 3.2.6 + '@lmdb/lmdb-win32-x64': 3.2.6 + optional: true loader-runner@4.3.1: {} @@ -13743,8 +13599,6 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.2.1: {} - lru-cache@10.4.3: {} lru-cache@11.2.2: {} @@ -13761,7 +13615,7 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.30.11: + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -13778,25 +13632,25 @@ snapshots: make-dir@3.1.0: dependencies: semver: 6.3.1 + optional: true make-dir@4.0.0: dependencies: semver: 7.7.3 - make-fetch-happen@13.0.1: + make-fetch-happen@14.0.3: dependencies: - '@npmcli/agent': 2.2.2 - cacache: 18.0.4 + '@npmcli/agent': 3.0.0 + cacache: 19.0.1 http-cache-semantics: 4.2.0 - is-lambda: 1.0.1 minipass: 7.1.2 - minipass-fetch: 3.0.5 + minipass-fetch: 4.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 - negotiator: 0.6.4 - proc-log: 4.2.0 + negotiator: 1.0.0 + proc-log: 5.0.0 promise-retry: 2.0.1 - ssri: 10.0.6 + ssri: 12.0.0 transitivePeerDependencies: - supports-color @@ -13857,11 +13711,11 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.0(webpack@5.94.0): + mini-css-extract-plugin@2.9.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) minimalistic-assert@1.0.1: {} @@ -13891,11 +13745,11 @@ snapshots: dependencies: minipass: 7.1.2 - minipass-fetch@3.0.5: + minipass-fetch@4.0.1: dependencies: minipass: 7.1.2 minipass-sized: 1.0.3 - minizlib: 2.1.2 + minizlib: 3.1.0 optionalDependencies: encoding: 0.1.13 @@ -13924,6 +13778,10 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + mkdirp@1.0.4: {} mlly@1.8.0: @@ -13935,7 +13793,7 @@ snapshots: mri@1.2.0: {} - mrmime@2.0.0: {} + mrmime@2.0.1: {} ms@2.0.0: {} @@ -13956,6 +13814,7 @@ snapshots: msgpackr@1.11.5: optionalDependencies: msgpackr-extract: 3.0.3 + optional: true muggle-string@0.4.1: {} @@ -13966,6 +13825,8 @@ snapshots: mute-stream@1.0.0: {} + mute-stream@2.0.0: {} + nanocolors@0.2.13: {} nanoid@3.3.11: {} @@ -13984,23 +13845,23 @@ snapshots: negotiator@0.6.4: {} + negotiator@1.0.0: {} + neo-async@2.6.2: {} - ng-packagr@18.2.1(@angular/compiler-cli@18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5))(tslib@2.8.1)(typescript@5.4.5): + ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3): dependencies: - '@angular/compiler-cli': 18.2.14(@angular/compiler@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.4.5) - '@rollup/plugin-json': 6.1.0(rollup@4.52.5) - '@rollup/plugin-node-resolve': 15.3.1(rollup@4.52.5) + '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) + '@rollup/plugin-json': 6.1.0(rollup@4.59.0) '@rollup/wasm-node': 4.52.5 - ajv: 8.17.1 + ajv: 8.18.0 ansi-colors: 4.1.3 - browserslist: 4.27.0 - cacache: 18.0.4 - chokidar: 3.6.0 - commander: 12.1.0 + browserslist: 4.28.2 + chokidar: 4.0.3 + commander: 13.1.0 convert-source-map: 2.0.0 dependency-graph: 1.0.0 - esbuild: 0.23.1 + esbuild: 0.25.12 fast-glob: 3.3.3 find-cache-dir: 3.3.2 injection-js: 2.6.1 @@ -14012,21 +13873,14 @@ snapshots: rxjs: 7.8.2 sass: 1.93.3 tslib: 2.8.1 - typescript: 5.4.5 + typescript: 5.6.3 optionalDependencies: - rollup: 4.52.5 - - nice-napi@1.0.2: - dependencies: - node-addon-api: 3.2.1 - node-gyp-build: 4.8.4 + rollup: 4.59.0 optional: true - node-addon-api@3.2.1: + node-addon-api@6.1.0: optional: true - node-addon-api@6.1.0: {} - node-addon-api@7.1.1: optional: true @@ -14041,22 +13895,20 @@ snapshots: node-gyp-build-optional-packages@5.2.2: dependencies: detect-libc: 2.1.2 - - node-gyp-build@4.8.4: optional: true - node-gyp@10.3.1: + node-gyp@11.5.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 - glob: 10.4.5 graceful-fs: 4.2.11 - make-fetch-happen: 13.0.1 - nopt: 7.2.1 - proc-log: 4.2.0 + make-fetch-happen: 14.0.3 + nopt: 8.1.0 + proc-log: 5.0.0 semver: 7.7.3 - tar: 6.2.1 - which: 4.0.0 + tar: 7.5.13 + tinyglobby: 0.2.15 + which: 5.0.0 transitivePeerDependencies: - supports-color @@ -14064,58 +13916,54 @@ snapshots: node-releases@2.0.27: {} - nopt@7.2.1: - dependencies: - abbrev: 2.0.0 + node-releases@2.0.37: {} - normalize-package-data@6.0.2: + nopt@8.1.0: dependencies: - hosted-git-info: 7.0.2 - semver: 7.7.3 - validate-npm-package-license: 3.0.4 + abbrev: 3.0.1 normalize-path@3.0.0: {} normalize-range@0.1.2: {} - npm-bundled@3.0.1: + npm-bundled@4.0.0: dependencies: - npm-normalize-package-bin: 3.0.1 + npm-normalize-package-bin: 4.0.0 - npm-install-checks@6.3.0: + npm-install-checks@7.1.2: dependencies: semver: 7.7.3 - npm-normalize-package-bin@3.0.1: {} + npm-normalize-package-bin@4.0.0: {} - npm-package-arg@11.0.3: + npm-package-arg@12.0.2: dependencies: - hosted-git-info: 7.0.2 - proc-log: 4.2.0 + hosted-git-info: 8.1.0 + proc-log: 5.0.0 semver: 7.7.3 - validate-npm-package-name: 5.0.1 + validate-npm-package-name: 6.0.2 - npm-packlist@8.0.2: + npm-packlist@9.0.0: dependencies: - ignore-walk: 6.0.5 + ignore-walk: 7.0.0 - npm-pick-manifest@9.1.0: + npm-pick-manifest@10.0.0: dependencies: - npm-install-checks: 6.3.0 - npm-normalize-package-bin: 3.0.1 - npm-package-arg: 11.0.3 + npm-install-checks: 7.1.2 + npm-normalize-package-bin: 4.0.0 + npm-package-arg: 12.0.2 semver: 7.7.3 - npm-registry-fetch@17.1.0: + npm-registry-fetch@18.0.2: dependencies: - '@npmcli/redact': 2.0.1 + '@npmcli/redact': 3.2.2 jsonparse: 1.3.1 - make-fetch-happen: 13.0.1 + make-fetch-happen: 14.0.3 minipass: 7.1.2 - minipass-fetch: 3.0.5 - minizlib: 2.1.2 - npm-package-arg: 11.0.3 - proc-log: 4.2.0 + minipass-fetch: 4.0.1 + minizlib: 3.1.0 + npm-package-arg: 12.0.2 + proc-log: 5.0.0 transitivePeerDependencies: - supports-color @@ -14182,6 +14030,8 @@ snapshots: obuf@1.1.2: {} + obug@2.1.1: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -14247,9 +14097,8 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - ordered-binary@1.6.0: {} - - os-tmpdir@1.0.2: {} + ordered-binary@1.6.0: + optional: true outdent@0.5.0: {} @@ -14311,9 +14160,7 @@ snapshots: p-map@2.1.0: {} - p-map@4.0.0: - dependencies: - aggregate-error: 3.1.0 + p-map@7.0.4: {} p-retry@6.2.1: dependencies: @@ -14335,27 +14182,26 @@ snapshots: package-manager-detector@1.5.0: {} - pacote@18.0.6: + pacote@20.0.0: dependencies: - '@npmcli/git': 5.0.8 - '@npmcli/installed-package-contents': 2.1.0 - '@npmcli/package-json': 5.2.1 - '@npmcli/promise-spawn': 7.0.2 - '@npmcli/run-script': 8.1.0 - cacache: 18.0.4 + '@npmcli/git': 6.0.3 + '@npmcli/installed-package-contents': 3.0.0 + '@npmcli/package-json': 6.2.0 + '@npmcli/promise-spawn': 8.0.3 + '@npmcli/run-script': 9.1.0 + cacache: 19.0.1 fs-minipass: 3.0.3 minipass: 7.1.2 - npm-package-arg: 11.0.3 - npm-packlist: 8.0.2 - npm-pick-manifest: 9.1.0 - npm-registry-fetch: 17.1.0 - proc-log: 4.2.0 + npm-package-arg: 12.0.2 + npm-packlist: 9.0.0 + npm-pick-manifest: 10.0.0 + npm-registry-fetch: 18.0.2 + proc-log: 5.0.0 promise-retry: 2.0.1 - sigstore: 2.3.1 - ssri: 10.0.6 + sigstore: 3.1.0 + ssri: 12.0.0 tar: 6.2.1 transitivePeerDependencies: - - bluebird - supports-color parent-module@1.0.1: @@ -14425,12 +14271,8 @@ snapshots: path-type@6.0.0: {} - pathe@1.1.2: {} - pathe@2.0.3: {} - pathval@2.0.1: {} - periscopic@3.1.0: dependencies: '@types/estree': 1.0.8 @@ -14441,23 +14283,25 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} - picomatch@4.0.3: {} + picomatch@4.0.4: {} + pify@4.0.1: {} - piscina@4.6.1: + piscina@4.8.0: optionalDependencies: - nice-napi: 1.0.2 + '@napi-rs/nice': 1.1.1 piscina@4.9.2: optionalDependencies: '@napi-rs/nice': 1.1.1 + optional: true pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + optional: true pkg-dir@7.0.0: dependencies: @@ -14477,14 +14321,14 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-loader@8.1.1(postcss@8.4.41)(typescript@5.4.5)(webpack@5.94.0): + postcss-loader@8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)): dependencies: - cosmiconfig: 9.0.0(typescript@5.4.5) + cosmiconfig: 9.0.0(typescript@5.6.3) jiti: 1.21.7 - postcss: 8.4.41 + postcss: 8.5.2 semver: 7.7.3 optionalDependencies: - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) transitivePeerDependencies: - typescript @@ -14518,7 +14362,7 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.41: + postcss@8.5.2: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -14555,12 +14399,10 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 - proc-log@4.2.0: {} + proc-log@5.0.0: {} process-nextick-args@2.0.1: {} - promise-inflight@1.0.1: {} - promise-retry@2.0.1: dependencies: err-code: 2.0.3 @@ -14718,13 +14560,13 @@ snapshots: resolve.exports@2.0.3: {} - resolve@1.22.11: + resolve@1.22.10: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@1.22.8: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 @@ -14748,60 +14590,41 @@ snapshots: rfdc@1.4.1: {} - rollup-plugin-preserve-directives@0.4.0(rollup@4.52.5): + rollup-plugin-preserve-directives@0.4.0(rollup@4.59.0): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) magic-string: 0.30.21 - rollup: 4.52.5 - - rollup@4.22.4: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.22.4 - '@rollup/rollup-android-arm64': 4.22.4 - '@rollup/rollup-darwin-arm64': 4.22.4 - '@rollup/rollup-darwin-x64': 4.22.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.22.4 - '@rollup/rollup-linux-arm-musleabihf': 4.22.4 - '@rollup/rollup-linux-arm64-gnu': 4.22.4 - '@rollup/rollup-linux-arm64-musl': 4.22.4 - '@rollup/rollup-linux-powerpc64le-gnu': 4.22.4 - '@rollup/rollup-linux-riscv64-gnu': 4.22.4 - '@rollup/rollup-linux-s390x-gnu': 4.22.4 - '@rollup/rollup-linux-x64-gnu': 4.22.4 - '@rollup/rollup-linux-x64-musl': 4.22.4 - '@rollup/rollup-win32-arm64-msvc': 4.22.4 - '@rollup/rollup-win32-ia32-msvc': 4.22.4 - '@rollup/rollup-win32-x64-msvc': 4.22.4 - fsevents: 2.3.3 + rollup: 4.59.0 - rollup@4.52.5: + rollup@4.59.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.5 - '@rollup/rollup-android-arm64': 4.52.5 - '@rollup/rollup-darwin-arm64': 4.52.5 - '@rollup/rollup-darwin-x64': 4.52.5 - '@rollup/rollup-freebsd-arm64': 4.52.5 - '@rollup/rollup-freebsd-x64': 4.52.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 - '@rollup/rollup-linux-arm-musleabihf': 4.52.5 - '@rollup/rollup-linux-arm64-gnu': 4.52.5 - '@rollup/rollup-linux-arm64-musl': 4.52.5 - '@rollup/rollup-linux-loong64-gnu': 4.52.5 - '@rollup/rollup-linux-ppc64-gnu': 4.52.5 - '@rollup/rollup-linux-riscv64-gnu': 4.52.5 - '@rollup/rollup-linux-riscv64-musl': 4.52.5 - '@rollup/rollup-linux-s390x-gnu': 4.52.5 - '@rollup/rollup-linux-x64-gnu': 4.52.5 - '@rollup/rollup-linux-x64-musl': 4.52.5 - '@rollup/rollup-openharmony-arm64': 4.52.5 - '@rollup/rollup-win32-arm64-msvc': 4.52.5 - '@rollup/rollup-win32-ia32-msvc': 4.52.5 - '@rollup/rollup-win32-x64-gnu': 4.52.5 - '@rollup/rollup-win32-x64-msvc': 4.52.5 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 run-applescript@7.1.0: {} @@ -14834,18 +14657,20 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@16.0.0(sass@1.77.6)(webpack@5.94.0): + sass-loader@16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)): dependencies: neo-async: 2.6.2 optionalDependencies: - sass: 1.77.6 - webpack: 5.94.0(esbuild@0.23.0) + sass: 1.85.0 + webpack: 5.105.0(esbuild@0.25.4) - sass@1.77.6: + sass@1.85.0: dependencies: - chokidar: 3.6.0 - immutable: 4.3.7 + chokidar: 4.0.3 + immutable: 5.1.4 source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.1 sass@1.93.3: dependencies: @@ -14854,6 +14679,7 @@ snapshots: source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.1 + optional: true sax@1.4.1: optional: true @@ -14866,12 +14692,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - schema-utils@3.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 @@ -14897,7 +14717,7 @@ snapshots: dependencies: lru-cache: 6.0.0 - semver@7.6.3: {} + semver@7.7.1: {} semver@7.7.3: {} @@ -15035,14 +14855,14 @@ snapshots: signal-exit@4.1.0: {} - sigstore@2.3.1: + sigstore@3.1.0: dependencies: - '@sigstore/bundle': 2.3.2 - '@sigstore/core': 1.1.0 - '@sigstore/protobuf-specs': 0.3.3 - '@sigstore/sign': 2.3.2 - '@sigstore/tuf': 2.3.4 - '@sigstore/verify': 1.2.1 + '@sigstore/bundle': 3.1.0 + '@sigstore/core': 2.0.0 + '@sigstore/protobuf-specs': 0.4.3 + '@sigstore/sign': 3.1.0 + '@sigstore/tuf': 3.1.1 + '@sigstore/verify': 2.1.1 transitivePeerDependencies: - supports-color @@ -15106,11 +14926,11 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.94.0): + source-map-loader@5.0.0(webpack@5.105.0(esbuild@0.25.4)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) source-map-support@0.5.21: dependencies: @@ -15165,7 +14985,7 @@ snapshots: sprintf-js@1.0.3: {} - ssri@10.0.6: + ssri@12.0.0: dependencies: minipass: 7.1.2 @@ -15177,7 +14997,7 @@ snapshots: statuses@2.0.1: {} - std-env@3.10.0: {} + std-env@4.1.0: {} string-argv@0.3.2: {} @@ -15237,15 +15057,15 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.3.3(picomatch@4.0.3)(svelte@4.2.20)(typescript@5.4.5): + svelte-check@4.3.3(picomatch@4.0.4)(svelte@4.2.20)(typescript@5.6.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 - fdir: 6.5.0(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.4) picocolors: 1.1.1 sade: 1.8.1 svelte: 4.2.20 - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - picomatch @@ -15253,12 +15073,12 @@ snapshots: dependencies: svelte: 4.2.20 - svelte2tsx@0.7.45(svelte@4.2.20)(typescript@5.4.5): + svelte2tsx@0.7.45(svelte@4.2.20)(typescript@5.6.3): dependencies: dedent-js: 1.0.1 scule: 1.3.0 svelte: 4.2.20 - typescript: 5.4.5 + typescript: 5.6.3 svelte@4.2.20: dependencies: @@ -15300,20 +15120,27 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.5.13: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + term-size@2.2.1: {} - terser-webpack-plugin@5.3.14(esbuild@0.23.0)(webpack@5.94.0): + terser-webpack-plugin@5.4.0(esbuild@0.25.4)(webpack@5.105.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.31.6 - webpack: 5.94.0(esbuild@0.23.0) + terser: 5.39.0 + webpack: 5.105.0(esbuild@0.25.4) optionalDependencies: - esbuild: 0.23.0 + esbuild: 0.25.4 - terser@5.31.6: + terser@5.39.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.15.0 @@ -15328,18 +15155,14 @@ snapshots: tinybench@2.9.0: {} - tinyexec@0.3.2: {} + tinyexec@1.1.1: {} tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - tinypool@1.1.1: {} - - tinyrainbow@1.2.0: {} - - tinyspy@3.0.2: {} + tinyrainbow@3.1.0: {} tldts-core@7.0.17: {} @@ -15347,10 +15170,6 @@ snapshots: dependencies: tldts-core: 7.0.17 - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - tmp@0.2.5: {} to-regex-range@5.0.1: @@ -15375,18 +15194,18 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.4.5): + ts-api-utils@2.1.0(typescript@5.6.3): dependencies: - typescript: 5.4.5 + typescript: 5.6.3 - ts-declaration-location@1.0.7(typescript@5.4.5): + ts-declaration-location@1.0.7(typescript@5.6.3): dependencies: - picomatch: 4.0.3 - typescript: 5.4.5 + picomatch: 4.0.4 + typescript: 5.6.3 - tsconfck@3.1.6(typescript@5.4.5): + tsconfck@3.1.6(typescript@5.6.3): optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 tsconfig-paths@4.2.0: dependencies: @@ -15394,17 +15213,15 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@2.6.3: {} - tslib@2.8.1: {} tsscmp@1.0.6: {} - tuf-js@2.2.1: + tuf-js@3.1.0: dependencies: - '@tufjs/models': 2.0.1 + '@tufjs/models': 3.0.1 debug: 4.4.3 - make-fetch-happen: 13.0.1 + make-fetch-happen: 14.0.3 transitivePeerDependencies: - supports-color @@ -15421,25 +15238,23 @@ snapshots: typed-assert@1.0.9: {} - typescript-eslint@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5): + typescript-eslint@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) - '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) - '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.4.5) - '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.6.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) eslint: 9.39.0(jiti@2.6.1) - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color typescript@5.4.2: {} - typescript@5.4.5: {} + typescript@5.6.3: {} ufo@1.6.1: {} - undici-types@6.21.0: {} - undici-types@7.16.0: {} undici@7.16.0: {} @@ -15457,11 +15272,11 @@ snapshots: unicorn-magic@0.3.0: {} - unique-filename@3.0.0: + unique-filename@4.0.0: dependencies: - unique-slug: 4.0.0 + unique-slug: 5.0.0 - unique-slug@4.0.0: + unique-slug@5.0.0: dependencies: imurmurhash: 0.1.4 @@ -15499,6 +15314,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -15514,52 +15335,34 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - validate-npm-package-name@5.0.1: {} + validate-npm-package-name@6.0.2: {} vary@1.1.2: {} - vite-node@2.1.9(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6): - dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 1.1.2 - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - vite-plugin-dts@4.2.3(@types/node@24.9.2)(rollup@4.52.5)(typescript@5.4.5)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)): + vite-plugin-dts@4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): dependencies: '@microsoft/api-extractor': 7.47.7(@types/node@24.9.2) - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) '@volar/typescript': 2.4.23 - '@vue/language-core': 2.1.6(typescript@5.4.5) + '@vue/language-core': 2.1.6(typescript@5.6.3) compare-versions: 6.1.1 debug: 4.4.3 kolorist: 1.8.0 local-pkg: 0.5.1 magic-string: 0.30.21 - typescript: 5.4.5 + typescript: 5.6.3 optionalDependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-externalize-deps@0.9.0(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)): + vite-plugin-externalize-deps@0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): dependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)): + vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): dependencies: '@babel/core': 7.28.5 '@types/babel__core': 7.20.5 @@ -15567,97 +15370,99 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.10 solid-refresh: 0.6.3(solid-js@1.9.10) - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) - vitefu: 1.1.1(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vitefu: 1.1.1(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) optionalDependencies: '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color - vite-tsconfig-paths@5.1.4(typescript@5.4.5)(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)): + vite-tsconfig-paths@5.1.4(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): dependencies: debug: 4.4.3 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.4.5) + tsconfck: 3.1.6(typescript@5.6.3) optionalDependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@5.4.21(@types/node@24.9.2)(less@4.2.0)(sass@1.77.6)(terser@5.31.6): + vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1): dependencies: - esbuild: 0.21.5 + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 postcss: 8.5.6 - rollup: 4.52.5 + rollup: 4.59.0 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.9.2 fsevents: 2.3.3 - less: 4.2.0 - sass: 1.77.6 - terser: 5.31.6 + jiti: 2.6.1 + less: 4.2.2 + sass: 1.85.0 + terser: 5.39.0 + yaml: 2.8.1 - vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6): + vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1): dependencies: - esbuild: 0.21.5 + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 postcss: 8.5.6 - rollup: 4.52.5 + rollup: 4.59.0 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.9.2 fsevents: 2.3.3 + jiti: 2.6.1 less: 4.4.2 sass: 1.93.3 - terser: 5.31.6 + terser: 5.39.0 + yaml: 2.8.1 - vitefu@0.2.5(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)): + vitefu@0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): optionalDependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - vitefu@1.1.1(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)): + vitefu@1.1.1(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): optionalDependencies: - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) - - vitest@2.1.9(@types/node@24.9.2)(jsdom@27.1.0)(less@4.4.2)(sass@1.93.3)(terser@5.31.6): - dependencies: - '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6)) - '@vitest/pretty-format': 2.1.9 - '@vitest/runner': 2.1.9 - '@vitest/snapshot': 2.1.9 - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - debug: 4.4.3 - expect-type: 1.2.2 + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + + vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + dependencies: + '@vitest/expect': 4.1.4 + '@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + '@vitest/pretty-format': 4.1.4 + '@vitest/runner': 4.1.4 + '@vitest/snapshot': 4.1.4 + '@vitest/spy': 4.1.4 + '@vitest/utils': 4.1.4 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 magic-string: 0.30.21 - pathe: 1.1.2 - std-env: 3.10.0 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.1.1 - tinyrainbow: 1.2.0 - vite: 5.4.21(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) - vite-node: 2.1.9(@types/node@24.9.2)(less@4.4.2)(sass@1.93.3)(terser@5.31.6) + tinyexec: 1.1.1 + tinyglobby: 0.2.15 + tinyrainbow: 3.1.0 + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.2 jsdom: 27.1.0 transitivePeerDependencies: - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser vscode-uri@3.1.0: {} - vue-demi@0.14.10(vue@3.5.22(typescript@5.4.5)): + vue-demi@0.14.10(vue@3.5.22(typescript@5.6.3)): dependencies: - vue: 3.5.22(typescript@5.4.5) + vue: 3.5.22(typescript@5.6.3) vue-eslint-parser@10.2.0(eslint@9.39.0(jiti@2.6.1)): dependencies: @@ -15671,21 +15476,21 @@ snapshots: transitivePeerDependencies: - supports-color - vue-tsc@2.2.12(typescript@5.4.5): + vue-tsc@2.2.12(typescript@5.6.3): dependencies: '@volar/typescript': 2.4.15 - '@vue/language-core': 2.2.12(typescript@5.4.5) - typescript: 5.4.5 + '@vue/language-core': 2.2.12(typescript@5.6.3) + typescript: 5.6.3 - vue@3.5.22(typescript@5.4.5): + vue@3.5.22(typescript@5.6.3): dependencies: '@vue/compiler-dom': 3.5.22 '@vue/compiler-sfc': 3.5.22 '@vue/runtime-dom': 3.5.22 - '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.4.5)) + '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.6.3)) '@vue/shared': 3.5.22 optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 w3c-xmlserializer@5.0.0: dependencies: @@ -15693,7 +15498,12 @@ snapshots: walk-up-path@4.0.0: {} - watchpack@2.4.1: + watchpack@2.4.2: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + watchpack@2.5.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -15706,13 +15516,14 @@ snapshots: dependencies: defaults: 1.0.4 - weak-lru-cache@1.2.2: {} + weak-lru-cache@1.2.2: + optional: true webidl-conversions@3.0.1: {} webidl-conversions@8.0.0: {} - webpack-dev-middleware@7.4.2(webpack@5.94.0(esbuild@0.23.0)): + webpack-dev-middleware@7.4.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: colorette: 2.0.20 memfs: 4.50.0 @@ -15721,9 +15532,9 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) - webpack-dev-server@5.2.2(webpack@5.94.0(esbuild@0.23.0)): + webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -15751,10 +15562,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.94.0(esbuild@0.23.0)) + webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) ws: 8.18.3 optionalDependencies: - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) transitivePeerDependencies: - bufferutil - debug @@ -15769,23 +15580,25 @@ snapshots: webpack-sources@3.3.3: {} - webpack-subresource-integrity@5.1.0(webpack@5.94.0): + webpack-subresource-integrity@5.1.0(webpack@5.105.0(esbuild@0.25.4)): dependencies: typed-assert: 1.0.9 - webpack: 5.94.0(esbuild@0.23.0) + webpack: 5.105.0(esbuild@0.25.4) - webpack@5.94.0(esbuild@0.23.0): + webpack@5.105.0(esbuild@0.25.4): dependencies: + '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) - browserslist: 4.27.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.3 - es-module-lexer: 1.7.0 + enhanced-resolve: 5.20.1 + es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -15794,10 +15607,10 @@ snapshots: loader-runner: 4.3.1 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 3.3.0 + schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(esbuild@0.23.0)(webpack@5.94.0) - watchpack: 2.4.1 + terser-webpack-plugin: 5.4.0(esbuild@0.25.4)(webpack@5.105.0) + watchpack: 2.5.1 webpack-sources: 3.3.3 transitivePeerDependencies: - '@swc/core' @@ -15832,7 +15645,7 @@ snapshots: dependencies: isexe: 2.0.0 - which@4.0.0: + which@5.0.0: dependencies: isexe: 3.1.1 @@ -15885,6 +15698,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml@2.8.1: {} yargs-parser@21.1.1: {} From ca8b4bae4011af5dd6bd60c5ecaa77c082d20169 Mon Sep 17 00:00:00 2001 From: Santosh Yadav Date: Sun, 26 Apr 2026 04:11:13 -0700 Subject: [PATCH 04/10] docs: update partner logos (#1145) --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2a437f2f9..5e460f451 100644 --- a/README.md +++ b/README.md @@ -57,21 +57,21 @@ A headless, framework‑agnostic virtualization library for rendering massive li - From 5ae5db111ef55df137a77fe3e6fbf19174f9cd11 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 13:38:08 +0200 Subject: [PATCH 05/10] ci: Version Packages (#1162) --- .changeset/gold-days-greet.md | 5 -- examples/angular/dynamic/package.json | 2 +- examples/angular/fixed/package.json | 2 +- examples/angular/infinite-scroll/package.json | 2 +- examples/angular/padding/package.json | 2 +- examples/angular/smooth-scroll/package.json | 2 +- examples/angular/sticky/package.json | 2 +- examples/angular/table/package.json | 2 +- examples/angular/variable/package.json | 2 +- examples/angular/window/package.json | 2 +- packages/angular-virtual/CHANGELOG.md | 6 ++ packages/angular-virtual/package.json | 2 +- pnpm-lock.yaml | 84 +++++++++---------- 13 files changed, 58 insertions(+), 57 deletions(-) delete mode 100644 .changeset/gold-days-greet.md diff --git a/.changeset/gold-days-greet.md b/.changeset/gold-days-greet.md deleted file mode 100644 index e606fd23f..000000000 --- a/.changeset/gold-days-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/angular-virtual': major ---- - -Angular +19 with proper lazy init diff --git a/examples/angular/dynamic/package.json b/examples/angular/dynamic/package.json index a863663aa..802f61bb7 100644 --- a/examples/angular/dynamic/package.json +++ b/examples/angular/dynamic/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/fixed/package.json b/examples/angular/fixed/package.json index ebc8abedd..1dbca6764 100644 --- a/examples/angular/fixed/package.json +++ b/examples/angular/fixed/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/infinite-scroll/package.json b/examples/angular/infinite-scroll/package.json index a55857eff..ede25efdd 100644 --- a/examples/angular/infinite-scroll/package.json +++ b/examples/angular/infinite-scroll/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@tanstack/angular-query-experimental": "5.80.7", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/padding/package.json b/examples/angular/padding/package.json index 981673126..a8cb1b742 100644 --- a/examples/angular/padding/package.json +++ b/examples/angular/padding/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/smooth-scroll/package.json b/examples/angular/smooth-scroll/package.json index eefc31796..1b033a33e 100644 --- a/examples/angular/smooth-scroll/package.json +++ b/examples/angular/smooth-scroll/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/sticky/package.json b/examples/angular/sticky/package.json index 1d5213bb1..642e5f3f6 100644 --- a/examples/angular/sticky/package.json +++ b/examples/angular/sticky/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/table/package.json b/examples/angular/table/package.json index b0a19837c..6d53b35e3 100644 --- a/examples/angular/table/package.json +++ b/examples/angular/table/package.json @@ -19,7 +19,7 @@ "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-table": "8.21.3", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/variable/package.json b/examples/angular/variable/package.json index fed28f9d2..3440f6bae 100644 --- a/examples/angular/variable/package.json +++ b/examples/angular/variable/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/window/package.json b/examples/angular/window/package.json index b8be6a829..7a71f362d 100644 --- a/examples/angular/window/package.json +++ b/examples/angular/window/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^4.0.13", + "@tanstack/angular-virtual": "^5.0.0", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/packages/angular-virtual/CHANGELOG.md b/packages/angular-virtual/CHANGELOG.md index 83ec12e89..397ff67dd 100644 --- a/packages/angular-virtual/CHANGELOG.md +++ b/packages/angular-virtual/CHANGELOG.md @@ -1,5 +1,11 @@ # @tanstack/angular-virtual +## 5.0.0 + +### Major Changes + +- Angular +19 with proper lazy init ([#1158](https://github.com/TanStack/virtual/pull/1158)) + ## 4.0.13 ### Patch Changes diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index e8e892ade..fecdc71fe 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/angular-virtual", - "version": "4.0.13", + "version": "5.0.0", "description": "Headless UI for virtualizing scrollable elements in Angular", "author": "Garrett Darnell", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0aae59636..984a869c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,7 +102,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -154,7 +154,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -209,7 +209,7 @@ importers: specifier: 5.80.7 version: 5.80.7(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -261,7 +261,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -313,7 +313,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -368,7 +368,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -426,7 +426,7 @@ importers: specifier: 8.21.3 version: 8.21.3(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -478,7 +478,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -530,7 +530,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.13 + specifier: ^5.0.0 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -8279,14 +8279,14 @@ snapshots: '@babel/preset-env': 7.26.9(@babel/core@7.26.10) '@babel/runtime': 7.26.10 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0) '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) - babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)) + babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0) browserslist: 4.27.0 - copy-webpack-plugin: 12.0.2(webpack@5.105.0(esbuild@0.25.4)) - css-loader: 7.1.2(webpack@5.105.0(esbuild@0.25.4)) + copy-webpack-plugin: 12.0.2(webpack@5.105.0) + css-loader: 7.1.2(webpack@5.105.0) esbuild-wasm: 0.25.4 fast-glob: 3.3.3 http-proxy-middleware: 3.0.5 @@ -8294,22 +8294,22 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.2.2 - less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)) - license-webpack-plugin: 4.0.2(webpack@5.105.0(esbuild@0.25.4)) + less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0) + license-webpack-plugin: 4.0.2(webpack@5.105.0) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.2(webpack@5.105.0(esbuild@0.25.4)) + mini-css-extract-plugin: 2.9.2(webpack@5.105.0) open: 10.1.0 ora: 5.4.1 picomatch: 4.0.4 piscina: 4.8.0 postcss: 8.5.2 - postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0) resolve-url-loader: 5.0.0 rxjs: 7.8.1 sass: 1.85.0 - sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)) + sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0) semver: 7.7.1 - source-map-loader: 5.0.0(webpack@5.105.0(esbuild@0.25.4)) + source-map-loader: 5.0.0(webpack@5.105.0) source-map-support: 0.5.21 terser: 5.39.0 tree-kill: 1.2.2 @@ -8319,7 +8319,7 @@ snapshots: webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.25.4)) + webpack-subresource-integrity: 5.1.0(webpack@5.105.0) optionalDependencies: esbuild: 0.25.4 ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) @@ -8364,14 +8364,14 @@ snapshots: '@babel/preset-env': 7.26.9(@babel/core@7.26.10) '@babel/runtime': 7.26.10 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0) '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) - babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)) + babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0) browserslist: 4.27.0 - copy-webpack-plugin: 12.0.2(webpack@5.105.0(esbuild@0.25.4)) - css-loader: 7.1.2(webpack@5.105.0(esbuild@0.25.4)) + copy-webpack-plugin: 12.0.2(webpack@5.105.0) + css-loader: 7.1.2(webpack@5.105.0) esbuild-wasm: 0.25.4 fast-glob: 3.3.3 http-proxy-middleware: 3.0.5 @@ -8379,22 +8379,22 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.2.2 - less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)) - license-webpack-plugin: 4.0.2(webpack@5.105.0(esbuild@0.25.4)) + less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0) + license-webpack-plugin: 4.0.2(webpack@5.105.0) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.2(webpack@5.105.0(esbuild@0.25.4)) + mini-css-extract-plugin: 2.9.2(webpack@5.105.0) open: 10.1.0 ora: 5.4.1 picomatch: 4.0.4 piscina: 4.8.0 postcss: 8.5.2 - postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) + postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0) resolve-url-loader: 5.0.0 rxjs: 7.8.1 sass: 1.85.0 - sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)) + sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0) semver: 7.7.1 - source-map-loader: 5.0.0(webpack@5.105.0(esbuild@0.25.4)) + source-map-loader: 5.0.0(webpack@5.105.0) source-map-support: 0.5.21 terser: 5.39.0 tree-kill: 1.2.2 @@ -8404,7 +8404,7 @@ snapshots: webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.25.4)) + webpack-subresource-integrity: 5.1.0(webpack@5.105.0) optionalDependencies: esbuild: 0.25.4 ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) @@ -10216,7 +10216,7 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@ngtools/webpack@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4))': + '@ngtools/webpack@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0)': dependencies: '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: 5.6.3 @@ -11766,7 +11766,7 @@ snapshots: axobject-query@4.1.0: {} - babel-loader@9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)): + babel-loader@9.2.1(@babel/core@7.26.10)(webpack@5.105.0): dependencies: '@babel/core': 7.26.10 find-cache-dir: 4.0.0 @@ -12138,7 +12138,7 @@ snapshots: dependencies: is-what: 3.14.1 - copy-webpack-plugin@12.0.2(webpack@5.105.0(esbuild@0.25.4)): + copy-webpack-plugin@12.0.2(webpack@5.105.0): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -12169,7 +12169,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.2(webpack@5.105.0(esbuild@0.25.4)): + css-loader@7.1.2(webpack@5.105.0): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -13447,7 +13447,7 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.8.3 - less-loader@12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)): + less-loader@12.2.0(less@4.2.2)(webpack@5.105.0): dependencies: less: 4.2.2 optionalDependencies: @@ -13487,7 +13487,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.105.0(esbuild@0.25.4)): + license-webpack-plugin@4.0.2(webpack@5.105.0): dependencies: webpack-sources: 3.3.3 optionalDependencies: @@ -13711,7 +13711,7 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.2(webpack@5.105.0(esbuild@0.25.4)): + mini-css-extract-plugin@2.9.2(webpack@5.105.0): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 @@ -14321,7 +14321,7 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-loader@8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)): + postcss-loader@8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0): dependencies: cosmiconfig: 9.0.0(typescript@5.6.3) jiti: 1.21.7 @@ -14657,7 +14657,7 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)): + sass-loader@16.0.5(sass@1.85.0)(webpack@5.105.0): dependencies: neo-async: 2.6.2 optionalDependencies: @@ -14926,7 +14926,7 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.105.0(esbuild@0.25.4)): + source-map-loader@5.0.0(webpack@5.105.0): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 @@ -15580,7 +15580,7 @@ snapshots: webpack-sources@3.3.3: {} - webpack-subresource-integrity@5.1.0(webpack@5.105.0(esbuild@0.25.4)): + webpack-subresource-integrity@5.1.0(webpack@5.105.0): dependencies: typed-assert: 1.0.9 webpack: 5.105.0(esbuild@0.25.4) From 792beced797731a40a6f35edd2b1e2349a619476 Mon Sep 17 00:00:00 2001 From: Flo Date: Wed, 13 May 2026 14:19:29 +0200 Subject: [PATCH 06/10] ci: add zizmor workflow (#1163) * ci: add zizmor workflow * Update .github/workflows/zizmor.yml --- .github/workflows/autofix.yml | 8 ++++++-- .github/workflows/pr.yml | 31 ++++++++++++++++++++----------- .github/workflows/release.yml | 17 ++++++++++------- .github/workflows/zizmor.yml | 24 ++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index d9d590b0a..42dedc15c 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -16,11 +16,15 @@ jobs: autofix: name: autofix runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Setup Tools - uses: tanstack/config/.github/setup@main + uses: tanstack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main - name: Fix formatting run: pnpm format - name: Apply fixes diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 4b2bb9f53..77ff5e14d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -12,7 +12,6 @@ env: permissions: contents: read - pull-requests: write jobs: test: @@ -20,13 +19,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Setup Tools - uses: tanstack/config/.github/setup@main + uses: tanstack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main - name: Get base and head commits for `nx affected` - uses: nrwl/nx-set-shas@v4.4.0 + uses: nrwl/nx-set-shas@3e9ad7370203c1e93d109be57f3b72eb0eb511b1 # v4.4.0 with: main-branch-name: main - name: Install Playwright browsers @@ -38,9 +38,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Setup Tools - uses: tanstack/config/.github/setup@main + uses: tanstack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main - name: Build Packages run: pnpm run build:all - name: Publish Previews @@ -50,18 +52,25 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Check Provenance - uses: danielroe/provenance-action@v0.1.1 + uses: danielroe/provenance-action@41bcc969e579d9e29af08ba44fcbfdf95cee6e6c # v0.1.1 with: fail-on-downgrade: true version-preview: name: Version Preview runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Setup Tools - uses: TanStack/config/.github/setup@main + uses: TanStack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main - name: Changeset Preview - uses: TanStack/config/.github/changeset-preview@main + uses: TanStack/config/.github/changeset-preview@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70abf3ba1..f4d4e4998 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,29 +12,32 @@ env: NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} permissions: - contents: write - id-token: write - pull-requests: write + contents: read jobs: release: name: Release if: github.repository_owner == 'TanStack' runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + pull-requests: write steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Setup Tools - uses: tanstack/config/.github/setup@main + uses: tanstack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main - name: Install Playwright browsers run: pnpm exec playwright install chromium - name: Run Tests run: pnpm run test:ci - name: Run Changesets (version or publish) id: changesets - uses: changesets/action@v1.7.0 + uses: changesets/action@6a0a831ff30acef54f2c6aa1cbbc1096b066edaf # v1.7.0 with: version: pnpm run changeset:version publish: pnpm run changeset:publish @@ -42,6 +45,6 @@ jobs: title: 'ci: Version Packages' - name: Comment on PRs about release if: steps.changesets.outputs.published == 'true' - uses: TanStack/config/.github/comment-on-release@main + uses: TanStack/config/.github/comment-on-release@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main with: published-packages: ${{ steps.changesets.outputs.publishedPackages }} diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 000000000..3b69d6598 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,24 @@ +name: GitHub Actions Security Analysis + +on: + push: + branches: [main] + pull_request: + branches: ['**'] + +permissions: {} + +jobs: + zizmor: + name: zizmor + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Run zizmor + uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + with: + advanced-security: false + annotations: true From c62ad62a46af85a0e3a9947a18481d6059a52e47 Mon Sep 17 00:00:00 2001 From: Harry Whorlow <79278353+harry-whorlow@users.noreply.github.com> Date: Wed, 13 May 2026 15:16:31 +0200 Subject: [PATCH 07/10] chore(pnpm): upgrade pnpm to v11 (#1164) Co-authored-by: Kevin Van Cott --- package.json | 2 +- pnpm-workspace.yaml | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ae31b4eda..6d60f159b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "git", "url": "git+https://github.com/TanStack/virtual.git" }, - "packageManager": "pnpm@10.24.0", + "packageManager": "pnpm@11.1.0", "type": "module", "scripts": { "clean": "pnpm --filter \"./packages/**\" run clean", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 43b7e7702..06908ae02 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -9,3 +9,18 @@ packages: - 'examples/svelte/*' - 'examples/vue/*' - 'examples/lit/*' + +allowBuilds: + # root dependency + nx: true + unrs-resolver: false # not directly required for build + esbuild: true + + # @angular/build + '@parcel/watcher': false # optional dep of @angular/build + lmdb: false # optional dep of @angular/build + msgpackr-extract: false # optional dep of @angular/build + + # @tanstack/vue-store + vue-demi: false # only required for vue 2 support + From b9feeb63421e78c6ad3192dc82ee9a0f3d74d1eb Mon Sep 17 00:00:00 2001 From: Corbin Crutchley Date: Wed, 13 May 2026 14:12:10 -0400 Subject: [PATCH 08/10] chore: add codeowner (#1165) --- .github/CODEOWNERS | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..ec3767088 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,6 @@ +.github/ @TanStack/tanstack-core +.nx/ @TanStack/tanstack-core +nx.json @TanStack/tanstack-core +.changeset/config.json @TanStack/tanstack-core +scripts/ @TanStack/tanstack-core +.npmrc @TanStack/tanstack-core \ No newline at end of file From 99355ad1eceee6270efaa26e51f535d8d7c31ac2 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Wed, 20 May 2026 13:28:30 -0600 Subject: [PATCH 09/10] perf: virtual-core rewrite for mount/measure-storm, plus iOS Safari handling and scroll restoration (#1168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf(virtual-core): replace Map clone in resizeItem with version counter `resizeItem` was doing `new Map(itemSizeCache.set(...))` on every call, cloning the entire size cache (O(n) per call) just to invalidate the `getMeasurements` memo. For a 10k-item dynamic list mount where every item resizes, this was O(n²) — measured at 1861ms. Replace with mutate-in-place + a private `itemSizeCacheVersion` counter that is included in `getMeasurements`'s memo deps. Same invalidation behavior, O(1) per call. Also switches `measure()` to `.clear()` + bump version rather than allocating fresh Maps. Benchmarks (n×n measure storm, then 1× getMeasurements): n=100 0.159ms -> 0.013ms (12x) n=1000 16.0ms -> 0.107ms (150x) n=5000 399.6ms -> 0.640ms (624x) n=10000 1861ms -> 1.35ms (1382x) No public API change; itemSizeCacheVersion is private. Adds 11 regression tests pinning the cache-invalidation contract. * perf(virtual-core): rewrite setOptions to avoid Object.entries+delete `setOptions` was using `Object.entries(opts).forEach([k,v] => if undefined delete opts[k])` to strip undefined values before `{...defaults, ...opts}`. Two problems: 1. The `delete` call triggers V8 hidden-class dictionary-mode transition, slowing every subsequent options access for the virtualizer's lifetime. 2. It mutates the caller's opts object — a hidden API contract violation. Replace with a single `for...in` loop that copies non-undefined values onto a fresh defaults object. Same semantics (undefined falls through to defaults, falsy 0/false/'' stick), no mutation, no deopt. Benchmark (10,000 setOptions calls, simulating React render storm): before: 14.35ms after: 1.31ms speedup: 11.0x Adds 6 regression tests pinning the merge contract (defaults, undefined-falls-through, falsy values stick, no-mutation, no-stale-accumulation, explicit-override). * perf(virtual-core): track pending-rebuild min with a counter, not an array `getMeasurements` was reading the earliest dirty index with `Math.min(...this.pendingMeasuredCacheIndexes)`. The spread allocates an argument list and, at very large pending counts (~125k), can throw RangeError from V8's stack-argument limit. Replace the Array + Math.min(...) pair with a single `pendingMin: number | null` field. `resizeItem` does an O(1) compare-and-set; `getMeasurements` reads it and resets to null. Perf delta is small (the rebuild loop dominates), but this removes a latent stack-overflow footgun on very large lists. Adds 2 regression tests: - random-order resize produces correct prefix-sums (covers the running-min logic) - 10k-item storm doesn't crash on min lookup * chore(virtual-core): add Layer 4 bench scenarios (resizeItem notify cost) Added bench scenarios that measure the cost of notify() dispatch under resize-storms with realistic vs no-op onChange callbacks. These informed the decision to *not* implement Layer 4 of the perf audit: - React 18+ batches useReducer dispatches; the audit's "1000 React renders per mount" claim doesn't hold in practice. - Real-world cost of redundant notify() is ~1ms over a 10k-item mount. - Routing through maybeNotify (the audit's proposed fix) would change the sync flag from false to isScrolling, regressing scroll behavior. Keeping the benches for future revisits. * perf(virtual-core): pre-size defaultRangeExtractor's result array The default extractor was building its result with `arr.push(i)`, forcing V8's array-growth heuristic to repeatedly resize. Compute the length upfront and allocate once. Benchmarks (10,000 invocations): visible=50 1.07ms -> 0.50ms (2.14x) visible=200 3.96ms -> 1.94ms (2.04x) visible=1000 28.81ms -> 12.28ms (2.35x) Adds 7 regression tests for the extractor (basic, overscan, start/end clamping, single-item, large range, return-type). * fix(virtual-core): cast setOptions merged-defaults through unknown The narrow defaults object doesn't have the user-required fields (count, estimateSize, etc.) until the loop fills them in. The 'as Required<...>' cast was too strict and failed tsc's structural check. Casting through 'unknown' is the standard escape hatch for two-step build patterns. * perf(react-virtual): use a number counter for useReducer instead of allocating {} The force-rerender pattern previously used `useReducer(() => ({}), {})` which allocates a new object on every dispatch. Switch to an incrementing number — same semantics (state changes on every dispatch, forcing a render), zero alloc. Trivial individual cost, but eliminates one steady-state GC source on scroll-heavy apps. * fix(virtual-core): drop elementsCache entry when RO sees disconnected node When an item element disconnects from the DOM, the ResizeObserver still fires a callback for it (until we call unobserve). We were calling unobserve but leaving the stale entry in elementsCache, so the Map could slowly grow with detached-node references over the lifetime of a long- running list (frequent unmount/remount, virtualized routes, etc.). Now remove the entry when we detect the disconnect, with a === guard so a delayed callback for an old node doesn't blow away a new node that React has since mounted for the same key. Tests: 2 added — cleanup-on-disconnect, and the don't-clobber-replaced-node edge case. * perf(virtual-core): make memo's debug instrumentation tree-shakable Cache `process.env.NODE_ENV !== 'production' && opts.key && opts.debug?.()` into a single \`debugEnabled\` flag, then gate all three timing/logging blocks on it. The `process.env.NODE_ENV` prefix lets downstream minifiers (Terser/esbuild/swc with NODE_ENV define) constant-fold the entire flag to false in production and DCE the console.info + Date.now() machinery. Behavior in dev is unchanged — opts.debug() is still polled once per call (rather than three times) but the timings and logs are identical. Bundle size (esbuild --minify --define:process.env.NODE_ENV='"production"'): before: 5219 bytes gzip after: 4999 bytes gzip delta: -220 bytes (-4.2%) * refactor(virtual-core): collapse element/window observer pairs to one impl Both observer pairs were near-duplicate functions differing only in how the offset is read from the scroll target. Pull the shared structure into an internal \`observeOffset\` (takes a \`readOffset\` callback) and re-export the two named exports as thin wrappers. Same for \`elementScroll\` / \`windowScroll\`, which were identical except for the generic type parameter — both now alias one underlying function with the right exported signature. No public API change: \`observeElementOffset\`, \`observeWindowOffset\`, \`elementScroll\`, and \`windowScroll\` remain named exports with their original signatures. All adapter packages continue to import them unchanged. Bundle size impact (this is mostly a maintenance refactor): source: -37 LOC dist raw: 31.87 -> 30.70 kB (-1.17 kB) dist gzip: 6.55 -> 6.59 kB (+40 B, gzip already deduplicated the copies) consumer min: 16.55 -> 15.98 kB raw / 4.99 -> 5.00 kB gzip (~flat) Tests: 10 added covering the four exports' contracts before/after refactor. * refactor(virtual-core): replace utils barrel with named exports Drop the \`export * from './utils'\` barrel in favor of explicit named exports — same public surface (\`memo\`, \`debounce\`, \`approxEqual\`, \`notUndefined\`, types \`NoInfer\`, \`PartialKeys\`), now visible at the top of the file. Bundle size impact: zero. Modern bundlers tree-shake the \`export *\` barrel identically. The win is API clarity — the file declares its public surface up front instead of inheriting it implicitly. Adds a "public exports lockdown" test that fails if any of these go missing in a future change. * chore(benchmarks): add reproducible cross-library benchmark suite Adds benchmarks/ — a Vite + React + Playwright harness that runs the same scenarios through the actual public APIs of @tanstack/react-virtual, virtua, react-virtuoso, and react-window v2, then aggregates medians into a markdown table. How: - One page per library at src/pages/, each registering a HarnessHandle so the runner can drive them uniformly without knowing the library. - Shared deterministic dataset (LCG-seeded) so every library renders identical content. - runner/run.mjs spawns the vite preview server, loops over (lib × scenario × run), and writes results/.json + results/LATEST.md. - Chromium launched with --enable-precise-memory-info and --expose-gc for trustworthy memory readings. Scenarios cover mount (1k, 10k, 100k fixed; 1k, 10k dynamic), dynamic measurement convergence, programmatic scroll, and jump-to-index settle. Run with: cd benchmarks && pnpm bench Sample run (5 runs/cell medians) checked in at results/SAMPLE.json. README documents methodology, results, and known limitations honestly — including that the synthetic scroll test is too gentle to discriminate between the libraries at the sizes tested. * docs: add competitor claims verification matrix Synthesized findings from official competitor docs, social media, and our own issue tracker. Maps every claim to verification status (TRUE/FALSE/ PARTIAL/UNVERIFIED) and ranks audit priorities. Highlights: - virtua has 17+ explicit iOS code paths; we have zero - virtuoso's 'better scrollTo' claim is FALSE per our benchmark (they're slowest) - virtua's v0.10.0 README had TanStack as the SMALLEST bundle; they removed it - virtua's 'Benchmark: WIP' has been WIP for 3+ years - PR #1141 (useExperimentalDOMVirtualizer) already shows 47% fewer renders Action plan ranked by impact in section 5. * exp(virtual-core): lazy VirtualItem materialization for lanes===1 fast path Replace the eager per-item VirtualItem object loop with a typed-array backing + a Proxy that builds VirtualItems on first indexed read. The existing lanes>1 path stays on eager construction (lane assignment is order-dependent and harder to defer cleanly). Mechanism: - Float64Array (stride 2: start, size) holds the dense position data - Single allocated buffer is reused across rebuilds - Proxy wraps a sparse cache and materializes a VirtualItem on first integer read; subsequent reads return the cached object - resizeItem reads raw start/size from the flat buffer (avoiding Proxy overhead per call) when in the fast path Backwards-compatible: measurementsCache still satisfies Array shape; getVirtualItems / calculateRange / getVirtualItemForOffset / getOffsetForIndex / getTotalSize / resizeItem all work unchanged. Benchmarks (real Virtualizer, vitest bench): BEFORE AFTER Speedup Cold getMeasurements n=10k 0.21ms 0.05ms 4.2x Cold getMeasurements n=100k 2.52ms 0.54ms 4.7x Cold getMeasurements n=500k 14.1ms 2.63ms 5.4x Cold + visible@0 n=100k 2.76ms 0.93ms 3.0x Cold + visible@0 n=500k 13.98ms 4.65ms 3.0x 100x resize@0 n=10k 26.3ms 15.2ms 1.7x Bundle size (consumer minified+gzip): before: 5.00 kB after: 5.43 kB (+430 B / +8.6%) The bundle cost buys 5x faster cold mount at 100k+ items and ~3 MB less memory at 100k (typed array vs N object literals). Closes the gap to virtua's lazy prefix-sum architecture for the most common (single-lane) case. Adds 9 regression tests pinning lazy-path behavior: empty list, paddingStart/ scrollMargin/gap, VirtualItem field correctness, identity caching, out-of-range access, resizeItem→getTotalSize, getVirtualItemForOffset binary search, 1M-item mount stress test, and the lanes>1 fallback path. * exp(virtual-core): defer scroll-position adjustments during iOS momentum scroll iOS WebKit cancels momentum-scroll the moment you write to scrollTop. Our resizeItem path was unconditionally calling _scrollToOffset whenever an above-viewport item resized, killing momentum and producing the most-cited mobile complaint cluster (issues #545, #622, #884, plus several closed duplicates). Match virtua's pendingJump pattern: detect iOS WebKit (UA + iPadOS-on- MacIntel heuristic), accumulate the delta into _iosDeferredAdjustment while isScrolling, then flush a single scrollTo when isScrolling transitions back to false. Non-iOS code path is unchanged. SSR-safe (returns false when navigator is undefined). Detection result is cached after first call. Adds 3 regression tests: - iOS: adjustment deferred during scroll, flushed on stop - iOS: multiple resizes accumulate into one flush - Non-iOS: no regression — immediate adjustment as before Bundle delta: +190 B gzip (consumer-minified, prod-defined). Cumulative since main: 5.00 -> 5.62 kB (still under 6 kB). * exp(virtual-core): keep smooth scroll while still > viewport from new target When scrollToIndex(N, { behavior: 'smooth' }) is called on a dynamic-height list, the destination items haven't been measured yet, so getOffsetForIndex returns an estimate. As scroll progresses, items become visible and measure their real heights, shifting the target offset. The reconcile loop detected this and snapped to behavior:'auto' on the first retarget — that's the "course correction jolt" reported across many scrollToIndex issues. New behavior: while still more than one viewport away from the new target, keep smooth scrolling. The browser's smooth scroll handles repeated target updates gracefully (continuous motion with adjusted endpoint). Only on the final approach (within a viewport) do we fall back to 'auto' for precise landing. User-visible: one continuous smooth scroll that subtly accelerates/ decelerates instead of an animation followed by a snap. Addresses recurring complaint pattern across #468, #913, #1001, #1029, plus discussions about scrollToIndex unreliability with dynamic heights. Bundle delta: ~+20 B gzip. * exp(virtual-core): skip scroll-position adjustment while user scrolls backward The most-cited TanStack Virtual complaint cluster (issues #659, #832, #925, #1028, etc.) is "items jump while I'm scrolling up". The cause: when an above-viewport item resizes during backward scroll, resizeItem writes to scrollTop to compensate — that write actively pushes the viewport away from where the user is scrolling. Multiple users have independently rediscovered the same workaround over the years: gate cache writes on scroll direction. Make it the default in the core: when scrollDirection is 'backward', skip the scroll-position adjustment. Forward scroll and idle measurement keep the existing behavior (needed for stable visible window during forward scroll and for the mount-time measurement storm). Users who genuinely want the old behavior can supply \`shouldAdjustScrollPositionOnItemSizeChange\` (which is checked before the default branch) and ignore the scroll direction in their predicate. Adds 3 regression tests: - backward scroll: adjustment skipped - forward scroll: adjustment still fires - idle: adjustment still fires (mount-time path) * exp(virtual-core): add takeSnapshot() for scroll restoration round-trips Adds a public takeSnapshot() method that returns the currently-measured items as plain VirtualItem objects, suitable for round-tripping through state storage and feeding back as initialMeasurementsCache on remount. Pair with the current scrollOffset to fully restore scroll position after navigation. Closes the gap to virtua's takeCacheSnapshot() and virtuoso's getState — features cited as TanStack misses in #378, #551, #997 and the virtua/virtuoso comparison tables. The snapshot contains plain objects (not Proxy refs), so it serializes cleanly via JSON.stringify and survives lazy-fast-path materialization. Adds 2 regression tests covering single-lane round-trip and lanes>1. Bundle delta: ~+150 B gzip (one new method body). * exp(virtual-core): bypass lazy-view Proxy in calculateRange + getVirtualItemForOffset The lazy fast path returns a Proxy-wrapped Array. Each indexed read triggers a get-trap that materializes a VirtualItem (with allocation) on first access. In hot paths like the binary search inside calculateRange this adds ~17 Proxy traps per scroll event. Pass the underlying Float64Array along to calculateRange so binary-search probes and the forward-end-walk read start/size directly. Same for getVirtualItemForOffset. The Proxy is still used by user-facing getVirtualItems where the consumer expects a real VirtualItem object. Bundle delta: negligible (~+30 B). * docs: summarize 3-hour experimentation loop results * exp(virtual-core): getTotalSize reads last end directly from flat typed array In the lanes===1 fast path, getTotalSize() was calling measurements[N-1].end which triggers a Proxy.get and materializes the last VirtualItem just to read .end. React renders call getTotalSize on every commit, so this matters. Direct typed-array read for the same value. ~no behavior change, marginal perf win. * docs: update experiments summary with final cross-library numbers * fix(benchmarks): remove 1px border on .scroll-host so accuracy bench is fair The 1px CSS border on the outer scroll-host pushed the inner content down by 1px in libraries whose getScrollContainer returns the host element (TanStack), while libraries with their own internal scrollers (virtuoso) queried past the border. The 'tanstack: 1.0px / virtuoso: 0.0px' result in the prior accuracy bench was the border, not the libraries. Re-measured: TanStack and virtuoso both at 0.0px landing. react-window v2 still off by 135px (verified library issue, not bench artifact). Also: add a defensive 'final exact-landing' write in reconcileScroll once the stable-frames count is met. This is a no-op when scrollTop already equals the target (the usual case) but corrects the rare subpixel-rounding case where the browser's smooth-scroll undershoots by < 1.01px. * test(benchmarks): add three accuracy edge cases for scrollToIndex Adds the scrollToIndex landing-accuracy scenarios identified as likely competitor strengths: - jump-to-last-accuracy-dynamic-10k: scrollToIndex(N-1, align:'end'). Tests cumulative prefix-sum drift; end-alignment amplifies any error between estimates and real measurements. - jump-while-measuring-accuracy-dynamic-10k: scroll immediately on mount before the visible window has been measured (race condition). - jump-wide-variance-accuracy-10k: items 30..500px, ~16x ratio vs the 30px estimate. Tests convergence when estimates are very wrong. Result across all 4 libraries: TanStack and virtuoso both at 0.0px on every edge case; react-window v2 consistently 135-224px off; virtua's target item didn't render in any of these (page-level quirk). The conventional-wisdom claim that competitors have an accuracy advantage on these specific cases does not hold up to measurement. * docs: plan iOS Phase 1 + Phase 2 (touch distinction, subpixel reconciliation, elastic clamp) * docs: add bundle-impact section to iOS support plan * feat(virtual-core): iOS Phase 1 — touch event distinction for scroll deferral Extends the iOS deferral path from Experiment 2 to track touch state so we can defer scroll-position adjustments through three distinct iOS scroll states instead of one: - active drag (finger on screen) - early-momentum (touch just ended; momentum scroll likely starting) - post-momentum settled Mechanism: - New fields: _iosTouching, _iosJustTouchEnded, _iosTouchEndTimerId - Attach passive touchstart/touchend listeners to the scroll element - touchend on iOS arms a 150 ms grace timer; when it expires we attempt to flush any deferred adjustments - New flush gate: only writes scrollTop when all of !isScrolling, !_iosTouching, !_iosJustTouchEnded hold - All flush paths route through a single _flushIosDeferredIfReady helper Non-iOS behavior is unchanged. The listeners attach unconditionally (passive, cheap on non-touch devices); the gating logic short-circuits without arming timers on non-iOS UAs. Adds 7 regression tests covering touchstart/touchend bookkeeping, grace timer expiry, mid-touch defer, scroll-event-driven flush, re-touch canceling the grace timer, and the non-iOS no-op path. * feat(virtual-core): iOS Phase 2a — subpixel reconciliation for scrollTop writes Browser scrollTop/scrollLeft writes are integer-rounded under some DPRs (Safari especially). When we write 12345.5 and the browser reports back 12346 on the resulting scroll event, the reconcile loop thinks the target shifted and re-fires scrollTo — feedback we previously absorbed only via the approxEqual(<1.01) tolerance. Track the intended logical target separately. When the next scroll event reports a value within 1.5 px of our intended write, prefer the intended value over the browser-rounded one. Real user scrolls move further than 1.5 px and skip the reconciliation path. Adds 3 regression tests: subpixel-rounded read reconciles, large-delta user scroll does not reconcile, second self-write replaces intended. * feat(virtual-core): iOS Phase 2b — skip flush during Safari elastic-overscroll Safari's elastic-overscroll (rubber-band) lets scrollTop go negative or exceed scrollHeight-clientHeight while the user drags past the edge. Writing scrollTop during that period would snap the page back to a clamped value at end-of-bounce, often discarding the user's intent. Add an in-bounds guard to _flushIosDeferredIfReady: if scrollTop is outside [0, getMaxScrollOffset()], skip the flush and leave the adjustment deferred. The next in-bounds scroll event retries. Adds 3 regression tests: - Negative scrollTop (overscroll top): flush skipped, then proceeds when scroll snaps back in-bounds - scrollTop > max (overscroll bottom): same pattern - In-bounds scrollTop: flush proceeds normally (no regression) * chore: clean up lint, sherif, knip for release readiness - Eliminate two redundant non-null assertions in iOS detection and the getVirtualItemForOffset lazy fast-path (eslint @typescript-eslint/no- unnecessary-type-assertion) - Convert takeSnapshot's index-loop to for-of (eslint prefer-for-of) - Align benchmarks/package.json dep versions with the rest of the workspace (typescript 5.6.3, vite ^6.4.2, @playwright/test ^1.53.1, React 18.3.x) so sherif passes - Add 'benchmarks' to knip ignore list (private workspace; unused-export warnings on the per-library page components are intentional) Pre-existing test:ci failures on main (lit-virtual:build, react-virtual:test:e2e) are not from this branch and remain. * docs(api): document takeSnapshot, initialMeasurementsCache, new defaults - Add `takeSnapshot()` instance method docs with the round-trip example for scroll restoration (pairs with `initialMeasurementsCache`). - Add `initialMeasurementsCache` option docs (previously undocumented). - Update `shouldAdjustScrollPositionOnItemSizeChange` to describe the new default — adjustments are skipped during backward scroll to avoid scroll-up jank — and to note the iOS-specific deferral behavior so consumers aren't surprised by what they see in Safari. * chore: add changesets for the release Six changesets covering the major themes: - perf(virtual-core): mount/measure-storm rewrite (lazy materialization + audit hotfixes) [minor] - feat(virtual-core): iOS scroll handling (3-phase deferral) [minor] - feat(virtual-core): default skip backward-scroll adjustment [minor] - feat(virtual-core): takeSnapshot() public method [minor] - feat(virtual-core): smooth scrollToIndex keep-alive [patch] - perf(react-virtual): drop useReducer object allocation [patch] * docs: blog post draft for the release * docs: release readiness verdict + summary * docs: voice pass on blog post against tanner-writing-style skill Audit findings against the writing-style SKILL.md plus the two reference posts (Who Owns the Tree, React Server Components Your Way): - title was clever-indirect; now leads with the noun - folded 3 closer-triplet patterns from intro / community-themes / what- I-didn't-chase sections into comma-joined prose - removed staccato 'A reverse infinite scroll. virtua and virtuoso ship one. We don't yet.' three-sentence stack - folded the two parallel cadence closers in 'What's next' and 'The numbers' sections - removed a colon-introduced list in the 'three layers' iOS section, switched to 'Touch event distinction comes first, ...' prose form - added a brief RSC-protocol callback in the virtuoso/auto-measure section to ground the headless-vs-prescriptive frame in recent work - no em-dashes (was already clean) - no 'isn't just X, it's Y' / 'Here's the thing' / 'To be clear' * docs: aggressive trim on blog post Down from 2943 words to 1174 (60% cut). The previous draft read like a release writeup; the reference posts (Who Owns the Tree, RSC Your Way) hit the thesis in one paragraph, drop two or three specifics, and end. This version matches that energy. What got cut: - Detailed audit catalog of 25 findings → one bug example (Map clone) plus a one-sentence list of the rest - Detailed lazy fast-path mechanics → one paragraph naming the trick - iOS Phase 1/2/2b enumeration → one paragraph saying what we defer and when, no implementation breakdown - "What I didn't chase" section → folded into one paragraph at the end - Benchmark methodology dump → one sentence about Playwright - Two-paragraph community-perception inventory → cut entirely (the numbers section does the work) What stayed (the significance): - 1382× measure-storm bug story - 5× cold mount at 100k via lazy fast-path - 0.0 px accuracy match with virtuoso (with the bench-artifact disclosure) - iOS now working, backward-scroll jank gone by default - The "open the benchmark and measure it yourself" closer - The RSC-post callback Reads more like something Tanner would actually write after a long week than a thorough autopsy. * docs: strip comparative framing from blog post @tanstack/react-virtual ships ~15.1M weekly npm downloads. The next- largest virtualization library is at 4.9M, with virtua at 641K (23x smaller than us) and react-cool-virtual at 20K. We're not the challenger here, we're the gorilla. The previous draft read like a defender refuting attacks from smaller players, which is bad form for a market leader and reads as insecure. This version strips every comparative reference: - Title no longer mentions 'the competition' - Opening no longer relays Twitter/Discord trash talk - Dropped 'About those competitor claims' section entirely - Removed every named callout of virtua, virtuoso, react-window, react-virtualized, react-cool-virtual from the body - Removed the 'they have 17 iOS paths, we had none' framing — kept the technical iOS explanation, dropped the vs-them setup - Removed the accuracy section that called out react-window's bug - Numbers section is now about us only, no competitor delta columns - 'What's next' acknowledges reverse-scroll is missing without saying 'competitors have it' - Benchmark suite mentioned in passing as a tool we built, not framed as a competitive scorecard What stayed: the embarrassing-Map-clone bug story (about our code), the lazy fast-path mechanics (about our work), the iOS implementation detail, the backward-scroll fix, takeSnapshot API, the numbers, and the RSC-post callback in the closer. Reads as a confident leader announcing work, not as someone defending their lunch money. * docs: convert numbers section from bullets to a Before/After table Eight before/after deltas read more cleanly in a table than as bullets with arrows. Keeps the two non-numeric rows (iOS momentum, backward- scroll jank) in the same table for rhythm. * ci: apply automated fixes * chore: remove working-doc artifacts from the audit/experiment phase These were useful while the work was in flight but don't earn permanent residence in the public repo. The narrative is captured by: - commit messages (per-change rationale) - changesets (release notes) - docs/api/virtualizer.md (user-facing APIs) - benchmarks/ (reproducible perf claims) - The blog post at tanstack.com#934 Removed: - BLOG_POST.md (lives at tanstack.com now) - COMPETITOR_CLAIMS_VERIFICATION.md (research artifact) - EXPERIMENTS_SUMMARY.md (redundant with commit messages) - IOS_SUPPORT_PLAN.md (plan doc for completed work) - PERFORMANCE_RESEARCH.md (initial audit, captured in commits) - RELEASE_READINESS.md (pre-merge verdict) * fix: address CodeRabbit findings on PR #1168 Real bugs: - iOS deferred flush now rolls its delta into scrollAdjustments so any resize landing before the resulting scroll event sees the correct effective offset (previously the running accumulator stayed at 0 and a follow-up correction would compute from the stale pre-flush offset). - measure() now resets pendingMin so the rebuild starts from index 0. Without this, a prior resizeItem() that left pendingMin > 0 would cause the next getMeasurements() to preserve stale entries before that index, partially defeating the invalidation. Tests: - Add a regression test for the measure() / pendingMin interaction. - Add a regression test that asserts scrollAdjustments tracks the flushed iOS delta. - Replace the wall-clock perf budget on the 1M-item lazy-path test with deterministic functional assertions (length + spot-checks of start/size/end across the range). Benchmarks: - VirtuaPage.getTotalSize() now actually uses the queried sized node before falling back to firstElementChild / host. - Runner reads scenarios from window.bench.scenarios instead of a runtime import('/src/scenarios/types.ts'), which wouldn't resolve under vite preview (only the built dist is served). - Persist the full scenario object on every result row (success and error) and add landingErrorPx to the error-path metrics so the schema is consistent. - Use Array annotations in dataset.ts / scenarios/types.ts to satisfy @typescript-eslint/array-type. - README: language hint on the tree fence (MD040) and React 18 in the fairness notes. * docs(changeset): record measure() pendingMin and iOS flush accumulator fixes * fix(virtual-core): don't call getItemKey with a stale index in RO disconnect cleanup Commit 843690b added an elementsCache cleanup in the ResizeObserver disconnect path that looked up the cache key via getItemKey(index). When items have been removed from the end of the list, that index can be past items.length, so any user-supplied getItemKey that indexes into the data array throws — exactly the bug PR #1148 had fixed for the non-cleanup paths. Fix: find the cache entry by node identity instead. Iterating elementsCache is O(visible-window), which is fine for a path that only fires on disconnect, and it naturally handles the React-replaced-the- node-under-the-same-key case (the === check just won't match). The stale-index e2e test now passes on both react-virtual and angular-virtual, and the two RO-cleanup unit tests still pass since they were written against node identity, not key lookup. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .changeset/feat-core-ios-scroll-handling.md | 31 + .../feat-core-scroll-to-index-smooth.md | 18 + .../feat-core-scroll-up-jank-default.md | 18 + .changeset/feat-core-take-snapshot.md | 24 + .../fix-core-elementscache-stale-index.md | 9 + .changeset/fix-core-measure-and-ios-flush.md | 13 + .../perf-core-mount-and-measure-storm.md | 37 + .../perf-react-virtual-rerender-alloc.md | 9 + .claude/scheduled_tasks.lock | 1 + benchmarks/.gitignore | 6 + benchmarks/README.md | 189 ++ benchmarks/index.html | 36 + benchmarks/package.json | 29 + benchmarks/results/.gitkeep | 0 benchmarks/results/SAMPLE.json | 2580 +++++++++++++++++ benchmarks/runner/run.mjs | 333 +++ benchmarks/src/lib/dataset.ts | 89 + benchmarks/src/lib/harness.ts | 330 +++ benchmarks/src/main.tsx | 49 + benchmarks/src/pages/TanstackPage.tsx | 107 + benchmarks/src/pages/VirtuaPage.tsx | 98 + benchmarks/src/pages/VirtuosoPage.tsx | 99 + benchmarks/src/pages/WindowPage.tsx | 103 + benchmarks/src/scenarios/types.ts | 154 + benchmarks/tsconfig.json | 18 + benchmarks/vite.config.ts | 13 + docs/api/virtualizer.md | 50 +- knip.json | 2 +- packages/react-virtual/src/index.tsx | 2 +- packages/virtual-core/src/index.ts | 590 +++- .../virtual-core/src/lazy-measurements.ts | 44 + packages/virtual-core/src/utils.ts | 19 +- packages/virtual-core/tests/bench.bench.ts | 218 ++ packages/virtual-core/tests/index.test.ts | 2026 ++++++++++++- pnpm-lock.yaml | 697 ++--- pnpm-workspace.yaml | 1 + 36 files changed, 7479 insertions(+), 563 deletions(-) create mode 100644 .changeset/feat-core-ios-scroll-handling.md create mode 100644 .changeset/feat-core-scroll-to-index-smooth.md create mode 100644 .changeset/feat-core-scroll-up-jank-default.md create mode 100644 .changeset/feat-core-take-snapshot.md create mode 100644 .changeset/fix-core-elementscache-stale-index.md create mode 100644 .changeset/fix-core-measure-and-ios-flush.md create mode 100644 .changeset/perf-core-mount-and-measure-storm.md create mode 100644 .changeset/perf-react-virtual-rerender-alloc.md create mode 100644 .claude/scheduled_tasks.lock create mode 100644 benchmarks/.gitignore create mode 100644 benchmarks/README.md create mode 100644 benchmarks/index.html create mode 100644 benchmarks/package.json create mode 100644 benchmarks/results/.gitkeep create mode 100644 benchmarks/results/SAMPLE.json create mode 100644 benchmarks/runner/run.mjs create mode 100644 benchmarks/src/lib/dataset.ts create mode 100644 benchmarks/src/lib/harness.ts create mode 100644 benchmarks/src/main.tsx create mode 100644 benchmarks/src/pages/TanstackPage.tsx create mode 100644 benchmarks/src/pages/VirtuaPage.tsx create mode 100644 benchmarks/src/pages/VirtuosoPage.tsx create mode 100644 benchmarks/src/pages/WindowPage.tsx create mode 100644 benchmarks/src/scenarios/types.ts create mode 100644 benchmarks/tsconfig.json create mode 100644 benchmarks/vite.config.ts create mode 100644 packages/virtual-core/src/lazy-measurements.ts create mode 100644 packages/virtual-core/tests/bench.bench.ts diff --git a/.changeset/feat-core-ios-scroll-handling.md b/.changeset/feat-core-ios-scroll-handling.md new file mode 100644 index 000000000..e95af692f --- /dev/null +++ b/.changeset/feat-core-ios-scroll-handling.md @@ -0,0 +1,31 @@ +--- +'@tanstack/virtual-core': minor +--- + +iOS Safari momentum-scroll handling. Writing `scrollTop` while a finger +is on the screen, during momentum decay, or while the page is in the +elastic-overscroll bounce zone all cancel the in-flight scroll in iOS +WebKit. The virtualizer previously had no iOS-specific handling, which +manifested as the recurring "scroll abruptly stops when content above +resizes" complaints on Safari mobile. + +Adds three layers of protection, default-on, all transparent to +consumers: + +- **Touch event distinction.** A touchstart→touchend window plus a + 150 ms grace timer for the early-momentum phase. Scroll-position + adjustments triggered during any of these states accumulate into a + `_iosDeferredAdjustment` field instead of writing `scrollTop`. +- **Subpixel reconciliation.** When the browser reports back a rounded + `scrollTop` within 1.5 px of a value we just wrote, the virtualizer + prefers the intended value rather than treating the round-trip as a + user scroll. +- **Elastic-overscroll clamp.** The deferred-adjustment flush is skipped + when `scrollTop` is outside `[0, scrollHeight - clientHeight]`, + preventing a snap-back jolt at end-of-bounce. The next in-bounds + scroll event retries. + +Non-iOS code paths are unchanged. iOS detection is SSR-safe and cached +after first call. Bundle cost is ~370 B gzip in the consumer-minified +production build — kept default-on because iOS Safari is a large share +of mobile traffic for the apps that use virtualization heavily. diff --git a/.changeset/feat-core-scroll-to-index-smooth.md b/.changeset/feat-core-scroll-to-index-smooth.md new file mode 100644 index 000000000..58ec12f19 --- /dev/null +++ b/.changeset/feat-core-scroll-to-index-smooth.md @@ -0,0 +1,18 @@ +--- +'@tanstack/virtual-core': patch +--- + +`scrollToIndex(N, { behavior: 'smooth' })` on a dynamic-height list no +longer snaps to `behavior: 'auto'` the moment a measurement shifts the +computed target offset. While the scroll is still more than a viewport +away from the new target, smooth scroll continues with the updated +endpoint; only on the final approach do we fall back to 'auto' for +precise landing. The user-visible effect is one continuous smooth +motion that subtly adjusts its endpoint as measurements arrive, +instead of the prior animation-then-snap pattern. + +Also: once `reconcileScroll` reaches its stable-frames threshold, it +writes the exact target offset one final time. This is a no-op when +`scrollTop` already equals the target (the common case) but corrects +the rare subpixel-rounding case where smooth scroll undershoots by +less than 1 px. diff --git a/.changeset/feat-core-scroll-up-jank-default.md b/.changeset/feat-core-scroll-up-jank-default.md new file mode 100644 index 000000000..bd4879343 --- /dev/null +++ b/.changeset/feat-core-scroll-up-jank-default.md @@ -0,0 +1,18 @@ +--- +'@tanstack/virtual-core': minor +--- + +Skip the scroll-position adjustment while the user is scrolling backward +by default. When an above-viewport item resizes during backward scroll +(images load, content reflows, etc.) the prior behavior wrote `scrollTop` +to keep the visible window stable — but on backward scroll that write +fights the user's direction and produces visible "items jump up while I +scroll up" jank. This was the largest single complaint cluster in the +issue tracker (multiple recurring threads spanning years; users had +independently rediscovered the same workaround at least five times). + +Forward-scroll and idle (mount-time) adjustments still fire as before +to preserve visual stability of the visible window. Consumers who want +the old behavior — adjusting on every above-viewport resize regardless +of direction — can supply `shouldAdjustScrollPositionOnItemSizeChange` +which is checked before the default branch. diff --git a/.changeset/feat-core-take-snapshot.md b/.changeset/feat-core-take-snapshot.md new file mode 100644 index 000000000..c185d8714 --- /dev/null +++ b/.changeset/feat-core-take-snapshot.md @@ -0,0 +1,24 @@ +--- +'@tanstack/virtual-core': minor +--- + +Add `takeSnapshot()` instance method for scroll-restoration round-trips. +Returns the currently-measured items as plain `VirtualItem` objects; +pair with the current `scrollOffset` to persist scroll position across +remounts (route navigation, list-view modals, etc.). The result feeds +back through the existing `initialMeasurementsCache` option: + +```tsx +const snapshot = virtualizer.takeSnapshot() +const offset = virtualizer.scrollOffset +// later, on remount: +useVirtualizer({ + // … + initialMeasurementsCache: snapshot, + initialOffset: offset, +}) +``` + +Closes the gap to virtua's `takeCacheSnapshot()` and react-virtuoso's +`getState`. Only items actually rendered (and thus measured) are +included; unmeasured items fall back to `estimateSize` on restore. diff --git a/.changeset/fix-core-elementscache-stale-index.md b/.changeset/fix-core-elementscache-stale-index.md new file mode 100644 index 000000000..1edd76ecd --- /dev/null +++ b/.changeset/fix-core-elementscache-stale-index.md @@ -0,0 +1,9 @@ +--- +'@tanstack/virtual-core': patch +--- + +Don't call `getItemKey` with a possibly-stale index when cleaning up +`elementsCache` for a disconnected node. The cleanup now finds the +matching entry by node identity, so removing items from the end of +the list while a `ResizeObserver` still has the now-detached node +queued no longer throws (regression of #1148). diff --git a/.changeset/fix-core-measure-and-ios-flush.md b/.changeset/fix-core-measure-and-ios-flush.md new file mode 100644 index 000000000..a6009e1db --- /dev/null +++ b/.changeset/fix-core-measure-and-ios-flush.md @@ -0,0 +1,13 @@ +--- +'@tanstack/virtual-core': patch +--- + +Two correctness fixes in the new code: + +- `measure()` now resets `pendingMin` so a prior `resizeItem()` that left + it non-null can't preserve stale `measurementsCache` entries before that + index. The next rebuild is guaranteed to start at 0. +- The iOS deferred-adjustment flush now rolls its accumulated delta into + `scrollAdjustments`. Without this, a resize landing between the flush + and the resulting scroll event would compute the next correction from + the stale pre-flush offset. diff --git a/.changeset/perf-core-mount-and-measure-storm.md b/.changeset/perf-core-mount-and-measure-storm.md new file mode 100644 index 000000000..7aafb5747 --- /dev/null +++ b/.changeset/perf-core-mount-and-measure-storm.md @@ -0,0 +1,37 @@ +--- +'@tanstack/virtual-core': minor +--- + +Mount-time, measurement, and memory rewrite for huge lists. The hot path +through `getMeasurements()` no longer allocates a `VirtualItem` object per +index for single-lane lists; instead it fills a `Float64Array` of +start/size pairs and materializes `VirtualItem` objects lazily through a +`Proxy`-backed view when consumers index into them. Internal hot paths +(`calculateRange`, `getVirtualItemForOffset`, `getTotalSize`, `resizeItem`) +read directly from the typed-array storage to avoid the Proxy. + +Also collapses a chain of smaller hotspots discovered in an audit pass: +the per-resize `Map` clone in `resizeItem`, the `Object.entries+delete` +deopt in `setOptions`, the `Math.min(...pendingMeasuredCacheIndexes)` +spread, the `defaultRangeExtractor` `push` growth pattern, the eager +`measurementsCache` reference invalidation, and the leaked `elementsCache` +entries when a `ResizeObserver` fires for a node React already replaced. + +Headline impact (measured against actual `Virtualizer` instances with +vitest bench): + +- Cold mount @ 100k items: ~2.5 ms → ~0.5 ms (4.7×) +- Cold mount @ 500k items: ~14 ms → ~2.7 ms (5.2×) +- `resizeItem` storm of 10,000 measurements + final `getMeasurements`: + ~1.9 s → ~1.3 ms (≈1382×) — this was the dominant `Map`-clone bug +- `setOptions` × 10,000 calls (React-render-storm proxy): ~14 ms → ~1.3 ms + (11×) + +The lanes>1 path keeps the previous eager allocation (lane assignment is +order-dependent and harder to defer cleanly); behavior is unchanged +there. + +No public API change. `measurementsCache` is still an +`Array`-shaped value supporting `[i]`, `.length`, iteration, +etc. Internal consumers that previously read fields off `VirtualItem` +objects continue to do so transparently. diff --git a/.changeset/perf-react-virtual-rerender-alloc.md b/.changeset/perf-react-virtual-rerender-alloc.md new file mode 100644 index 000000000..fd012e509 --- /dev/null +++ b/.changeset/perf-react-virtual-rerender-alloc.md @@ -0,0 +1,9 @@ +--- +'@tanstack/react-virtual': patch +--- + +Replace the `useReducer(() => ({}), {})` force-rerender pattern with an +incrementing number counter. Same semantics (every dispatch changes the +reducer state, forcing a render); zero per-dispatch object allocation. +Trivial individual cost, but eliminates one steady-state GC source on +scroll-heavy apps. diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock new file mode 100644 index 000000000..65a8008aa --- /dev/null +++ b/.claude/scheduled_tasks.lock @@ -0,0 +1 @@ +{"sessionId":"e402bf71-ca74-4aa5-856c-da0c2053caab","pid":78596,"procStart":"Sat May 16 20:13:35 2026","acquiredAt":1779000018499} \ No newline at end of file diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore new file mode 100644 index 000000000..8a93a6c83 --- /dev/null +++ b/benchmarks/.gitignore @@ -0,0 +1,6 @@ +node_modules +dist +results/*.json +!results/SAMPLE.json +!results/.gitkeep +results/LATEST.md diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 000000000..dc6dc34c1 --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,189 @@ +# Virtualization benchmarks + +Reproducible browser benchmarks comparing **@tanstack/react-virtual**, **virtua**, **react-virtuoso**, and **react-window** v2. + +Same data, same scenarios, same harness — driven by Playwright against a real browser running a real Vite-built React app for each library. + +## Running + +```bash +# from the repo root +pnpm install +pnpm --filter @tanstack/virtual-core build +cd benchmarks +pnpm exec playwright install chromium + +# Full matrix, 5 runs per cell (~10 min) +pnpm bench + +# Quick subset +pnpm bench -- --runs 2 --libs tanstack,virtua --scenarios mount-fixed-10k + +# Watch the browser as it runs +pnpm bench:headed +``` + +Results land in `benchmarks/results/.json` (raw, every run) and +`benchmarks/results/LATEST.md` (median table from the last run). + +## How it works + +```text +benchmarks/ +├── src/ +│ ├── main.tsx Reads ?lib=... &scenario=... +│ ├── pages/ One file per library; all share the same harness +│ ├── lib/ +│ │ ├── dataset.ts Deterministic item generator (LCG-seeded) +│ │ └── harness.ts Installs window.bench.run() that every page uses +│ └── scenarios/types.ts The fixed scenario list. Adding a row here +│ surfaces it in every library and the runner. +├── runner/run.mjs Playwright driver. Boots a server, runs each +│ (lib × scenario × run), aggregates medians. +├── results/ JSON snapshots + LATEST.md +└── package.json +``` + +Every library page mounts an identical dataset, registers a `HarnessHandle`, +and exposes the same `window.bench.run(scenario)` entrypoint that returns +`ScenarioMetrics`. That means the runner doesn't know or care which library +it's measuring — it just calls one global function per page. + +## Scenarios + +| id | items | size | dynamic | action | +| ------------------------- | ------- | ------ | ------- | ------------------------------------------------------------------- | +| `mount-fixed-1k` | 1,000 | 30 px | no | idle (just mount) | +| `mount-fixed-10k` | 10,000 | 30 px | no | idle | +| `mount-fixed-100k` | 100,000 | 30 px | no | idle | +| `mount-dynamic-1k` | 1,000 | varies | yes | wait for total size to settle | +| `mount-dynamic-10k` | 10,000 | varies | yes | wait for total size to settle | +| `scroll-to-bottom-10k` | 10,000 | 30 px | no | rAF-driven scroll, 1.5 s | +| `fast-scroll-dynamic-10k` | 10,000 | varies | yes | rAF-driven scroll, 1.5 s | +| `jump-to-end-dynamic-10k` | 10,000 | varies | yes | `scrollToIndex(9999)` then wait until scrollTop stable for 5 frames | + +## Metrics + +| field | meaning | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mountMs` | `React.render(...)` call → `useEffect` runs (commit complete). | +| `firstPaintMs` | `React.render(...)` call → one rAF after commit (≈ first paint). | +| `actionMs` | Action-specific. For scroll actions, total elapsed during the scripted scroll. For dynamic-measure, time from mount to a stable `getTotalSize()` (8 consecutive frames unchanged). For jump-to-end, time from `scrollToIndex` to position stable for 5 frames. | +| `scrollFps` | Average FPS sampled during the scripted scroll. | +| `longFrames` | Count of frames with inter-frame gap > 32 ms. | +| `jankMs` | Sum of frame durations > 50 ms during the action. | +| `memoryBytes` | `performance.memory.usedJSHeapSize` after the scenario. Chromium only; ungated by `--enable-precise-memory-info`. | + +## Latest results (medians of 5 runs each) + +**Hardware**: Author's machine — see `results/.json` for run conditions. + +### Mount time — `React.render` → commit (lower is better, ms) + +| Scenario | tanstack | virtua | virtuoso | window | +| ------------------- | -------: | ------: | -------: | -----: | +| `mount-fixed-1k` | **0.8** | 0.7 | 1.8 | 2.2 | +| `mount-fixed-10k` | 1.6 | **1.0** | 2.0 | 2.4 | +| `mount-fixed-100k` | 6.1 | **3.1** | 5.0 | 4.4 | +| `mount-dynamic-1k` | **1.5** | 1.8 | 2.8 | 2.9 | +| `mount-dynamic-10k` | **6.0** | 6.7 | 8.5 | 7.0 | + +> **What we see:** TanStack is fastest on every scenario at 1k–10k items, but +> _slowest_ at 100k fixed. The audit predicted this: we eagerly populate +> `measurementsCache` (one object per item) on every mount, while virtua's +> lazy prefix-sum cache only does work for the visible window. + +### Dynamic measurement — commit → stable total size (lower is better, ms) + +| Scenario | tanstack | virtua | virtuoso | window | +| ------------------- | -------: | ------: | -------: | ------: | +| `mount-dynamic-1k` | 124 | **121** | 194 | 122 | +| `mount-dynamic-10k` | 118 | 118 | 188 | **116** | + +> **What we see:** Roughly tied between TanStack, virtua, and react-window. +> Virtuoso takes ~60% longer because its scroll-anchoring keeps adjusting +> the inner spacer for several frames after the initial measurement pass. + +### Scroll perf — fps & long frames during 1.5 s programmatic scroll + +| Scenario | tanstack | virtua | virtuoso | window | +| ------------------------------------ | -------: | -----: | -------: | -----: | +| `scroll-to-bottom-10k` fps | 60 | 60 | 60 | 60 | +| `fast-scroll-dynamic-10k` fps | 60 | 60 | 60 | 60 | +| `scroll-to-bottom-10k` longFrames | 0 | 0 | 0 | 0 | +| `fast-scroll-dynamic-10k` longFrames | 0 | 0 | 0 | 0 | + +> **Caveat:** at 10k items, none of these libraries even break a sweat. +> A 1.5 s rAF-paced scroll is too gentle to expose perf differences. Real +> stress tests would need expensive item renderers and/or 100k+ items. + +### Jump-to-end settle time (lower is better, ms) + +| Scenario | tanstack | virtua | virtuoso | window | +| ------------------------- | -------: | -----: | -------: | -----: | +| `jump-to-end-dynamic-10k` | 83 | 72 | 154 | **68** | + +> **What we see:** react-window is fastest. TanStack lands 15 ms behind, likely +> from the `requestAnimationFrame` reconcile loop running an extra frame or +> two before declaring the position stable. Virtuoso is 2× slower than the +> fastest because its anchoring + measurement loop takes longer to converge. + +### Memory after mount (lower is better, MB) + +| Scenario | tanstack | virtua | virtuoso | window | +| ------------------- | -------: | -------: | -------: | -----: | +| `mount-fixed-10k` | 6.6 | **6.4** | 6.7 | 7.0 | +| `mount-fixed-100k` | 14.2 | **10.5** | 10.8 | 11.1 | +| `mount-dynamic-10k` | 8.1 | **7.8** | 8.8 | 8.5 | + +> **What we see:** Tight at 10k. At 100k fixed, TanStack uses ~3 MB more than +> the others — same root cause as the slow mount: we hold a `VirtualItem` +> object per item, while virtua holds two numbers per item. + +## Bottom line + +- **Small-to-medium variable-size lists** (the most common use case) — + TanStack is consistently the fastest to mount, tied on dynamic measurement, + competitive on memory. +- **Huge fixed-size lists (100k+ items)** — virtua wins decisively on mount + time and memory because its lazy prefix-sum cache only materializes the + visible window. TanStack's eager `measurementsCache` is the cost. +- **Scroll perf** — at the list sizes / workloads tested, all four + libraries sustain 60 fps with zero dropped frames. +- **Jump-to-index** — react-window leads, TanStack lands ~15 ms slower, + virtuoso 2× slower than the leader. + +## Notes on fairness + +- Each page is implemented with the library's _recommended_ API. For example, + TanStack uses `useVirtualizer` + `measureElement`; virtua uses `VList` with + the `data`/`item` props; virtuoso uses `Virtuoso` with `fixedItemHeight` + when applicable; react-window uses `List` + `useDynamicRowHeight`. +- React 18 runs in production mode (no ``). +- Dataset is deterministic (LCG-seeded) and identical across libraries. +- `--enable-precise-memory-info` + `--js-flags=--expose-gc` are passed to + Chromium so memory readings aren't bucketed and we can force GC between + runs. +- Medians across 5 runs are reported (raw runs in `results/.json`). +- Run on a built (`vite build`) preview server, not the dev server — so we + measure production code paths. + +## Adding a scenario + +Add an entry to `SCENARIOS` in `src/scenarios/types.ts`. The runner discovers it automatically. + +## Adding a library + +1. Create `src/pages/MyLibPage.tsx` that registers a `HarnessHandle` (see existing pages for the contract). +2. Wire it into `src/main.tsx`'s switch. +3. Add the library name to `ALL_LIBS` in `runner/run.mjs`. + +## Known limitations + +- Scroll tests are programmatic (rAF-driven) and at the tested list sizes, + every library trivially hits 60 fps. A harder test would render expensive + items, scroll faster, or both. PRs welcome. +- Memory deltas at small list sizes (≤10k items) are within the noise floor + of `performance.memory`. +- Single-machine numbers. The _shape_ of the comparison transfers across + machines, the absolute values don't. diff --git a/benchmarks/index.html b/benchmarks/index.html new file mode 100644 index 000000000..cb4d3a210 --- /dev/null +++ b/benchmarks/index.html @@ -0,0 +1,36 @@ + + + + + + Virtualization benchmarks + + + +
+ + + diff --git a/benchmarks/package.json b/benchmarks/package.json new file mode 100644 index 000000000..96638d6c7 --- /dev/null +++ b/benchmarks/package.json @@ -0,0 +1,29 @@ +{ + "name": "@tanstack/virtual-benchmarks", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview --port 4173", + "bench": "node runner/run.mjs", + "bench:headed": "node runner/run.mjs --headed" + }, + "dependencies": { + "@tanstack/react-virtual": "workspace:*", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-virtuoso": "^4.15.0", + "react-window": "^2.2.4", + "virtua": "^0.49.0" + }, + "devDependencies": { + "@playwright/test": "^1.53.1", + "@types/react": "^18.3.23", + "@types/react-dom": "^18.3.7", + "@vitejs/plugin-react": "^4.5.2", + "typescript": "5.6.3", + "vite": "^6.4.2" + } +} diff --git a/benchmarks/results/.gitkeep b/benchmarks/results/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/benchmarks/results/SAMPLE.json b/benchmarks/results/SAMPLE.json new file mode 100644 index 000000000..9e9c07c0b --- /dev/null +++ b/benchmarks/results/SAMPLE.json @@ -0,0 +1,2580 @@ +{ + "opts": { + "headed": false, + "runs": 5, + "libs": ["tanstack", "virtua", "virtuoso", "window"], + "scenarios": [ + "mount-fixed-1k", + "mount-fixed-10k", + "mount-fixed-100k", + "mount-dynamic-1k", + "mount-dynamic-10k", + "scroll-to-bottom-10k", + "fast-scroll-dynamic-10k", + "jump-to-end-dynamic-10k" + ], + "useDev": false + }, + "results": [ + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 5.099999904632568, + "firstPaintMs": 12.300000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6086427 + }, + "ranAt": "2026-05-17T06:27:57.062Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.9000000953674316, + "firstPaintMs": 8.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6088087 + }, + "ranAt": "2026-05-17T06:27:57.089Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.8000001907348633, + "firstPaintMs": 5.200000286102295, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6095999 + }, + "ranAt": "2026-05-17T06:27:57.113Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.6999998092651367, + "firstPaintMs": 9.599999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6095106 + }, + "ranAt": "2026-05-17T06:27:57.135Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.6999998092651367, + "firstPaintMs": 9.299999713897705, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6095107 + }, + "ranAt": "2026-05-17T06:27:57.157Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.4000000953674316, + "firstPaintMs": 4.900000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6887007 + }, + "ranAt": "2026-05-17T06:27:57.181Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1.700000286102295, + "firstPaintMs": 10.100000381469727, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6887691 + }, + "ranAt": "2026-05-17T06:27:57.205Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1.5999999046325684, + "firstPaintMs": 5.899999618530273, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6888900 + }, + "ranAt": "2026-05-17T06:27:57.229Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1.5999999046325684, + "firstPaintMs": 11.099999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6888088 + }, + "ranAt": "2026-05-17T06:27:57.255Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1.5999999046325684, + "firstPaintMs": 4.399999618530273, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6888623 + }, + "ranAt": "2026-05-17T06:27:57.281Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 10.5, + "firstPaintMs": 12.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 14867350 + }, + "ranAt": "2026-05-17T06:27:57.317Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 6.300000190734863, + "firstPaintMs": 9.200000286102295, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 14867346 + }, + "ranAt": "2026-05-17T06:27:57.349Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 6, + "firstPaintMs": 10.599999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 14867938 + }, + "ranAt": "2026-05-17T06:27:57.379Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 6.099999904632568, + "firstPaintMs": 15.900000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 14867265 + }, + "ranAt": "2026-05-17T06:27:57.408Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 5.900000095367432, + "firstPaintMs": 6.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 14868104 + }, + "ranAt": "2026-05-17T06:27:57.439Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.4000000953674316, + "firstPaintMs": 5.400000095367432, + "actionMs": 125.2000002861023, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 15919900 + }, + "ranAt": "2026-05-17T06:27:57.591Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.5, + "firstPaintMs": 3.6000003814697266, + "actionMs": 124.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6428115 + }, + "ranAt": "2026-05-17T06:27:57.741Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.299999713897705, + "firstPaintMs": 3.5999999046325684, + "actionMs": 124.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6426506 + }, + "ranAt": "2026-05-17T06:27:57.891Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.5, + "firstPaintMs": 3.9000000953674316, + "actionMs": 121.19999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6427068 + }, + "ranAt": "2026-05-17T06:27:58.041Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.6999998092651367, + "firstPaintMs": 10.900000095367432, + "actionMs": 120.59999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6432238 + }, + "ranAt": "2026-05-17T06:27:58.191Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 5.800000190734863, + "firstPaintMs": 8.800000190734863, + "actionMs": 119.19999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8523135 + }, + "ranAt": "2026-05-17T06:27:58.341Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 6, + "firstPaintMs": 9.200000286102295, + "actionMs": 118.2999997138977, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8523169 + }, + "ranAt": "2026-05-17T06:27:58.491Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 5.900000095367432, + "firstPaintMs": 8.900000095367432, + "actionMs": 118.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8523310 + }, + "ranAt": "2026-05-17T06:27:58.641Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 6.299999713897705, + "firstPaintMs": 9.699999809265137, + "actionMs": 116.90000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8523318 + }, + "ranAt": "2026-05-17T06:27:58.791Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7.100000381469727, + "firstPaintMs": 10.5, + "actionMs": 114.5, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8523301 + }, + "ranAt": "2026-05-17T06:27:58.940Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1.5, + "firstPaintMs": 4, + "actionMs": 1527.8999996185303, + "scrollFps": 59.99868134766269, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9818195 + }, + "ranAt": "2026-05-17T06:28:00.491Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1.6999998092651367, + "firstPaintMs": 5, + "actionMs": 1525.7999997138977, + "scrollFps": 60.0065941312232, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9572074 + }, + "ranAt": "2026-05-17T06:28:02.057Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.1999998092651367, + "firstPaintMs": 4.099999904632568, + "actionMs": 1519.8000001907349, + "scrollFps": 60.00659413122322, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9443114 + }, + "ranAt": "2026-05-17T06:28:03.608Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.1999998092651367, + "firstPaintMs": 3.9000000953674316, + "actionMs": 1521.2999997138977, + "scrollFps": 59.99868134766269, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9443822 + }, + "ranAt": "2026-05-17T06:28:05.157Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.200000286102295, + "firstPaintMs": 3.700000286102295, + "actionMs": 1519.7000002861023, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9436839 + }, + "ranAt": "2026-05-17T06:28:06.707Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 7.800000190734863, + "firstPaintMs": 14.5, + "actionMs": 1525.5, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9624712 + }, + "ranAt": "2026-05-17T06:28:08.273Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 6.400000095367432, + "firstPaintMs": 10.800000190734863, + "actionMs": 1516, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9646331 + }, + "ranAt": "2026-05-17T06:28:09.824Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 6.799999713897705, + "firstPaintMs": 13.899999618530273, + "actionMs": 1525, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9635143 + }, + "ranAt": "2026-05-17T06:28:11.390Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 7.099999904632568, + "firstPaintMs": 11, + "actionMs": 1518.6999998092651, + "scrollFps": 60.0052488107751, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9651463 + }, + "ranAt": "2026-05-17T06:28:12.958Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 7.699999809265137, + "firstPaintMs": 15, + "actionMs": 1528.4000000953674, + "scrollFps": 60.00659413122322, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 10133675 + }, + "ranAt": "2026-05-17T06:28:14.524Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 8.5, + "firstPaintMs": 14.799999713897705, + "actionMs": 90.89999961853027, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9698153 + }, + "ranAt": "2026-05-17T06:28:14.657Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 7.099999904632568, + "firstPaintMs": 10.799999713897705, + "actionMs": 82.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9699761 + }, + "ranAt": "2026-05-17T06:28:14.773Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.800000190734863, + "firstPaintMs": 10.700000286102295, + "actionMs": 83, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9699668 + }, + "ranAt": "2026-05-17T06:28:14.890Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.5, + "firstPaintMs": 10, + "actionMs": 83.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9697280 + }, + "ranAt": "2026-05-17T06:28:15.006Z" + }, + { + "library": "tanstack", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.800000190734863, + "firstPaintMs": 10.599999904632568, + "actionMs": 83.10000038146973, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9701473 + }, + "ranAt": "2026-05-17T06:28:15.123Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 2.3000001907348633, + "firstPaintMs": 9.5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6300409 + }, + "ranAt": "2026-05-17T06:28:15.147Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.5999999046325684, + "firstPaintMs": 8.599999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6288497 + }, + "ranAt": "2026-05-17T06:28:15.168Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.6999998092651367, + "firstPaintMs": 8.399999618530273, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6288897 + }, + "ranAt": "2026-05-17T06:28:15.188Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.5999999046325684, + "firstPaintMs": 8.300000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6289526 + }, + "ranAt": "2026-05-17T06:28:15.208Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 0.6999998092651367, + "firstPaintMs": 3.9000000953674316, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6301637 + }, + "ranAt": "2026-05-17T06:28:15.229Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 0.9000000953674316, + "firstPaintMs": 9, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6721789 + }, + "ranAt": "2026-05-17T06:28:15.251Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1, + "firstPaintMs": 8.799999713897705, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6722421 + }, + "ranAt": "2026-05-17T06:28:15.273Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1, + "firstPaintMs": 4.199999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6734957 + }, + "ranAt": "2026-05-17T06:28:15.295Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1.0999999046325684, + "firstPaintMs": 10.900000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6722660 + }, + "ranAt": "2026-05-17T06:28:15.318Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 0.9000000953674316, + "firstPaintMs": 6.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6734719 + }, + "ranAt": "2026-05-17T06:28:15.342Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 3.0999999046325684, + "firstPaintMs": 11.099999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11055465 + }, + "ranAt": "2026-05-17T06:28:15.367Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 3, + "firstPaintMs": 10.400000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11043105 + }, + "ranAt": "2026-05-17T06:28:15.390Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 3.0999999046325684, + "firstPaintMs": 10.700000286102295, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11056189 + }, + "ranAt": "2026-05-17T06:28:15.414Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 3, + "firstPaintMs": 10.800000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11043145 + }, + "ranAt": "2026-05-17T06:28:15.438Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.200000286102295, + "firstPaintMs": 5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11055785 + }, + "ranAt": "2026-05-17T06:28:15.463Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.5, + "firstPaintMs": 9.299999713897705, + "actionMs": 121.7000002861023, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6479289 + }, + "ranAt": "2026-05-17T06:28:15.607Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.8000001907348633, + "firstPaintMs": 10.5, + "actionMs": 123, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6462551 + }, + "ranAt": "2026-05-17T06:28:15.757Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.6999998092651367, + "firstPaintMs": 9.900000095367432, + "actionMs": 121.40000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6477684 + }, + "ranAt": "2026-05-17T06:28:15.907Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.8999996185302734, + "firstPaintMs": 10.199999809265137, + "actionMs": 120.30000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6479772 + }, + "ranAt": "2026-05-17T06:28:16.057Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 1.9000000953674316, + "firstPaintMs": 10.800000190734863, + "actionMs": 121.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6479237 + }, + "ranAt": "2026-05-17T06:28:16.207Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 8.400000095367432, + "firstPaintMs": 16.90000009536743, + "actionMs": 122.40000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8199423 + }, + "ranAt": "2026-05-17T06:28:16.374Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 6.700000286102295, + "firstPaintMs": 13.5, + "actionMs": 117.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8217282 + }, + "ranAt": "2026-05-17T06:28:16.524Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 6.599999904632568, + "firstPaintMs": 14.800000190734863, + "actionMs": 118.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8200907 + }, + "ranAt": "2026-05-17T06:28:16.674Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7.699999809265137, + "firstPaintMs": 15.099999904632568, + "actionMs": 113.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8215592 + }, + "ranAt": "2026-05-17T06:28:16.823Z" + }, + { + "library": "virtua", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 5.600000381469727, + "firstPaintMs": 16.5, + "actionMs": 113.90000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8217661 + }, + "ranAt": "2026-05-17T06:28:16.992Z" + }, + { + "library": "virtua", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1.4000000953674316, + "firstPaintMs": 7.700000286102295, + "actionMs": 1525.4000000953674, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 6783343 + }, + "ranAt": "2026-05-17T06:28:18.623Z" + }, + { + "library": "virtua", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1, + "firstPaintMs": 1.3000001907348633, + "actionMs": 1526.5999999046326, + "scrollFps": 60.00659413122322, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 6782755 + }, + "ranAt": "2026-05-17T06:28:20.177Z" + }, + { + "library": "virtua", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1.4000000953674316, + "firstPaintMs": 13.800000190734863, + "actionMs": 1531.0999999046326, + "scrollFps": 60.001304376182084, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 7909894 + }, + "ranAt": "2026-05-17T06:28:21.740Z" + }, + { + "library": "virtua", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1.0999999046325684, + "firstPaintMs": 2.5999999046325684, + "actionMs": 1526.5, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 6784469 + }, + "ranAt": "2026-05-17T06:28:23.290Z" + }, + { + "library": "virtua", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 1.1999998092651367, + "firstPaintMs": 11.099999904632568, + "actionMs": 1517.7999997138977, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 6798621 + }, + "ranAt": "2026-05-17T06:28:24.840Z" + }, + { + "library": "virtua", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 9.900000095367432, + "firstPaintMs": 16.699999809265137, + "actionMs": 1531, + "scrollFps": 60.001304376182084, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 8258693 + }, + "ranAt": "2026-05-17T06:28:26.406Z" + }, + { + "library": "virtua", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 6.300000190734863, + "firstPaintMs": 13.800000190734863, + "actionMs": 1522.4000000953674, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 8242370 + }, + "ranAt": "2026-05-17T06:28:27.959Z" + }, + { + "library": "virtua", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 10.799999713897705, + "firstPaintMs": 17.899999618530273, + "actionMs": 1523.3000001907349, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 8241079 + }, + "ranAt": "2026-05-17T06:28:29.523Z" + }, + { + "library": "virtua", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 8.5, + "firstPaintMs": 14.599999904632568, + "actionMs": 1532.8000001907349, + "scrollFps": 60.005217845029996, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 8259372 + }, + "ranAt": "2026-05-17T06:28:31.090Z" + }, + { + "library": "virtua", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 5.699999809265137, + "firstPaintMs": 13.299999713897705, + "actionMs": 1519.5, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 8241608 + }, + "ranAt": "2026-05-17T06:28:32.639Z" + }, + { + "library": "virtua", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 5.699999809265137, + "firstPaintMs": 13.299999713897705, + "actionMs": 72.10000038146973, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8208066 + }, + "ranAt": "2026-05-17T06:28:32.739Z" + }, + { + "library": "virtua", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 5.700000286102295, + "firstPaintMs": 13, + "actionMs": 72.59999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8207584 + }, + "ranAt": "2026-05-17T06:28:32.839Z" + }, + { + "library": "virtua", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 5.700000286102295, + "firstPaintMs": 14.099999904632568, + "actionMs": 71.2000002861023, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8208218 + }, + "ranAt": "2026-05-17T06:28:32.939Z" + }, + { + "library": "virtua", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 5.799999713897705, + "firstPaintMs": 13.799999713897705, + "actionMs": 72.30000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8207269 + }, + "ranAt": "2026-05-17T06:28:33.039Z" + }, + { + "library": "virtua", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 5.699999809265137, + "firstPaintMs": 13.300000190734863, + "actionMs": 72.69999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8207237 + }, + "ranAt": "2026-05-17T06:28:33.140Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 5.099999904632568, + "firstPaintMs": 22.09999990463257, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6808084 + }, + "ranAt": "2026-05-17T06:28:33.206Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 2, + "firstPaintMs": 12.899999618530273, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6621739 + }, + "ranAt": "2026-05-17T06:28:33.238Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 1.5, + "firstPaintMs": 2, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6621144 + }, + "ranAt": "2026-05-17T06:28:33.264Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 1.8000001907348633, + "firstPaintMs": 7, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6621747 + }, + "ranAt": "2026-05-17T06:28:33.292Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 1.799999713897705, + "firstPaintMs": 9.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6621196 + }, + "ranAt": "2026-05-17T06:28:33.317Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.0999999046325684, + "firstPaintMs": 9.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7053550 + }, + "ranAt": "2026-05-17T06:28:33.341Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.1999998092651367, + "firstPaintMs": 9.199999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7054616 + }, + "ranAt": "2026-05-17T06:28:33.364Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2, + "firstPaintMs": 10, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7054713 + }, + "ranAt": "2026-05-17T06:28:33.388Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 1.8000001907348633, + "firstPaintMs": 5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7055528 + }, + "ranAt": "2026-05-17T06:28:33.411Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2, + "firstPaintMs": 9.899999618530273, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7054001 + }, + "ranAt": "2026-05-17T06:28:33.434Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 5.5, + "firstPaintMs": 7.300000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11375543 + }, + "ranAt": "2026-05-17T06:28:33.461Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 5.5, + "firstPaintMs": 12.099999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11374922 + }, + "ranAt": "2026-05-17T06:28:33.487Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.800000190734863, + "firstPaintMs": 5.900000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11375187 + }, + "ranAt": "2026-05-17T06:28:33.512Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.799999713897705, + "firstPaintMs": 11.400000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11374938 + }, + "ranAt": "2026-05-17T06:28:33.537Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 5, + "firstPaintMs": 5.199999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11375679 + }, + "ranAt": "2026-05-17T06:28:33.562Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.4000000953674316, + "firstPaintMs": 9.699999809265137, + "actionMs": 204.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7492389 + }, + "ranAt": "2026-05-17T06:28:33.790Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.799999713897705, + "firstPaintMs": 7.799999713897705, + "actionMs": 190, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7492783 + }, + "ranAt": "2026-05-17T06:28:34.023Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.8000001907348633, + "firstPaintMs": 6.099999904632568, + "actionMs": 194.2999997138977, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7494064 + }, + "ranAt": "2026-05-17T06:28:34.255Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.5, + "firstPaintMs": 11.599999904632568, + "actionMs": 200.5, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7494020 + }, + "ranAt": "2026-05-17T06:28:34.489Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 3, + "firstPaintMs": 10.699999809265137, + "actionMs": 190.59999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7493013 + }, + "ranAt": "2026-05-17T06:28:34.706Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 8.200000286102295, + "firstPaintMs": 15.099999904632568, + "actionMs": 200.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9229536 + }, + "ranAt": "2026-05-17T06:28:34.939Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 8.199999809265137, + "firstPaintMs": 14, + "actionMs": 188.40000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9223223 + }, + "ranAt": "2026-05-17T06:28:35.156Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 8.5, + "firstPaintMs": 14.699999809265137, + "actionMs": 188.2000002861023, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9224195 + }, + "ranAt": "2026-05-17T06:28:35.373Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 9.300000190734863, + "firstPaintMs": 16, + "actionMs": 185.30000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9224355 + }, + "ranAt": "2026-05-17T06:28:35.589Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 9.299999713897705, + "firstPaintMs": 15.5, + "actionMs": 184.69999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9221197 + }, + "ranAt": "2026-05-17T06:28:35.806Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2, + "firstPaintMs": 2.1999998092651367, + "actionMs": 1525.3999996185303, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 7440593 + }, + "ranAt": "2026-05-17T06:28:37.356Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.0999999046325684, + "firstPaintMs": 10.199999809265137, + "actionMs": 1520.7000002861023, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 7439349 + }, + "ranAt": "2026-05-17T06:28:38.906Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.3000001907348633, + "firstPaintMs": 10.700000286102295, + "actionMs": 1520.9000000953674, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 7442852 + }, + "ranAt": "2026-05-17T06:28:40.456Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.3000001907348633, + "firstPaintMs": 12.5, + "actionMs": 1517.6000003814697, + "scrollFps": 60.00659413122322, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 7443093 + }, + "ranAt": "2026-05-17T06:28:42.006Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.1999998092651367, + "firstPaintMs": 11.099999904632568, + "actionMs": 1519.5, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 7442861 + }, + "ranAt": "2026-05-17T06:28:43.556Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 8, + "firstPaintMs": 14.299999713897705, + "actionMs": 1519.8000001907349, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9264603 + }, + "ranAt": "2026-05-17T06:28:45.105Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 7.100000381469727, + "firstPaintMs": 10.900000095367432, + "actionMs": 1530.4000000953674, + "scrollFps": 60.00388720834523, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9266951 + }, + "ranAt": "2026-05-17T06:28:46.690Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 11.900000095367432, + "firstPaintMs": 18.700000286102295, + "actionMs": 1522.9000000953674, + "scrollFps": 59.99868134766269, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9265587 + }, + "ranAt": "2026-05-17T06:28:48.255Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 7.699999809265137, + "firstPaintMs": 14.099999904632568, + "actionMs": 1517.5999999046326, + "scrollFps": 60.0052488107751, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9264575 + }, + "ranAt": "2026-05-17T06:28:49.806Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 10.400000095367432, + "firstPaintMs": 16.90000009536743, + "actionMs": 1531.2999997138977, + "scrollFps": 60.005217845029996, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 9266098 + }, + "ranAt": "2026-05-17T06:28:51.373Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 11.599999904632568, + "firstPaintMs": 11.899999618530273, + "actionMs": 161, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9764416 + }, + "ranAt": "2026-05-17T06:28:51.572Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 8.400000095367432, + "firstPaintMs": 14.200000286102295, + "actionMs": 154.09999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9765043 + }, + "ranAt": "2026-05-17T06:28:51.755Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 9.099999904632568, + "firstPaintMs": 15, + "actionMs": 152, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9764524 + }, + "ranAt": "2026-05-17T06:28:51.938Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 8.399999618530273, + "firstPaintMs": 14.5, + "actionMs": 155.19999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9764875 + }, + "ranAt": "2026-05-17T06:28:52.122Z" + }, + { + "library": "virtuoso", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 9, + "firstPaintMs": 15.199999809265137, + "actionMs": 152.60000038146973, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 9764410 + }, + "ranAt": "2026-05-17T06:28:52.305Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 3.3999996185302734, + "firstPaintMs": 4.699999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6861779 + }, + "ranAt": "2026-05-17T06:28:52.333Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 2.1999998092651367, + "firstPaintMs": 7.5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6861306 + }, + "ranAt": "2026-05-17T06:28:52.358Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 2.1999998092651367, + "firstPaintMs": 11.5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6853417 + }, + "ranAt": "2026-05-17T06:28:52.384Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 1.9000000953674316, + "firstPaintMs": 6, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6861215 + }, + "ranAt": "2026-05-17T06:28:52.410Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-1k" + }, + "metrics": { + "mountMs": 2.0999999046325684, + "firstPaintMs": 10.199999809265137, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 6835843 + }, + "ranAt": "2026-05-17T06:28:52.434Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.5, + "firstPaintMs": 5.599999904632568, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7288925 + }, + "ranAt": "2026-05-17T06:28:52.461Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.700000286102295, + "firstPaintMs": 11.300000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7274572 + }, + "ranAt": "2026-05-17T06:28:52.486Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.299999713897705, + "firstPaintMs": 5.5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7289497 + }, + "ranAt": "2026-05-17T06:28:52.511Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.299999713897705, + "firstPaintMs": 10.400000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7273282 + }, + "ranAt": "2026-05-17T06:28:52.537Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-10k" + }, + "metrics": { + "mountMs": 2.4000000953674316, + "firstPaintMs": 5.300000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7288917 + }, + "ranAt": "2026-05-17T06:28:52.563Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.300000190734863, + "firstPaintMs": 13.900000095367432, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11594216 + }, + "ranAt": "2026-05-17T06:28:52.591Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.300000190734863, + "firstPaintMs": 13.5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11594230 + }, + "ranAt": "2026-05-17T06:28:52.620Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.400000095367432, + "firstPaintMs": 6.800000190734863, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11618086 + }, + "ranAt": "2026-05-17T06:28:52.648Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.399999618530273, + "firstPaintMs": 9.5, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11609882 + }, + "ranAt": "2026-05-17T06:28:52.677Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-fixed-100k" + }, + "metrics": { + "mountMs": 4.5, + "firstPaintMs": 13.799999713897705, + "actionMs": null, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 11598957 + }, + "ranAt": "2026-05-17T06:28:52.705Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.6999998092651367, + "firstPaintMs": 5.599999904632568, + "actionMs": 122.90000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7159536 + }, + "ranAt": "2026-05-17T06:28:52.855Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 3, + "firstPaintMs": 4.300000190734863, + "actionMs": 121.69999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7159412 + }, + "ranAt": "2026-05-17T06:28:53.005Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 3.0999999046325684, + "firstPaintMs": 4.400000095367432, + "actionMs": 120.69999980926514, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7159082 + }, + "ranAt": "2026-05-17T06:28:53.155Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.9000000953674316, + "firstPaintMs": 4.5, + "actionMs": 120.40000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7168948 + }, + "ranAt": "2026-05-17T06:28:53.305Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-1k" + }, + "metrics": { + "mountMs": 2.799999713897705, + "firstPaintMs": 4.099999904632568, + "actionMs": 121.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 7169319 + }, + "ranAt": "2026-05-17T06:28:53.455Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7, + "firstPaintMs": 8.199999809265137, + "actionMs": 116.89999961853027, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 10015714 + }, + "ranAt": "2026-05-17T06:28:53.605Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7, + "firstPaintMs": 8.300000190734863, + "actionMs": 115.89999961853027, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 10018054 + }, + "ranAt": "2026-05-17T06:28:53.755Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7.100000381469727, + "firstPaintMs": 8.400000095367432, + "actionMs": 115.7999997138977, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8908000 + }, + "ranAt": "2026-05-17T06:28:53.905Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7.099999904632568, + "firstPaintMs": 8.599999904632568, + "actionMs": 115.89999961853027, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8906157 + }, + "ranAt": "2026-05-17T06:28:54.055Z" + }, + { + "library": "window", + "scenario": { + "id": "mount-dynamic-10k" + }, + "metrics": { + "mountMs": 7, + "firstPaintMs": 9.900000095367432, + "actionMs": 117.80000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 8905100 + }, + "ranAt": "2026-05-17T06:28:54.205Z" + }, + { + "library": "window", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.4000000953674316, + "firstPaintMs": 3.6000003814697266, + "actionMs": 1524.4000000953674, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 12030498 + }, + "ranAt": "2026-05-17T06:28:55.755Z" + }, + { + "library": "window", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.5999999046325684, + "firstPaintMs": 3.8000001907348633, + "actionMs": 1522, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 12016529 + }, + "ranAt": "2026-05-17T06:28:57.305Z" + }, + { + "library": "window", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.700000286102295, + "firstPaintMs": 3.8000001907348633, + "actionMs": 1521.1999998092651, + "scrollFps": 60.002637478570485, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11771363 + }, + "ranAt": "2026-05-17T06:28:58.855Z" + }, + { + "library": "window", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.799999713897705, + "firstPaintMs": 4, + "actionMs": 1522.0999999046326, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11740186 + }, + "ranAt": "2026-05-17T06:29:00.405Z" + }, + { + "library": "window", + "scenario": { + "id": "scroll-to-bottom-10k" + }, + "metrics": { + "mountMs": 2.700000286102295, + "firstPaintMs": 3.8000001907348633, + "actionMs": 1522.9000000953674, + "scrollFps": 60.00659413122322, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11948823 + }, + "ranAt": "2026-05-17T06:29:01.955Z" + }, + { + "library": "window", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 9.5, + "firstPaintMs": 13.200000286102295, + "actionMs": 1521.6999998092651, + "scrollFps": 59.99868134766269, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11210447 + }, + "ranAt": "2026-05-17T06:29:03.522Z" + }, + { + "library": "window", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 8.800000190734863, + "firstPaintMs": 12, + "actionMs": 1521.5999999046326, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11923206 + }, + "ranAt": "2026-05-17T06:29:05.089Z" + }, + { + "library": "window", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 8.300000190734863, + "firstPaintMs": 11.400000095367432, + "actionMs": 1523.1999998092651, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 61265957 + }, + "ranAt": "2026-05-17T06:29:06.655Z" + }, + { + "library": "window", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 8.200000286102295, + "firstPaintMs": 9.700000286102295, + "actionMs": 1527.0999999046326, + "scrollFps": 60.00263747857049, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11205786 + }, + "ranAt": "2026-05-17T06:29:08.222Z" + }, + { + "library": "window", + "scenario": { + "id": "fast-scroll-dynamic-10k" + }, + "metrics": { + "mountMs": 8.400000095367432, + "firstPaintMs": 12.700000286102295, + "actionMs": 1524.2999997138977, + "scrollFps": 60.00659413122322, + "longFrames": 0, + "jankMs": 0, + "memoryBytes": 11923803 + }, + "ranAt": "2026-05-17T06:29:09.789Z" + }, + { + "library": "window", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 8.5, + "firstPaintMs": 11.599999904632568, + "actionMs": 70.89999961853027, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 38619317 + }, + "ranAt": "2026-05-17T06:29:09.904Z" + }, + { + "library": "window", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.700000286102295, + "firstPaintMs": 9.300000190734863, + "actionMs": 68.30000019073486, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 38622133 + }, + "ranAt": "2026-05-17T06:29:10.004Z" + }, + { + "library": "window", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.699999809265137, + "firstPaintMs": 7.900000095367432, + "actionMs": 66.59999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 38606492 + }, + "ranAt": "2026-05-17T06:29:10.105Z" + }, + { + "library": "window", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.800000190734863, + "firstPaintMs": 8.200000286102295, + "actionMs": 67.59999990463257, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 38620488 + }, + "ranAt": "2026-05-17T06:29:10.204Z" + }, + { + "library": "window", + "scenario": { + "id": "jump-to-end-dynamic-10k" + }, + "metrics": { + "mountMs": 6.800000190734863, + "firstPaintMs": 9.5, + "actionMs": 67.90000009536743, + "scrollFps": null, + "longFrames": null, + "jankMs": null, + "memoryBytes": 38622070 + }, + "ranAt": "2026-05-17T06:29:10.305Z" + } + ] +} diff --git a/benchmarks/runner/run.mjs b/benchmarks/runner/run.mjs new file mode 100644 index 000000000..cec981e55 --- /dev/null +++ b/benchmarks/runner/run.mjs @@ -0,0 +1,333 @@ +// Reproducible cross-library benchmark runner. +// Usage: +// pnpm bench # headless +// pnpm bench:headed # with browser window for debugging +// pnpm bench -- --runs 5 --libs tanstack,virtua # subset + +import { chromium } from '@playwright/test' +import { spawn } from 'node:child_process' +import { setTimeout as sleep } from 'node:timers/promises' +import { writeFileSync, mkdirSync } from 'node:fs' +import path from 'node:path' +import url from 'node:url' + +const __dirname = path.dirname(url.fileURLToPath(import.meta.url)) +const BENCH_DIR = path.resolve(__dirname, '..') +const PORT = 4173 +const BASE = `http://localhost:${PORT}` + +const ALL_LIBS = ['tanstack', 'virtua', 'virtuoso', 'window'] +const ALL_SCENARIOS = [ + 'mount-fixed-1k', + 'mount-fixed-10k', + 'mount-fixed-100k', + 'mount-dynamic-1k', + 'mount-dynamic-10k', + 'scroll-to-bottom-10k', + 'fast-scroll-dynamic-10k', + 'jump-to-end-dynamic-10k', + 'jump-to-middle-accuracy-dynamic-10k', + 'jump-to-last-accuracy-dynamic-10k', + 'jump-while-measuring-accuracy-dynamic-10k', + 'jump-wide-variance-accuracy-10k', +] + +function parseArgs() { + const args = process.argv.slice(2) + const out = { + headed: false, + runs: 3, + libs: ALL_LIBS, + scenarios: ALL_SCENARIOS, + useDev: false, + } + for (let i = 0; i < args.length; i++) { + const a = args[i] + if (a === '--headed') out.headed = true + else if (a === '--runs') out.runs = Number(args[++i]) + else if (a === '--libs') out.libs = args[++i].split(',') + else if (a === '--scenarios') out.scenarios = args[++i].split(',') + else if (a === '--dev') out.useDev = true + } + return out +} + +async function waitForServer(url, timeoutMs = 30_000) { + const start = Date.now() + while (Date.now() - start < timeoutMs) { + try { + const r = await fetch(url) + if (r.ok) return true + } catch {} + await sleep(200) + } + throw new Error(`server never came up at ${url}`) +} + +function spawnDevServer(useDev = false) { + const child = spawn('pnpm', [useDev ? 'dev' : 'preview'], { + cwd: BENCH_DIR, + stdio: ['ignore', 'pipe', 'pipe'], + }) + child.stdout?.on('data', (d) => + process.stderr.write(`[server] ${d.toString()}`), + ) + child.stderr?.on('data', (d) => + process.stderr.write(`[server-err] ${d.toString()}`), + ) + return child +} + +async function runScenario(page, lib, scenarioId) { + const url = `${BASE}/?lib=${lib}&scenario=${scenarioId}` + await page.goto(url, { waitUntil: 'domcontentloaded' }) + // Wait until the harness reports ready (means React mounted and registered). + await page.waitForFunction(() => !!window.bench?.ready?.(), null, { + timeout: 15_000, + }) + // Pull the scenario object back from the page so we run with the exact same + // shape the page is using. We read from window.bench.scenarios (populated + // at mount) rather than a runtime `import('/src/scenarios/types.ts')`, + // since `vite preview` only serves the built dist, not source files. + const result = await page.evaluate(async (id) => { + const scenario = window.bench?.scenarios.find((s) => s.id === id) + if (!scenario) throw new Error('unknown scenario: ' + id) + // Force GC where supported so memory readings aren't poisoned by previous run. + if ('gc' in globalThis) { + try { + globalThis.gc() + } catch {} + } + const metrics = await window.bench.run(scenario) + return { scenario, metrics } + }, scenarioId) + return result +} + +function fmt(n, digits = 1) { + if (n == null || Number.isNaN(n)) return '—' + if (Math.abs(n) >= 1000) + return n.toLocaleString(undefined, { + maximumFractionDigits: 0, + }) + return n.toFixed(digits) +} + +function median(xs) { + const ys = xs + .filter((x) => x != null && !Number.isNaN(x)) + .sort((a, b) => a - b) + if (ys.length === 0) return null + const mid = Math.floor(ys.length / 2) + return ys.length % 2 ? ys[mid] : (ys[mid - 1] + ys[mid]) / 2 +} + +function p95(xs) { + const ys = xs + .filter((x) => x != null && !Number.isNaN(x)) + .sort((a, b) => a - b) + if (ys.length === 0) return null + return ys[Math.min(ys.length - 1, Math.floor(ys.length * 0.95))] +} + +function makeTable(results, libs, scenarios) { + // For each (lib, scenario) we have N runs; pick median for table. + const cell = (lib, scenarioId, key) => { + const runs = results + .filter((r) => r.library === lib && r.scenario.id === scenarioId) + .map((r) => r.metrics[key]) + return median(runs) + } + + const sections = [ + { + title: 'Mount time — React.render → commit (lower is better, ms)', + key: 'mountMs', + scenarios: [ + 'mount-fixed-1k', + 'mount-fixed-10k', + 'mount-fixed-100k', + 'mount-dynamic-1k', + 'mount-dynamic-10k', + ], + }, + { + title: + 'Dynamic measurement — commit → stable total size (lower is better, ms)', + key: 'actionMs', + scenarios: ['mount-dynamic-1k', 'mount-dynamic-10k'], + }, + { + title: 'First paint (lower is better, ms)', + key: 'firstPaintMs', + scenarios: ['mount-fixed-1k', 'mount-fixed-10k', 'mount-fixed-100k'], + }, + { + title: 'Scroll perf — fps (higher is better)', + key: 'scrollFps', + scenarios: ['scroll-to-bottom-10k', 'fast-scroll-dynamic-10k'], + }, + { + title: 'Scroll jank — long frames count (lower is better)', + key: 'longFrames', + scenarios: ['scroll-to-bottom-10k', 'fast-scroll-dynamic-10k'], + }, + { + title: 'Jump-to-end settle time (lower is better, ms)', + key: 'actionMs', + scenarios: ['jump-to-end-dynamic-10k'], + }, + { + title: + 'scrollToIndex landing accuracy — px offset from target (lower is better)', + key: 'landingErrorPx', + scenarios: [ + 'jump-to-middle-accuracy-dynamic-10k', + 'jump-to-last-accuracy-dynamic-10k', + 'jump-while-measuring-accuracy-dynamic-10k', + 'jump-wide-variance-accuracy-10k', + ], + }, + { + title: 'Memory after mount (lower is better, MB)', + key: 'memoryBytes', + scenarios: ['mount-fixed-10k', 'mount-fixed-100k', 'mount-dynamic-10k'], + }, + ] + + const lines = [] + for (const sec of sections) { + lines.push(`\n### ${sec.title}\n`) + lines.push(`| Scenario | ${libs.map((l) => l).join(' | ')} |`) + lines.push(`|---|${libs.map(() => '---:').join('|')}|`) + for (const s of sec.scenarios) { + const cells = libs.map((l) => { + const v = cell(l, s, sec.key) + if (v == null) return '—' + if (sec.key === 'memoryBytes') return fmt(v / 1024 / 1024) + if (sec.key === 'scrollFps') return fmt(v) + return fmt(v) + }) + lines.push(`| \`${s}\` | ${cells.join(' | ')} |`) + } + } + return lines.join('\n') +} + +async function main() { + const opts = parseArgs() + console.error(`config: ${JSON.stringify(opts)}`) + + if (!opts.useDev) { + // Build the app once for the preview server (production code paths). + await new Promise((resolve, reject) => { + const c = spawn('pnpm', ['build'], { cwd: BENCH_DIR, stdio: 'inherit' }) + c.on('exit', (code) => + code === 0 ? resolve() : reject(new Error('build failed')), + ) + }) + } + + let server = null + // If a server is already listening on PORT, skip starting one. + let needsServer = true + try { + const r = await fetch(BASE) + if (r.ok) needsServer = false + } catch {} + if (needsServer) { + server = spawnDevServer(opts.useDev) + } else { + console.error('using already-running server at ' + BASE) + } + try { + await waitForServer(BASE) + const browser = await chromium.launch({ + headless: !opts.headed, + args: [ + // Precise memory reporting (otherwise bucketed to ~10MB granularity). + '--enable-precise-memory-info', + '--js-flags=--expose-gc', + // Disable network throttling and other interference. + '--disable-background-timer-throttling', + '--disable-renderer-backgrounding', + ], + }) + const context = await browser.newContext({ + viewport: { width: 800, height: 700 }, + }) + const page = await context.newPage() + + const results = [] + for (const lib of opts.libs) { + for (const scenarioId of opts.scenarios) { + for (let r = 0; r < opts.runs; r++) { + process.stderr.write( + `\n ${lib.padEnd(9)} ${scenarioId.padEnd(28)} run ${r + 1}/${opts.runs} ... `, + ) + try { + const { scenario, metrics } = await runScenario( + page, + lib, + scenarioId, + ) + results.push({ + library: lib, + scenario, + metrics, + ranAt: new Date().toISOString(), + }) + process.stderr.write( + `mount=${fmt(metrics.mountMs)}ms action=${fmt(metrics.actionMs)}ms`, + ) + } catch (e) { + process.stderr.write(`ERROR: ${e.message}`) + results.push({ + library: lib, + scenario: { id: scenarioId }, + metrics: { + mountMs: NaN, + firstPaintMs: NaN, + actionMs: NaN, + scrollFps: null, + longFrames: null, + jankMs: null, + memoryBytes: null, + landingErrorPx: null, + }, + ranAt: new Date().toISOString(), + notes: 'error: ' + e.message, + }) + } + } + } + } + + await browser.close() + + mkdirSync(path.join(BENCH_DIR, 'results'), { recursive: true }) + const stamp = new Date().toISOString().replace(/[:.]/g, '-') + writeFileSync( + path.join(BENCH_DIR, 'results', `${stamp}.json`), + JSON.stringify({ opts, results }, null, 2), + ) + + const md = makeTable(results, opts.libs, opts.scenarios) + console.log(`# Virtualization benchmarks — ${new Date().toISOString()}\n`) + console.log(`runs per cell: ${opts.runs} (table shows medians)\n`) + console.log(`libraries: ${opts.libs.join(', ')}\n`) + console.log(md) + + writeFileSync( + path.join(BENCH_DIR, 'results', 'LATEST.md'), + `# Virtualization benchmarks — ${new Date().toISOString()}\n\nruns per cell: ${opts.runs}\n${md}\n`, + ) + } finally { + server?.kill('SIGTERM') + } +} + +main().catch((e) => { + console.error(e) + process.exit(1) +}) diff --git a/benchmarks/src/lib/dataset.ts b/benchmarks/src/lib/dataset.ts new file mode 100644 index 000000000..416f98d23 --- /dev/null +++ b/benchmarks/src/lib/dataset.ts @@ -0,0 +1,89 @@ +// Deterministic dataset generation. Every library renders the SAME content for +// the same scenario, so any timing differences come from the library itself, +// not from input variance. +// +// For dynamic scenarios we vary content length so each item naturally has a +// different height (5..14 lines worth of text). For fixed scenarios every item +// is a single line of text. + +export interface Item { + id: number + // Text rendered into the item DOM. For dynamic scenarios, length varies. + text: string +} + +const WORDS = [ + 'alpha', + 'bravo', + 'charlie', + 'delta', + 'echo', + 'foxtrot', + 'golf', + 'hotel', + 'india', + 'juliet', + 'kilo', + 'lima', + 'mike', + 'november', + 'oscar', + 'papa', + 'quebec', + 'romeo', + 'sierra', + 'tango', + 'uniform', + 'victor', + 'whiskey', + 'x-ray', + 'yankee', + 'zulu', +] + +// Simple LCG so the same seed yields the same sequence in any JS runtime. +function lcg(seed: number) { + let s = seed >>> 0 + return () => { + s = (s * 1664525 + 1013904223) >>> 0 + return s / 0x100000000 + } +} + +export function makeDataset( + count: number, + dynamic: boolean, + wideVariance = false, +): Array { + const rand = lcg(424242) + const items: Array = new Array(count) + for (let i = 0; i < count; i++) { + if (dynamic) { + if (wideVariance) { + // Wide-variance dataset: heights span ~30..500 px (≈16× ratio). + // 1 → 50 words distributed log-normally so most items are short + // but a meaningful tail is very tall. + const wc = 1 + Math.floor(Math.pow(rand(), 2) * 49) + const parts: Array = new Array(wc) + for (let w = 0; w < wc; w++) { + parts[w] = WORDS[Math.floor(rand() * WORDS.length)]! + } + items[i] = { id: i, text: `#${i} ${parts.join(' ')}` } + } else { + // 5..14 words → ~ one line; lengths picked deterministically. + const wc = 5 + Math.floor(rand() * 10) + const parts: Array = new Array(wc) + for (let w = 0; w < wc; w++) { + parts[w] = WORDS[Math.floor(rand() * WORDS.length)]! + } + // 25% of dynamic items get a multi-line burst for height variation. + const burst = + rand() < 0.25 ? ' ' + parts.join(' ') + ' ' + parts.join(' ') : '' + items[i] = { id: i, text: `#${i} ${parts.join(' ')}${burst}` } + } + } else { + items[i] = { id: i, text: `Item ${i}` } + } + } + return items +} diff --git a/benchmarks/src/lib/harness.ts b/benchmarks/src/lib/harness.ts new file mode 100644 index 000000000..141f00c0a --- /dev/null +++ b/benchmarks/src/lib/harness.ts @@ -0,0 +1,330 @@ +import { SCENARIOS } from '../scenarios/types' +import type { ScenarioInput, ScenarioMetrics } from '../scenarios/types' + +// Each library page mounts and waits, then a global driver runs the scripted +// action and returns metrics. To keep measurements uniform we share this +// harness. + +export interface HarnessHandle { + /** Container element the library is told to scroll. */ + getScrollContainer: () => HTMLElement | null + /** Programmatically scroll to a target offset (px). */ + scrollToOffset?: (offset: number) => void + /** Programmatically scroll to a target index. Some libraries expose + * scrollToIndex; if absent, harness falls back to scrollTo(maxOffset). */ + scrollToIndex?: (index: number, opts?: { align?: 'start' | 'end' }) => void + /** Total scrollable height in px. Read after mount. */ + getTotalSize: () => number + /** Returns true once every item in the visible range has had its real size + * measured. Used for the wait-dynamic-measure action. */ + isFullyMeasured?: () => boolean +} + +declare global { + interface Window { + __bench?: { + handle?: HarnessHandle + mountStart?: number + mountEnd?: number + firstPaintEnd?: number + ready?: boolean + } + bench?: { + run: (scenario: ScenarioInput) => Promise + ready: () => boolean + // Exposed so the Node-side Playwright runner can resolve a scenario + // id to its full object without a runtime source-file import (which + // wouldn't survive `vite preview`'s built-only serving). + scenarios: ReadonlyArray + } + } +} + +function nextFrame(): Promise { + return new Promise((resolve) => requestAnimationFrame(resolve)) +} + +function waitFor( + predicate: () => T | false | null | undefined, + timeoutMs = 8000, +): Promise { + return new Promise((resolve, reject) => { + const start = performance.now() + const tick = () => { + const r = predicate() + if (r) return resolve(r as T) + if (performance.now() - start > timeoutMs) { + return reject(new Error('timeout waiting for predicate')) + } + requestAnimationFrame(tick) + } + tick() + }) +} + +async function measureScrollFps( + el: HTMLElement, + startOffset: number, + targetOffset: number, + durationMs = 1500, +): Promise<{ fps: number; longFrames: number; jankMs: number }> { + // Programmatic, requestAnimationFrame-driven scroll. We sample frame + // timestamps and infer FPS / jank from inter-frame gaps. + const frames: number[] = [] + let lastT = performance.now() + let stop = false + const onFrame = (t: number) => { + frames.push(t - lastT) + lastT = t + if (!stop) requestAnimationFrame(onFrame) + } + requestAnimationFrame((t) => { + lastT = t + requestAnimationFrame(onFrame) + }) + + const startT = performance.now() + while (performance.now() - startT < durationMs) { + const elapsed = performance.now() - startT + const t = Math.min(elapsed / durationMs, 1) + el.scrollTop = startOffset + (targetOffset - startOffset) * t + await nextFrame() + } + stop = true + await nextFrame() + + const longFrames = frames.filter((f) => f > 32).length + const jankMs = frames.filter((f) => f > 50).reduce((s, f) => s + f, 0) + const avgFrame = frames.length + ? frames.reduce((s, f) => s + f, 0) / frames.length + : 0 + const fps = avgFrame > 0 ? 1000 / avgFrame : 0 + return { fps, longFrames, jankMs } +} + +export function registerHarness(handle: HarnessHandle): void { + window.__bench = window.__bench || {} + window.__bench.handle = handle + window.__bench.ready = true +} + +export function markMountStart(): void { + window.__bench = window.__bench || {} + window.__bench.mountStart = performance.now() +} + +export function markMountEnd(): void { + window.__bench = window.__bench || {} + if (window.__bench.mountEnd == null) { + window.__bench.mountEnd = performance.now() + } +} + +export function markFirstPaint(): void { + // Wait one rAF then mark — gives the browser a chance to actually paint. + requestAnimationFrame(() => { + window.__bench = window.__bench || {} + if (window.__bench.firstPaintEnd == null) { + window.__bench.firstPaintEnd = performance.now() + } + }) +} + +export function installBenchAPI(): void { + window.bench = { + ready: () => !!window.__bench?.ready, + scenarios: SCENARIOS, + run: async (scenario: ScenarioInput): Promise => { + const h = await waitFor(() => window.__bench?.handle ?? null) + const mountStart = window.__bench?.mountStart ?? 0 + const mountEnd = window.__bench?.mountEnd ?? performance.now() + const firstPaintEnd = window.__bench?.firstPaintEnd ?? performance.now() + + const mountMs = Math.max(0, mountEnd - mountStart) + const firstPaintMs = Math.max(0, firstPaintEnd - mountStart) + + let actionMs: number | null = null + let scrollFps: number | null = null + let longFrames: number | null = null + let jankMs: number | null = null + + const container = h.getScrollContainer() + if (!container) { + throw new Error('harness: scroll container not available') + } + + if (scenario.action === 'scroll-to-bottom') { + const total = h.getTotalSize() + const target = Math.max(0, total - container.clientHeight) + const t0 = performance.now() + const r = await measureScrollFps(container, 0, target, 1500) + actionMs = performance.now() - t0 + scrollFps = r.fps + longFrames = r.longFrames + jankMs = r.jankMs + } else if (scenario.action === 'jump-to-end') { + const t0 = performance.now() + if (h.scrollToIndex) { + h.scrollToIndex(scenario.count - 1, { align: 'end' }) + } else { + const total = h.getTotalSize() + container.scrollTop = total + } + // Wait for scroll position to settle and not change for 5 frames + let stableCount = 0 + let lastTop = container.scrollTop + while (stableCount < 5 && performance.now() - t0 < 5000) { + await nextFrame() + const cur = container.scrollTop + if (Math.abs(cur - lastTop) < 1) stableCount++ + else stableCount = 0 + lastTop = cur + } + actionMs = performance.now() - t0 + } else if (scenario.action === 'jump-to-middle-accuracy') { + // Accuracy test: ask the library to scroll to a specific index in + // the middle of a dynamic-height list, then verify how close the + // resulting scroll position is to where that item *actually* lives. + // Smaller landingErrorPx means more accurate scrollToIndex. + const targetIndex = Math.floor(scenario.count / 2) // e.g. 5000 of 10000 + const t0 = performance.now() + if (h.scrollToIndex) { + h.scrollToIndex(targetIndex, { align: 'start' }) + } + // Wait for the scroll to fully settle. + let stableCount = 0 + let lastTop = container.scrollTop + while (stableCount < 8 && performance.now() - t0 < 5000) { + await nextFrame() + const cur = container.scrollTop + if (Math.abs(cur - lastTop) < 0.5) stableCount++ + else stableCount = 0 + lastTop = cur + } + actionMs = performance.now() - t0 + + // Now: find the DOM element for the target index. Its viewport-relative + // top tells us where it actually landed. With align:'start', we want + // item[targetIndex]'s top to be at viewport top — i.e., offset 0. + const itemSelector = `[data-index="${targetIndex}"]` + const itemEl = container.querySelector( + itemSelector, + ) as HTMLElement | null + if (itemEl) { + const itemRect = itemEl.getBoundingClientRect() + const containerRect = container.getBoundingClientRect() + // Distance from container's top to item's top — should be ≈ 0 + // for align:'start'. Anything > 1px is a landing error. + ;(window as any).__landingErrorPx = Math.abs( + itemRect.top - containerRect.top, + ) + } else { + // Item not in the DOM at all — major accuracy failure + ;(window as any).__landingErrorPx = -1 + } + } else if ( + scenario.action === 'jump-to-last-accuracy' || + scenario.action === 'jump-while-measuring-accuracy' || + scenario.action === 'jump-wide-variance-accuracy' + ) { + // Three accuracy edge cases sharing the same measurement skeleton: + // - jump-to-last: align='end', target = last index. Tests cumulative + // prefix-sum error on dynamic lists; end-alignment amplifies any + // drift between estimates and real measurements. + // - jump-while-measuring: scroll BEFORE the initial visible window + // has finished measuring. The race condition that competitors + // handle differently (virtuoso retries, virtua pre-measures). + // - jump-wide-variance: 30..500px items, 16x size variance vs the + // 30px estimate. Tests how each lib converges when estimates are + // drastically wrong. + const isLast = scenario.action === 'jump-to-last-accuracy' + const isWhileMeasuring = + scenario.action === 'jump-while-measuring-accuracy' + // Target choice + alignment per case + const targetIndex = isLast + ? scenario.count - 1 + : Math.floor(scenario.count / 2) + const align: 'start' | 'end' = isLast ? 'end' : 'start' + + // For jump-while-measuring, do NOT wait — scroll immediately so the + // race condition is realistic. For others, wait a tick to allow + // initial measurements. + if (!isWhileMeasuring) { + await nextFrame() + } + + const t0 = performance.now() + if (h.scrollToIndex) { + h.scrollToIndex(targetIndex, { align }) + } + // Wait for scroll to fully settle + let stableCount = 0 + let lastTop = container.scrollTop + while (stableCount < 8 && performance.now() - t0 < 5000) { + await nextFrame() + const cur = container.scrollTop + if (Math.abs(cur - lastTop) < 0.5) stableCount++ + else stableCount = 0 + lastTop = cur + } + actionMs = performance.now() - t0 + + // Compute landing error: distance between the relevant edge of the + // target item and the relevant edge of the viewport. + const itemEl = container.querySelector( + `[data-index="${targetIndex}"]`, + ) as HTMLElement | null + if (itemEl) { + const iRect = itemEl.getBoundingClientRect() + const cRect = container.getBoundingClientRect() + const err = + align === 'end' + ? Math.abs(iRect.bottom - cRect.bottom) + : Math.abs(iRect.top - cRect.top) + ;(window as any).__landingErrorPx = err + } else { + ;(window as any).__landingErrorPx = -1 + } + } else if (scenario.action === 'wait-dynamic-measure') { + // Uniform metric across libraries: time until the total scroll height + // stops changing for 8 consecutive frames. Libraries finish measuring + // their visible window in different ways but they all converge on a + // stable getTotalSize(). + const t0 = performance.now() + let lastTotal = h.getTotalSize() + let stableCount = 0 + while (stableCount < 8 && performance.now() - t0 < 3000) { + await nextFrame() + const cur = h.getTotalSize() + if (cur === lastTotal && cur > 0) stableCount++ + else stableCount = 0 + lastTotal = cur + } + actionMs = performance.now() - t0 + } + + const mem = (performance as any).memory + const memoryBytes = + mem && typeof mem.usedJSHeapSize === 'number' + ? mem.usedJSHeapSize + : null + + const landingErrorPx = + typeof (window as any).__landingErrorPx === 'number' + ? (window as any).__landingErrorPx + : null + ;(window as any).__landingErrorPx = undefined + + return { + mountMs, + firstPaintMs, + actionMs, + scrollFps, + longFrames, + jankMs, + memoryBytes, + landingErrorPx, + } + }, + } +} diff --git a/benchmarks/src/main.tsx b/benchmarks/src/main.tsx new file mode 100644 index 000000000..e4ceca2cf --- /dev/null +++ b/benchmarks/src/main.tsx @@ -0,0 +1,49 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import { TanstackPageRoot } from './pages/TanstackPage' +import { VirtuaPageRoot } from './pages/VirtuaPage' +import { VirtuosoPageRoot } from './pages/VirtuosoPage' +import { WindowPageRoot } from './pages/WindowPage' +import { installBenchAPI } from './lib/harness' +import { + SCENARIOS, + type LibraryName, + type ScenarioInput, +} from './scenarios/types' + +// Install window.bench BEFORE React renders so the Playwright runner can +// wait for it deterministically. +installBenchAPI() + +function readQuery(): { lib: LibraryName; scenario: ScenarioInput } { + const q = new URLSearchParams(window.location.search) + const lib = (q.get('lib') ?? 'tanstack') as LibraryName + const id = q.get('scenario') ?? 'mount-fixed-1k' + const scenario = SCENARIOS.find((s) => s.id === id) ?? SCENARIOS[0]! + return { lib, scenario } +} + +function App() { + const { lib, scenario } = readQuery() + switch (lib) { + case 'tanstack': + return + case 'virtua': + return + case 'virtuoso': + return + case 'window': + return + default: + return ( +
+

Unknown library: {lib}

+

Try ?lib=tanstack&scenario=mount-fixed-1k

+
+ ) + } +} + +const root = createRoot(document.getElementById('root')!) +// We measure raw library cost, not StrictMode's double-render. Run without it. +root.render() diff --git a/benchmarks/src/pages/TanstackPage.tsx b/benchmarks/src/pages/TanstackPage.tsx new file mode 100644 index 000000000..02157bae1 --- /dev/null +++ b/benchmarks/src/pages/TanstackPage.tsx @@ -0,0 +1,107 @@ +import { useEffect, useMemo, useRef } from 'react' +import { useVirtualizer } from '@tanstack/react-virtual' +import { + markFirstPaint, + markMountEnd, + markMountStart, + registerHarness, +} from '../lib/harness' +import { makeDataset } from '../lib/dataset' +import type { ScenarioInput } from '../scenarios/types' + +interface Props { + scenario: ScenarioInput +} + +export function TanstackPage({ scenario }: Props) { + // Mount-start mark is set BEFORE this component renders by main.tsx. + const items = useMemo( + () => + makeDataset( + scenario.count, + scenario.dynamic, + scenario.action === 'jump-wide-variance-accuracy', + ), + [scenario.count, scenario.dynamic, scenario.action], + ) + + const parentRef = useRef(null) + + const virtualizer = useVirtualizer({ + count: items.length, + getScrollElement: () => parentRef.current, + estimateSize: () => scenario.itemSize, + overscan: 5, + }) + + // Register the bench harness once we have a ref. + useEffect(() => { + registerHarness({ + getScrollContainer: () => parentRef.current, + scrollToIndex: (i, opts) => + virtualizer.scrollToIndex(i, { align: opts?.align ?? 'start' }), + getTotalSize: () => virtualizer.getTotalSize(), + isFullyMeasured: () => { + // For dynamic scenarios, all items must have a measured size in + // measurementsCache (size differs from estimateSize). Because we + // render with overscan only, "fully measured" here means: scroll + // position reaches a steady state. We use cache size as a proxy. + const sized = (virtualizer.measurementsCache ?? []).filter( + (m) => m.size !== scenario.itemSize, + ).length + // For static scenarios there's nothing to wait on. + if (!scenario.dynamic) return true + // ~visible window size; dynamic mount only renders visible+overscan + // so this is the right proxy for "done with first measurement pass". + return sized > 0 + }, + }) + markMountEnd() + markFirstPaint() + }, [virtualizer, scenario.dynamic, scenario.itemSize]) + + return ( +
+
+ {virtualizer.getVirtualItems().map((vi) => { + const item = items[vi.index]! + return ( +
+ {item.text} +
+ ) + })} +
+
+ ) +} + +// Convenience: page-level wrapper that calls markMountStart synchronously. +// Used by main.tsx for every library. +export function TanstackPageRoot({ scenario }: Props) { + markMountStart() + return +} diff --git a/benchmarks/src/pages/VirtuaPage.tsx b/benchmarks/src/pages/VirtuaPage.tsx new file mode 100644 index 000000000..f30406755 --- /dev/null +++ b/benchmarks/src/pages/VirtuaPage.tsx @@ -0,0 +1,98 @@ +import { useEffect, useMemo, useRef } from 'react' +import { VList, type VListHandle } from 'virtua' +import { + markFirstPaint, + markMountEnd, + markMountStart, + registerHarness, +} from '../lib/harness' +import { makeDataset } from '../lib/dataset' +import type { ScenarioInput } from '../scenarios/types' + +interface Props { + scenario: ScenarioInput +} + +export function VirtuaPage({ scenario }: Props) { + const items = useMemo( + () => + makeDataset( + scenario.count, + scenario.dynamic, + scenario.action === 'jump-wide-variance-accuracy', + ), + [scenario.count, scenario.dynamic, scenario.action], + ) + + const ref = useRef(null) + const hostRef = useRef(null) + const measuredSet = useRef(new Set()) + + useEffect(() => { + registerHarness({ + getScrollContainer: () => hostRef.current, + scrollToIndex: (i, opts) => + ref.current?.scrollToIndex(i, { + align: opts?.align ?? 'start', + }), + getTotalSize: () => { + // VList sets scrollSize implicitly on its sized inner div; prefer + // that node's scrollHeight, then firstElementChild, then host. + const el = hostRef.current?.querySelector( + '[style*="height:"]', + ) as HTMLElement | null + return ( + el?.scrollHeight ?? + (hostRef.current?.firstElementChild as HTMLElement | null) + ?.scrollHeight ?? + hostRef.current?.scrollHeight ?? + 0 + ) + }, + isFullyMeasured: () => { + if (!scenario.dynamic) return true + // virtua measures items as they enter viewport; "fully measured" is a + // proxy: at least the visible window has been observed once. + return measuredSet.current.size >= 10 + }, + }) + markMountEnd() + markFirstPaint() + }, [scenario.dynamic]) + + return ( +
+ ( +
+ {data.text} +
+ )} + onScroll={() => { + // VList doesn't expose visible range directly; mark progress. + measuredSet.current.add(measuredSet.current.size) + }} + /> +
+ ) +} + +export function VirtuaPageRoot({ scenario }: Props) { + markMountStart() + return +} diff --git a/benchmarks/src/pages/VirtuosoPage.tsx b/benchmarks/src/pages/VirtuosoPage.tsx new file mode 100644 index 000000000..7851aa37f --- /dev/null +++ b/benchmarks/src/pages/VirtuosoPage.tsx @@ -0,0 +1,99 @@ +import { useEffect, useMemo, useRef } from 'react' +import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso' +import { + markFirstPaint, + markMountEnd, + markMountStart, + registerHarness, +} from '../lib/harness' +import { makeDataset } from '../lib/dataset' +import type { ScenarioInput } from '../scenarios/types' + +interface Props { + scenario: ScenarioInput +} + +export function VirtuosoPage({ scenario }: Props) { + const items = useMemo( + () => + makeDataset( + scenario.count, + scenario.dynamic, + scenario.action === 'jump-wide-variance-accuracy', + ), + [scenario.count, scenario.dynamic, scenario.action], + ) + + const ref = useRef(null) + const hostRef = useRef(null) + const measuredRef = useRef(0) + + useEffect(() => { + registerHarness({ + getScrollContainer: () => { + // Virtuoso owns its own scroll container internally. + return ( + (hostRef.current?.querySelector( + '[data-testid="virtuoso-scroller"]', + ) as HTMLElement | null) ?? hostRef.current + ) + }, + scrollToIndex: (i, opts) => + ref.current?.scrollToIndex({ + index: i, + align: opts?.align === 'end' ? 'end' : 'start', + behavior: 'auto', + }), + getTotalSize: () => { + // Virtuoso renders a tall inner div; read its height. + const scroller = hostRef.current?.querySelector( + '[data-testid="virtuoso-scroller"]', + ) as HTMLElement | null + return scroller?.scrollHeight ?? 0 + }, + isFullyMeasured: () => { + if (!scenario.dynamic) return true + return measuredRef.current >= 10 + }, + }) + markMountEnd() + markFirstPaint() + }, [scenario.dynamic]) + + return ( +
+ { + measuredRef.current = Math.max(measuredRef.current, r.endIndex) + }} + fixedItemHeight={scenario.dynamic ? undefined : scenario.itemSize} + itemContent={(i) => { + const item = items[i]! + return ( +
+ {item.text} +
+ ) + }} + /> +
+ ) +} + +export function VirtuosoPageRoot({ scenario }: Props) { + markMountStart() + return +} diff --git a/benchmarks/src/pages/WindowPage.tsx b/benchmarks/src/pages/WindowPage.tsx new file mode 100644 index 000000000..771e4ffa4 --- /dev/null +++ b/benchmarks/src/pages/WindowPage.tsx @@ -0,0 +1,103 @@ +import { useEffect, useMemo, useRef } from 'react' +import { + List, + useDynamicRowHeight, + useListRef, + type RowComponentProps, +} from 'react-window' +import { + markFirstPaint, + markMountEnd, + markMountStart, + registerHarness, +} from '../lib/harness' +import { makeDataset, type Item } from '../lib/dataset' +import type { ScenarioInput } from '../scenarios/types' + +interface Props { + scenario: ScenarioInput +} + +function Row({ + index, + style, + items, + ariaAttributes, +}: RowComponentProps<{ items: Item[] }>) { + const item = items[index]! + return ( +
+ {item.text} +
+ ) +} + +export function WindowPage({ scenario }: Props) { + const items = useMemo( + () => + makeDataset( + scenario.count, + scenario.dynamic, + scenario.action === 'jump-wide-variance-accuracy', + ), + [scenario.count, scenario.dynamic, scenario.action], + ) + + const hostRef = useRef(null) + const listRef = useListRef() + const dynamic = useDynamicRowHeight({ defaultRowHeight: scenario.itemSize }) + + useEffect(() => { + registerHarness({ + getScrollContainer: () => { + // react-window v2 mounts the scrolling element as the first child. + return ( + (hostRef.current?.firstElementChild as HTMLElement | null) ?? + hostRef.current + ) + }, + scrollToIndex: (i, opts) => + listRef.current?.scrollToRow({ + index: i, + align: opts?.align ?? 'start', + behavior: 'instant', + }), + getTotalSize: () => { + const el = hostRef.current?.firstElementChild as HTMLElement | null + return el?.scrollHeight ?? 0 + }, + isFullyMeasured: () => { + if (!scenario.dynamic) return true + const avg = dynamic.getAverageRowHeight() + return avg > 0 + }, + }) + markMountEnd() + markFirstPaint() + }, [listRef, dynamic, scenario.dynamic]) + + return ( +
+ + listRef={listRef} + rowComponent={Row} + rowCount={items.length} + rowProps={{ items }} + rowHeight={scenario.dynamic ? dynamic : scenario.itemSize} + defaultHeight={600} + style={{ height: '100%', width: '100%' }} + overscanCount={5} + /> +
+ ) +} + +export function WindowPageRoot({ scenario }: Props) { + markMountStart() + return +} diff --git a/benchmarks/src/scenarios/types.ts b/benchmarks/src/scenarios/types.ts new file mode 100644 index 000000000..48210d163 --- /dev/null +++ b/benchmarks/src/scenarios/types.ts @@ -0,0 +1,154 @@ +// Shared scenario definitions used by every library page + the Playwright runner. +// JSON-serializable so the runner can pass them as JS args via page.evaluate(). + +export type LibraryName = 'tanstack' | 'virtua' | 'virtuoso' | 'window' + +export interface ScenarioInput { + /** Stable id used for table keys and result filenames. */ + id: string + /** Number of items to render. */ + count: number + /** Fixed item size in px (lower bound used as estimate when dynamic). */ + itemSize: number + /** If true, items vary in height by content; forces ResizeObserver storms. */ + dynamic: boolean + /** Which scripted action to run after mount. */ + action: + | 'idle' + | 'scroll-to-bottom' + | 'jump-to-end' + | 'jump-to-middle-accuracy' + | 'jump-to-last-accuracy' + | 'jump-while-measuring-accuracy' + | 'jump-wide-variance-accuracy' + | 'wait-dynamic-measure' +} + +export interface ScenarioMetrics { + /** ms from React.render call to "list is mounted" (first item rendered). */ + mountMs: number + /** ms from React.render to a fully painted first frame. */ + firstPaintMs: number + /** Action-specific. For scroll-to-bottom: total animation ms. For wait-dynamic-measure: total ms. */ + actionMs: number | null + /** FPS averaged during the scripted action (scroll), or null. */ + scrollFps: number | null + /** Number of dropped frames during the action (frames longer than 32ms). */ + longFrames: number | null + /** Sum of frame durations > 50ms ("long tasks") during the action, in ms. */ + jankMs: number | null + /** Heap snapshot after mount (Chromium only; null elsewhere). */ + memoryBytes: number | null + /** Accuracy metric for jump-to-middle: |actual landing position - target| in pixels. + * Lower is better. Null for scenarios that don't measure accuracy. */ + landingErrorPx: number | null +} + +export interface ScenarioResult { + library: LibraryName + scenario: ScenarioInput + metrics: ScenarioMetrics + /** ISO timestamp the scenario ran. */ + ranAt: string + /** Notes from the page (e.g. opt-outs, library-specific caveats). */ + notes?: string +} + +// The fixed scenarios all libraries run. Adding scenarios here surfaces them +// in the runner without further plumbing. +export const SCENARIOS: Array = [ + { + id: 'mount-fixed-1k', + count: 1_000, + itemSize: 30, + dynamic: false, + action: 'idle', + }, + { + id: 'mount-fixed-10k', + count: 10_000, + itemSize: 30, + dynamic: false, + action: 'idle', + }, + { + id: 'mount-fixed-100k', + count: 100_000, + itemSize: 30, + dynamic: false, + action: 'idle', + }, + { + id: 'mount-dynamic-1k', + count: 1_000, + itemSize: 30, + dynamic: true, + action: 'wait-dynamic-measure', + }, + { + id: 'mount-dynamic-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'wait-dynamic-measure', + }, + { + id: 'scroll-to-bottom-10k', + count: 10_000, + itemSize: 30, + dynamic: false, + action: 'scroll-to-bottom', + }, + { + id: 'fast-scroll-dynamic-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'scroll-to-bottom', + }, + { + id: 'jump-to-end-dynamic-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'jump-to-end', + }, + { + id: 'jump-to-middle-accuracy-dynamic-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'jump-to-middle-accuracy', + }, + { + // End-alignment edge case: scrollToIndex(last, { align: 'end' }) should + // pin the last item to the bottom of the viewport. The cumulative size + // sum on dynamic items can drift from estimates, and end-alignment + // amplifies any prefix-sum error. + id: 'jump-to-last-accuracy-dynamic-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'jump-to-last-accuracy', + }, + { + // Race condition: scrollToIndex called BEFORE the visible items have + // measured. Tests how each library handles target drift while + // simultaneous measurements come in. + id: 'jump-while-measuring-accuracy-dynamic-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'jump-while-measuring-accuracy', + }, + { + // Wide size variance: items range 30..500px. estimateSize stays at 30. + // The 16x gap between estimate and actual exaggerates the running + // prefix-sum error that scrollToIndex relies on. + id: 'jump-wide-variance-accuracy-10k', + count: 10_000, + itemSize: 30, + dynamic: true, + action: 'jump-wide-variance-accuracy', + }, +] diff --git a/benchmarks/tsconfig.json b/benchmarks/tsconfig.json new file mode 100644 index 000000000..2bfbac127 --- /dev/null +++ b/benchmarks/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "jsx": "react-jsx", + "strict": true, + "noEmit": true, + "isolatedModules": true, + "esModuleInterop": true, + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "types": ["vite/client"] + }, + "include": ["src", "runner"] +} diff --git a/benchmarks/vite.config.ts b/benchmarks/vite.config.ts new file mode 100644 index 000000000..091db4510 --- /dev/null +++ b/benchmarks/vite.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], + server: { + port: 4173, + strictPort: true, + }, + build: { + target: 'esnext', + }, +}) diff --git a/docs/api/virtualizer.md b/docs/api/virtualizer.md index 54542063f..a7af4d632 100644 --- a/docs/api/virtualizer.md +++ b/docs/api/virtualizer.md @@ -273,6 +273,18 @@ isRtl: boolean Whether to invert horizontal scrolling to support right-to-left language locales. +### `initialMeasurementsCache` + +```tsx +initialMeasurementsCache: Array +``` + +**Default:** `[]` + +A previously-captured snapshot of measured item sizes (from `takeSnapshot()`) to seed the virtualizer with on mount. Useful for restoring scroll position after navigation: persist the result of `takeSnapshot()` (plus the current `scrollOffset`) in your route state, then pass them back as `initialMeasurementsCache` and `initialOffset` to land users at the same position without re-measuring everything from scratch. + +Items not present in the cache fall back to `estimateSize`; items present have their measured `size` restored. The cache is consumed only once, on the first `getMeasurements()` call after mount. + ### `useAnimationFrameWithResizeObserver` ```tsx @@ -393,6 +405,38 @@ measure: () => void Resets any prev item measurements. +### `takeSnapshot` + +```tsx +takeSnapshot: () => Array +``` + +Returns a snapshot of currently-measured items as plain `VirtualItem` +objects, suitable for round-tripping through state storage and feeding +back as `initialMeasurementsCache` on remount. Pair with the current +`scrollOffset` to restore exact scroll position after navigation. + +Only items the consumer has actually rendered (and thus measured) appear +in the snapshot; unmeasured items will fall back to `estimateSize` on +restore. Returns an empty array if no items have been measured. + +```tsx +// Capture state on unmount +const snapshot = virtualizer.takeSnapshot() +const offset = virtualizer.scrollOffset +sessionStorage.setItem('myList', JSON.stringify({ snapshot, offset })) + +// Restore on remount +const saved = JSON.parse(sessionStorage.getItem('myList') ?? 'null') +useVirtualizer({ + count: items.length, + estimateSize: () => 50, + getScrollElement: () => parentRef.current, + initialMeasurementsCache: saved?.snapshot, + initialOffset: saved?.offset, +}) +``` + ### `measureElement` ```tsx @@ -438,7 +482,11 @@ Current `Rect` of the scroll element. shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) ``` -The shouldAdjustScrollPositionOnItemSizeChange method enables fine-grained control over the adjustment of scroll position when the size of dynamically rendered items differs from the estimated size. When jumping in the middle of the list and scrolling backward new elements may have a different size than the initially estimated size. This discrepancy can cause subsequent items to shift, potentially disrupting the user's scrolling experience, particularly when navigating backward through the list. +Provides fine-grained control over the scroll-position adjustment that fires when an above-viewport item's measured size differs from its estimated size. By default the virtualizer applies this correction only when the user is **not** scrolling backward, which avoids the well-known "items jump while scrolling up" jank. Supply this callback only if you want to override that default — for example, to apply corrections during backward scroll, or to skip them in additional scenarios. + +The callback receives the resized `item`, the size `delta`, and the `instance`; return `true` to apply the scroll adjustment, `false` to skip it. + +On iOS WebKit, scroll-position writes are deferred regardless of this callback while a finger is on screen, during momentum-scroll, and during elastic-overscroll bounce. The cumulative delta is flushed in a single write once the scroll settles, preserving iOS's native momentum physics. ### `isScrolling` diff --git a/knip.json b/knip.json index 490dfd010..6babde9da 100644 --- a/knip.json +++ b/knip.json @@ -1,6 +1,6 @@ { "$schema": "https://unpkg.com/knip@5/schema.json", - "ignoreWorkspaces": ["examples/**"], + "ignoreWorkspaces": ["examples/**", "benchmarks"], "ignoreDependencies": ["@angular/cli"], "ignore": ["packages/react-virtual/e2e/app/**"] } diff --git a/packages/react-virtual/src/index.tsx b/packages/react-virtual/src/index.tsx index 313c3d4f9..89678ad63 100644 --- a/packages/react-virtual/src/index.tsx +++ b/packages/react-virtual/src/index.tsx @@ -33,7 +33,7 @@ function useVirtualizerBase< TScrollElement, TItemElement > { - const rerender = React.useReducer(() => ({}), {})[1] + const rerender = React.useReducer((x: number) => x + 1, 0)[1] const resolvedOptions: VirtualizerOptions = { ...options, diff --git a/packages/virtual-core/src/index.ts b/packages/virtual-core/src/index.ts index 75dcbdb75..a1e9dcc78 100644 --- a/packages/virtual-core/src/index.ts +++ b/packages/virtual-core/src/index.ts @@ -1,6 +1,29 @@ +import { createLazyMeasurementsView } from './lazy-measurements' import { approxEqual, debounce, memo, notUndefined } from './utils' -export * from './utils' +// Browser-aware iOS detection. Programmatic `scrollTo`/`scrollTop` writes +// during a momentum-scroll cancel the momentum on iOS WebKit, so we defer +// scroll-position adjustments triggered by mid-scroll resizes until the +// scroll settles. SSR-safe (returns false when navigator is unavailable). +let _isIOSResult: boolean | undefined +const isIOSWebKit = (): boolean => { + if (_isIOSResult !== undefined) return _isIOSResult + if (typeof navigator === 'undefined') return (_isIOSResult = false) + if (/iP(hone|od|ad)/.test(navigator.userAgent)) return (_isIOSResult = true) + // iPadOS 13+ reports as MacIntel; touch-points distinguishes it from desktop. + const mtp = (navigator as Navigator & { maxTouchPoints?: number }) + .maxTouchPoints + return (_isIOSResult = + navigator.platform === 'MacIntel' && mtp !== undefined && mtp > 0) +} + +// Test hook: reset the iOS detection cache. Not exported. +export const _resetIOSDetectionForTests = () => { + _isIOSResult = undefined +} + +export { approxEqual, debounce, memo, notUndefined } from './utils' +export type { NoInfer, PartialKeys } from './utils' // @@ -54,13 +77,12 @@ export const defaultKeyExtractor = (index: number) => index export const defaultRangeExtractor = (range: Range) => { const start = Math.max(range.startIndex - range.overscan, 0) const end = Math.min(range.endIndex + range.overscan, range.count - 1) + const len = end - start + 1 - const arr = [] - - for (let i = start; i <= end; i++) { - arr.push(i) + const arr = new Array(len) + for (let i = 0; i < len; i++) { + arr[i] = start + i } - return arr } @@ -143,9 +165,13 @@ const supportsScrollend = type ObserveOffsetCallBack = (offset: number, isScrolling: boolean) => void -export const observeElementOffset = ( +// Shared core: both element and window variants attach scroll/scrollend +// listeners with the same lifecycle; they only differ in how to read the +// current offset from the scroll target. +const observeOffset = ( instance: Virtualizer, cb: ObserveOffsetCallBack, + readOffset: (target: T) => number, ) => { const element = instance.scrollElement if (!element) { @@ -156,32 +182,27 @@ export const observeElementOffset = ( return } - let offset = 0 - const fallback = + const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend - ? () => undefined - : debounce( - targetWindow, - () => { - cb(offset, false) - }, - instance.options.isScrollingResetDelay, - ) + + let offset = 0 + const fallback = registerScrollendEvent + ? null + : debounce( + targetWindow, + () => cb(offset, false), + instance.options.isScrollingResetDelay, + ) const createHandler = (isScrolling: boolean) => () => { - const { horizontal, isRtl } = instance.options - offset = horizontal - ? element['scrollLeft'] * ((isRtl && -1) || 1) - : element['scrollTop'] - fallback() + offset = readOffset(element) + fallback?.() cb(offset, isScrolling) } const handler = createHandler(true) const endHandler = createHandler(false) element.addEventListener('scroll', handler, addEventListenerOptions) - const registerScrollendEvent = - instance.options.useScrollendEvent && supportsScrollend if (registerScrollendEvent) { element.addEventListener('scrollend', endHandler, addEventListenerOptions) } @@ -193,52 +214,22 @@ export const observeElementOffset = ( } } +export const observeElementOffset = ( + instance: Virtualizer, + cb: ObserveOffsetCallBack, +) => + observeOffset(instance, cb, (el) => { + const { horizontal, isRtl } = instance.options + return horizontal ? el.scrollLeft * ((isRtl && -1) || 1) : el.scrollTop + }) + export const observeWindowOffset = ( instance: Virtualizer, cb: ObserveOffsetCallBack, -) => { - const element = instance.scrollElement - if (!element) { - return - } - const targetWindow = instance.targetWindow - if (!targetWindow) { - return - } - - let offset = 0 - const fallback = - instance.options.useScrollendEvent && supportsScrollend - ? () => undefined - : debounce( - targetWindow, - () => { - cb(offset, false) - }, - instance.options.isScrollingResetDelay, - ) - - const createHandler = (isScrolling: boolean) => () => { - offset = element[instance.options.horizontal ? 'scrollX' : 'scrollY'] - fallback() - cb(offset, isScrolling) - } - const handler = createHandler(true) - const endHandler = createHandler(false) - - element.addEventListener('scroll', handler, addEventListenerOptions) - const registerScrollendEvent = - instance.options.useScrollendEvent && supportsScrollend - if (registerScrollendEvent) { - element.addEventListener('scrollend', endHandler, addEventListenerOptions) - } - return () => { - element.removeEventListener('scroll', handler) - if (registerScrollendEvent) { - element.removeEventListener('scrollend', endHandler) - } - } -} +) => + observeOffset(instance, cb, (win) => + instance.options.horizontal ? win.scrollX : win.scrollY, + ) export const measureElement = ( element: TItemElement, @@ -260,37 +251,31 @@ export const measureElement = ( ] } -export const windowScroll = ( +const scrollWithAdjustments = ( offset: number, { adjustments = 0, behavior, }: { adjustments?: number; behavior?: ScrollBehavior }, - instance: Virtualizer, + instance: Virtualizer, ) => { - const toOffset = offset + adjustments - instance.scrollElement?.scrollTo?.({ - [instance.options.horizontal ? 'left' : 'top']: toOffset, + [instance.options.horizontal ? 'left' : 'top']: offset + adjustments, behavior, }) } -export const elementScroll = ( +export const windowScroll: ( offset: number, - { - adjustments = 0, - behavior, - }: { adjustments?: number; behavior?: ScrollBehavior }, + options: { adjustments?: number; behavior?: ScrollBehavior }, instance: Virtualizer, -) => { - const toOffset = offset + adjustments +) => void = scrollWithAdjustments - instance.scrollElement?.scrollTo?.({ - [instance.options.horizontal ? 'left' : 'top']: toOffset, - behavior, - }) -} +export const elementScroll: ( + offset: number, + options: { adjustments?: number; behavior?: ScrollBehavior }, + instance: Virtualizer, +) => void = scrollWithAdjustments type LaneAssignmentMode = 'estimate' | 'measured' @@ -378,9 +363,14 @@ export class Virtualizer< isScrolling = false private scrollState: ScrollState | null = null measurementsCache: Array = [] + // Flat backing store for the lanes===1 fast path: [start_0, size_0, start_1, size_1, ...]. + // null until the first single-lane build; reused (and grown) across rebuilds. + private _flatMeasurements: Float64Array | null = null private itemSizeCache = new Map() + private itemSizeCacheVersion = 0 private laneAssignments = new Map() // index → lane cache - private pendingMeasuredCacheIndexes: Array = [] + // Earliest index dirtied since last getMeasurements() rebuild, or null. + private pendingMin: number | null = null private prevLanes: number | undefined = undefined private lanesChangedFlag = false private lanesSettling = false @@ -388,6 +378,28 @@ export class Virtualizer< scrollOffset: number | null = null scrollDirection: ScrollDirection | null = null private scrollAdjustments = 0 + // Sum of size-change deltas above-viewport that were skipped during + // iOS momentum scroll (writing scrollTop mid-momentum cancels it). + // Flushed in a single scrollTo when iOS is fully settled. + private _iosDeferredAdjustment = 0 + // Touch state. iOS WebKit cancels momentum when scrollTop is written, so + // we defer adjustments not only during `isScrolling` but also through the + // touchstart→touchend window (active drag) and a short tail after + // touchend (early-momentum window — iOS only fires touch events once at + // the start of momentum, so we use a timer rather than another event). + private _iosTouching = false + private _iosJustTouchEnded = false + private _iosTouchEndTimerId: number | null = null + // Subpixel reconciliation. Safari (and Chrome/Firefox under certain DPRs) + // round scrollTop/scrollLeft writes to integer pixels. If we wrote 12345.5 + // but the browser reports back 12346, the next reconcileScroll sees a + // "target changed" and re-fires scrollTo — a feedback loop that the + // approxEqual(<1.01) tolerance otherwise absorbs as a workaround. + // By remembering the intended value of our most-recent self-driven + // scrollTo, we can match the browser's rounded read back to the intended + // value when the diff is < 1.5 px, distinguishing it from a real user + // scroll. The +0.5 over Math.abs lets us also absorb the +1 / -1 cases. + private _intendedScrollOffset: number | null = null shouldAdjustScrollPositionOnItemSizeChange: | undefined | (( @@ -417,6 +429,20 @@ export class Virtualizer< if (!node.isConnected) { this.observer.unobserve(node) + // Find the cache entry pointing to this exact node and remove + // it. We can't call getItemKey(index) here because items may + // have been removed since this node was rendered — the index + // could be stale and out-of-bounds in the user's data array + // (regression test in e2e/.../stale-index.spec.ts, fix #1148). + // The === comparison naturally handles the React-replaced- + // a-node-for-the-same-key case: that entry now points to a + // different node, so this loop won't match. + for (const [cacheKey, cachedNode] of this.elementsCache) { + if (cachedNode === node) { + this.elementsCache.delete(cacheKey) + break + } + } return } @@ -451,11 +477,9 @@ export class Virtualizer< } setOptions = (opts: VirtualizerOptions) => { - Object.entries(opts).forEach(([key, value]) => { - if (typeof value === 'undefined') delete (opts as any)[key] - }) - - this.options = { + // Skip `{...defaults, ...opts}` because explicit `undefined` values in + // opts would override defaults with `undefined`. + const merged = { debug: false, initialOffset: 0, overscan: 1, @@ -480,8 +504,14 @@ export class Virtualizer< useScrollendEvent: false, useAnimationFrameWithResizeObserver: false, laneAssignmentMode: 'estimate', - ...opts, + } as unknown as Required> + + for (const key in opts) { + const v = (opts as any)[key] + if (v !== undefined) (merged as any)[key] = v } + + this.options = merged } private notify = (sync: boolean) => { @@ -565,6 +595,21 @@ export class Virtualizer< this.unsubs.push( this.options.observeElementOffset(this, (offset, isScrolling) => { + // If this scroll event looks like the browser's read-back of a + // value we just wrote, prefer our intended (sub-pixel-accurate) + // value over the browser's rounded one. The 1.5 px tolerance is + // tight enough to avoid mistaking a real user scroll for a + // self-write — by the time the user has moved 1.5 px, the + // intended value will already have been consumed by a prior + // scroll event and cleared. + if ( + this._intendedScrollOffset !== null && + Math.abs(offset - this._intendedScrollOffset) < 1.5 + ) { + offset = this._intendedScrollOffset + } + this._intendedScrollOffset = null + this.scrollAdjustments = 0 this.scrollDirection = isScrolling ? this.getScrollOffset() < offset @@ -574,6 +619,11 @@ export class Virtualizer< this.scrollOffset = offset this.isScrolling = isScrolling + // Flush deferred iOS adjustments if we're now fully settled. + // "Fully settled" means: not actively scrolling, no finger on + // screen, and the post-touchend grace window has expired. + this._flushIosDeferredIfReady() + if (this.scrollState) { this.scheduleScrollReconcile() } @@ -581,6 +631,56 @@ export class Virtualizer< }), ) + // Touch event listeners (iOS-aware deferral). We attach unconditionally + // — the listeners are passive and cheap; on non-touch devices they + // simply never fire. The gating by isIOSWebKit() lives in resizeItem + // and _flushIosDeferredIfReady so we only burn the path on iOS. + if ('addEventListener' in this.scrollElement) { + const scrollEl = this.scrollElement as unknown as EventTarget + const onTouchStart = () => { + this._iosTouching = true + this._iosJustTouchEnded = false + if (this._iosTouchEndTimerId !== null && this.targetWindow != null) { + this.targetWindow.clearTimeout(this._iosTouchEndTimerId) + this._iosTouchEndTimerId = null + } + } + const onTouchEnd = () => { + this._iosTouching = false + if (!isIOSWebKit() || this.targetWindow == null) { + // Non-iOS: nothing more to track. Just clear the touching flag. + return + } + this._iosJustTouchEnded = true + // After ~150 ms with no scroll/touch events, momentum is done. + this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => { + this._iosJustTouchEnded = false + this._iosTouchEndTimerId = null + // After the grace window, attempt to flush. The scroll event + // for momentum decay may have already fired before our timer. + this._flushIosDeferredIfReady() + }, 150) + } + scrollEl.addEventListener( + 'touchstart', + onTouchStart, + addEventListenerOptions, + ) + scrollEl.addEventListener( + 'touchend', + onTouchEnd, + addEventListenerOptions, + ) + this.unsubs.push(() => { + scrollEl.removeEventListener('touchstart', onTouchStart) + scrollEl.removeEventListener('touchend', onTouchEnd) + if (this._iosTouchEndTimerId !== null && this.targetWindow != null) { + this.targetWindow.clearTimeout(this._iosTouchEndTimerId) + this._iosTouchEndTimerId = null + } + }) + } + this._scrollToOffset(this.getScrollOffset(), { adjustments: undefined, behavior: undefined, @@ -588,6 +688,34 @@ export class Virtualizer< } } + // Apply any accumulated iOS-deferred scroll adjustment, but only when we're + // truly settled — not actively scrolling, not under an active touch, and + // past the post-touchend grace window. Called from the scroll callback + // and the touchend grace-timer. + private _flushIosDeferredIfReady = () => { + if (this._iosDeferredAdjustment === 0) return + if (this.isScrolling) return + if (this._iosTouching) return + if (this._iosJustTouchEnded) return + // Phase 2b: Safari elastic-overscroll (rubber-band) lets scrollTop go + // negative or beyond scrollHeight - clientHeight. Writing scrollTop + // while in that zone snaps the page back to the clamped value at the + // end of the bounce, often discarding the user's intent. Skip the + // flush; the next in-bounds scroll event will retry. + const cur = this.getScrollOffset() + const max = this.getMaxScrollOffset() + if (cur < 0 || cur > max) return + const delta = this._iosDeferredAdjustment + this._iosDeferredAdjustment = 0 + // Roll the deferred delta into the running accumulator so any resize + // landing between now and the resulting scroll event computes from the + // post-flush offset rather than the stale one. + this._scrollToOffset(cur, { + adjustments: (this.scrollAdjustments += delta), + behavior: undefined, + }) + } + private rafId: number | null = null private scheduleScrollReconcile() { if (!this.targetWindow) { @@ -631,6 +759,18 @@ export class Virtualizer< if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) { this.scrollState.stableFrames++ if (this.scrollState.stableFrames >= STABLE_FRAMES) { + // Final-pass exact landing. The reconcile-stable check uses a 1.01px + // tolerance (approxEqual) so we don't fight subpixel browser rounding + // during the converging phase. Once we're definitively settled, + // commit the exact target so consumers calling scrollToIndex(N) + // end up at the EXACT computed position of item N — matching + // virtuoso's 0px landing accuracy rather than our prior 0.5-1px. + if (this.getScrollOffset() !== targetOffset) { + this._scrollToOffset(targetOffset, { + adjustments: undefined, + behavior: 'auto', + }) + } this.scrollState = null return } @@ -638,14 +778,26 @@ export class Virtualizer< this.scrollState.stableFrames = 0 if (targetChanged) { + // When the target moves during smooth scroll (because items came into + // view and got measured, shifting positions), the original logic was + // to immediately snap to 'auto' — visibly jarring on long + // scroll-to-index calls. Now: keep smooth while we're still far + // (more than a viewport) from the new target. Only fall back to + // 'auto' for the final approach, so the user sees one continuous + // motion that smoothly adjusts its endpoint as measurements arrive. + const viewport = this.getSize() || 600 + const distance = Math.abs(targetOffset - this.getScrollOffset()) + const keepSmooth = + this.scrollState.behavior === 'smooth' && distance > viewport + this.scrollState.lastTargetOffset = targetOffset - // Switch to 'auto' behavior once measurements cause target to change - // We want to jump directly to the correct position, not smoothly animate to it - this.scrollState.behavior = 'auto' + if (!keepSmooth) { + this.scrollState.behavior = 'auto' + } this._scrollToOffset(targetOffset, { adjustments: undefined, - behavior: 'auto', + behavior: keepSmooth ? 'smooth' : 'auto', }) } } @@ -751,7 +903,7 @@ export class Virtualizer< } this.prevLanes = lanes - this.pendingMeasuredCacheIndexes = [] + this.pendingMin = null return { count, @@ -769,7 +921,7 @@ export class Virtualizer< ) private getMeasurements = memo( - () => [this.getMeasurementOptions(), this.itemSizeCache], + () => [this.getMeasurementOptions(), this.itemSizeCacheVersion], ( { count, @@ -780,8 +932,9 @@ export class Virtualizer< lanes, laneAssignmentMode, }, - itemSizeCache, + _itemSizeCacheVersion, ) => { + const itemSizeCache = this.itemSizeCache if (!enabled) { this.measurementsCache = [] this.itemSizeCache.clear() @@ -805,8 +958,8 @@ export class Virtualizer< this.measurementsCache = [] this.itemSizeCache.clear() this.laneAssignments.clear() // Clear lane cache for new lane count - // Clear pending indexes to force min = 0 - this.pendingMeasuredCacheIndexes = [] + // Force min = 0 on the rebuild + this.pendingMin = null } // Don't restore from initialMeasurementsCache during lane changes @@ -818,19 +971,62 @@ export class Virtualizer< }) } - // ✅ During lanes settling, ignore pendingMeasuredCacheIndexes to prevent repositioning - const min = this.lanesSettling - ? 0 - : this.pendingMeasuredCacheIndexes.length > 0 - ? Math.min(...this.pendingMeasuredCacheIndexes) - : 0 - this.pendingMeasuredCacheIndexes = [] + // During lanes settling, ignore pendingMin to prevent repositioning + const min = this.lanesSettling ? 0 : (this.pendingMin ?? 0) + this.pendingMin = null // ✅ End settling period when cache is fully built if (this.lanesSettling && this.measurementsCache.length === count) { this.lanesSettling = false } + // ─── Fast path: single-lane lazy materialization ──────────────────── + // For lanes === 1 (the default and most common case), skip the + // per-item VirtualItem object allocation. We write start/size pairs + // into a Float64Array and return a Proxy that builds VirtualItem + // objects on demand (only the indices a consumer actually reads). + // + // At n=100k this drops cold-mount cost from ~2.5ms (eager object + // allocation) to roughly the cost of a single typed-array fill. + if (lanes === 1) { + const gap = this.options.gap + // Reuse flat backing if large enough; else grow (preserving data + // before `min` to mirror the slice-and-rebuild contract). + const need = count * 2 + let flat = this._flatMeasurements + if (!flat || flat.length < need) { + const next = new Float64Array(need) + if (flat && min > 0) next.set(flat.subarray(0, min * 2)) + flat = next + this._flatMeasurements = flat + } + + let runningStart: number + if (min === 0) { + runningStart = paddingStart + scrollMargin + } else { + // Continue from where we left off + const prevIdx = min - 1 + runningStart = flat[prevIdx * 2]! + flat[prevIdx * 2 + 1]! + gap + } + + for (let i = min; i < count; i++) { + const key = getItemKey(i) + const measuredSize = itemSizeCache.get(key) + const size = + typeof measuredSize === 'number' + ? measuredSize + : this.options.estimateSize(i) + flat[i * 2] = runningStart + flat[i * 2 + 1] = size + runningStart += size + gap + } + + const view = createLazyMeasurementsView(count, flat, getItemKey) + this.measurementsCache = view + return view + } + const measurements = this.measurementsCache.slice(0, min) // ✅ Performance: Track last item index per lane for O(1) lookup @@ -932,6 +1128,13 @@ export class Virtualizer< outerSize, scrollOffset, lanes, + // Pass the typed array so binary search + forward-walk can + // read start/end directly from Float64Array, skipping the + // Proxy traps that materialize a full VirtualItem per probe. + flat: + lanes === 1 && this._flatMeasurements != null + ? this._flatMeasurements + : null, }) : null) }, @@ -1056,30 +1259,82 @@ export class Virtualizer< } resizeItem = (index: number, size: number) => { - const item = this.measurementsCache[index] - if (!item) return + if (index < 0 || index >= this.options.count) return + + // Fast field reads. For lanes===1 we read raw start/size from the flat + // typed array, avoiding a Proxy.get + VirtualItem allocation per call. + // For lanes>1 we fall back to the cached VirtualItem array. + let cachedSize: number + let itemStart: number + let key: Key + const flat = this._flatMeasurements + if (this.options.lanes === 1 && flat !== null) { + key = this.options.getItemKey(index) + itemStart = flat[index * 2]! + cachedSize = flat[index * 2 + 1]! + } else { + const item = this.measurementsCache[index] + if (!item) return + key = item.key + itemStart = item.start + cachedSize = item.size + } - const itemSize = this.itemSizeCache.get(item.key) ?? item.size + const itemSize = this.itemSizeCache.get(key) ?? cachedSize const delta = size - itemSize if (delta !== 0) { if ( this.scrollState?.behavior !== 'smooth' && (this.shouldAdjustScrollPositionOnItemSizeChange !== undefined - ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) - : item.start < this.getScrollOffset() + this.scrollAdjustments) + ? this.shouldAdjustScrollPositionOnItemSizeChange( + // The callback expects a VirtualItem; build one lazily only + // when the consumer actually supplied a custom predicate. + this.measurementsCache[index] ?? { + index, + key, + start: itemStart, + size: cachedSize, + end: itemStart + cachedSize, + lane: 0, + }, + delta, + this, + ) + : // Default: adjust scrollTop only when the resize is an above- + // viewport item AND we're not actively scrolling backward. + // Adjusting during backward scroll fights the user's scroll + // direction and produces the "items jump while scrolling up" + // jank reported across many issues. Users who want the old + // behavior can pass shouldAdjustScrollPositionOnItemSizeChange. + itemStart < this.getScrollOffset() + this.scrollAdjustments && + this.scrollDirection !== 'backward') ) { if (process.env.NODE_ENV !== 'production' && this.options.debug) { console.info('correction', delta) } - this._scrollToOffset(this.getScrollOffset(), { - adjustments: (this.scrollAdjustments += delta), - behavior: undefined, - }) + // On iOS WebKit, writing scrollTop while a finger is on screen or + // momentum-scroll is running cancels the in-flight scroll. Defer + // the adjustment until iOS is fully settled — flushed by either + // the scroll callback or the touchend grace-timer. + if ( + isIOSWebKit() && + (this.isScrolling || this._iosTouching || this._iosJustTouchEnded) + ) { + this._iosDeferredAdjustment += delta + } else { + this._scrollToOffset(this.getScrollOffset(), { + adjustments: (this.scrollAdjustments += delta), + behavior: undefined, + }) + } } - this.pendingMeasuredCacheIndexes.push(item.index) - this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size)) + if (this.pendingMin === null || index < this.pendingMin) { + this.pendingMin = index + } + this.itemSizeCache.set(key, size) + this.itemSizeCacheVersion++ this.notify(false) } @@ -1110,16 +1365,20 @@ export class Virtualizer< if (measurements.length === 0) { return undefined } - return notUndefined( - measurements[ - findNearestBinarySearch( - 0, - measurements.length - 1, - (index: number) => notUndefined(measurements[index]).start, - offset, - ) - ], + // Same fast-path as calculateRange: read start values directly from the + // typed array during binary search to skip the Proxy.get materialization + // per probe. + const flat = this._flatMeasurements + const useFlat = this.options.lanes === 1 && flat != null + const idx = findNearestBinarySearch( + 0, + measurements.length - 1, + useFlat + ? (i: number) => flat[i * 2]! + : (i: number) => notUndefined(measurements[i]).start, + offset, ) + return notUndefined(measurements[idx]) } private getMaxScrollOffset = () => { @@ -1284,7 +1543,16 @@ export class Virtualizer< if (measurements.length === 0) { end = this.options.paddingStart } else if (this.options.lanes === 1) { - end = measurements[measurements.length - 1]?.end ?? 0 + // Fast path: read last item's end directly from the flat typed array + // when available; avoids a Proxy.get + VirtualItem materialization + // just to call getTotalSize (which React renders trigger every commit). + const lastIdx = measurements.length - 1 + const flat = this._flatMeasurements + if (flat != null) { + end = flat[lastIdx * 2]! + flat[lastIdx * 2 + 1]! + } else { + end = measurements[lastIdx]?.end ?? 0 + } } else { const endByLane = Array(this.options.lanes).fill(null) let endIndex = measurements.length - 1 @@ -1306,6 +1574,39 @@ export class Virtualizer< ) } + /** + * Returns a snapshot of currently-measured items suitable for round- + * tripping through state storage (sessionStorage, history, etc.) and + * passing back as `initialMeasurementsCache` on remount. Pair with the + * current `scrollOffset` to restore exact scroll position after navigation. + * + * Only items the consumer has actually rendered (and thus measured) appear + * in the snapshot; unmeasured items will fall back to `estimateSize` on + * restore. Returns an empty array if no items have been measured. + */ + takeSnapshot = (): Array => { + const snapshot: Array = [] + if (this.itemSizeCache.size === 0) return snapshot + // Iterate measurementsCache only for indices whose key is in itemSizeCache + // (i.e., have been measured). We build VirtualItem objects with the + // current start/size/end so they can be persisted as plain data. + const m = this.getMeasurements() + for (const item of m) { + if (item && this.itemSizeCache.has(item.key)) { + // Force materialization (lazy path) and copy plain fields. + snapshot.push({ + index: item.index, + key: item.key, + start: item.start, + size: item.size, + end: item.end, + lane: item.lane, + }) + } + } + return snapshot + } + private _scrollToOffset = ( offset: number, { @@ -1316,12 +1617,20 @@ export class Virtualizer< behavior: ScrollBehavior | undefined }, ) => { + // Record the intended logical scroll target so the next scroll event + // can reconcile against subpixel rounding by the browser. + this._intendedScrollOffset = offset + (adjustments ?? 0) this.options.scrollToFn(offset, { behavior, adjustments }, this) } measure = () => { - this.itemSizeCache = new Map() - this.laneAssignments = new Map() // Clear lane cache for full re-layout + // Reset pendingMin so the next getMeasurements rebuilds from index 0. + // Without this, a prior resizeItem() that left pendingMin > 0 would + // cause the rebuild to preserve stale items before that index. + this.pendingMin = null + this.itemSizeCache.clear() + this.laneAssignments.clear() // Clear lane cache for full re-layout + this.itemSizeCacheVersion++ this.notify(false) } } @@ -1357,14 +1666,24 @@ function calculateRange({ outerSize, scrollOffset, lanes, + flat, }: { measurements: Array outerSize: number scrollOffset: number lanes: number + flat: Float64Array | null }) { const lastIndex = measurements.length - 1 - const getOffset = (index: number) => measurements[index]!.start + // When the lanes===1 fast-path is active, read start/end directly from the + // flat Float64Array instead of going through the lazy-view Proxy. Cuts + // ~17 Proxy.get traps per scroll for the binary search alone. + const getStart = flat + ? (index: number) => flat[index * 2]! + : (index: number) => measurements[index]!.start + const getEnd = flat + ? (index: number) => flat[index * 2]! + flat[index * 2 + 1]! + : (index: number) => measurements[index]!.end // handle case when item count is less than or equal to lanes if (measurements.length <= lanes) { @@ -1374,18 +1693,13 @@ function calculateRange({ } } - let startIndex = findNearestBinarySearch( - 0, - lastIndex, - getOffset, - scrollOffset, - ) + let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset) let endIndex = startIndex if (lanes === 1) { while ( endIndex < lastIndex && - measurements[endIndex]!.end < scrollOffset + outerSize + getEnd(endIndex) < scrollOffset + outerSize ) { endIndex++ } diff --git a/packages/virtual-core/src/lazy-measurements.ts b/packages/virtual-core/src/lazy-measurements.ts new file mode 100644 index 000000000..4b8cd425d --- /dev/null +++ b/packages/virtual-core/src/lazy-measurements.ts @@ -0,0 +1,44 @@ +// Lazy materialization for the lanes===1 fast path. Backed by a +// Float64Array (stride 2: start, size, …); VirtualItems are constructed on +// first indexed read and cached. Saves the per-item object allocation at +// large list counts where most items are never visible. + +import type { VirtualItem } from './index' + +type Key = number | string | bigint + +export function createLazyMeasurementsView( + count: number, + flat: Float64Array, + getItemKey: (i: number) => Key, +): Array { + const cache: Array = new Array(count) + return new Proxy(cache as any, { + get(target, prop, receiver) { + if (typeof prop === 'string') { + // Cheap digit-prefix sniff before number coerce. + const c = prop.charCodeAt(0) + if (c >= 48 && c <= 57) { + const i = +prop + if (Number.isInteger(i) && i >= 0 && i < count) { + let v = target[i] + if (!v) { + const s = flat[i * 2]! + v = target[i] = { + index: i, + key: getItemKey(i), + start: s, + size: flat[i * 2 + 1]!, + end: s + flat[i * 2 + 1]!, + lane: 0, + } + } + return v + } + } + if (prop === 'length') return count + } + return Reflect.get(target, prop, receiver) + }, + }) as Array +} diff --git a/packages/virtual-core/src/utils.ts b/packages/virtual-core/src/utils.ts index 4d824b8d9..5e16080cd 100644 --- a/packages/virtual-core/src/utils.ts +++ b/packages/virtual-core/src/utils.ts @@ -18,8 +18,13 @@ export function memo, TResult>( let isInitial = true function memoizedFunction(): TResult { - let depTime: number - if (opts.key && opts.debug?.()) depTime = Date.now() + // Debug-only timing. In production builds, `process.env.NODE_ENV !== + // 'production'` is constant-folded to `false` by downstream minifiers + // (Terser/esbuild/swc with `define`), which DCEs the entire block. + const debugEnabled = + process.env.NODE_ENV !== 'production' && !!opts.key && !!opts.debug?.() + let depTime = 0 + if (debugEnabled) depTime = Date.now() const newDeps = getDeps() @@ -33,14 +38,14 @@ export function memo, TResult>( deps = newDeps - let resultTime: number - if (opts.key && opts.debug?.()) resultTime = Date.now() + let resultTime = 0 + if (debugEnabled) resultTime = Date.now() result = fn(...newDeps) - if (opts.key && opts.debug?.()) { - const depEndTime = Math.round((Date.now() - depTime!) * 100) / 100 - const resultEndTime = Math.round((Date.now() - resultTime!) * 100) / 100 + if (debugEnabled) { + const depEndTime = Math.round((Date.now() - depTime) * 100) / 100 + const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100 const resultFpsPercentage = resultEndTime / 16 const pad = (str: number | string, num: number) => { diff --git a/packages/virtual-core/tests/bench.bench.ts b/packages/virtual-core/tests/bench.bench.ts new file mode 100644 index 000000000..ea9464c00 --- /dev/null +++ b/packages/virtual-core/tests/bench.bench.ts @@ -0,0 +1,218 @@ +// Real benchmarks against the actual Virtualizer class. +// Run with: cd packages/virtual-core && npx vitest bench --run +// +// Compare before/after by running this script, saving output, applying a fix, +// re-running, diffing. + +import { bench, describe } from 'vitest' +import { Virtualizer, defaultRangeExtractor } from '../src/index' + +function makeVirt(count: number, lanes = 1): Virtualizer { + const v = new Virtualizer({ + count, + lanes, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + }) + // Warm getMeasurements + ;(v as any).getMeasurements() + return v +} + +// ─── Exp 1: Cold-mount cost — getMeasurements with no measured items ───────── + +describe('Exp 1: Cold mount — first getMeasurements call (no measurements)', () => { + for (const n of [1000, 10000, 100000, 500000]) { + bench(`n=${n}`, () => { + const v = new Virtualizer({ + count: n, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + }) + ;(v as any).getMeasurements() + }) + } +}) + +describe('Exp 1: Cold mount — visible-range query for visible window only', () => { + // Realistic: mount then ask "what is at offset 0" — should not materialize + // the whole list, only walk to ~20 items. + for (const n of [1000, 10000, 100000, 500000]) { + bench(`n=${n} getVirtualItemForOffset(0)`, () => { + const v = new Virtualizer({ + count: n, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + }) + ;(v as any).getVirtualItemForOffset(0) + }) + } +}) + +// ─── Layer 1: Map clone bug — resizeItem under measure storm ───────────────── + +describe('Layer 1: resizeItem measure storm — full N resizes then 1× getMeasurements', () => { + for (const n of [100, 1000, 5000, 10000]) { + bench(`n=${n}`, () => { + const v = makeVirt(n) + for (let i = 0; i < n; i++) v.resizeItem(i, 30 + (i % 7)) + ;(v as any).getMeasurements() + }) + } +}) + +describe('Layer 1: resizeItem measure storm — getMeasurements per call', () => { + for (const n of [100, 1000, 5000]) { + bench(`n=${n}`, () => { + const v = makeVirt(n) + for (let i = 0; i < n; i++) { + v.resizeItem(i, 30 + (i % 7)) + ;(v as any).getMeasurements() + } + }) + } +}) + +describe('Layer 4: notify cost — no-op vs realistic onChange', () => { + // Comparison: how much time does the notify call add per resizeItem? + const N = 10000 + bench(`n=${N}, no-op onChange (lower bound)`, () => { + const v = new Virtualizer({ + count: N, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + }) + ;(v as any).getMeasurements() + for (let i = 0; i < N; i++) v.resizeItem(i, 30 + (i % 7)) + }) + bench(`n=${N}, realistic onChange (alloc per call)`, () => { + let prev: any = null + const v = new Virtualizer({ + count: N, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + onChange: () => { + prev = {} + }, + }) + ;(v as any).getMeasurements() + for (let i = 0; i < N; i++) v.resizeItem(i, 30 + (i % 7)) + }) +}) + +describe('Layer 4: onChange callbacks fired per resize-storm', () => { + // Pre-Layer-4: resizeItem calls notify(false) on every call, even when + // the visible range doesn't change. This benchmark counts callbacks and + // measures cost when onChange is a non-trivial function (closer to real + // React adapter cost than the no-op default). + for (const n of [100, 1000, 10000]) { + bench(`n=${n}, realistic onChange (counter + identity check)`, () => { + let count = 0 + let prev: any = null + const v = new Virtualizer({ + count: n, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + // Simulates React adapter: dispatches a "rerender" each call + onChange: (instance) => { + count++ + prev = { state: count } // alloc per call, like useReducer(() => ({})) + }, + }) + ;(v as any).getMeasurements() + for (let i = 0; i < n; i++) v.resizeItem(i, 30 + (i % 7)) + }) + } +}) + +describe('Layer 3: pending-min lookup under heavy storms', () => { + // Stress the "find earliest dirty index" path. Pre-Layer-3 used + // `Math.min(...pendingMeasuredCacheIndexes)` which spreads onto the stack. + for (const n of [10000, 50000, 100000]) { + bench( + `n=${n} resizes in reverse order (worst case for running min)`, + () => { + const v = makeVirt(n) + // Reverse order means every push lowers the min — exercises the + // running-min branch on every single push. + for (let i = n - 1; i >= 0; i--) v.resizeItem(i, 30 + (i % 7)) + ;(v as any).getMeasurements() + }, + ) + } +}) + +describe('Layer 1: repeated resize at index 0', () => { + for (const n of [1000, 10000, 50000]) { + bench(`n=${n}, 100× resize+getMeasurements`, () => { + const v = makeVirt(n) + for (let i = 0; i < 100; i++) { + v.resizeItem(0, 30 + (i % 5)) + ;(v as any).getMeasurements() + } + }) + } +}) + +// ─── Layer 2: setOptions per render ────────────────────────────────────────── + +describe('Layer 2: setOptions() — simulating React render storm', () => { + bench('setOptions × 10,000', () => { + const v = new Virtualizer({ + count: 1000, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + }) + for (let i = 0; i < 10_000; i++) { + v.setOptions({ + count: 1000, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: () => {}, + observeElementRect: () => {}, + observeElementOffset: () => {}, + overscan: undefined as any, + paddingStart: undefined as any, + paddingEnd: undefined as any, + } as any) + } + }) +}) + +// ─── Layer 6: defaultRangeExtractor ────────────────────────────────────────── + +describe('Layer 6: defaultRangeExtractor', () => { + for (const visible of [50, 200, 1000]) { + bench(`visible=${visible} × 10,000`, () => { + for (let i = 0; i < 10_000; i++) { + defaultRangeExtractor({ + startIndex: 0, + endIndex: visible - 1, + overscan: 5, + count: 100_000, + }) + } + }) + } +}) diff --git a/packages/virtual-core/tests/index.test.ts b/packages/virtual-core/tests/index.test.ts index 0d9495845..d49db8aa4 100644 --- a/packages/virtual-core/tests/index.test.ts +++ b/packages/virtual-core/tests/index.test.ts @@ -1,5 +1,13 @@ import { expect, test, vi } from 'vitest' -import { Virtualizer } from '../src/index' +import { + Virtualizer, + _resetIOSDetectionForTests, + defaultRangeExtractor, + elementScroll, + observeElementOffset, + observeWindowOffset, + windowScroll, +} from '../src/index' test('should export the Virtualizer class', () => { expect(Virtualizer).toBeDefined() @@ -502,3 +510,2019 @@ test('cleanup should cancel pending RAF and clear scrollState', () => { expect(virtualizer['rafId']).toBeNull() expect(mockWindow.cancelAnimationFrame).toHaveBeenCalled() }) + +// ─── resizeItem / measurement cache invalidation ───────────────────────────── +// These tests pin down the contract that resizeItem invalidates the +// getMeasurements memo so subsequent reads reflect the new sizes. +// They guard against regressions when changing the invalidation mechanism +// (e.g. Map clone → version counter). + +test('resizeItem should persist size for a single index', () => { + const virtualizer = new Virtualizer({ + count: 5, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + // Seed measurementsCache + virtualizer['getMeasurements']() + + virtualizer.resizeItem(2, 130) + + const measurements = virtualizer['getMeasurements']() + expect(measurements[2]!.size).toBe(130) + // Items after should be shifted by the delta (130 - 50 = 80) + expect(measurements[3]!.start).toBe(50 + 50 + 130) + expect(measurements[4]!.start).toBe(50 + 50 + 130 + 50) +}) + +test('resizeItem should persist sizes across many sequential calls', () => { + const N = 50 + const virtualizer = new Virtualizer({ + count: N, + estimateSize: () => 10, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + + // Resize every item to a unique size + for (let i = 0; i < N; i++) { + virtualizer.resizeItem(i, 100 + i) + } + + const measurements = virtualizer['getMeasurements']() + let runningStart = 0 + for (let i = 0; i < N; i++) { + expect(measurements[i]!.size).toBe(100 + i) + expect(measurements[i]!.start).toBe(runningStart) + runningStart += 100 + i + } +}) + +test('resizeItem should invalidate getMeasurements memo even when same key resized twice', () => { + const virtualizer = new Virtualizer({ + count: 3, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + + virtualizer.resizeItem(1, 100) + expect(virtualizer['getMeasurements']()[1]!.size).toBe(100) + + virtualizer.resizeItem(1, 200) + expect(virtualizer['getMeasurements']()[1]!.size).toBe(200) + + virtualizer.resizeItem(1, 75) + expect(virtualizer['getMeasurements']()[1]!.size).toBe(75) +}) + +test('resizeItem with same size as cached should be a no-op (no invalidation)', () => { + const virtualizer = new Virtualizer({ + count: 3, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + virtualizer.resizeItem(0, 80) + const before = virtualizer['getMeasurements']() + const beforeRef = before + // Same value, should short-circuit (delta === 0) + virtualizer.resizeItem(0, 80) + const after = virtualizer['getMeasurements']() + // Memo should return the same array reference + expect(after).toBe(beforeRef) +}) + +test('measure() should clear size cache and lane assignments', () => { + const virtualizer = new Virtualizer({ + count: 4, + lanes: 2, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + virtualizer.resizeItem(0, 200) + virtualizer.resizeItem(1, 100) + + expect(virtualizer['itemSizeCache'].size).toBe(2) + expect(virtualizer['laneAssignments'].size).toBeGreaterThan(0) + + virtualizer.measure() + + expect(virtualizer['itemSizeCache'].size).toBe(0) + expect(virtualizer['laneAssignments'].size).toBe(0) + + // After measure(), sizes should fall back to estimateSize + const measurements = virtualizer['getMeasurements']() + expect(measurements[0]!.size).toBe(50) + expect(measurements[1]!.size).toBe(50) +}) + +test('measure() should fully invalidate when a later index was dirtied without an intervening getMeasurements()', () => { + // Regression: measure() used to clear itemSizeCache but not pendingMin. + // If resizeItem() had been called without a subsequent getMeasurements() + // to flush pendingMin, the next rebuild would preserve measurementsCache + // entries before that index — even though measure() is supposed to wipe + // everything. + const virtualizer = new Virtualizer({ + count: 6, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + // Seed item 0 with a non-estimate size, then flush so it's in measurementsCache. + virtualizer.resizeItem(0, 999) + virtualizer['getMeasurements']() + // Now dirty a later index without flushing — pendingMin will be 2. + virtualizer.resizeItem(2, 888) + expect(virtualizer['pendingMin']).toBe(2) + + virtualizer.measure() + + // After measure(), pendingMin must be null so the rebuild starts at 0 + // and discards the stale item-0 entry. + expect(virtualizer['pendingMin']).toBe(null) + + const m = virtualizer['getMeasurements']() + expect(m[0]!.size).toBe(50) + expect(m[2]!.size).toBe(50) +}) + +test('measure() should trigger a re-measurement on subsequent getMeasurements', () => { + let sizeFn = (i: number) => 50 + const virtualizer = new Virtualizer({ + count: 3, + estimateSize: (i) => sizeFn(i), + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + const before = virtualizer['getMeasurements']() + expect(before[0]!.size).toBe(50) + + // Change the estimateSize function via setOptions + sizeFn = () => 100 + virtualizer.measure() + + const after = virtualizer['getMeasurements']() + expect(after[0]!.size).toBe(100) +}) + +test('resizeItem on unknown index is a no-op', () => { + const virtualizer = new Virtualizer({ + count: 3, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + // Index out of bounds — should not crash + expect(() => virtualizer.resizeItem(99, 100)).not.toThrow() + + // Cache should be untouched + expect(virtualizer['itemSizeCache'].size).toBe(0) +}) + +test('resizeItem out-of-order should produce correct positions regardless of measurement order', () => { + const N = 10 + const virtualizer = new Virtualizer({ + count: N, + estimateSize: () => 20, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + + // Resize in reverse order — should still produce a valid prefix-sum + for (let i = N - 1; i >= 0; i--) { + virtualizer.resizeItem(i, 30 + i) + } + + const measurements = virtualizer['getMeasurements']() + let runningStart = 0 + for (let i = 0; i < N; i++) { + expect(measurements[i]!.size).toBe(30 + i) + expect(measurements[i]!.start).toBe(runningStart) + runningStart += 30 + i + } +}) + +test('getMeasurements memo should return same array reference when nothing changed', () => { + const virtualizer = new Virtualizer({ + count: 5, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + const a = virtualizer['getMeasurements']() + const b = virtualizer['getMeasurements']() + expect(a).toBe(b) +}) + +test('getMeasurements memo should return new array reference after resizeItem', () => { + const virtualizer = new Virtualizer({ + count: 5, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + const a = virtualizer['getMeasurements']() + virtualizer.resizeItem(0, 100) + const b = virtualizer['getMeasurements']() + expect(a).not.toBe(b) + expect(b[0]!.size).toBe(100) +}) + +// ─── elementsCache leak: disconnected node cleanup ─────────────────────────── + +test('RO callback should remove disconnected node from elementsCache', () => { + // Pins down that when the ResizeObserver fires for a node that has been + // disconnected from the DOM, that node is removed from elementsCache. + // Without the fix, elementsCache accumulates stale entries. + let roCallback: ResizeObserverCallback | null = null + const MockResizeObserver = vi.fn(function (cb: ResizeObserverCallback) { + roCallback = cb + return { + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn(), + } + }) + + const mockWindow = { + requestAnimationFrame: vi.fn(), + cancelAnimationFrame: vi.fn(), + performance: { now: () => Date.now() }, + ResizeObserver: MockResizeObserver, + } + + const mockScrollElement = { + scrollTop: 0, + scrollLeft: 0, + scrollWidth: 1000, + scrollHeight: 5000, + offsetWidth: 400, + offsetHeight: 600, + ownerDocument: { defaultView: mockWindow }, + } as unknown as HTMLDivElement + + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => mockScrollElement, + scrollToFn: vi.fn(), + observeElementRect: (_inst, cb) => { + cb({ width: 400, height: 600 }) + return () => {} + }, + observeElementOffset: (_inst, cb) => { + cb(0, false) + return () => {} + }, + }) + + virtualizer._willUpdate() + + // Simulate React mounting an element by calling measureElement ref callback + const node = { + getAttribute: (name: string) => (name === 'data-index' ? '3' : null), + getBoundingClientRect: () => ({ height: 50, width: 400 }), + isConnected: true, + setAttribute: vi.fn(), + } as unknown as HTMLElement + + virtualizer.measureElement(node) + expect(virtualizer.elementsCache.get(3)).toBe(node) + + // Now simulate the node being disconnected from DOM + ;(node as any).isConnected = false + + // Fire the RO callback for this node — pretending it just resized + expect(roCallback).not.toBeNull() + roCallback!( + [ + { + target: node, + contentRect: { height: 50, width: 400 } as DOMRectReadOnly, + borderBoxSize: [{ blockSize: 50, inlineSize: 400 }], + contentBoxSize: [{ blockSize: 50, inlineSize: 400 }], + devicePixelContentBoxSize: [{ blockSize: 50, inlineSize: 400 }], + } as ResizeObserverEntry, + ], + {} as ResizeObserver, + ) + + // elementsCache should no longer contain the disconnected node + expect(virtualizer.elementsCache.has(3)).toBe(false) +}) + +test('RO callback should not delete cache entry if node was replaced by React', () => { + // Edge case: if React unmounts node A and mounts node B for the same key, + // a delayed RO callback for the now-disconnected node A must not delete + // the entry that now points to node B. + let roCallback: ResizeObserverCallback | null = null + const MockResizeObserver = vi.fn(function (cb: ResizeObserverCallback) { + roCallback = cb + return { + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn(), + } + }) + + const mockWindow = { + requestAnimationFrame: vi.fn(), + cancelAnimationFrame: vi.fn(), + performance: { now: () => Date.now() }, + ResizeObserver: MockResizeObserver, + } + + const mockScrollElement = { + scrollTop: 0, + scrollLeft: 0, + scrollWidth: 1000, + scrollHeight: 5000, + offsetWidth: 400, + offsetHeight: 600, + ownerDocument: { defaultView: mockWindow }, + } as unknown as HTMLDivElement + + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => mockScrollElement, + scrollToFn: vi.fn(), + observeElementRect: (_inst, cb) => { + cb({ width: 400, height: 600 }) + return () => {} + }, + observeElementOffset: (_inst, cb) => { + cb(0, false) + return () => {} + }, + }) + + virtualizer._willUpdate() + + // Mount nodeA at index 3 + const nodeA = { + getAttribute: () => '3', + getBoundingClientRect: () => ({ height: 50, width: 400 }), + isConnected: true, + setAttribute: vi.fn(), + } as unknown as HTMLElement + virtualizer.measureElement(nodeA) + expect(virtualizer.elementsCache.get(3)).toBe(nodeA) + + // Mount nodeB for the same index — replaces nodeA in elementsCache + const nodeB = { + getAttribute: () => '3', + getBoundingClientRect: () => ({ height: 50, width: 400 }), + isConnected: true, + setAttribute: vi.fn(), + } as unknown as HTMLElement + virtualizer.measureElement(nodeB) + expect(virtualizer.elementsCache.get(3)).toBe(nodeB) + + // Now fire a delayed RO callback for the now-disconnected nodeA. + // This must NOT delete elementsCache[3] (which points to nodeB). + ;(nodeA as any).isConnected = false + roCallback!( + [ + { + target: nodeA, + contentRect: { height: 50, width: 400 } as DOMRectReadOnly, + borderBoxSize: [{ blockSize: 50, inlineSize: 400 }], + contentBoxSize: [{ blockSize: 50, inlineSize: 400 }], + devicePixelContentBoxSize: [{ blockSize: 50, inlineSize: 400 }], + } as ResizeObserverEntry, + ], + {} as ResizeObserver, + ) + + expect(virtualizer.elementsCache.get(3)).toBe(nodeB) +}) + +// ─── setOptions behavioral contract ────────────────────────────────────────── +// These tests pin down how setOptions merges defaults with user-supplied opts. +// They guard against regressions when changing the merge mechanism +// (currently: mutate opts + spread with defaults; will become: copy-without-undefined). + +test('setOptions: undefined values should fall back to defaults', () => { + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + paddingStart: 100, + }) + + // First confirm explicit value sticks + expect(virtualizer.options.paddingStart).toBe(100) + + // Now setOptions with paddingStart: undefined → should fall back to default (0) + virtualizer.setOptions({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + paddingStart: undefined as any, + }) + + expect(virtualizer.options.paddingStart).toBe(0) +}) + +test('setOptions: missing keys should fall back to defaults', () => { + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + // Defaults should apply for all unset options + expect(virtualizer.options.paddingStart).toBe(0) + expect(virtualizer.options.paddingEnd).toBe(0) + expect(virtualizer.options.overscan).toBe(1) + expect(virtualizer.options.horizontal).toBe(false) + expect(virtualizer.options.gap).toBe(0) + expect(virtualizer.options.lanes).toBe(1) + expect(virtualizer.options.enabled).toBe(true) +}) + +test('setOptions: explicit falsy values (0, false) should NOT fall back to defaults', () => { + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + paddingStart: 50, + overscan: 3, + enabled: true, + }) + + // Now set them all to explicit falsy values + virtualizer.setOptions({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + paddingStart: 0, + overscan: 0, + enabled: false, + }) + + expect(virtualizer.options.paddingStart).toBe(0) + expect(virtualizer.options.overscan).toBe(0) + expect(virtualizer.options.enabled).toBe(false) +}) + +test('setOptions: subsequent calls do not accumulate stale options', () => { + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + paddingStart: 100, + overscan: 5, + }) + + // Now call again with only count — paddingStart and overscan should reset to defaults + virtualizer.setOptions({ + count: 20, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + expect(virtualizer.options.count).toBe(20) + expect(virtualizer.options.paddingStart).toBe(0) + expect(virtualizer.options.overscan).toBe(1) +}) + +test('setOptions: does not mutate the caller-supplied opts object', () => { + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + const userOpts = { + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + paddingStart: undefined as any, + overscan: undefined as any, + } + const beforeKeys = Object.keys(userOpts).sort() + + virtualizer.setOptions(userOpts) + + const afterKeys = Object.keys(userOpts).sort() + expect(afterKeys).toEqual(beforeKeys) + // Specifically: undefined-valued keys should still exist on the user's object + expect('paddingStart' in userOpts).toBe(true) + expect('overscan' in userOpts).toBe(true) +}) + +// ─── pending min pointer for measure storms ────────────────────────────────── + +test('resizeItem random order should rebuild from earliest dirty index', () => { + // This pins down the min-of-pending-indices behavior. If indices 5, 0, 8 are + // dirtied in that order, getMeasurements must rebuild from index 0 onward so + // all later items have correct offsets. + const N = 20 + const virtualizer = new Virtualizer({ + count: N, + estimateSize: () => 10, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + + virtualizer.resizeItem(5, 50) + virtualizer.resizeItem(0, 30) + virtualizer.resizeItem(8, 70) + virtualizer.resizeItem(15, 100) + virtualizer.resizeItem(3, 40) + + const measurements = virtualizer['getMeasurements']() + // Sizes + expect(measurements[0]!.size).toBe(30) + expect(measurements[3]!.size).toBe(40) + expect(measurements[5]!.size).toBe(50) + expect(measurements[8]!.size).toBe(70) + expect(measurements[15]!.size).toBe(100) + + // Verify start/end are correct (prefix-sum invariant) for ALL items, + // even those that were not resized — they must have absorbed the shifts + // from earlier resized items. + let runningStart = 0 + for (let i = 0; i < N; i++) { + expect(measurements[i]!.start).toBe(runningStart) + runningStart += measurements[i]!.size + } +}) + +test('resizeItem in massive storm (10k items) does not crash on min lookup', () => { + // Regression: Math.min(...arr) spreads the array onto the call stack. + // V8's argument-list limit is around 125k. With many pending indices, + // this can throw RangeError. We test 10k to be well within range but + // catch any regression in the running-min mechanism. + const N = 10_000 + const virtualizer = new Virtualizer({ + count: N, + estimateSize: () => 10, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + virtualizer['getMeasurements']() + + // Resize every item before reading measurements — accumulates N pending indices + for (let i = 0; i < N; i++) { + virtualizer.resizeItem(i, 20 + (i % 13)) + } + + expect(() => virtualizer['getMeasurements']()).not.toThrow() + const measurements = virtualizer['getMeasurements']() + expect(measurements.length).toBe(N) + // Verify last item has correct prefix-sum + let expected = 0 + for (let i = 0; i < N; i++) expected += 20 + (i % 13) + expect(measurements[N - 1]!.start + measurements[N - 1]!.size).toBe(expected) +}) + +// ─── defaultRangeExtractor ─────────────────────────────────────────────────── + +test('defaultRangeExtractor: simple range with no overscan', () => { + const result = defaultRangeExtractor({ + startIndex: 5, + endIndex: 10, + overscan: 0, + count: 100, + }) + expect(result).toEqual([5, 6, 7, 8, 9, 10]) +}) + +test('defaultRangeExtractor: range with overscan', () => { + const result = defaultRangeExtractor({ + startIndex: 5, + endIndex: 10, + overscan: 2, + count: 100, + }) + expect(result).toEqual([3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) +}) + +test('defaultRangeExtractor: clamps start to 0 when overscan would go negative', () => { + const result = defaultRangeExtractor({ + startIndex: 1, + endIndex: 5, + overscan: 5, + count: 100, + }) + expect(result).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + expect(result[0]).toBe(0) +}) + +test('defaultRangeExtractor: clamps end to count-1 when overscan would go past', () => { + const result = defaultRangeExtractor({ + startIndex: 95, + endIndex: 99, + overscan: 5, + count: 100, + }) + expect(result).toEqual([90, 91, 92, 93, 94, 95, 96, 97, 98, 99]) + expect(result[result.length - 1]).toBe(99) +}) + +test('defaultRangeExtractor: single item range', () => { + const result = defaultRangeExtractor({ + startIndex: 5, + endIndex: 5, + overscan: 0, + count: 100, + }) + expect(result).toEqual([5]) +}) + +test('defaultRangeExtractor: returns a plain Array (not iterable proxy)', () => { + const result = defaultRangeExtractor({ + startIndex: 0, + endIndex: 3, + overscan: 0, + count: 100, + }) + expect(Array.isArray(result)).toBe(true) + expect(result.length).toBe(4) +}) + +test('defaultRangeExtractor: large range produces correct length', () => { + const result = defaultRangeExtractor({ + startIndex: 0, + endIndex: 999, + overscan: 0, + count: 1000, + }) + expect(result.length).toBe(1000) + expect(result[0]).toBe(0) + expect(result[999]).toBe(999) +}) + +// ─── Lazy fast path (lanes === 1) edge cases ───────────────────────────────── +// Pins down behavior of the typed-array-backed lazy measurements view. + +test('lazy fast path: empty list (count=0)', () => { + const v = new Virtualizer({ + count: 0, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + expect(m.length).toBe(0) + expect(v.getTotalSize()).toBe(0) +}) + +test('lazy fast path: respects paddingStart + scrollMargin + gap', () => { + const v = new Virtualizer({ + count: 5, + estimateSize: () => 40, + paddingStart: 10, + scrollMargin: 20, + gap: 8, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + // First item starts at paddingStart + scrollMargin = 30 + expect(m[0]!.start).toBe(30) + expect(m[0]!.size).toBe(40) + expect(m[0]!.end).toBe(70) + // Subsequent items separated by gap + expect(m[1]!.start).toBe(70 + 8) // prev.end + gap + expect(m[1]!.size).toBe(40) +}) + +test('lazy fast path: VirtualItem fields are correct', () => { + const v = new Virtualizer({ + count: 3, + estimateSize: () => 50, + getItemKey: (i) => `item-${i}`, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + expect(m[0]!.index).toBe(0) + expect(m[0]!.key).toBe('item-0') + expect(m[0]!.start).toBe(0) + expect(m[0]!.size).toBe(50) + expect(m[0]!.end).toBe(50) + expect(m[0]!.lane).toBe(0) + expect(m[1]!.index).toBe(1) + expect(m[1]!.key).toBe('item-1') + expect(m[2]!.key).toBe('item-2') +}) + +test('lazy fast path: same item read twice returns identical reference (cache works)', () => { + const v = new Virtualizer({ + count: 10, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + const a = m[5] + const b = m[5] + expect(a).toBe(b) +}) + +test('lazy fast path: out-of-range access returns undefined', () => { + const v = new Virtualizer({ + count: 5, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + expect(m[10]).toBeUndefined() + expect(m[-1]).toBeUndefined() + expect(m[5]).toBeUndefined() +}) + +test('lazy fast path: getTotalSize after resizeItem reflects new size', () => { + const v = new Virtualizer({ + count: 5, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + expect(v.getTotalSize()).toBe(150) + v.resizeItem(2, 100) + expect(v.getTotalSize()).toBe(120 + 100) // 4 * 30 + 100 +}) + +test('lazy fast path: getVirtualItemForOffset binary search returns correct item', () => { + const v = new Virtualizer({ + count: 100, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const found = v.getVirtualItemForOffset(500) + // Item at offset 500 should be index 16 (500/30 = 16.67) + expect(found?.index).toBe(16) + expect(found?.start).toBe(480) + expect(found?.end).toBe(510) +}) + +test('lazy fast path: 1M-item list returns a sparse view, not an eagerly-allocated array', () => { + // Functional contract for the lazy fast path: a 1M-item virtualizer + // returns measurements that report the correct total length and produce + // exact start/size/end values on indexed access without requiring the + // whole array to be materialized. Sparse spot-checks across the range + // would fail if the fast path were silently allocating N VirtualItems + // (or if the typed-array backing computed offsets incorrectly). + const v = new Virtualizer({ + count: 1_000_000, + estimateSize: () => 30, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + expect(m.length).toBe(1_000_000) + expect(m[0]!.start).toBe(0) + expect(m[0]!.size).toBe(30) + expect(m[0]!.end).toBe(30) + expect(m[500_000]!.start).toBe(15_000_000) + expect(m[500_000]!.end).toBe(15_000_030) + expect(m[999_999]!.start).toBe(29_999_970) + expect(m[999_999]!.end).toBe(30_000_000) +}) + +// ─── iOS momentum-safe scroll adjustments ─────────────────────────────────── + +function withFakeIOSUserAgent(fn: () => T): T { + // jsdom navigator.userAgent lives on the prototype; we set an own property + // to shadow it, then remove the own property in finally so the prototype + // value is visible again for subsequent tests. + Object.defineProperty(navigator, 'userAgent', { + value: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)', + configurable: true, + }) + _resetIOSDetectionForTests() + try { + return fn() + } finally { + delete (navigator as any).userAgent + _resetIOSDetectionForTests() + } +} + +test('iOS deferral: scroll-position write is deferred during isScrolling', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCallback: + | ((offset: number, isScrolling: boolean) => void) + | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(100, true) // Start scrolling + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + // Resize an item above the current scroll position while isScrolling=true + // The default condition (item.start < scrollOffset + scrollAdjustments) + // would normally trigger an immediate scroll adjustment. + v.resizeItem(0, 100) // item 0 was at start=0; now 50→100 grows by 50 + + // On iOS during scroll, the adjustment should be DEFERRED — scrollToFn + // should NOT have been called for the adjustment. + expect(scrollToFn).not.toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(50) + + // Now transition isScrolling → false + scrollCallback!(100, false) + + // The deferred adjustment should be flushed. + expect(scrollToFn).toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(0) + }) +}) + +test('iOS deferral: multiple resizes during scroll accumulate and flush as one', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCallback: + | ((offset: number, isScrolling: boolean) => void) + | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 200, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(200, true) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + // Three resizes during scroll: 10 + 15 + 20 = 45 total + v.resizeItem(0, 60) + v.resizeItem(1, 65) + v.resizeItem(2, 70) + + expect(scrollToFn).not.toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(45) + + scrollCallback!(200, false) + // Single flush call + expect(scrollToFn).toHaveBeenCalledTimes(1) + expect(v['_iosDeferredAdjustment']).toBe(0) + }) +}) + +test('iOS deferral: flushed delta is rolled into scrollAdjustments so back-to-back resizes stay consistent', () => { + // Regression: the deferred flush used to write `adjustments: delta` + // directly without updating `this.scrollAdjustments`. If a second resize + // landed before the resulting scroll event fired (and reset the + // accumulator), the comparison `itemStart < getScrollOffset() + + // scrollAdjustments` would miss the flushed delta and the next correction + // would compute from the stale offset. + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCallback: + | ((offset: number, isScrolling: boolean) => void) + | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 200, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(200, true) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + // Build up a deferred adjustment of 50 during scroll. + v.resizeItem(0, 100) + expect(v['_iosDeferredAdjustment']).toBe(50) + expect(v['scrollAdjustments']).toBe(0) + + // Settle: scroll event resets scrollAdjustments to 0, then the flush + // runs and must roll the deferred delta back into scrollAdjustments. + scrollCallback!(200, false) + + expect(scrollToFn).toHaveBeenCalledTimes(1) + const [, opts] = scrollToFn.mock.calls[0]! + expect(opts.adjustments).toBe(50) + // The running accumulator must now reflect the flushed delta — any + // resize landing before the resulting scroll event fires has to see + // the correct effective offset. + expect(v['scrollAdjustments']).toBe(50) + }) +}) + +// ─── Phase 1: touch event distinction ──────────────────────────────────────── + +// Mock EventTarget that records listeners so tests can dispatch events +// without requiring a real DOM. Works in any environment, jsdom or not. +function makeMockScrollElement(props: Record) { + const listeners = new Map void>>() + return { + ...props, + addEventListener(name: string, fn: (e: Event) => void) { + let s = listeners.get(name) + if (!s) listeners.set(name, (s = new Set())) + s.add(fn) + }, + removeEventListener(name: string, fn: (e: Event) => void) { + listeners.get(name)?.delete(fn) + }, + _dispatch(name: string) { + listeners.get(name)?.forEach((fn) => fn({} as Event)) + }, + } as any +} + +function makeIOSVirtualizerWithRealEl( + scrollToFn: ReturnType, + mockWindow: any, +) { + const el = makeMockScrollElement({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + ownerDocument: { defaultView: mockWindow }, + }) + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => el as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + cb(100, false) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + return { v, el } +} + +function dispatchTouchEvent(el: any, type: 'touchstart' | 'touchend') { + el._dispatch(type) +} + +test('iOS Phase 1: touchstart sets _iosTouching=true and clears justTouchEnded', () => { + withFakeIOSUserAgent(() => { + const mockWindow = { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + } + const { v, el } = makeIOSVirtualizerWithRealEl(vi.fn(), mockWindow) + ;(v as any)._iosJustTouchEnded = true // pretend a prior touchend left this set + dispatchTouchEvent(el, 'touchstart') + expect(v['_iosTouching']).toBe(true) + expect(v['_iosJustTouchEnded']).toBe(false) + }) +}) + +test('iOS Phase 1: touchend sets justTouchEnded + starts grace timer, then expires', async () => { + await withFakeIOSUserAgent(async () => { + let timerId = 0 + const timers = new Map void>() + const mockWindow = { + setTimeout: (fn: () => void, _ms: number) => { + const id = ++timerId + timers.set(id, fn) + return id + }, + clearTimeout: (id: number) => timers.delete(id), + } + const { v, el } = makeIOSVirtualizerWithRealEl(vi.fn(), mockWindow) + dispatchTouchEvent(el, 'touchstart') + dispatchTouchEvent(el, 'touchend') + expect(v['_iosTouching']).toBe(false) + expect(v['_iosJustTouchEnded']).toBe(true) + expect(v['_iosTouchEndTimerId']).not.toBeNull() + + // Fire the timer manually (simulating 150ms elapsing). + const fn = timers.get(v['_iosTouchEndTimerId']!)! + fn() + expect(v['_iosJustTouchEnded']).toBe(false) + expect(v['_iosTouchEndTimerId']).toBeNull() + }) +}) + +test('iOS Phase 1: resize during active touch defers (no scrollTop write)', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + const mockWindow = { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + } + const { v, el } = makeIOSVirtualizerWithRealEl(scrollToFn, mockWindow) + // Bring scroll state to a typical "user touched the screen" pose. + dispatchTouchEvent(el, 'touchstart') + scrollToFn.mockClear() + + // Above-viewport item resizes mid-drag. Must defer. + v.resizeItem(0, 100) + expect(scrollToFn).not.toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(50) + }) +}) + +test('iOS Phase 1: resize in post-touchend grace window defers; flushes when timer fires', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let timerId = 0 + const timers = new Map void>() + const mockWindow = { + setTimeout: (fn: () => void, _ms: number) => { + const id = ++timerId + timers.set(id, fn) + return id + }, + clearTimeout: (id: number) => timers.delete(id), + } + const { v, el } = makeIOSVirtualizerWithRealEl(scrollToFn, mockWindow) + dispatchTouchEvent(el, 'touchstart') + dispatchTouchEvent(el, 'touchend') + expect(v['_iosJustTouchEnded']).toBe(true) + scrollToFn.mockClear() + + // Items measure during the grace window — must defer + v.resizeItem(0, 100) + v.resizeItem(1, 65) + expect(scrollToFn).not.toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(50 + 15) + + // Expire the grace timer; the timer callback flushes the accumulated delta. + const fn = timers.get(v['_iosTouchEndTimerId']!)! + fn() + expect(v['_iosJustTouchEnded']).toBe(false) + expect(scrollToFn).toHaveBeenCalledTimes(1) + expect(v['_iosDeferredAdjustment']).toBe(0) + }) +}) + +test('iOS Phase 1: scroll-event after touchend timer cleanup also flushes', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCallback: ((o: number, s: boolean) => void) | null = null + const el = makeMockScrollElement({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + ownerDocument: { + defaultView: { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }, + }, + }) + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => el as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(100, true) // scrolling + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + // Resize during scroll (no touch tracked here — pure scroll). + v.resizeItem(0, 100) + expect(scrollToFn).not.toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(50) + + // Scroll ends. Touch never started here, so the flush gate's + // !isScrolling && !_iosTouching && !_iosJustTouchEnded all hold. + scrollCallback!(100, false) + expect(scrollToFn).toHaveBeenCalledTimes(1) + expect(v['_iosDeferredAdjustment']).toBe(0) + }) +}) + +test('iOS Phase 1: new touchstart during grace window cancels pending flush timer', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let timerId = 0 + const timers = new Map void>() + const mockWindow = { + setTimeout: (fn: () => void, _ms: number) => { + const id = ++timerId + timers.set(id, fn) + return id + }, + clearTimeout: (id: number) => timers.delete(id), + } + const { v, el } = makeIOSVirtualizerWithRealEl(scrollToFn, mockWindow) + dispatchTouchEvent(el, 'touchstart') + dispatchTouchEvent(el, 'touchend') + const firstTimerId = v['_iosTouchEndTimerId']! + expect(timers.has(firstTimerId)).toBe(true) + + // User puts finger back down before grace window expired. + dispatchTouchEvent(el, 'touchstart') + // The pending timer must have been canceled. + expect(timers.has(firstTimerId)).toBe(false) + expect(v['_iosTouchEndTimerId']).toBeNull() + expect(v['_iosTouching']).toBe(true) + }) +}) + +// ─── Phase 2a: subpixel scrollTop reconciliation ───────────────────────────── + +test('Phase 2a: browser-rounded scrollTop after self-write is reconciled to intended value', () => { + let scrollCallback: ((o: number, s: boolean) => void) | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 0, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + scrollTo: vi.fn(), + }) as any, + scrollToFn: vi.fn(), + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(0, false) + return () => {} + }, + }) + v._willUpdate() + + // Simulate a self-write to 123.5 (subpixel target). + v.scrollToOffset(123.5, { behavior: 'auto' }) + expect(v['_intendedScrollOffset']).toBe(123.5) + + // Browser fires a scroll event reporting 123 (integer-rounded). + scrollCallback!(123, false) + + // We should have reconciled the offset back to the intended 123.5, + // not stored the browser's rounded 123. + expect(v.scrollOffset).toBe(123.5) + expect(v['_intendedScrollOffset']).toBeNull() +}) + +test('Phase 2a: user-initiated scroll (large delta) is NOT reconciled to intended value', () => { + let scrollCallback: ((o: number, s: boolean) => void) | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 0, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + scrollTo: vi.fn(), + }) as any, + scrollToFn: vi.fn(), + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(0, false) + return () => {} + }, + }) + v._willUpdate() + v.scrollToOffset(100, { behavior: 'auto' }) + expect(v['_intendedScrollOffset']).toBe(100) + + // User then scrolls way past — browser reports 500. Diff (400) > 1.5 px + // tolerance, so we trust the browser-reported value. + scrollCallback!(500, true) + expect(v.scrollOffset).toBe(500) + expect(v['_intendedScrollOffset']).toBeNull() +}) + +// ─── Phase 2b: scrollTopMax elastic-overscroll clamp ───────────────────────── + +test('Phase 2b: flush skipped when scrollTop is in elastic-overscroll zone (negative)', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCb: ((o: number, s: boolean) => void) | null = null + const el = makeMockScrollElement({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + ownerDocument: { + defaultView: { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }, + }, + }) + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => el as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCb = cb + cb(100, true) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + // Resize during scroll: defers + v.resizeItem(0, 100) + expect(v['_iosDeferredAdjustment']).toBe(50) + + // User rubber-bands past the top: scrollTop becomes negative. + // Even though isScrolling=false now, the elastic-zone check blocks + // the flush so we don't snap-back to a clamped position. + el.scrollTop = -25 + scrollCb!(-25, false) + expect(scrollToFn).not.toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(50) // still deferred + + // User releases, scroll snaps back in-bounds. Next scroll event + // should successfully flush. + el.scrollTop = 100 + scrollCb!(100, false) + expect(scrollToFn).toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(0) + }) +}) + +test('Phase 2b: flush skipped when scrollTop > scrollHeight-clientHeight (overscroll bottom)', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCb: ((o: number, s: boolean) => void) | null = null + const el = makeMockScrollElement({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, // max valid scrollTop = 300 + offsetHeight: 200, + ownerDocument: { + defaultView: { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }, + }, + }) + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => el as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCb = cb + cb(100, true) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + v.resizeItem(0, 100) + + // User pulls past the bottom: scrollTop becomes 350 (> max 300). + el.scrollTop = 350 + scrollCb!(350, false) + expect(scrollToFn).not.toHaveBeenCalled() + + // Bounce-back resolves + el.scrollTop = 300 + scrollCb!(300, false) + expect(scrollToFn).toHaveBeenCalled() + }) +}) + +test('Phase 2b: in-bounds flush proceeds normally (no regression)', () => { + withFakeIOSUserAgent(() => { + const scrollToFn = vi.fn() + let scrollCb: ((o: number, s: boolean) => void) | null = null + const el = makeMockScrollElement({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + ownerDocument: { + defaultView: { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }, + }, + }) + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => el as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCb = cb + cb(100, true) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + v.resizeItem(0, 100) + el.scrollTop = 150 + scrollCb!(150, false) // in-bounds (0..300) + expect(scrollToFn).toHaveBeenCalledTimes(1) + expect(v['_iosDeferredAdjustment']).toBe(0) + }) +}) + +test('Phase 2a: a second self-write replaces the intended target', () => { + let scrollCallback: ((o: number, s: boolean) => void) | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 0, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + scrollTo: vi.fn(), + }) as any, + scrollToFn: vi.fn(), + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCallback = cb + cb(0, false) + return () => {} + }, + }) + v._willUpdate() + v.scrollToOffset(100, { behavior: 'auto' }) + v.scrollToOffset(200.7, { behavior: 'auto' }) + expect(v['_intendedScrollOffset']).toBe(200.7) + // First scrollTo's offset (100) was overwritten — a scroll event near it + // would NOT reconcile. + scrollCallback!(101, true) + // 101 is not within 1.5px of 200.7, so browser value wins. + expect(v.scrollOffset).toBe(101) +}) + +test('iOS Phase 1: non-iOS still does NOT install touch state machine', () => { + // On non-iOS, touchend should not arm the grace timer. + _resetIOSDetectionForTests() + const scrollToFn = vi.fn() + const mockWindow = { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + } + const { v, el } = makeIOSVirtualizerWithRealEl(scrollToFn, mockWindow) + + dispatchTouchEvent(el, 'touchstart') + expect(v['_iosTouching']).toBe(true) // touchstart still flips the flag (cheap) + dispatchTouchEvent(el, 'touchend') + // Non-iOS path returns before setting justTouchEnded / arming timer + expect(v['_iosJustTouchEnded']).toBe(false) + expect(v['_iosTouchEndTimerId']).toBeNull() +}) + +test('non-iOS: adjustment is applied immediately during scroll (no regression)', () => { + // Without the iOS user-agent, the normal flow should run unchanged. + _resetIOSDetectionForTests() + const scrollToFn = vi.fn() + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + cb(100, true) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + scrollToFn.mockClear() + + v.resizeItem(0, 100) + + // Should have fired immediately + expect(scrollToFn).toHaveBeenCalled() + expect(v['_iosDeferredAdjustment']).toBe(0) +}) + +test('scroll-up jank: backward-scroll skips scroll-position adjustment by default', () => { + // Default behavior change: when an above-viewport item resizes while the + // user is scrolling BACKWARD, we no longer write to scrollTop. This avoids + // the well-known "items jump while scrolling up" jank. + const scrollToFn = vi.fn() + let scrollCb: ((o: number, s: boolean) => void) | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 200, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCb = cb + // Simulate user starting at scrollTop=200, then scrolling up to 100. + cb(200, false) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + // Now simulate backward scroll: from 200 to 100 (offset decreases). + scrollCb!(100, true) + expect(v.scrollDirection).toBe('backward') + scrollToFn.mockClear() + + // Resize an above-viewport item while scrolling backward. + v.resizeItem(0, 100) // item 0 grows by 50px + + // Default behavior: no scroll-position adjustment fires. + expect(scrollToFn).not.toHaveBeenCalled() +}) + +test('scroll-up jank: forward-scroll still applies adjustment (no regression)', () => { + const scrollToFn = vi.fn() + let scrollCb: ((o: number, s: boolean) => void) | null = null + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + scrollCb = cb + cb(100, false) + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + // Forward scroll: 100 → 200 + scrollCb!(200, true) + expect(v.scrollDirection).toBe('forward') + scrollToFn.mockClear() + + v.resizeItem(0, 100) + + // Forward scroll: adjustment still fires. + expect(scrollToFn).toHaveBeenCalled() +}) + +test('scroll-up jank: idle (scrollDirection=null) still applies adjustment', () => { + // When not actively scrolling, adjustment still fires — needed for the + // mount-time measurement storm where items measure before any scroll. + const scrollToFn = vi.fn() + const v = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => + ({ + scrollTop: 100, + scrollLeft: 0, + scrollHeight: 500, + clientHeight: 200, + offsetHeight: 200, + }) as any, + scrollToFn, + observeElementRect: () => {}, + observeElementOffset: (_inst, cb) => { + cb(100, false) // not scrolling + return () => {} + }, + }) + v._willUpdate() + v['getMeasurements']() + expect(v.scrollDirection).toBeNull() + scrollToFn.mockClear() + + v.resizeItem(0, 100) + expect(scrollToFn).toHaveBeenCalled() +}) + +test('takeSnapshot: returns measured items only, restorable via initialMeasurementsCache', () => { + const v1 = new Virtualizer({ + count: 20, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + v1['getMeasurements']() + + // No measurements yet → empty snapshot + expect(v1.takeSnapshot()).toEqual([]) + + // Measure a few items + v1.resizeItem(0, 80) + v1.resizeItem(1, 60) + v1.resizeItem(2, 100) + + const snapshot = v1.takeSnapshot() + expect(snapshot.length).toBe(3) + expect(snapshot[0]!.size).toBe(80) + expect(snapshot[1]!.size).toBe(60) + expect(snapshot[2]!.size).toBe(100) + // snapshot entries are plain objects (not Proxy refs) + expect(Object.keys(snapshot[0]!).sort()).toEqual([ + 'end', + 'index', + 'key', + 'lane', + 'size', + 'start', + ]) + + // Restore: pass snapshot to a fresh virtualizer + const v2 = new Virtualizer({ + count: 20, + estimateSize: () => 50, + initialMeasurementsCache: snapshot, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m2 = v2['getMeasurements']() + // Restored sizes match the snapshot + expect(m2[0]!.size).toBe(80) + expect(m2[1]!.size).toBe(60) + expect(m2[2]!.size).toBe(100) + // Unmeasured items fall back to estimateSize + expect(m2[5]!.size).toBe(50) +}) + +test('takeSnapshot: works with lanes>1 too', () => { + const v = new Virtualizer({ + count: 6, + lanes: 2, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + v['getMeasurements']() + v.resizeItem(0, 80) + v.resizeItem(1, 90) + const snap = v.takeSnapshot() + expect(snap.length).toBe(2) + expect(snap[0]!.size).toBe(80) + expect(snap[1]!.size).toBe(90) +}) + +test('reconcileScroll: smooth scroll retargets remain smooth while distance > viewport', () => { + // When target drifts during a smooth scroll (because newly visible items + // measured in and shifted positions), the prior behavior snapped to + // behavior:'auto' on the first retarget. New behavior: keep smooth while + // we're still more than a viewport away, snap only on final approach. + const { rafCallbacks, mockScrollElement, scrollToFn } = + createMockEnvironment() + const virtualizer = new Virtualizer({ + count: 10000, + estimateSize: () => 50, + getScrollElement: () => mockScrollElement, + scrollToFn, + observeElementRect: (_inst, cb) => { + cb({ width: 400, height: 600 }) + return () => {} + }, + observeElementOffset: (_inst, cb) => { + cb(0, false) + return () => {} + }, + }) + virtualizer._willUpdate() + scrollToFn.mockClear() + + virtualizer.scrollToIndex(5000, { behavior: 'smooth' }) + // First call: smooth, with our best estimate target + const firstCall = scrollToFn.mock.calls[0] + expect(firstCall![1].behavior).toBe('smooth') + + // Simulate a measurement that moved the target. Force resizeItem at a + // visible-enough position so getOffsetForIndex(5000) returns a different + // value than what scrollState.lastTargetOffset has. + virtualizer.resizeItem(0, 80) + + // Now trigger the reconcile RAF + rafCallbacks.forEach((cb) => cb(0)) + + // The reconcile retarget should be smooth (we're far from target). + const lastCall = scrollToFn.mock.calls[scrollToFn.mock.calls.length - 1] + expect(lastCall![1].behavior).toBe('smooth') +}) + +test('lazy fast path: lanes>1 still uses eager path (regression guard)', () => { + const v = new Virtualizer({ + count: 10, + lanes: 2, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + const m = v['getMeasurements']() + // Eager array, so m is a real Array; both lanes present + const lanes = new Set(m.map((x) => x.lane)) + expect(lanes.has(0)).toBe(true) + expect(lanes.has(1)).toBe(true) +}) + +test('setOptions: explicit value overrides default', () => { + const virtualizer = new Virtualizer({ + count: 10, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + overscan: 7, + gap: 12, + lanes: 3, + }) + + expect(virtualizer.options.overscan).toBe(7) + expect(virtualizer.options.gap).toBe(12) + expect(virtualizer.options.lanes).toBe(3) +}) + +// ─── elementScroll / windowScroll public exports ───────────────────────────── + +function makeBaseInstance(scrollEl: any, opts: any = {}) { + return { + scrollElement: scrollEl, + options: { + horizontal: false, + ...opts, + }, + } as any +} + +test('elementScroll: calls scrollTo with top + behavior on the scroll element', () => { + const scrollTo = vi.fn() + const scrollEl = { scrollTo } + elementScroll(100, { behavior: 'smooth' }, makeBaseInstance(scrollEl) as any) + expect(scrollTo).toHaveBeenCalledWith({ top: 100, behavior: 'smooth' }) +}) + +test('elementScroll: applies adjustments offset', () => { + const scrollTo = vi.fn() + const scrollEl = { scrollTo } + elementScroll( + 100, + { adjustments: 50, behavior: 'auto' }, + makeBaseInstance(scrollEl) as any, + ) + expect(scrollTo).toHaveBeenCalledWith({ top: 150, behavior: 'auto' }) +}) + +test('elementScroll: uses left when horizontal is true', () => { + const scrollTo = vi.fn() + const scrollEl = { scrollTo } + elementScroll( + 100, + { behavior: 'auto' }, + makeBaseInstance(scrollEl, { horizontal: true }) as any, + ) + expect(scrollTo).toHaveBeenCalledWith({ left: 100, behavior: 'auto' }) +}) + +test('windowScroll: calls scrollTo with top + behavior on the window', () => { + const scrollTo = vi.fn() + const win = { scrollTo } + windowScroll(250, { behavior: 'smooth' }, makeBaseInstance(win) as any) + expect(scrollTo).toHaveBeenCalledWith({ top: 250, behavior: 'smooth' }) +}) + +test('windowScroll: applies adjustments + horizontal', () => { + const scrollTo = vi.fn() + const win = { scrollTo } + windowScroll( + 250, + { adjustments: -10, behavior: 'auto' }, + makeBaseInstance(win, { horizontal: true }) as any, + ) + expect(scrollTo).toHaveBeenCalledWith({ left: 240, behavior: 'auto' }) +}) + +test('elementScroll / windowScroll: no-op when scrollElement is null', () => { + expect(() => + elementScroll(100, {}, makeBaseInstance(null) as any), + ).not.toThrow() + expect(() => + windowScroll(100, {}, makeBaseInstance(null) as any), + ).not.toThrow() +}) + +// ─── observeElementOffset / observeWindowOffset ────────────────────────────── + +function makeObserveInstance( + element: any, + opts: { + horizontal?: boolean + isRtl?: boolean + useScrollendEvent?: boolean + isScrollingResetDelay?: number + } = {}, + targetWindow: any = { + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }, +) { + return { + scrollElement: element, + targetWindow, + options: { + horizontal: false, + isRtl: false, + useScrollendEvent: false, + isScrollingResetDelay: 150, + ...opts, + }, + } as any +} + +test('observeElementOffset: returns undefined when scrollElement is null', () => { + const cb = vi.fn() + expect( + observeElementOffset(makeObserveInstance(null) as any, cb), + ).toBeUndefined() + expect(cb).not.toHaveBeenCalled() +}) + +test('observeElementOffset: attaches scroll listener and fires callback with scrollTop', () => { + const cb = vi.fn() + const listeners = new Map() + const el: any = { + scrollTop: 50, + scrollLeft: 0, + addEventListener: (name: string, fn: any) => listeners.set(name, fn), + removeEventListener: (name: string) => listeners.delete(name), + } + const cleanup = observeElementOffset(makeObserveInstance(el) as any, cb) + expect(listeners.has('scroll')).toBe(true) + // No scrollend listener by default + expect(listeners.has('scrollend')).toBe(false) + // Trigger scroll + listeners.get('scroll')!({} as Event) + expect(cb).toHaveBeenCalledWith(50, true) + cleanup?.() + expect(listeners.has('scroll')).toBe(false) +}) + +test('observeElementOffset: reads scrollLeft + applies isRtl when horizontal', () => { + const cb = vi.fn() + const listeners = new Map() + const el: any = { + scrollTop: 0, + scrollLeft: 80, + addEventListener: (name: string, fn: any) => listeners.set(name, fn), + removeEventListener: (name: string) => listeners.delete(name), + } + observeElementOffset( + makeObserveInstance(el, { horizontal: true, isRtl: true }) as any, + cb, + ) + listeners.get('scroll')!({} as Event) + // isRtl flips sign + expect(cb).toHaveBeenCalledWith(-80, true) +}) + +test('observeWindowOffset: returns undefined when scrollElement is null', () => { + const cb = vi.fn() + expect( + observeWindowOffset(makeObserveInstance(null) as any, cb), + ).toBeUndefined() +}) + +test('observeWindowOffset: attaches scroll listener and fires callback with scrollY', () => { + const cb = vi.fn() + const listeners = new Map() + const win: any = { + scrollX: 0, + scrollY: 120, + addEventListener: (name: string, fn: any) => listeners.set(name, fn), + removeEventListener: (name: string) => listeners.delete(name), + } + const cleanup = observeWindowOffset(makeObserveInstance(win) as any, cb) + expect(listeners.has('scroll')).toBe(true) + listeners.get('scroll')!({} as Event) + expect(cb).toHaveBeenCalledWith(120, true) + cleanup?.() + expect(listeners.has('scroll')).toBe(false) +}) + +// ─── Public-exports lockdown ───────────────────────────────────────────────── +// If any of these go missing the next minor bump silently breaks consumers. + +test('public runtime exports from @tanstack/virtual-core', async () => { + const mod = await import('../src/index') + // Class + helpers + expect(typeof mod.Virtualizer).toBe('function') + expect(typeof mod.defaultKeyExtractor).toBe('function') + expect(typeof mod.defaultRangeExtractor).toBe('function') + // Observers + expect(typeof mod.observeElementRect).toBe('function') + expect(typeof mod.observeWindowRect).toBe('function') + expect(typeof mod.observeElementOffset).toBe('function') + expect(typeof mod.observeWindowOffset).toBe('function') + // Scrollers + expect(typeof mod.elementScroll).toBe('function') + expect(typeof mod.windowScroll).toBe('function') + // Measurement + expect(typeof mod.measureElement).toBe('function') + // Utilities (historically re-exported from utils) + expect(typeof mod.memo).toBe('function') + expect(typeof mod.debounce).toBe('function') + expect(typeof mod.notUndefined).toBe('function') + expect(typeof mod.approxEqual).toBe('function') +}) + +test('observeWindowOffset: reads scrollX when horizontal', () => { + const cb = vi.fn() + const listeners = new Map() + const win: any = { + scrollX: 75, + scrollY: 0, + addEventListener: (name: string, fn: any) => listeners.set(name, fn), + removeEventListener: (name: string) => listeners.delete(name), + } + observeWindowOffset(makeObserveInstance(win, { horizontal: true }) as any, cb) + listeners.get('scroll')!({} as Event) + expect(cb).toHaveBeenCalledWith(75, true) +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 984a869c3..e19d5ffe2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: version: 0.3.4(@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.6.3) '@tanstack/vite-config': specifier: 0.4.3 - version: 0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.9.1 @@ -67,10 +67,50 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vitest: specifier: ^4.1.4 - version: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) + + benchmarks: + dependencies: + '@tanstack/react-virtual': + specifier: workspace:* + version: link:../packages/react-virtual + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-virtuoso: + specifier: ^4.15.0 + version: 4.18.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-window: + specifier: ^2.2.4 + version: 2.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + virtua: + specifier: ^0.49.0 + version: 0.49.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(solid-js@1.9.10)(svelte@4.2.20)(vue@3.5.22(typescript@5.6.3)) + devDependencies: + '@playwright/test': + specifier: ^1.53.1 + version: 1.56.1 + '@types/react': + specifier: ^18.3.23 + version: 18.3.26 + '@types/react-dom': + specifier: ^18.3.7 + version: 18.3.7(@types/react@18.3.26) + '@vitejs/plugin-react': + specifier: ^4.5.2 + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) + typescript: + specifier: 5.6.3 + version: 5.6.3 + vite: + specifier: ^6.4.2 + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/angular/dynamic: dependencies: @@ -116,7 +156,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -168,7 +208,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -223,7 +263,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -275,7 +315,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -327,7 +367,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -382,7 +422,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -440,7 +480,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -492,7 +532,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -544,7 +584,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -578,7 +618,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/lit/fixed: dependencies: @@ -603,7 +643,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/dynamic: dependencies: @@ -631,13 +671,13 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/fixed: dependencies: @@ -662,13 +702,13 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/infinite-scroll: dependencies: @@ -693,10 +733,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/padding: dependencies: @@ -718,10 +758,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/scroll-padding: dependencies: @@ -746,10 +786,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/smooth-scroll: dependencies: @@ -771,10 +811,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/sticky: dependencies: @@ -805,10 +845,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/table: dependencies: @@ -836,10 +876,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/variable: dependencies: @@ -861,10 +901,10 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/react/window: dependencies: @@ -889,13 +929,13 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/svelte/dynamic: dependencies: @@ -908,7 +948,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -926,7 +966,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/svelte/fixed: dependencies: @@ -936,7 +976,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -954,7 +994,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/svelte/infinite-scroll: dependencies: @@ -967,7 +1007,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -985,7 +1025,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/svelte/smooth-scroll: dependencies: @@ -998,7 +1038,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -1016,7 +1056,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/svelte/sticky: dependencies: @@ -1032,7 +1072,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -1050,7 +1090,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/svelte/table: dependencies: @@ -1066,7 +1106,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.5 @@ -1084,7 +1124,7 @@ importers: version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) examples/vue/dynamic: dependencies: @@ -1103,13 +1143,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1128,13 +1168,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1156,13 +1196,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1181,13 +1221,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1209,13 +1249,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1234,13 +1274,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1268,13 +1308,13 @@ importers: version: 4.17.20 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1299,13 +1339,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1324,13 +1364,13 @@ importers: version: 0.1.1-alpha.16 '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 vite: specifier: ^6.4.2 - version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + version: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue-tsc: specifier: ^2.2.10 version: 2.2.12(typescript@5.6.3) @@ -1343,7 +1383,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.0.0 - version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) + version: 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1) '@angular/cli': specifier: ^19.0.0 version: 19.2.24(@types/node@24.9.2)(chokidar@4.0.3) @@ -1402,7 +1442,7 @@ importers: version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) react: specifier: ^18.3.1 version: 18.3.1 @@ -1424,7 +1464,7 @@ importers: version: 1.9.10 vite-plugin-solid: specifier: ^2.11.6 - version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) packages/svelte-virtual: dependencies: @@ -1437,7 +1477,7 @@ importers: version: 2.5.4(svelte@4.2.20)(typescript@5.6.3) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + version: 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) svelte: specifier: ^4.2.20 version: 4.2.20 @@ -1452,7 +1492,7 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) + version: 5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3)) vue: specifier: ^3.5.16 version: 3.5.22(typescript@5.6.3) @@ -1662,6 +1702,10 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.5': resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} @@ -3060,42 +3104,49 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@napi-rs/nice-linux-arm64-musl@1.1.1': resolution: {integrity: sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@napi-rs/nice-linux-ppc64-gnu@1.1.1': resolution: {integrity: sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==} engines: {node: '>= 10'} cpu: [ppc64] os: [linux] + libc: [glibc] '@napi-rs/nice-linux-riscv64-gnu@1.1.1': resolution: {integrity: sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] + libc: [glibc] '@napi-rs/nice-linux-s390x-gnu@1.1.1': resolution: {integrity: sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==} engines: {node: '>= 10'} cpu: [s390x] os: [linux] + libc: [glibc] '@napi-rs/nice-linux-x64-gnu@1.1.1': resolution: {integrity: sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@napi-rs/nice-linux-x64-musl@1.1.1': resolution: {integrity: sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@napi-rs/nice-openharmony-arm64@1.1.1': resolution: {integrity: sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==} @@ -3215,21 +3266,25 @@ packages: resolution: {integrity: sha512-wgpPaTpQKl+cCkSuE5zamTVrg14mRvT+bLAeN/yHSUgMztvGxwl3Ll+K9DgEcktBo1PLECTWNkVaW8IAsJm4Rg==} cpu: [arm64] os: [linux] + libc: [glibc] '@nx/nx-linux-arm64-musl@22.1.3': resolution: {integrity: sha512-o9XmQehSPR2y0RD4evD+Ob3lNFuwsFOL5upVJqZ3rcE6GkJIFPg8SwEP5FaRIS5MwS04fxnek20NZ18BHjjV/g==} cpu: [arm64] os: [linux] + libc: [musl] '@nx/nx-linux-x64-gnu@22.1.3': resolution: {integrity: sha512-ekcinyDNTa2huVe02T2SFMR8oArohozRbMGO19zftbObXXI4dLdoAuLNb3vK9Pe4vYOpkhfxBVkZvcWMmx7JdA==} cpu: [x64] os: [linux] + libc: [glibc] '@nx/nx-linux-x64-musl@22.1.3': resolution: {integrity: sha512-CqpRIJeIgELCqIgjtSsYnnLi6G0uqjbp/Pw9d7w4im4/NmJXqaE9gxpdHA1eowXLgAy9W1LkfzCPS8Q2IScPuQ==} cpu: [x64] os: [linux] + libc: [musl] '@nx/nx-win32-arm64-msvc@22.1.3': resolution: {integrity: sha512-YbuWb8KQsAR9G0+7b4HA16GV962/VWtRcdS7WY2yaScmPT2W5rObl528Y2j4DuB0j/MVZj12qJKrYfUyjL+UJA==} @@ -3295,41 +3350,49 @@ packages: resolution: {integrity: sha512-JJNyN1ueryETKTUsG57+u0GDbtHKVcwcUoC6YyJmDdWE0o/3twXtHuS+F/121a2sVK8PKlROqGAev+STx3AuuQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-arm64-musl@11.12.0': resolution: {integrity: sha512-rQHoxL0H0WwYUuukPUscLyzWwTl/hyogptYsY+Ye6AggJEOuvgJxMum2glY7etGIGOXxrfjareHnNO1tNY7WYg==} cpu: [arm64] os: [linux] + libc: [musl] '@oxc-resolver/binding-linux-ppc64-gnu@11.12.0': resolution: {integrity: sha512-XPUZSctO+FrC0314Tcth+GrTtzy2yaYqyl8weBMAbKFMwuV8VnR2SHg9dmtI9vkukmM3auOLj0Kqjpl3YXwXiw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-riscv64-gnu@11.12.0': resolution: {integrity: sha512-AmMjcP+6zHLF1JNq/p3yPEcXmZW/Xw5Xl19Zd0eBCSyGORJRuUOkcnyC8bwMO43b/G7PtausB83fclnFL5KZ3w==} cpu: [riscv64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-riscv64-musl@11.12.0': resolution: {integrity: sha512-K2/yFBqFQOKyVwQxYDAKqDtk2kS4g58aGyj/R1bvYPr2P7v7971aUG/5m2WD5u2zSqWBfu1o4PdhX0lsqvA3vQ==} cpu: [riscv64] os: [linux] + libc: [musl] '@oxc-resolver/binding-linux-s390x-gnu@11.12.0': resolution: {integrity: sha512-uSl4jo78tONGZtwsOA4ldT/OI7/hoHJhSMlGYE4Z/lzwMjkAaBdX4soAK5P/rL+U2yCJlRMnnoUckhXlZvDbSw==} cpu: [s390x] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-x64-gnu@11.12.0': resolution: {integrity: sha512-YjL8VAkbPyQ1kUuR6pOBk1O+EkxOoLROTa+ia1/AmFLuXYNltLGI1YxOY14i80cKpOf0Z59IXnlrY3coAI9NDQ==} cpu: [x64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-x64-musl@11.12.0': resolution: {integrity: sha512-qpHPU0qqeJXh7cPzA+I+WWA6RxtRArfmSrhTXidbiQ08G5A1e55YQwExWkitB2rSqN6YFxnpfhHKo9hyhpyfSg==} cpu: [x64] os: [linux] + libc: [musl] '@oxc-resolver/binding-wasm32-wasi@11.12.0': resolution: {integrity: sha512-oqg80bERZAagWLqYmngnesE0/2miv4lST7+wiiZniD6gyb1SoRckwEkbTsytGutkudFtw7O61Pon6pNlOvyFaA==} @@ -3380,36 +3443,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.1': resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.1': resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} @@ -3460,15 +3529,6 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/plugin-json@6.1.0': - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -3512,66 +3572,79 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -3603,11 +3676,6 @@ packages: cpu: [x64] os: [win32] - '@rollup/wasm-node@4.52.5': - resolution: {integrity: sha512-ldY4tEzSMBHNwB8TfRpi7RRRjjyfKlwjdebw5pS1lu0xaY3g4RDc6ople2wEYulVOKVeH7ZJwRx0iw4pGtjMHg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - '@rushstack/node-core-library@5.7.0': resolution: {integrity: sha512-Ff9Cz/YlWu9ce4dmqNBZpA45AEya04XaBFIjV7xTVeEf+y/kTjEasmozqFELXlNG4ROdevss75JrrZ5WgufDkQ==} peerDependencies: @@ -4108,41 +4176,49 @@ packages: resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -4796,10 +4872,6 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -4810,9 +4882,6 @@ packages: common-path-prefix@3.0.0: resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} @@ -5028,10 +5097,6 @@ packages: resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} engines: {node: '>= 0.6.0'} - dependency-graph@1.0.0: - resolution: {integrity: sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==} - engines: {node: '>=4'} - dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -5422,10 +5487,6 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} - find-cache-dir@3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} - find-cache-dir@4.0.0: resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} engines: {node: '>=14.16'} @@ -5786,9 +5847,6 @@ packages: resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==} engines: {node: ^18.17.0 || >=20.5.0} - injection-js@2.6.1: - resolution: {integrity: sha512-dbR5bdhi7TWDoCye9cByZqeg/gAfamm8Vu3G1KZOTYkOif8WkuM8CD0oeDPtZYMzT5YH76JAFB7bkmyY9OJi2A==} - internal-ip@6.2.0: resolution: {integrity: sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==} engines: {node: '>=10'} @@ -6119,11 +6177,6 @@ packages: engines: {node: '>=6'} hasBin: true - less@4.4.2: - resolution: {integrity: sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==} - engines: {node: '>=14'} - hasBin: true - levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -6251,10 +6304,6 @@ packages: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} - make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -6489,19 +6538,6 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@19.2.2: - resolution: {integrity: sha512-dFuwFsDJMBSd1YtmLLcX5bNNUCQUlRqgf34aXA+79PmkOP+0eF8GP2949wq3+jMjmFTNm80Oo8IUYiSLwklKCQ==} - engines: {node: ^18.19.1 || >=20.11.1} - hasBin: true - peerDependencies: - '@angular/compiler-cli': ^19.0.0 || ^19.1.0-next.0 || ^19.2.0-next.0 - tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 - tslib: ^2.3.0 - typescript: '>=5.5 <5.9' - peerDependenciesMeta: - tailwindcss: - optional: true - node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -6832,13 +6868,6 @@ packages: piscina@4.8.0: resolution: {integrity: sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==} - piscina@4.9.2: - resolution: {integrity: sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==} - - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - pkg-dir@7.0.0: resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} engines: {node: '>=14.16'} @@ -7014,6 +7043,18 @@ packages: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} + react-virtuoso@4.18.7: + resolution: {integrity: sha512-xNF5zDGEEIMB7cKwcen/pLig0YDf6OnfFrVgKFa7sHPf9fRem0CaLshyObbBcP88jzn0enavL39EgplgdyT21g==} + peerDependencies: + react: '>=16 || >=17 || >= 18 || >= 19' + react-dom: '>=16 || >=17 || >= 18 || >=19' + + react-window@2.2.7: + resolution: {integrity: sha512-SH5nvfUQwGHYyriDUAOt7wfPsfG9Qxd6OdzQxl5oQ4dsSsUicqQvjV7dR+NqZ4coY0fUn3w1jnC5PwzIUWEg5w==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -7207,11 +7248,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - sass@1.93.3: - resolution: {integrity: sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==} - engines: {node: '>=14.0.0'} - hasBin: true - sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} @@ -7852,6 +7888,26 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + virtua@0.49.1: + resolution: {integrity: sha512-6f79msqg3jzNFdqJiS0FSzhRN1EHlDhR7EvW7emp6z5qQ22VdsReiDHflkpMEMhoAyUuYr69nwT0aagiM7NrUg==} + peerDependencies: + react: '>=16.14.0' + react-dom: '>=16.14.0' + solid-js: '>=1.0' + svelte: '>=5.0' + vue: '>=3.2' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + svelte: + optional: true + vue: + optional: true + vite-plugin-dts@4.2.3: resolution: {integrity: sha512-O5NalzHANQRwVw1xj8KQun3Bv8OSDAlNJXrnqoAz10BOuW8FVvY5g4ygj+DlJZL5mtSPuMu9vd3OfrdW5d4k6w==} engines: {node: ^14.18.0 || >=16.0.0} @@ -8261,13 +8317,13 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1)': + '@angular-devkit/build-angular@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)))(webpack@5.105.0(esbuild@0.25.4)) + '@angular-devkit/build-webpack': 0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0))(webpack@5.105.0(esbuild@0.25.4)) '@angular-devkit/core': 19.2.24(chokidar@4.0.3) - '@angular/build': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1) + '@angular/build': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1) '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) '@babel/core': 7.26.10 '@babel/generator': 7.26.10 @@ -8279,14 +8335,14 @@ snapshots: '@babel/preset-env': 7.26.9(@babel/core@7.26.10) '@babel/runtime': 7.26.10 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0) + '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) - babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0) + babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)) browserslist: 4.27.0 - copy-webpack-plugin: 12.0.2(webpack@5.105.0) - css-loader: 7.1.2(webpack@5.105.0) + copy-webpack-plugin: 12.0.2(webpack@5.105.0(esbuild@0.25.4)) + css-loader: 7.1.2(webpack@5.105.0(esbuild@0.25.4)) esbuild-wasm: 0.25.4 fast-glob: 3.3.3 http-proxy-middleware: 3.0.5 @@ -8294,35 +8350,34 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.2.2 - less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0) - license-webpack-plugin: 4.0.2(webpack@5.105.0) + less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)) + license-webpack-plugin: 4.0.2(webpack@5.105.0(esbuild@0.25.4)) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.2(webpack@5.105.0) + mini-css-extract-plugin: 2.9.2(webpack@5.105.0(esbuild@0.25.4)) open: 10.1.0 ora: 5.4.1 picomatch: 4.0.4 piscina: 4.8.0 postcss: 8.5.2 - postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0) + postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)) resolve-url-loader: 5.0.0 rxjs: 7.8.1 sass: 1.85.0 - sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0) + sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)) semver: 7.7.1 - source-map-loader: 5.0.0(webpack@5.105.0) + source-map-loader: 5.0.0(webpack@5.105.0(esbuild@0.25.4)) source-map-support: 0.5.21 terser: 5.39.0 tree-kill: 1.2.2 tslib: 2.8.1 typescript: 5.6.3 webpack: 5.105.0(esbuild@0.25.4) - webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) - webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) + webpack-dev-middleware: 7.4.2(webpack@5.105.0) + webpack-dev-server: 5.2.2(webpack@5.105.0) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.105.0) + webpack-subresource-integrity: 5.1.0(webpack@5.105.0(esbuild@0.25.4)) optionalDependencies: esbuild: 0.25.4 - ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) transitivePeerDependencies: - '@angular/compiler' - '@rspack/core' @@ -8346,97 +8401,12 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-angular@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(yaml@2.8.1)': + '@angular-devkit/build-webpack@0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0))(webpack@5.105.0(esbuild@0.25.4))': dependencies: - '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)))(webpack@5.105.0(esbuild@0.25.4)) - '@angular-devkit/core': 19.2.24(chokidar@4.0.3) - '@angular/build': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1) - '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) - '@babel/core': 7.26.10 - '@babel/generator': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/plugin-transform-async-generator-functions': 7.26.8(@babel/core@7.26.10) - '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.26.10) - '@babel/preset-env': 7.26.9(@babel/core@7.26.10) - '@babel/runtime': 7.26.10 - '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0) - '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) - ansi-colors: 4.1.3 - autoprefixer: 10.4.20(postcss@8.5.2) - babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.105.0) - browserslist: 4.27.0 - copy-webpack-plugin: 12.0.2(webpack@5.105.0) - css-loader: 7.1.2(webpack@5.105.0) - esbuild-wasm: 0.25.4 - fast-glob: 3.3.3 - http-proxy-middleware: 3.0.5 - istanbul-lib-instrument: 6.0.3 - jsonc-parser: 3.3.1 - karma-source-map-support: 1.4.0 - less: 4.2.2 - less-loader: 12.2.0(less@4.2.2)(webpack@5.105.0) - license-webpack-plugin: 4.0.2(webpack@5.105.0) - loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.2(webpack@5.105.0) - open: 10.1.0 - ora: 5.4.1 - picomatch: 4.0.4 - piscina: 4.8.0 - postcss: 8.5.2 - postcss-loader: 8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0) - resolve-url-loader: 5.0.0 rxjs: 7.8.1 - sass: 1.85.0 - sass-loader: 16.0.5(sass@1.85.0)(webpack@5.105.0) - semver: 7.7.1 - source-map-loader: 5.0.0(webpack@5.105.0) - source-map-support: 0.5.21 - terser: 5.39.0 - tree-kill: 1.2.2 - tslib: 2.8.1 - typescript: 5.6.3 webpack: 5.105.0(esbuild@0.25.4) - webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) - webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) - webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.105.0) - optionalDependencies: - esbuild: 0.25.4 - ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) - transitivePeerDependencies: - - '@angular/compiler' - - '@rspack/core' - - '@swc/core' - - '@types/node' - - bufferutil - - chokidar - - debug - - html-webpack-plugin - - jiti - - lightningcss - - node-sass - - sass-embedded - - stylus - - sugarss - - supports-color - - tsx - - uglify-js - - utf-8-validate - - vite - - webpack-cli - - yaml - - '@angular-devkit/build-webpack@0.1902.24(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)))(webpack@5.105.0(esbuild@0.25.4))': - dependencies: - '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) - rxjs: 7.8.1 - webpack: 5.105.0(esbuild@0.25.4) - webpack-dev-server: 5.2.2(webpack@5.105.0(esbuild@0.25.4)) + webpack-dev-server: 5.2.2(webpack@5.105.0) transitivePeerDependencies: - chokidar @@ -8467,7 +8437,7 @@ snapshots: '@angular/core': 19.2.20(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 - '@angular/build@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3))(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1)': + '@angular/build@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(@angular/compiler@19.2.20)(@types/node@24.9.2)(chokidar@4.0.3)(jiti@2.6.1)(less@4.2.2)(postcss@8.5.2)(terser@5.39.0)(typescript@5.6.3)(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.24(chokidar@4.0.3) @@ -8501,7 +8471,6 @@ snapshots: optionalDependencies: less: 4.2.2 lmdb: 3.2.6 - ng-packagr: 19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3) postcss: 8.5.2 transitivePeerDependencies: - '@types/node' @@ -8627,6 +8596,12 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.28.5': {} '@babel/core@7.26.10': @@ -10216,7 +10191,7 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@ngtools/webpack@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0)': + '@ngtools/webpack@19.2.24(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4))': dependencies: '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) typescript: 5.6.3 @@ -10495,13 +10470,6 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/plugin-json@6.1.0(rollup@4.59.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - optionalDependencies: - rollup: 4.59.0 - optional: true - '@rollup/pluginutils@5.3.0(rollup@4.59.0)': dependencies: '@types/estree': 1.0.8 @@ -10585,13 +10553,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@rollup/wasm-node@4.52.5': - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - optional: true - '@rushstack/node-core-library@5.7.0(@types/node@24.9.2)': dependencies: ajv: 8.13.0 @@ -10693,26 +10654,26 @@ snapshots: transitivePeerDependencies: - typescript - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) debug: 4.4.3 svelte: 4.2.20 - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)))(svelte@4.2.20)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) debug: 4.4.3 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.21 svelte: 4.2.20 svelte-hmr: 0.16.0(svelte@4.2.20) - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - vitefu: 0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) + vitefu: 0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) transitivePeerDependencies: - supports-color @@ -10787,13 +10748,13 @@ snapshots: '@tanstack/table-core@8.21.3': {} - '@tanstack/vite-config@0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': + '@tanstack/vite-config@0.4.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))': dependencies: rollup-plugin-preserve-directives: 0.4.0(rollup@4.59.0) - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - vite-plugin-dts: 4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) - vite-plugin-externalize-deps: 0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) - vite-tsconfig-paths: 5.1.4(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) + vite-plugin-dts: 4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) + vite-plugin-externalize-deps: 0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) + vite-tsconfig-paths: 5.1.4(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) transitivePeerDependencies: - '@types/node' - rollup @@ -10815,7 +10776,7 @@ snapshots: '@testing-library/dom@10.4.1': dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.29.0 '@babel/runtime': 7.28.4 '@types/aria-query': 5.0.4 aria-query: 5.3.0 @@ -11254,11 +11215,7 @@ snapshots: dependencies: vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) - '@vitejs/plugin-basic-ssl@1.2.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': - dependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - - '@vitejs/plugin-react@4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': + '@vitejs/plugin-react@4.7.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -11266,13 +11223,13 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3))': + '@vitejs/plugin-vue@5.2.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.6.3))': dependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) vue: 3.5.22(typescript@5.6.3) '@vitest/expect@4.1.4': @@ -11284,13 +11241,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1))': + '@vitest/mocker@4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1))': dependencies: '@vitest/spy': 4.1.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) '@vitest/pretty-format@4.1.4': dependencies: @@ -11766,7 +11723,7 @@ snapshots: axobject-query@4.1.0: {} - babel-loader@9.2.1(@babel/core@7.26.10)(webpack@5.105.0): + babel-loader@9.2.1(@babel/core@7.26.10)(webpack@5.105.0(esbuild@0.25.4)): dependencies: '@babel/core': 7.26.10 find-cache-dir: 4.0.0 @@ -12077,18 +12034,12 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@13.1.0: - optional: true - commander@2.20.3: {} comment-parser@1.4.1: {} common-path-prefix@3.0.0: {} - commondir@1.0.1: - optional: true - compare-versions@6.1.1: {} compressible@2.0.18: @@ -12138,7 +12089,7 @@ snapshots: dependencies: is-what: 3.14.1 - copy-webpack-plugin@12.0.2(webpack@5.105.0): + copy-webpack-plugin@12.0.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -12169,7 +12120,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.2(webpack@5.105.0): + css-loader@7.1.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -12276,9 +12227,6 @@ snapshots: dependency-graph@0.11.0: {} - dependency-graph@1.0.0: - optional: true - dequal@2.0.3: {} destroy@1.2.0: {} @@ -12753,13 +12701,6 @@ snapshots: transitivePeerDependencies: - supports-color - find-cache-dir@3.3.2: - dependencies: - commondir: 1.0.1 - make-dir: 3.1.0 - pkg-dir: 4.2.0 - optional: true - find-cache-dir@4.0.0: dependencies: common-path-prefix: 3.0.0 @@ -13118,11 +13059,6 @@ snapshots: ini@5.0.0: {} - injection-js@2.6.1: - dependencies: - tslib: 2.8.1 - optional: true - internal-ip@6.2.0: dependencies: default-gateway: 6.0.3 @@ -13447,7 +13383,7 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.8.3 - less-loader@12.2.0(less@4.2.2)(webpack@5.105.0): + less-loader@12.2.0(less@4.2.2)(webpack@5.105.0(esbuild@0.25.4)): dependencies: less: 4.2.2 optionalDependencies: @@ -13467,27 +13403,12 @@ snapshots: needle: 3.3.1 source-map: 0.6.1 - less@4.4.2: - dependencies: - copy-anything: 2.0.6 - parse-node-version: 1.0.1 - tslib: 2.8.1 - optionalDependencies: - errno: 0.1.8 - graceful-fs: 4.2.11 - image-size: 0.5.5 - make-dir: 2.1.0 - mime: 1.6.0 - needle: 3.3.1 - source-map: 0.6.1 - optional: true - levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.105.0): + license-webpack-plugin@4.0.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: webpack-sources: 3.3.3 optionalDependencies: @@ -13629,11 +13550,6 @@ snapshots: semver: 5.7.2 optional: true - make-dir@3.1.0: - dependencies: - semver: 6.3.1 - optional: true - make-dir@4.0.0: dependencies: semver: 7.7.3 @@ -13711,7 +13627,7 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.2(webpack@5.105.0): + mini-css-extract-plugin@2.9.2(webpack@5.105.0(esbuild@0.25.4)): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 @@ -13849,35 +13765,6 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@19.2.2(@angular/compiler-cli@19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3))(tslib@2.8.1)(typescript@5.6.3): - dependencies: - '@angular/compiler-cli': 19.2.20(@angular/compiler@19.2.20)(typescript@5.6.3) - '@rollup/plugin-json': 6.1.0(rollup@4.59.0) - '@rollup/wasm-node': 4.52.5 - ajv: 8.18.0 - ansi-colors: 4.1.3 - browserslist: 4.28.2 - chokidar: 4.0.3 - commander: 13.1.0 - convert-source-map: 2.0.0 - dependency-graph: 1.0.0 - esbuild: 0.25.12 - fast-glob: 3.3.3 - find-cache-dir: 3.3.2 - injection-js: 2.6.1 - jsonc-parser: 3.3.1 - less: 4.4.2 - ora: 5.4.1 - piscina: 4.9.2 - postcss: 8.5.6 - rxjs: 7.8.2 - sass: 1.93.3 - tslib: 2.8.1 - typescript: 5.6.3 - optionalDependencies: - rollup: 4.59.0 - optional: true - node-addon-api@6.1.0: optional: true @@ -14293,16 +14180,6 @@ snapshots: optionalDependencies: '@napi-rs/nice': 1.1.1 - piscina@4.9.2: - optionalDependencies: - '@napi-rs/nice': 1.1.1 - optional: true - - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - optional: true - pkg-dir@7.0.0: dependencies: find-up: 6.3.0 @@ -14321,7 +14198,7 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-loader@8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0): + postcss-loader@8.1.1(postcss@8.5.2)(typescript@5.6.3)(webpack@5.105.0(esbuild@0.25.4)): dependencies: cosmiconfig: 9.0.0(typescript@5.6.3) jiti: 1.21.7 @@ -14464,6 +14341,16 @@ snapshots: react-refresh@0.17.0: {} + react-virtuoso@4.18.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-window@2.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -14657,7 +14544,7 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@16.0.5(sass@1.85.0)(webpack@5.105.0): + sass-loader@16.0.5(sass@1.85.0)(webpack@5.105.0(esbuild@0.25.4)): dependencies: neo-async: 2.6.2 optionalDependencies: @@ -14672,15 +14559,6 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.1 - sass@1.93.3: - dependencies: - chokidar: 4.0.3 - immutable: 5.1.4 - source-map-js: 1.2.1 - optionalDependencies: - '@parcel/watcher': 2.5.1 - optional: true - sax@1.4.1: optional: true @@ -14926,7 +14804,7 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.105.0): + source-map-loader@5.0.0(webpack@5.105.0(esbuild@0.25.4)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 @@ -15339,7 +15217,15 @@ snapshots: vary@1.1.2: {} - vite-plugin-dts@4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + virtua@0.49.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(solid-js@1.9.10)(svelte@4.2.20)(vue@3.5.22(typescript@5.6.3)): + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + solid-js: 1.9.10 + svelte: 4.2.20 + vue: 3.5.22(typescript@5.6.3) + + vite-plugin-dts@4.2.3(@types/node@24.9.2)(rollup@4.59.0)(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): dependencies: '@microsoft/api-extractor': 7.47.7(@types/node@24.9.2) '@rollup/pluginutils': 5.3.0(rollup@4.59.0) @@ -15352,17 +15238,17 @@ snapshots: magic-string: 0.30.21 typescript: 5.6.3 optionalDependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-externalize-deps@0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + vite-plugin-externalize-deps@0.10.0(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): dependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) - vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): dependencies: '@babel/core': 7.28.5 '@types/babel__core': 7.20.5 @@ -15370,20 +15256,20 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.10 solid-refresh: 0.6.3(solid-js@1.9.10) - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) - vitefu: 1.1.1(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) + vitefu: 1.1.1(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) optionalDependencies: '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color - vite-tsconfig-paths@5.1.4(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.6.3)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.6.3) optionalDependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript @@ -15405,35 +15291,18 @@ snapshots: terser: 5.39.0 yaml: 2.8.1 - vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1): - dependencies: - esbuild: 0.25.12 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - postcss: 8.5.6 - rollup: 4.59.0 - tinyglobby: 0.2.15 + vitefu@0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): optionalDependencies: - '@types/node': 24.9.2 - fsevents: 2.3.3 - jiti: 2.6.1 - less: 4.4.2 - sass: 1.93.3 - terser: 5.39.0 - yaml: 2.8.1 - - vitefu@0.2.5(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): - optionalDependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) - vitefu@1.1.1(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + vitefu@1.1.1(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): optionalDependencies: - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) - vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)): + vitest@4.1.4(@types/node@24.9.2)(jsdom@27.1.0)(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)): dependencies: '@vitest/expect': 4.1.4 - '@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1)) + '@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1)) '@vitest/pretty-format': 4.1.4 '@vitest/runner': 4.1.4 '@vitest/snapshot': 4.1.4 @@ -15450,7 +15319,7 @@ snapshots: tinyexec: 1.1.1 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.4.2)(sass@1.93.3)(terser@5.39.0)(yaml@2.8.1) + vite: 6.4.2(@types/node@24.9.2)(jiti@2.6.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.2 @@ -15523,7 +15392,7 @@ snapshots: webidl-conversions@8.0.0: {} - webpack-dev-middleware@7.4.2(webpack@5.105.0(esbuild@0.25.4)): + webpack-dev-middleware@7.4.2(webpack@5.105.0): dependencies: colorette: 2.0.20 memfs: 4.50.0 @@ -15534,7 +15403,7 @@ snapshots: optionalDependencies: webpack: 5.105.0(esbuild@0.25.4) - webpack-dev-server@5.2.2(webpack@5.105.0(esbuild@0.25.4)): + webpack-dev-server@5.2.2(webpack@5.105.0): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -15562,7 +15431,7 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.105.0(esbuild@0.25.4)) + webpack-dev-middleware: 7.4.2(webpack@5.105.0) ws: 8.18.3 optionalDependencies: webpack: 5.105.0(esbuild@0.25.4) @@ -15580,7 +15449,7 @@ snapshots: webpack-sources@3.3.3: {} - webpack-subresource-integrity@5.1.0(webpack@5.105.0): + webpack-subresource-integrity@5.1.0(webpack@5.105.0(esbuild@0.25.4)): dependencies: typed-assert: 1.0.9 webpack: 5.105.0(esbuild@0.25.4) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 06908ae02..0ed91db03 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -9,6 +9,7 @@ packages: - 'examples/svelte/*' - 'examples/vue/*' - 'examples/lit/*' + - 'benchmarks' allowBuilds: # root dependency From 949180be8adf66ea8428b326db72ebad42d5b4c3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 14:11:06 -0600 Subject: [PATCH 10/10] ci: Version Packages (#1169) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/feat-core-ios-scroll-handling.md | 31 ---- .../feat-core-scroll-to-index-smooth.md | 18 --- .../feat-core-scroll-up-jank-default.md | 18 --- .changeset/feat-core-take-snapshot.md | 24 ---- .../fix-core-elementscache-stale-index.md | 9 -- .changeset/fix-core-measure-and-ios-flush.md | 13 -- .../perf-core-mount-and-measure-storm.md | 37 ----- .../perf-react-virtual-rerender-alloc.md | 9 -- benchmarks/CHANGELOG.md | 8 ++ benchmarks/package.json | 2 +- examples/angular/dynamic/package.json | 2 +- examples/angular/fixed/package.json | 2 +- examples/angular/infinite-scroll/package.json | 2 +- examples/angular/padding/package.json | 2 +- examples/angular/smooth-scroll/package.json | 2 +- examples/angular/sticky/package.json | 2 +- examples/angular/table/package.json | 2 +- examples/angular/variable/package.json | 2 +- examples/angular/window/package.json | 2 +- examples/lit/dynamic/package.json | 4 +- examples/lit/fixed/package.json | 4 +- examples/react/dynamic/package.json | 2 +- examples/react/fixed/package.json | 2 +- examples/react/infinite-scroll/package.json | 2 +- examples/react/padding/package.json | 2 +- examples/react/scroll-padding/package.json | 2 +- examples/react/smooth-scroll/package.json | 2 +- examples/react/sticky/package.json | 2 +- examples/react/table/package.json | 2 +- examples/react/variable/package.json | 2 +- examples/react/window/package.json | 2 +- examples/svelte/dynamic/package.json | 2 +- examples/svelte/fixed/package.json | 2 +- examples/svelte/infinite-scroll/package.json | 2 +- examples/svelte/smooth-scroll/package.json | 2 +- examples/svelte/sticky/package.json | 2 +- examples/svelte/table/package.json | 2 +- examples/vue/dynamic/package.json | 2 +- examples/vue/fixed/package.json | 2 +- examples/vue/infinite-scroll/package.json | 2 +- examples/vue/padding/package.json | 2 +- examples/vue/scroll-padding/package.json | 2 +- examples/vue/smooth-scroll/package.json | 2 +- examples/vue/sticky/package.json | 2 +- examples/vue/table/package.json | 2 +- examples/vue/variable/package.json | 2 +- packages/angular-virtual/CHANGELOG.md | 7 + packages/angular-virtual/package.json | 2 +- packages/lit-virtual/CHANGELOG.md | 7 + packages/lit-virtual/package.json | 2 +- packages/react-virtual/CHANGELOG.md | 12 ++ packages/react-virtual/package.json | 2 +- packages/solid-virtual/CHANGELOG.md | 7 + packages/solid-virtual/package.json | 2 +- packages/svelte-virtual/CHANGELOG.md | 7 + packages/svelte-virtual/package.json | 2 +- packages/virtual-core/CHANGELOG.md | 132 ++++++++++++++++++ packages/virtual-core/package.json | 2 +- packages/vue-virtual/CHANGELOG.md | 7 + packages/vue-virtual/package.json | 2 +- pnpm-lock.yaml | 76 +++++----- 61 files changed, 271 insertions(+), 243 deletions(-) delete mode 100644 .changeset/feat-core-ios-scroll-handling.md delete mode 100644 .changeset/feat-core-scroll-to-index-smooth.md delete mode 100644 .changeset/feat-core-scroll-up-jank-default.md delete mode 100644 .changeset/feat-core-take-snapshot.md delete mode 100644 .changeset/fix-core-elementscache-stale-index.md delete mode 100644 .changeset/fix-core-measure-and-ios-flush.md delete mode 100644 .changeset/perf-core-mount-and-measure-storm.md delete mode 100644 .changeset/perf-react-virtual-rerender-alloc.md create mode 100644 benchmarks/CHANGELOG.md diff --git a/.changeset/feat-core-ios-scroll-handling.md b/.changeset/feat-core-ios-scroll-handling.md deleted file mode 100644 index e95af692f..000000000 --- a/.changeset/feat-core-ios-scroll-handling.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -iOS Safari momentum-scroll handling. Writing `scrollTop` while a finger -is on the screen, during momentum decay, or while the page is in the -elastic-overscroll bounce zone all cancel the in-flight scroll in iOS -WebKit. The virtualizer previously had no iOS-specific handling, which -manifested as the recurring "scroll abruptly stops when content above -resizes" complaints on Safari mobile. - -Adds three layers of protection, default-on, all transparent to -consumers: - -- **Touch event distinction.** A touchstart→touchend window plus a - 150 ms grace timer for the early-momentum phase. Scroll-position - adjustments triggered during any of these states accumulate into a - `_iosDeferredAdjustment` field instead of writing `scrollTop`. -- **Subpixel reconciliation.** When the browser reports back a rounded - `scrollTop` within 1.5 px of a value we just wrote, the virtualizer - prefers the intended value rather than treating the round-trip as a - user scroll. -- **Elastic-overscroll clamp.** The deferred-adjustment flush is skipped - when `scrollTop` is outside `[0, scrollHeight - clientHeight]`, - preventing a snap-back jolt at end-of-bounce. The next in-bounds - scroll event retries. - -Non-iOS code paths are unchanged. iOS detection is SSR-safe and cached -after first call. Bundle cost is ~370 B gzip in the consumer-minified -production build — kept default-on because iOS Safari is a large share -of mobile traffic for the apps that use virtualization heavily. diff --git a/.changeset/feat-core-scroll-to-index-smooth.md b/.changeset/feat-core-scroll-to-index-smooth.md deleted file mode 100644 index 58ec12f19..000000000 --- a/.changeset/feat-core-scroll-to-index-smooth.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@tanstack/virtual-core': patch ---- - -`scrollToIndex(N, { behavior: 'smooth' })` on a dynamic-height list no -longer snaps to `behavior: 'auto'` the moment a measurement shifts the -computed target offset. While the scroll is still more than a viewport -away from the new target, smooth scroll continues with the updated -endpoint; only on the final approach do we fall back to 'auto' for -precise landing. The user-visible effect is one continuous smooth -motion that subtly adjusts its endpoint as measurements arrive, -instead of the prior animation-then-snap pattern. - -Also: once `reconcileScroll` reaches its stable-frames threshold, it -writes the exact target offset one final time. This is a no-op when -`scrollTop` already equals the target (the common case) but corrects -the rare subpixel-rounding case where smooth scroll undershoots by -less than 1 px. diff --git a/.changeset/feat-core-scroll-up-jank-default.md b/.changeset/feat-core-scroll-up-jank-default.md deleted file mode 100644 index bd4879343..000000000 --- a/.changeset/feat-core-scroll-up-jank-default.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -Skip the scroll-position adjustment while the user is scrolling backward -by default. When an above-viewport item resizes during backward scroll -(images load, content reflows, etc.) the prior behavior wrote `scrollTop` -to keep the visible window stable — but on backward scroll that write -fights the user's direction and produces visible "items jump up while I -scroll up" jank. This was the largest single complaint cluster in the -issue tracker (multiple recurring threads spanning years; users had -independently rediscovered the same workaround at least five times). - -Forward-scroll and idle (mount-time) adjustments still fire as before -to preserve visual stability of the visible window. Consumers who want -the old behavior — adjusting on every above-viewport resize regardless -of direction — can supply `shouldAdjustScrollPositionOnItemSizeChange` -which is checked before the default branch. diff --git a/.changeset/feat-core-take-snapshot.md b/.changeset/feat-core-take-snapshot.md deleted file mode 100644 index c185d8714..000000000 --- a/.changeset/feat-core-take-snapshot.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -Add `takeSnapshot()` instance method for scroll-restoration round-trips. -Returns the currently-measured items as plain `VirtualItem` objects; -pair with the current `scrollOffset` to persist scroll position across -remounts (route navigation, list-view modals, etc.). The result feeds -back through the existing `initialMeasurementsCache` option: - -```tsx -const snapshot = virtualizer.takeSnapshot() -const offset = virtualizer.scrollOffset -// later, on remount: -useVirtualizer({ - // … - initialMeasurementsCache: snapshot, - initialOffset: offset, -}) -``` - -Closes the gap to virtua's `takeCacheSnapshot()` and react-virtuoso's -`getState`. Only items actually rendered (and thus measured) are -included; unmeasured items fall back to `estimateSize` on restore. diff --git a/.changeset/fix-core-elementscache-stale-index.md b/.changeset/fix-core-elementscache-stale-index.md deleted file mode 100644 index 1edd76ecd..000000000 --- a/.changeset/fix-core-elementscache-stale-index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@tanstack/virtual-core': patch ---- - -Don't call `getItemKey` with a possibly-stale index when cleaning up -`elementsCache` for a disconnected node. The cleanup now finds the -matching entry by node identity, so removing items from the end of -the list while a `ResizeObserver` still has the now-detached node -queued no longer throws (regression of #1148). diff --git a/.changeset/fix-core-measure-and-ios-flush.md b/.changeset/fix-core-measure-and-ios-flush.md deleted file mode 100644 index a6009e1db..000000000 --- a/.changeset/fix-core-measure-and-ios-flush.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@tanstack/virtual-core': patch ---- - -Two correctness fixes in the new code: - -- `measure()` now resets `pendingMin` so a prior `resizeItem()` that left - it non-null can't preserve stale `measurementsCache` entries before that - index. The next rebuild is guaranteed to start at 0. -- The iOS deferred-adjustment flush now rolls its accumulated delta into - `scrollAdjustments`. Without this, a resize landing between the flush - and the resulting scroll event would compute the next correction from - the stale pre-flush offset. diff --git a/.changeset/perf-core-mount-and-measure-storm.md b/.changeset/perf-core-mount-and-measure-storm.md deleted file mode 100644 index 7aafb5747..000000000 --- a/.changeset/perf-core-mount-and-measure-storm.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -Mount-time, measurement, and memory rewrite for huge lists. The hot path -through `getMeasurements()` no longer allocates a `VirtualItem` object per -index for single-lane lists; instead it fills a `Float64Array` of -start/size pairs and materializes `VirtualItem` objects lazily through a -`Proxy`-backed view when consumers index into them. Internal hot paths -(`calculateRange`, `getVirtualItemForOffset`, `getTotalSize`, `resizeItem`) -read directly from the typed-array storage to avoid the Proxy. - -Also collapses a chain of smaller hotspots discovered in an audit pass: -the per-resize `Map` clone in `resizeItem`, the `Object.entries+delete` -deopt in `setOptions`, the `Math.min(...pendingMeasuredCacheIndexes)` -spread, the `defaultRangeExtractor` `push` growth pattern, the eager -`measurementsCache` reference invalidation, and the leaked `elementsCache` -entries when a `ResizeObserver` fires for a node React already replaced. - -Headline impact (measured against actual `Virtualizer` instances with -vitest bench): - -- Cold mount @ 100k items: ~2.5 ms → ~0.5 ms (4.7×) -- Cold mount @ 500k items: ~14 ms → ~2.7 ms (5.2×) -- `resizeItem` storm of 10,000 measurements + final `getMeasurements`: - ~1.9 s → ~1.3 ms (≈1382×) — this was the dominant `Map`-clone bug -- `setOptions` × 10,000 calls (React-render-storm proxy): ~14 ms → ~1.3 ms - (11×) - -The lanes>1 path keeps the previous eager allocation (lane assignment is -order-dependent and harder to defer cleanly); behavior is unchanged -there. - -No public API change. `measurementsCache` is still an -`Array`-shaped value supporting `[i]`, `.length`, iteration, -etc. Internal consumers that previously read fields off `VirtualItem` -objects continue to do so transparently. diff --git a/.changeset/perf-react-virtual-rerender-alloc.md b/.changeset/perf-react-virtual-rerender-alloc.md deleted file mode 100644 index fd012e509..000000000 --- a/.changeset/perf-react-virtual-rerender-alloc.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@tanstack/react-virtual': patch ---- - -Replace the `useReducer(() => ({}), {})` force-rerender pattern with an -incrementing number counter. Same semantics (every dispatch changes the -reducer state, forcing a render); zero per-dispatch object allocation. -Trivial individual cost, but eliminates one steady-state GC source on -scroll-heavy apps. diff --git a/benchmarks/CHANGELOG.md b/benchmarks/CHANGELOG.md new file mode 100644 index 000000000..1a027e3fd --- /dev/null +++ b/benchmarks/CHANGELOG.md @@ -0,0 +1,8 @@ +# @tanstack/virtual-benchmarks + +## 0.0.1 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/react-virtual@3.13.25 diff --git a/benchmarks/package.json b/benchmarks/package.json index 96638d6c7..efc24d012 100644 --- a/benchmarks/package.json +++ b/benchmarks/package.json @@ -1,7 +1,7 @@ { "name": "@tanstack/virtual-benchmarks", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { "dev": "vite", diff --git a/examples/angular/dynamic/package.json b/examples/angular/dynamic/package.json index 802f61bb7..85db0193d 100644 --- a/examples/angular/dynamic/package.json +++ b/examples/angular/dynamic/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/fixed/package.json b/examples/angular/fixed/package.json index 1dbca6764..3f0f0bb99 100644 --- a/examples/angular/fixed/package.json +++ b/examples/angular/fixed/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/infinite-scroll/package.json b/examples/angular/infinite-scroll/package.json index ede25efdd..e5b8b9b69 100644 --- a/examples/angular/infinite-scroll/package.json +++ b/examples/angular/infinite-scroll/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@tanstack/angular-query-experimental": "5.80.7", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/padding/package.json b/examples/angular/padding/package.json index a8cb1b742..dd82276a9 100644 --- a/examples/angular/padding/package.json +++ b/examples/angular/padding/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/smooth-scroll/package.json b/examples/angular/smooth-scroll/package.json index 1b033a33e..c03af4296 100644 --- a/examples/angular/smooth-scroll/package.json +++ b/examples/angular/smooth-scroll/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/sticky/package.json b/examples/angular/sticky/package.json index 642e5f3f6..ac48a8fb5 100644 --- a/examples/angular/sticky/package.json +++ b/examples/angular/sticky/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/table/package.json b/examples/angular/table/package.json index 6d53b35e3..bcb63c2e4 100644 --- a/examples/angular/table/package.json +++ b/examples/angular/table/package.json @@ -19,7 +19,7 @@ "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-table": "8.21.3", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/variable/package.json b/examples/angular/variable/package.json index 3440f6bae..75cd2c3d0 100644 --- a/examples/angular/variable/package.json +++ b/examples/angular/variable/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/window/package.json b/examples/angular/window/package.json index 7a71f362d..86f339baf 100644 --- a/examples/angular/window/package.json +++ b/examples/angular/window/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/lit/dynamic/package.json b/examples/lit/dynamic/package.json index 26e226a79..485af5b01 100644 --- a/examples/lit/dynamic/package.json +++ b/examples/lit/dynamic/package.json @@ -9,8 +9,8 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/lit-virtual": "^3.13.25", - "@tanstack/virtual-core": "^3.14.0", + "@tanstack/lit-virtual": "^3.13.26", + "@tanstack/virtual-core": "^3.15.0", "lit": "^3.3.0" }, "devDependencies": { diff --git a/examples/lit/fixed/package.json b/examples/lit/fixed/package.json index 3dea50249..ab3f85048 100644 --- a/examples/lit/fixed/package.json +++ b/examples/lit/fixed/package.json @@ -9,8 +9,8 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/lit-virtual": "^3.13.25", - "@tanstack/virtual-core": "^3.14.0", + "@tanstack/lit-virtual": "^3.13.26", + "@tanstack/virtual-core": "^3.15.0", "lit": "^3.3.0" }, "devDependencies": { diff --git a/examples/react/dynamic/package.json b/examples/react/dynamic/package.json index c2f8ab1bc..87ded4099 100644 --- a/examples/react/dynamic/package.json +++ b/examples/react/dynamic/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/fixed/package.json b/examples/react/fixed/package.json index 652871821..af92e2f54 100644 --- a/examples/react/fixed/package.json +++ b/examples/react/fixed/package.json @@ -8,7 +8,7 @@ "serve": "vite preview" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/infinite-scroll/package.json b/examples/react/infinite-scroll/package.json index 2f541b45e..427a2111f 100644 --- a/examples/react/infinite-scroll/package.json +++ b/examples/react/infinite-scroll/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@tanstack/react-query": "^5.80.7", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/padding/package.json b/examples/react/padding/package.json index a9e4b904e..4a27b3dc3 100644 --- a/examples/react/padding/package.json +++ b/examples/react/padding/package.json @@ -9,7 +9,7 @@ "start": "vite" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/scroll-padding/package.json b/examples/react/scroll-padding/package.json index cfa93d193..fcce013b7 100644 --- a/examples/react/scroll-padding/package.json +++ b/examples/react/scroll-padding/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@react-hookz/web": "^25.1.1", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/smooth-scroll/package.json b/examples/react/smooth-scroll/package.json index eb9ca3218..c56afcf20 100644 --- a/examples/react/smooth-scroll/package.json +++ b/examples/react/smooth-scroll/package.json @@ -9,7 +9,7 @@ "start": "vite" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/sticky/package.json b/examples/react/sticky/package.json index b8c14583e..41e7267d4 100644 --- a/examples/react/sticky/package.json +++ b/examples/react/sticky/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "lodash": "^4.17.21", "react": "^18.3.1", "react-dom": "^18.3.1" diff --git a/examples/react/table/package.json b/examples/react/table/package.json index 7a451f38c..925d5e94e 100644 --- a/examples/react/table/package.json +++ b/examples/react/table/package.json @@ -11,7 +11,7 @@ "dependencies": { "@faker-js/faker": "^8.4.1", "@tanstack/react-table": "^8.21.3", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/variable/package.json b/examples/react/variable/package.json index 78feb0406..46ba91a98 100644 --- a/examples/react/variable/package.json +++ b/examples/react/variable/package.json @@ -9,7 +9,7 @@ "start": "vite" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/window/package.json b/examples/react/window/package.json index e74ee5187..c1a78d43b 100644 --- a/examples/react/window/package.json +++ b/examples/react/window/package.json @@ -8,7 +8,7 @@ "serve": "vite preview" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/svelte/dynamic/package.json b/examples/svelte/dynamic/package.json index 9e2c27e78..ffe7ade48 100644 --- a/examples/svelte/dynamic/package.json +++ b/examples/svelte/dynamic/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/fixed/package.json b/examples/svelte/fixed/package.json index 59fe40d8c..06e644ce9 100644 --- a/examples/svelte/fixed/package.json +++ b/examples/svelte/fixed/package.json @@ -9,7 +9,7 @@ "check": "svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/infinite-scroll/package.json b/examples/svelte/infinite-scroll/package.json index 8970550f8..57130e71c 100644 --- a/examples/svelte/infinite-scroll/package.json +++ b/examples/svelte/infinite-scroll/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@tanstack/svelte-query": "^5.80.7", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/smooth-scroll/package.json b/examples/svelte/smooth-scroll/package.json index 2b4689b3e..d6766b75d 100644 --- a/examples/svelte/smooth-scroll/package.json +++ b/examples/svelte/smooth-scroll/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/sticky/package.json b/examples/svelte/sticky/package.json index 742c8c9e9..c82393be5 100644 --- a/examples/svelte/sticky/package.json +++ b/examples/svelte/sticky/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/svelte-virtual": "^3.13.24", + "@tanstack/svelte-virtual": "^3.13.25", "lodash": "^4.17.21" }, "devDependencies": { diff --git a/examples/svelte/table/package.json b/examples/svelte/table/package.json index ce43eb5e1..e13197b19 100644 --- a/examples/svelte/table/package.json +++ b/examples/svelte/table/package.json @@ -11,7 +11,7 @@ "dependencies": { "@faker-js/faker": "^8.4.1", "@tanstack/svelte-table": "^8.21.3", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/vue/dynamic/package.json b/examples/vue/dynamic/package.json index b208d1fd1..cf72a3b1d 100644 --- a/examples/vue/dynamic/package.json +++ b/examples/vue/dynamic/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/fixed/package.json b/examples/vue/fixed/package.json index 98116db25..d0abefcd7 100644 --- a/examples/vue/fixed/package.json +++ b/examples/vue/fixed/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/infinite-scroll/package.json b/examples/vue/infinite-scroll/package.json index 1c799f0bd..8c1f5fb6d 100644 --- a/examples/vue/infinite-scroll/package.json +++ b/examples/vue/infinite-scroll/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@tanstack/vue-query": "^5.80.7", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/padding/package.json b/examples/vue/padding/package.json index 44c968273..c55fe2ef3 100644 --- a/examples/vue/padding/package.json +++ b/examples/vue/padding/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/scroll-padding/package.json b/examples/vue/scroll-padding/package.json index 828113304..585f8031d 100644 --- a/examples/vue/scroll-padding/package.json +++ b/examples/vue/scroll-padding/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "@vueuse/core": "^12.8.2", "vue": "^3.5.16" }, diff --git a/examples/vue/smooth-scroll/package.json b/examples/vue/smooth-scroll/package.json index 2d9e16c1b..d67a8bbf0 100644 --- a/examples/vue/smooth-scroll/package.json +++ b/examples/vue/smooth-scroll/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/sticky/package.json b/examples/vue/sticky/package.json index 37a46bf12..3c0013d1a 100644 --- a/examples/vue/sticky/package.json +++ b/examples/vue/sticky/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "lodash": "^4.17.21", "vue": "^3.5.16" }, diff --git a/examples/vue/table/package.json b/examples/vue/table/package.json index 1b097983d..0776776b1 100644 --- a/examples/vue/table/package.json +++ b/examples/vue/table/package.json @@ -10,7 +10,7 @@ "dependencies": { "@faker-js/faker": "^8.4.1", "@tanstack/vue-table": "^8.21.3", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/variable/package.json b/examples/vue/variable/package.json index 3539f7c9e..4f5620029 100644 --- a/examples/vue/variable/package.json +++ b/examples/vue/variable/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/packages/angular-virtual/CHANGELOG.md b/packages/angular-virtual/CHANGELOG.md index 397ff67dd..6468d502e 100644 --- a/packages/angular-virtual/CHANGELOG.md +++ b/packages/angular-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/angular-virtual +## 5.0.1 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 5.0.0 ### Major Changes diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index fecdc71fe..8273490e6 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/angular-virtual", - "version": "5.0.0", + "version": "5.0.1", "description": "Headless UI for virtualizing scrollable elements in Angular", "author": "Garrett Darnell", "license": "MIT", diff --git a/packages/lit-virtual/CHANGELOG.md b/packages/lit-virtual/CHANGELOG.md index cdf1fac8e..2a20701d5 100644 --- a/packages/lit-virtual/CHANGELOG.md +++ b/packages/lit-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/lit-virtual +## 3.13.26 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.25 ### Patch Changes diff --git a/packages/lit-virtual/package.json b/packages/lit-virtual/package.json index b1afa1209..825e32902 100644 --- a/packages/lit-virtual/package.json +++ b/packages/lit-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/lit-virtual", - "version": "3.13.25", + "version": "3.13.26", "description": "Headless UI for virtualizing scrollable elements in Lit", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/react-virtual/CHANGELOG.md b/packages/react-virtual/CHANGELOG.md index 3cb1d2a46..1fb8189c4 100644 --- a/packages/react-virtual/CHANGELOG.md +++ b/packages/react-virtual/CHANGELOG.md @@ -1,5 +1,17 @@ # @tanstack/react-virtual +## 3.13.25 + +### Patch Changes + +- Replace the `useReducer(() => ({}), {})` force-rerender pattern with an ([#1168](https://github.com/TanStack/virtual/pull/1168)) + incrementing number counter. Same semantics (every dispatch changes the + reducer state, forcing a render); zero per-dispatch object allocation. + Trivial individual cost, but eliminates one steady-state GC source on + scroll-heavy apps. +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/react-virtual/package.json b/packages/react-virtual/package.json index 096f654aa..0e867e077 100644 --- a/packages/react-virtual/package.json +++ b/packages/react-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in React", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/solid-virtual/CHANGELOG.md b/packages/solid-virtual/CHANGELOG.md index 676902a22..866442c94 100644 --- a/packages/solid-virtual/CHANGELOG.md +++ b/packages/solid-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/solid-virtual +## 3.13.25 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/solid-virtual/package.json b/packages/solid-virtual/package.json index ba884dfec..75b8351b1 100644 --- a/packages/solid-virtual/package.json +++ b/packages/solid-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in Solid", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/svelte-virtual/CHANGELOG.md b/packages/svelte-virtual/CHANGELOG.md index a81b06b48..7b05ae82c 100644 --- a/packages/svelte-virtual/CHANGELOG.md +++ b/packages/svelte-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/svelte-virtual +## 3.13.25 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/svelte-virtual/package.json b/packages/svelte-virtual/package.json index f6fdefb76..993bb06ea 100644 --- a/packages/svelte-virtual/package.json +++ b/packages/svelte-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in Svelte", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/virtual-core/CHANGELOG.md b/packages/virtual-core/CHANGELOG.md index dafdafe4f..f812e332b 100644 --- a/packages/virtual-core/CHANGELOG.md +++ b/packages/virtual-core/CHANGELOG.md @@ -1,5 +1,137 @@ # @tanstack/virtual-core +## 3.15.0 + +### Minor Changes + +- iOS Safari momentum-scroll handling. Writing `scrollTop` while a finger ([#1168](https://github.com/TanStack/virtual/pull/1168)) + is on the screen, during momentum decay, or while the page is in the + elastic-overscroll bounce zone all cancel the in-flight scroll in iOS + WebKit. The virtualizer previously had no iOS-specific handling, which + manifested as the recurring "scroll abruptly stops when content above + resizes" complaints on Safari mobile. + + Adds three layers of protection, default-on, all transparent to + consumers: + - **Touch event distinction.** A touchstart→touchend window plus a + 150 ms grace timer for the early-momentum phase. Scroll-position + adjustments triggered during any of these states accumulate into a + `_iosDeferredAdjustment` field instead of writing `scrollTop`. + - **Subpixel reconciliation.** When the browser reports back a rounded + `scrollTop` within 1.5 px of a value we just wrote, the virtualizer + prefers the intended value rather than treating the round-trip as a + user scroll. + - **Elastic-overscroll clamp.** The deferred-adjustment flush is skipped + when `scrollTop` is outside `[0, scrollHeight - clientHeight]`, + preventing a snap-back jolt at end-of-bounce. The next in-bounds + scroll event retries. + + Non-iOS code paths are unchanged. iOS detection is SSR-safe and cached + after first call. Bundle cost is ~370 B gzip in the consumer-minified + production build — kept default-on because iOS Safari is a large share + of mobile traffic for the apps that use virtualization heavily. + +- Skip the scroll-position adjustment while the user is scrolling backward ([#1168](https://github.com/TanStack/virtual/pull/1168)) + by default. When an above-viewport item resizes during backward scroll + (images load, content reflows, etc.) the prior behavior wrote `scrollTop` + to keep the visible window stable — but on backward scroll that write + fights the user's direction and produces visible "items jump up while I + scroll up" jank. This was the largest single complaint cluster in the + issue tracker (multiple recurring threads spanning years; users had + independently rediscovered the same workaround at least five times). + + Forward-scroll and idle (mount-time) adjustments still fire as before + to preserve visual stability of the visible window. Consumers who want + the old behavior — adjusting on every above-viewport resize regardless + of direction — can supply `shouldAdjustScrollPositionOnItemSizeChange` + which is checked before the default branch. + +- Add `takeSnapshot()` instance method for scroll-restoration round-trips. ([#1168](https://github.com/TanStack/virtual/pull/1168)) + Returns the currently-measured items as plain `VirtualItem` objects; + pair with the current `scrollOffset` to persist scroll position across + remounts (route navigation, list-view modals, etc.). The result feeds + back through the existing `initialMeasurementsCache` option: + + ```tsx + const snapshot = virtualizer.takeSnapshot() + const offset = virtualizer.scrollOffset + // later, on remount: + useVirtualizer({ + // … + initialMeasurementsCache: snapshot, + initialOffset: offset, + }) + ``` + + Closes the gap to virtua's `takeCacheSnapshot()` and react-virtuoso's + `getState`. Only items actually rendered (and thus measured) are + included; unmeasured items fall back to `estimateSize` on restore. + +- Mount-time, measurement, and memory rewrite for huge lists. The hot path ([#1168](https://github.com/TanStack/virtual/pull/1168)) + through `getMeasurements()` no longer allocates a `VirtualItem` object per + index for single-lane lists; instead it fills a `Float64Array` of + start/size pairs and materializes `VirtualItem` objects lazily through a + `Proxy`-backed view when consumers index into them. Internal hot paths + (`calculateRange`, `getVirtualItemForOffset`, `getTotalSize`, `resizeItem`) + read directly from the typed-array storage to avoid the Proxy. + + Also collapses a chain of smaller hotspots discovered in an audit pass: + the per-resize `Map` clone in `resizeItem`, the `Object.entries+delete` + deopt in `setOptions`, the `Math.min(...pendingMeasuredCacheIndexes)` + spread, the `defaultRangeExtractor` `push` growth pattern, the eager + `measurementsCache` reference invalidation, and the leaked `elementsCache` + entries when a `ResizeObserver` fires for a node React already replaced. + + Headline impact (measured against actual `Virtualizer` instances with + vitest bench): + - Cold mount @ 100k items: ~2.5 ms → ~0.5 ms (4.7×) + - Cold mount @ 500k items: ~14 ms → ~2.7 ms (5.2×) + - `resizeItem` storm of 10,000 measurements + final `getMeasurements`: + ~1.9 s → ~1.3 ms (≈1382×) — this was the dominant `Map`-clone bug + - `setOptions` × 10,000 calls (React-render-storm proxy): ~14 ms → ~1.3 ms + (11×) + + The lanes>1 path keeps the previous eager allocation (lane assignment is + order-dependent and harder to defer cleanly); behavior is unchanged + there. + + No public API change. `measurementsCache` is still an + `Array`-shaped value supporting `[i]`, `.length`, iteration, + etc. Internal consumers that previously read fields off `VirtualItem` + objects continue to do so transparently. + +### Patch Changes + +- `scrollToIndex(N, { behavior: 'smooth' })` on a dynamic-height list no ([#1168](https://github.com/TanStack/virtual/pull/1168)) + longer snaps to `behavior: 'auto'` the moment a measurement shifts the + computed target offset. While the scroll is still more than a viewport + away from the new target, smooth scroll continues with the updated + endpoint; only on the final approach do we fall back to 'auto' for + precise landing. The user-visible effect is one continuous smooth + motion that subtly adjusts its endpoint as measurements arrive, + instead of the prior animation-then-snap pattern. + + Also: once `reconcileScroll` reaches its stable-frames threshold, it + writes the exact target offset one final time. This is a no-op when + `scrollTop` already equals the target (the common case) but corrects + the rare subpixel-rounding case where smooth scroll undershoots by + less than 1 px. + +- Don't call `getItemKey` with a possibly-stale index when cleaning up ([#1168](https://github.com/TanStack/virtual/pull/1168)) + `elementsCache` for a disconnected node. The cleanup now finds the + matching entry by node identity, so removing items from the end of + the list while a `ResizeObserver` still has the now-detached node + queued no longer throws (regression of #1148). + +- Two correctness fixes in the new code: ([#1168](https://github.com/TanStack/virtual/pull/1168)) + - `measure()` now resets `pendingMin` so a prior `resizeItem()` that left + it non-null can't preserve stale `measurementsCache` entries before that + index. The next rebuild is guaranteed to start at 0. + - The iOS deferred-adjustment flush now rolls its accumulated delta into + `scrollAdjustments`. Without this, a resize landing between the flush + and the resulting scroll event would compute the next correction from + the stale pre-flush offset. + ## 3.14.0 ### Minor Changes diff --git a/packages/virtual-core/package.json b/packages/virtual-core/package.json index 98e97e4ec..603a65c76 100644 --- a/packages/virtual-core/package.json +++ b/packages/virtual-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/virtual-core", - "version": "3.14.0", + "version": "3.15.0", "description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/vue-virtual/CHANGELOG.md b/packages/vue-virtual/CHANGELOG.md index 526efddc8..5a0a8b227 100644 --- a/packages/vue-virtual/CHANGELOG.md +++ b/packages/vue-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/vue-virtual +## 3.13.25 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/vue-virtual/package.json b/packages/vue-virtual/package.json index f57a1b391..060f17da9 100644 --- a/packages/vue-virtual/package.json +++ b/packages/vue-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/vue-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in Vue", "author": "Tanner Linsley", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e19d5ffe2..415ad7695 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -142,7 +142,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -194,7 +194,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -249,7 +249,7 @@ importers: specifier: 5.80.7 version: 5.80.7(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -301,7 +301,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -353,7 +353,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -408,7 +408,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -466,7 +466,7 @@ importers: specifier: 8.21.3 version: 8.21.3(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -518,7 +518,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -570,7 +570,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -601,10 +601,10 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/lit-virtual': - specifier: ^3.13.25 + specifier: ^3.13.26 version: link:../../../packages/lit-virtual '@tanstack/virtual-core': - specifier: ^3.14.0 + specifier: ^3.15.0 version: link:../../../packages/virtual-core lit: specifier: ^3.3.0 @@ -626,10 +626,10 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/lit-virtual': - specifier: ^3.13.25 + specifier: ^3.13.26 version: link:../../../packages/lit-virtual '@tanstack/virtual-core': - specifier: ^3.14.0 + specifier: ^3.15.0 version: link:../../../packages/virtual-core lit: specifier: ^3.3.0 @@ -651,7 +651,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -682,7 +682,7 @@ importers: examples/react/fixed: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -716,7 +716,7 @@ importers: specifier: ^5.80.7 version: 5.90.5(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -741,7 +741,7 @@ importers: examples/react/padding: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -769,7 +769,7 @@ importers: specifier: ^25.1.1 version: 25.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -794,7 +794,7 @@ importers: examples/react/smooth-scroll: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -822,7 +822,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual lodash: specifier: ^4.17.21 @@ -859,7 +859,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -884,7 +884,7 @@ importers: examples/react/variable: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -909,7 +909,7 @@ importers: examples/react/window: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -943,7 +943,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -971,7 +971,7 @@ importers: examples/svelte/fixed: dependencies: '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1002,7 +1002,7 @@ importers: specifier: ^5.80.7 version: 5.90.2(svelte@4.2.20) '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1033,7 +1033,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1064,7 +1064,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual lodash: specifier: ^4.17.21 @@ -1101,7 +1101,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(svelte@4.2.20) '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1132,7 +1132,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1157,7 +1157,7 @@ importers: examples/vue/fixed: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1185,7 +1185,7 @@ importers: specifier: ^5.80.7 version: 5.90.5(vue@3.5.22(typescript@5.6.3)) '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1210,7 +1210,7 @@ importers: examples/vue/padding: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1235,7 +1235,7 @@ importers: examples/vue/scroll-padding: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual '@vueuse/core': specifier: ^12.8.2 @@ -1263,7 +1263,7 @@ importers: examples/vue/smooth-scroll: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1291,7 +1291,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual lodash: specifier: ^4.17.21 @@ -1328,7 +1328,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(vue@3.5.22(typescript@5.6.3)) '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1353,7 +1353,7 @@ importers: examples/vue/variable: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16
- - - - - CodeRabbit - - + + + + + CodeRabbit + + + - - - - Cloudflare - + + + + Cloudflare +