diff --git a/examples/preact/basic-external-atoms/index.html b/examples/preact/basic-external-atoms/index.html
index 88776ec7ae..fff0f71352 100644
--- a/examples/preact/basic-external-atoms/index.html
+++ b/examples/preact/basic-external-atoms/index.html
@@ -4,7 +4,6 @@
-
+ onInput={(e) =>
table.setGlobalFilter((e.target as HTMLInputElement).value)
}
className="summary-panel"
@@ -363,7 +363,7 @@ function Filter({
+ onInput={(e) =>
column.setFilterValue((old: any) => [
(e.target as HTMLInputElement).value,
old?.[1],
@@ -375,7 +375,7 @@ function Filter({
+ onInput={(e) =>
column.setFilterValue((old: any) => [
old?.[0],
(e.target as HTMLInputElement).value,
@@ -389,7 +389,7 @@ function Filter({
+ onInput={(e) =>
column.setFilterValue((e.target as HTMLInputElement).value)
}
placeholder={`Search...`}
diff --git a/examples/preact/sorting/index.html b/examples/preact/sorting/index.html
index 88776ec7ae..fff0f71352 100644
--- a/examples/preact/sorting/index.html
+++ b/examples/preact/sorting/index.html
@@ -4,7 +4,6 @@
-
Vite + Preact
diff --git a/examples/preact/sub-components/index.html b/examples/preact/sub-components/index.html
index 88776ec7ae..fff0f71352 100644
--- a/examples/preact/sub-components/index.html
+++ b/examples/preact/sub-components/index.html
@@ -4,7 +4,6 @@
-
Vite + Preact
diff --git a/examples/preact/with-tanstack-query/index.html b/examples/preact/with-tanstack-query/index.html
index 88776ec7ae..fff0f71352 100644
--- a/examples/preact/with-tanstack-query/index.html
+++ b/examples/preact/with-tanstack-query/index.html
@@ -4,7 +4,6 @@
-
Vite + Preact
diff --git a/examples/react/mantine-react-table/package.json b/examples/react/mantine-react-table/package.json
index d1bf583467..575ff33e08 100644
--- a/examples/react/mantine-react-table/package.json
+++ b/examples/react/mantine-react-table/package.json
@@ -20,7 +20,7 @@
"@tanstack/react-table": "^9.0.0-alpha.41",
"@tanstack/react-virtual": "^3.13.24",
"clsx": "^2.1.1",
- "dayjs": "^1.11.13",
+ "dayjs": "^1.11.20",
"react": "^19.2.5",
"react-dom": "^19.2.5"
},
diff --git a/examples/react/with-tanstack-form/package.json b/examples/react/with-tanstack-form/package.json
index 0061549869..2f8059b016 100644
--- a/examples/react/with-tanstack-form/package.json
+++ b/examples/react/with-tanstack-form/package.json
@@ -15,7 +15,7 @@
"@tanstack/react-table": "^9.0.0-alpha.41",
"react": "^19.2.5",
"react-dom": "^19.2.5",
- "zod": "^4.4.1"
+ "zod": "^4.4.2"
},
"devDependencies": {
"@rolldown/plugin-babel": "^0.2.3",
diff --git a/examples/react/with-tanstack-router/package.json b/examples/react/with-tanstack-router/package.json
index 0f3faa70cb..b921d08b19 100644
--- a/examples/react/with-tanstack-router/package.json
+++ b/examples/react/with-tanstack-router/package.json
@@ -20,7 +20,7 @@
"@faker-js/faker": "^10.4.0",
"@rolldown/plugin-babel": "^0.2.3",
"@rollup/plugin-replace": "^6.0.3",
- "@tanstack/router-vite-plugin": "^1.166.46",
+ "@tanstack/router-vite-plugin": "^1.166.47",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
diff --git a/examples/solid/with-tanstack-form/package.json b/examples/solid/with-tanstack-form/package.json
index 52df05c4a4..70894aed0f 100644
--- a/examples/solid/with-tanstack-form/package.json
+++ b/examples/solid/with-tanstack-form/package.json
@@ -19,6 +19,6 @@
"@tanstack/solid-form": "^1.29.1",
"@tanstack/solid-table": "^9.0.0-alpha.41",
"solid-js": "^1.9.12",
- "zod": "^4.4.1"
+ "zod": "^4.4.2"
}
}
diff --git a/examples/solid/with-tanstack-router/package.json b/examples/solid/with-tanstack-router/package.json
index 65da14580d..bd61c17805 100644
--- a/examples/solid/with-tanstack-router/package.json
+++ b/examples/solid/with-tanstack-router/package.json
@@ -11,7 +11,7 @@
"license": "MIT",
"devDependencies": {
"@faker-js/faker": "^10.4.0",
- "@tanstack/router-vite-plugin": "^1.166.46",
+ "@tanstack/router-vite-plugin": "^1.166.47",
"typescript": "6.0.3",
"vite": "^8.0.10",
"vite-plugin-solid": "^2.11.12"
diff --git a/examples/svelte/with-tanstack-form/package.json b/examples/svelte/with-tanstack-form/package.json
index 83a8e9aa38..bf5828ee6c 100644
--- a/examples/svelte/with-tanstack-form/package.json
+++ b/examples/svelte/with-tanstack-form/package.json
@@ -23,6 +23,6 @@
"@tanstack/form-core": "^1.29.1",
"@tanstack/svelte-form": "^1.29.1",
"@tanstack/svelte-table": "^9.0.0-alpha.41",
- "zod": "^4.4.1"
+ "zod": "^4.4.2"
}
}
diff --git a/examples/vue/with-tanstack-form/package.json b/examples/vue/with-tanstack-form/package.json
index 2864758c5f..ca707f2b3e 100644
--- a/examples/vue/with-tanstack-form/package.json
+++ b/examples/vue/with-tanstack-form/package.json
@@ -13,7 +13,7 @@
"@tanstack/vue-form": "^1.29.1",
"@tanstack/vue-table": "^9.0.0-alpha.41",
"vue": "^3.5.33",
- "zod": "^4.4.1"
+ "zod": "^4.4.2"
},
"devDependencies": {
"@types/node": "^25.6.0",
diff --git a/packages/angular-table/package.json b/packages/angular-table/package.json
index db2ed980a3..995706d312 100644
--- a/packages/angular-table/package.json
+++ b/packages/angular-table/package.json
@@ -55,7 +55,6 @@
"test:build": "publint --strict",
"test:eslint": "eslint ./src",
"test:lib": "vitest",
- "test:benchmark": "vitest bench",
"test:lib:dev": "vitest --watch",
"test:types": "tsc && vitest --typecheck"
},
diff --git a/packages/angular-table/src/helpers/createTableHook.ts b/packages/angular-table/src/helpers/createTableHook.ts
index f6c278655c..0d1ab14097 100644
--- a/packages/angular-table/src/helpers/createTableHook.ts
+++ b/packages/angular-table/src/helpers/createTableHook.ts
@@ -446,8 +446,11 @@ export function createTableHook<
const options = {
...defaultTableOptions,
...tableOptions(),
+ _features: {
+ ...defaultTableOptions._features,
+ appTableFeatures,
+ },
} as TableOptions
- options._features = { ...options._features, appTableFeatures }
return options
}, selector) as AngularTable
}
diff --git a/packages/angular-table/src/injectTable.ts b/packages/angular-table/src/injectTable.ts
index 06a2bd6531..4a12ee11fe 100644
--- a/packages/angular-table/src/injectTable.ts
+++ b/packages/angular-table/src/injectTable.ts
@@ -4,15 +4,11 @@ import {
computed,
effect,
inject,
- signal,
untracked,
} from '@angular/core'
-import {
- constructReactivityFeature,
- constructTable,
-} from '@tanstack/table-core'
-import { injectSelector } from '@tanstack/angular-store'
+import { constructTable } from '@tanstack/table-core'
import { lazyInit } from './lazySignalInitializer'
+import { angularReactivity } from './reactivity'
import type { Atom, ReadonlyAtom } from '@tanstack/angular-store'
import type {
RowData,
@@ -60,10 +56,13 @@ export type AngularTable<
*/
readonly value: Signal>
/**
- * Alias: **`Subscribe`** — same function reference as `computed` (naming parity with other adapters).
+ * Creates a computed that subscribe to changes in the table store with a custom selector.
+ * Default equality function is "shallow".
*/
- computed: AngularTableComputed
- Subscribe: AngularTableComputed
+ computed: (props: {
+ selector: (state: TableState) => TSubSelected
+ equal?: ValueEqualityFn
+ }) => Signal>
}
/**
@@ -133,104 +132,56 @@ export function injectTable<
): AngularTable {
assertInInjectionContext(injectTable)
const injector = inject(Injector)
- const stateNotifier = signal(0)
- const angularReactivityFeature = constructReactivityFeature({
- stateNotifier: () => stateNotifier(),
- })
return lazyInit(() => {
- const resolvedOptions: TableOptions = {
+ const table = constructTable({
...options(),
_features: {
+ coreReativityFeature: angularReactivity(injector),
...options()._features,
- angularReactivityFeature,
- },
- }
-
- const table = constructTable(resolvedOptions) as AngularTable<
- TFeatures,
- TData,
- TSelected
- >
- const tableState = injectSelector(table.store, (state) => state, {
- injector,
- })
- const tableOptions = injectSelector(table.optionsStore, (state) => state, {
- injector,
- })
-
- const updatedOptions = computed>(() => {
- const tableOptionsValue = options()
- const result: TableOptions = {
- ...untracked(() => table.options),
- ...tableOptionsValue,
- _features: { ...tableOptionsValue._features, angularReactivityFeature },
- }
- if (tableOptionsValue.state) {
- result.state = tableOptionsValue.state
- }
- return result
- })
-
- effect(
- () => {
- const newOptions = updatedOptions()
- untracked(() => table.setOptions(newOptions))
},
- { injector, debugName: 'tableOptionsUpdate' },
- )
+ }) as AngularTable
let isMount = true
effect(
() => {
- void [tableOptions(), tableState()]
- if (!isMount) untracked(() => stateNotifier.update((n) => n + 1))
- isMount && (isMount = false)
+ const newOptions = options()
+ if (isMount) {
+ isMount = false
+ return
+ }
+ untracked(() =>
+ table.setOptions((previous) => ({
+ ...previous,
+ ...newOptions,
+ })),
+ )
},
- { injector, debugName: 'tableStateNotifier' },
+ { injector, debugName: 'tableOptionsUpdate' },
)
- const computedFn = function computedSubscribe(props: {
- source?: Atom | ReadonlyAtom
- selector?: (state: unknown) => unknown
- equal?: ValueEqualityFn
+ table.computed = function Subscribe(props: {
+ selector: (state: TableState) => TSubSelected
+ equal?: ValueEqualityFn
}) {
- if (props.source !== undefined) {
- return injectSelector(
- props.source,
- props.selector ?? ((value) => value),
- {
- injector,
- ...(props.equal && { compare: props.equal }),
- },
- )
- }
- return injectSelector(table.store, props.selector, {
- injector,
- ...(props.equal && { compare: props.equal }),
+ return computed(() => props.selector(table.store.get()), {
+ equal: props.equal,
})
}
- table.computed = computedFn as AngularTable<
- TFeatures,
- TData,
- TSelected
- >['computed']
- table.Subscribe = computedFn as AngularTable<
- TFeatures,
- TData,
- TSelected
- >['Subscribe']
Object.defineProperty(table, 'state', {
- value: injectSelector(table.store, selector, { injector }),
+ value: computed(() => selector(table.store.get())),
})
Object.defineProperty(table, 'value', {
- value: computed(() => {
- tableOptions()
- tableState()
- return table
- }),
+ value: computed(
+ () => {
+ table.store.get()
+ table.optionsStore.get()
+ return table
+ },
+ { equal: () => false },
+ ),
})
return table
diff --git a/packages/angular-table/src/reactivity.ts b/packages/angular-table/src/reactivity.ts
new file mode 100644
index 0000000000..71ed087f62
--- /dev/null
+++ b/packages/angular-table/src/reactivity.ts
@@ -0,0 +1,65 @@
+import { computed, signal, untracked } from '@angular/core'
+import { toObservable } from '@angular/core/rxjs-interop'
+import type { Atom, Observer, ReadonlyAtom } from '@tanstack/angular-store'
+import type {
+ TableAtomOptions,
+ TableReactivityBindings,
+} from '@tanstack/table-core/reactivity'
+import type { Injector, Signal, WritableSignal } from '@angular/core'
+
+function signalToReadonlyAtom(
+ signal: Signal,
+ injector: Injector,
+): ReadonlyAtom {
+ return Object.assign(signal, {
+ get: () => signal(),
+ subscribe: (observer: Observer) => {
+ return toObservable(computed(signal), { injector: injector }).subscribe(
+ observer,
+ )
+ },
+ })
+}
+
+function signalToWritableAtom(
+ signal: WritableSignal,
+ injector: Injector,
+): Atom {
+ return Object.assign(signal.asReadonly(), {
+ set: (updater: T | ((prevVal: T) => T)) => {
+ typeof updater === 'function'
+ ? signal.update(updater as (val: T) => T)
+ : signal.set(updater)
+ },
+ get: () => signal(),
+ subscribe: (observer: Observer) => {
+ return toObservable(computed(signal), { injector: injector }).subscribe(
+ observer,
+ )
+ },
+ })
+}
+
+export function angularReactivity(injector: Injector): TableReactivityBindings {
+ return {
+ createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => {
+ const signal = computed(() => fn(), {
+ equal: options?.compare,
+ debugName: options?.debugName,
+ })
+ return signalToReadonlyAtom(signal, injector)
+ },
+ createWritableAtom: (
+ value: T,
+ options?: TableAtomOptions,
+ ): Atom => {
+ const writableSignal = signal(value, {
+ equal: options?.compare,
+ debugName: options?.debugName,
+ })
+ return signalToWritableAtom(writableSignal, injector)
+ },
+ untrack: untracked,
+ batch: (fn) => fn(),
+ }
+}
diff --git a/packages/angular-table/tests/angularReactivityFeature.test.ts b/packages/angular-table/tests/angularReactivityFeature.test.ts
index 461c0addd2..35f381d716 100644
--- a/packages/angular-table/tests/angularReactivityFeature.test.ts
+++ b/packages/angular-table/tests/angularReactivityFeature.test.ts
@@ -30,12 +30,6 @@ describe('angularReactivityFeature', () => {
_features: { ...stockFeatures },
columns: columns,
getRowId: (row) => row.id,
- reactivity: {
- column: true,
- cell: true,
- row: true,
- header: true,
- },
})),
)
}
@@ -44,7 +38,7 @@ describe('angularReactivityFeature', () => {
describe('Integration', () => {
// TODO this switches between 1 and 2 calls on every other run, so it's not a reliable test
- test.skip('methods within effect will be re-trigger when options/state changes', () => {
+ test('methods within effect will be re-trigger when options/state changes', () => {
const data = signal>([{ id: '1', title: 'Title' }])
const table = createTestTable(data)
const isSelectedRow1Captor = vi.fn<(val: boolean) => void>()
@@ -86,35 +80,23 @@ describe('angularReactivityFeature', () => {
TestBed.tick()
expect(isSelectedRow1Captor).toHaveBeenCalledTimes(2)
expect(cellGetValueCaptor).toHaveBeenCalledTimes(1)
- expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(2)
+ expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(1)
data.set([{ id: '1', title: 'Title 3' }])
TestBed.tick()
- // Row/cell instances are memoized by id in the atoms-based table, so a
- // data change that preserves ids does not emit a new cell reference.
- // `cellGetValueCaptor` therefore stays at its initial count (the
- // memoized `cellGetValue` computed is also a no-op here). Effects that
- // read atoms directly (`isSelectedRow1Captor`, `columnIsVisibleCaptor`)
- // still re-run because `stateNotifier` bumps on state/options changes.
expect(isSelectedRow1Captor).toHaveBeenCalledTimes(3)
- expect(cellGetValueCaptor).toHaveBeenCalledTimes(1)
- expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(3)
+ expect(cellGetValueCaptor).toHaveBeenCalledTimes(2)
+ expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(2)
cell().column.toggleVisibility(false)
TestBed.tick()
- expect(isSelectedRow1Captor).toHaveBeenCalledTimes(4)
- expect(cellGetValueCaptor).toHaveBeenCalledTimes(1)
- expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(4)
+ expect(isSelectedRow1Captor).toHaveBeenCalledTimes(3)
+ expect(cellGetValueCaptor).toHaveBeenCalledTimes(2)
+ expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(3)
- expect(isSelectedRow1Captor.mock.calls).toEqual([
- [false],
- [true],
- [true],
- [true],
- ])
- expect(cellGetValueCaptor.mock.calls).toEqual([['1']])
+ expect(isSelectedRow1Captor.mock.calls).toEqual([[false], [true], [true]])
+ expect(cellGetValueCaptor.mock.calls).toEqual([['1'], ['1']])
expect(columnIsVisibleCaptor.mock.calls).toEqual([
- [true],
[true],
[true],
[false],
diff --git a/packages/angular-table/tests/benchmarks/injectTable.benchmark.ts b/packages/angular-table/tests/benchmarks/injectTable.benchmark.ts
deleted file mode 100644
index 78e24cd7d4..0000000000
--- a/packages/angular-table/tests/benchmarks/injectTable.benchmark.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { setTimeout } from 'node:timers/promises'
-import { bench, describe } from 'vitest'
-import { benchCases, columns, createTestTable, dataMap } from './setup'
-
-const nIteration = 5
-
-for (const benchCase of benchCases) {
- describe(`injectTable - ${benchCase.size} elements`, () => {
- const data = dataMap[benchCase.size]!
-
- bench(
- `No reactivity`,
- async () => {
- const table = createTestTable(false, data, columns)
- await setTimeout(0)
- table.getRowModel()
- },
- {
- iterations: nIteration,
- },
- )
-
- bench(
- `Full reactivity`,
- async () => {
- const table = createTestTable(true, data, columns)
- await setTimeout(0)
- table.getRowModel()
- },
- {
- iterations: nIteration,
- },
- )
- })
-}
diff --git a/packages/angular-table/tests/benchmarks/setup.ts b/packages/angular-table/tests/benchmarks/setup.ts
deleted file mode 100644
index 00fbe06dc4..0000000000
--- a/packages/angular-table/tests/benchmarks/setup.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { injectTable, stockFeatures } from '../../src'
-import type { ColumnDef } from '../../src'
-
-export function createData(size: number) {
- return Array.from({ length: size }, (_, index) => ({
- id: index,
- title: `title-${index}`,
- name: `name-${index}`,
- }))
-}
-
-export const columns: Array> = [
- { id: 'col1' },
- { id: 'col2' },
- { id: 'col3' },
- { id: 'col4' },
- { id: 'col5' },
- { id: 'col6' },
- { id: 'col7' },
-]
-
-export function createTestTable(
- enableGranularReactivity: boolean,
- data: Array,
- columns: Array,
-) {
- return injectTable(() => ({
- _features: stockFeatures,
- columns: columns,
- data,
- reactivity: {
- table: enableGranularReactivity,
- row: enableGranularReactivity,
- column: enableGranularReactivity,
- cell: enableGranularReactivity,
- header: enableGranularReactivity,
- },
- }))
-}
-
-export const benchCases = [
- { size: 100, max: 5, threshold: 10 },
- { size: 1000, max: 25, threshold: 50 },
- { size: 2000, max: 50, threshold: 100 },
- { size: 5000, max: 100, threshold: 500 },
- { size: 10_000, max: 200, threshold: 1000 },
- { size: 25_000, max: 500, threshold: 1000 },
- { size: 50_000, max: 1500, threshold: 1000 },
- { size: 100_000, max: 2000, threshold: 1500 },
-]
-
-console.log('Seeding data...')
-
-export const dataMap = {} as Record>
-
-for (const benchCase of benchCases) {
- dataMap[benchCase.size] = createData(benchCase.size)
-}
-
-console.log('Seed data completed')
diff --git a/packages/angular-table/tests/flex-render/flex-render-table.test.ts b/packages/angular-table/tests/flex-render/flex-render-table.test.ts
index 8a9a71cd12..c3111e43f9 100644
--- a/packages/angular-table/tests/flex-render/flex-render-table.test.ts
+++ b/packages/angular-table/tests/flex-render/flex-render-table.test.ts
@@ -535,9 +535,6 @@ export function createTestTable(
return {
...(optionsFn?.() ?? {}),
_features: stockFeatures,
- _rowModels: {
- coreRowModel: createCoreRowModel(),
- },
columns: this.columns(),
data: this.data(),
} as TableOptions
diff --git a/packages/angular-table/tests/injectTable.test.ts b/packages/angular-table/tests/injectTable.test.ts
index 0173cf4d23..8de7e0b51f 100644
--- a/packages/angular-table/tests/injectTable.test.ts
+++ b/packages/angular-table/tests/injectTable.test.ts
@@ -121,7 +121,10 @@ describe('injectTable', () => {
TestBed.tick()
- expect(coreRowModelFn).toHaveBeenCalledOnce()
+ // TODO: pagination state update twice during first table construct
+ // optionsStore is a signal -> so if updated with state in queuemicrotask will trigger twice
+ expect(coreRowModelFn).toHaveBeenCalledTimes(2)
+ expect(coreRowModelFn.mock.calls[0]![0].rows.length).toEqual(10)
expect(coreRowModelFn.mock.calls[0]![0].rows.length).toEqual(10)
expect(rowModelFn).toHaveBeenCalledTimes(2)
diff --git a/packages/angular-table/vite.config.ts b/packages/angular-table/vite.config.ts
index f1dc9d9158..cf80dec4c6 100644
--- a/packages/angular-table/vite.config.ts
+++ b/packages/angular-table/vite.config.ts
@@ -5,7 +5,7 @@ import packageJson from './package.json'
const tsconfigPath = path.join(import.meta.dirname, 'tsconfig.test.json')
const testDirPath = path.join(import.meta.dirname, 'tests')
-const angularPlugin = angular({ tsconfig: tsconfigPath, jit: true })
+const angularPlugin = angular({ tsconfig: tsconfigPath })
export default defineConfig({
plugins: [angularPlugin],
diff --git a/packages/lit-table/src/TableController.ts b/packages/lit-table/src/TableController.ts
index a8cbc84870..b759d572db 100644
--- a/packages/lit-table/src/TableController.ts
+++ b/packages/lit-table/src/TableController.ts
@@ -1,7 +1,5 @@
-import {
- constructReactivityFeature,
- constructTable,
-} from '@tanstack/table-core'
+import { constructTable } from '@tanstack/table-core'
+import { constructReactivityBindings } from '@tanstack/table-core/reactivity'
import { FlexRender } from './flexRender'
import type { Atom, ReadonlyAtom } from '@tanstack/store'
import type {
@@ -146,18 +144,11 @@ export class TableController<
({}) as TSelected,
): LitTable {
if (!this._table) {
- const litReactivityFeature = constructReactivityFeature(
- {
- stateNotifier: () => this._notifier,
- optionsNotifier: () => this._notifier,
- },
- )
-
const mergedOptions: TableOptions = {
...tableOptions,
_features: {
+ coreReativityFeature: constructReactivityBindings(),
...tableOptions._features,
- litReactivityFeature,
},
mergeOptions: (
defaultOptions: TableOptions,
diff --git a/packages/lit-table/tests/unit/defaultReactivity.test.ts b/packages/lit-table/tests/unit/defaultReactivity.test.ts
new file mode 100644
index 0000000000..9d8e572681
--- /dev/null
+++ b/packages/lit-table/tests/unit/defaultReactivity.test.ts
@@ -0,0 +1,22 @@
+import { describe, expect, test } from 'vitest'
+import { TableController } from '../../src/TableController'
+
+describe('TableController', () => {
+ test('uses default reactivity when constructing a table', () => {
+ const host = {
+ addController: () => {},
+ requestUpdate: () => {},
+ }
+ const controller = new TableController(host)
+
+ const table = controller.table({
+ _features: {},
+ _rowModels: {},
+ columns: [],
+ data: [],
+ })
+
+ expect(table._reactivity).toBeDefined()
+ expect(table.store.get()).toEqual({})
+ })
+})
diff --git a/packages/preact-table/package.json b/packages/preact-table/package.json
index 07d4f02224..3379439cf6 100644
--- a/packages/preact-table/package.json
+++ b/packages/preact-table/package.json
@@ -57,6 +57,7 @@
"build": "tsdown"
},
"dependencies": {
+ "@preact/signals": "^2.9.0",
"@tanstack/preact-store": "^0.13.0",
"@tanstack/table-core": "workspace:*"
},
diff --git a/packages/preact-table/src/reactivity.ts b/packages/preact-table/src/reactivity.ts
new file mode 100644
index 0000000000..08ac3488ea
--- /dev/null
+++ b/packages/preact-table/src/reactivity.ts
@@ -0,0 +1,63 @@
+// TOTO - re-explore preact signals for reactivity
+import { batch, computed, signal, untracked } from '@preact/signals'
+import type {
+ TableAtomOptions,
+ TableReactivityBindings,
+} from '@tanstack/table-core/reactivity'
+import type { Atom, Observer, ReadonlyAtom } from '@tanstack/preact-store'
+
+function observerToCallback(
+ observerOrNext: Observer | ((value: T) => void),
+): (value: T) => void {
+ return typeof observerOrNext === 'function'
+ ? observerOrNext
+ : (value) => observerOrNext.next?.(value)
+}
+
+function signalToReadonlyAtom(source: {
+ value: T
+ subscribe: (observer: (value: T) => void) => () => void
+}): ReadonlyAtom {
+ return Object.assign(source, {
+ get: () => source.value,
+ subscribe: ((observerOrNext: Observer | ((value: T) => void)) => {
+ const unsubscribe = source.subscribe(observerToCallback(observerOrNext))
+ return { unsubscribe }
+ }) as ReadonlyAtom['subscribe'],
+ })
+}
+
+function signalToWritableAtom(source: {
+ value: T
+ subscribe: (observer: (value: T) => void) => () => void
+}): Atom {
+ return Object.assign(source, {
+ set: (updater: T | ((prevVal: T) => T)) => {
+ source.value =
+ typeof updater === 'function'
+ ? (updater as (prevVal: T) => T)(source.value)
+ : updater
+ },
+ get: () => source.value,
+ subscribe: ((observerOrNext: Observer | ((value: T) => void)) => {
+ const unsubscribe = source.subscribe(observerToCallback(observerOrNext))
+ return { unsubscribe }
+ }) as Atom['subscribe'],
+ })
+}
+
+export function preactReactivity(): TableReactivityBindings {
+ return {
+ createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => {
+ return signalToReadonlyAtom(computed(fn))
+ },
+ createWritableAtom: (
+ value: T,
+ _options?: TableAtomOptions,
+ ): Atom => {
+ return signalToWritableAtom(signal(value))
+ },
+ untrack: untracked,
+ batch: batch,
+ }
+}
diff --git a/packages/preact-table/src/useTable.ts b/packages/preact-table/src/useTable.ts
index 39e4edcc7a..977d7a7431 100644
--- a/packages/preact-table/src/useTable.ts
+++ b/packages/preact-table/src/useTable.ts
@@ -1,8 +1,10 @@
-import { useMemo, useState } from 'preact/hooks'
+import { useEffect, useMemo, useState } from 'preact/hooks'
import { constructTable } from '@tanstack/table-core'
import { shallow, useSelector } from '@tanstack/preact-store'
+import { constructReactivityBindings } from '@tanstack/table-core/reactivity'
import { FlexRender } from './FlexRender'
import { Subscribe } from './Subscribe'
+// import { preactReactivity } from './reactivity'
import type {
CellData,
RowData,
@@ -92,11 +94,13 @@ export function useTable<
({}) as TSelected,
): PreactTable {
const [table] = useState(() => {
- const tableInstance = constructTable(tableOptions) as PreactTable<
- TFeatures,
- TData,
- TSelected
- >
+ const tableInstance = constructTable({
+ ...tableOptions,
+ _features: {
+ coreReativityFeature: constructReactivityBindings(), // preactReactivity() currently causes infinite re-renders
+ ...tableOptions._features,
+ },
+ }) as PreactTable
tableInstance.Subscribe = ((props: any) => {
return Subscribe({
@@ -110,27 +114,24 @@ export function useTable<
return tableInstance
})
- // sync table options on every render
- table.setOptions((prev) => ({
- ...prev,
- ...tableOptions,
- }))
+ useEffect(() => {
+ table.setOptions((prev) => ({
+ ...prev,
+ ...tableOptions,
+ }))
+ }, [table, tableOptions])
- const selectorWithDataAndColumns = (state: TableState) => ({
- columns: tableOptions.columns,
- data: tableOptions.data,
- ...selector(state),
- })
-
- const state = useSelector(table.store, selectorWithDataAndColumns, {
+ const state = useSelector(table.store, selector, { compare: shallow })
+ const options = useSelector(table.optionsStore, (options) => options, {
compare: shallow,
})
return useMemo(
() => ({
...table,
+ options,
state,
}),
- [state, table],
+ [table, options, state],
) as PreactTable
}
diff --git a/packages/preact-table/tests/unit/signals.test.ts b/packages/preact-table/tests/unit/signals.test.ts
new file mode 100644
index 0000000000..6706b4b07c
--- /dev/null
+++ b/packages/preact-table/tests/unit/signals.test.ts
@@ -0,0 +1,20 @@
+import { describe, expect, test } from 'vitest'
+import { preactReactivity } from '../../src/reactivity'
+
+describe('preactReactivity', () => {
+ test('creates writable and readonly atoms from Preact signals', () => {
+ const reactivity = preactReactivity()
+ const count = reactivity.createWritableAtom(1, { debugName: 'count' })
+ const doubled = reactivity.createReadonlyAtom(() => count.get() * 2, {
+ debugName: 'doubled',
+ })
+
+ expect(count.get()).toBe(1)
+ expect(doubled.get()).toBe(2)
+
+ count.set((value) => value + 1)
+
+ expect(count.get()).toBe(2)
+ expect(doubled.get()).toBe(4)
+ })
+})
diff --git a/packages/react-table-devtools/package.json b/packages/react-table-devtools/package.json
index 4b002c7dc5..331ca66a17 100644
--- a/packages/react-table-devtools/package.json
+++ b/packages/react-table-devtools/package.json
@@ -51,7 +51,7 @@
"@tanstack/table-devtools": "workspace:*"
},
"devDependencies": {
- "@eslint-react/eslint-plugin": "^5.6.6",
+ "@eslint-react/eslint-plugin": "^5.7.0",
"@tanstack/table-core": "workspace:*",
"@types/react": "^19.2.14",
"@vitejs/plugin-react": "^6.0.1",
diff --git a/packages/react-table/package.json b/packages/react-table/package.json
index c6045c4f50..e83de21f77 100644
--- a/packages/react-table/package.json
+++ b/packages/react-table/package.json
@@ -65,7 +65,7 @@
"@tanstack/table-core": "workspace:*"
},
"devDependencies": {
- "@eslint-react/eslint-plugin": "^5.6.6",
+ "@eslint-react/eslint-plugin": "^5.7.0",
"@types/react": "^19.2.14",
"@vitejs/plugin-react": "^6.0.1",
"eslint-plugin-react-compiler": "19.1.0-rc.2",
diff --git a/packages/react-table/src/useLegacyTable.ts b/packages/react-table/src/useLegacyTable.ts
index eec0d424da..daa0ad7474 100644
--- a/packages/react-table/src/useLegacyTable.ts
+++ b/packages/react-table/src/useLegacyTable.ts
@@ -15,7 +15,7 @@ import {
sortFns,
stockFeatures,
} from '@tanstack/table-core'
-import { useCallback, useMemo } from 'react'
+import { useCallback, useMemo, useState } from 'react'
import { useTable } from './useTable'
import type {
AggregationFns,
@@ -402,52 +402,55 @@ export function useLegacyTable(
...restOptions
} = options
- // Build the _rowModels object based on which legacy options were provided
- const _rowModels: CreateRowModels_All = {}
-
- // Map v8 row model factories to v9 _rowModels
- // Note: getCoreRowModel is handled automatically in v9, so we ignore it
-
- if (getFilteredRowModel) {
- _rowModels.filteredRowModel = createFilteredRowModel({
- ...filterFns,
- ...options.filterFns,
- })
- }
-
- if (getSortedRowModel) {
- _rowModels.sortedRowModel = createSortedRowModel({
- ...sortFns,
- ...options.sortFns,
- })
- }
-
- if (getPaginationRowModel) {
- _rowModels.paginatedRowModel = createPaginatedRowModel()
- }
-
- if (getExpandedRowModel) {
- _rowModels.expandedRowModel = createExpandedRowModel()
- }
-
- if (getGroupedRowModel) {
- _rowModels.groupedRowModel = createGroupedRowModel({
- ...aggregationFns,
- ...options.aggregationFns,
- })
- }
-
- if (getFacetedRowModel) {
- _rowModels.facetedRowModel = createFacetedRowModel()
- }
-
- if (getFacetedMinMaxValues) {
- _rowModels.facetedMinMaxValues = createFacetedMinMaxValues()
- }
-
- if (getFacetedUniqueValues) {
- _rowModels.facetedUniqueValues = createFacetedUniqueValues()
- }
+ const [_rowModels] = useState(() => {
+ const rowModels: CreateRowModels_All = {}
+
+ // Legacy row model options are setup-only. Capture the first render's
+ // marker options to match the table instance lifecycle.
+
+ if (getFilteredRowModel) {
+ rowModels.filteredRowModel = createFilteredRowModel({
+ ...filterFns,
+ ...options.filterFns,
+ })
+ }
+
+ if (getSortedRowModel) {
+ rowModels.sortedRowModel = createSortedRowModel({
+ ...sortFns,
+ ...options.sortFns,
+ })
+ }
+
+ if (getPaginationRowModel) {
+ rowModels.paginatedRowModel = createPaginatedRowModel()
+ }
+
+ if (getExpandedRowModel) {
+ rowModels.expandedRowModel = createExpandedRowModel()
+ }
+
+ if (getGroupedRowModel) {
+ rowModels.groupedRowModel = createGroupedRowModel({
+ ...aggregationFns,
+ ...options.aggregationFns,
+ })
+ }
+
+ if (getFacetedRowModel) {
+ rowModels.facetedRowModel = createFacetedRowModel()
+ }
+
+ if (getFacetedMinMaxValues) {
+ rowModels.facetedMinMaxValues = createFacetedMinMaxValues()
+ }
+
+ if (getFacetedUniqueValues) {
+ rowModels.facetedUniqueValues = createFacetedUniqueValues()
+ }
+
+ return rowModels
+ })
// Call useTable with the v9 API, subscribing to all state changes
const table = useTable>(
@@ -460,12 +463,7 @@ export function useLegacyTable(
)
const getState = useCallback(() => {
- // all state except for columns and data
- return {
- ...table.state,
- columns: undefined,
- data: undefined,
- }
+ return table.state
}, [table])
const setState = useCallback(
diff --git a/packages/react-table/src/useTable.ts b/packages/react-table/src/useTable.ts
index 4fe97567f9..aea2b679a7 100644
--- a/packages/react-table/src/useTable.ts
+++ b/packages/react-table/src/useTable.ts
@@ -1,10 +1,14 @@
'use client'
-import { useMemo, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
import { constructTable } from '@tanstack/table-core'
import { shallow, useSelector } from '@tanstack/react-store'
+import { constructReactivityBindings } from '@tanstack/table-core/reactivity'
import { FlexRender } from './FlexRender'
import { Subscribe } from './Subscribe'
+import type { Atom, ReadonlyAtom } from '@tanstack/react-store'
+import type { FlexRenderProps } from './FlexRender'
+import type { SubscribePropsWithStore } from './Subscribe'
import type {
CellData,
RowData,
@@ -13,10 +17,7 @@ import type {
TableOptions,
TableState,
} from '@tanstack/table-core'
-import type { Atom, ReadonlyAtom } from '@tanstack/react-store'
import type { FunctionComponent, ReactNode } from 'react'
-import type { FlexRenderProps } from './FlexRender'
-import type { SubscribePropsWithStore } from './Subscribe'
export type ReactTable<
TFeatures extends TableFeatures,
@@ -121,11 +122,13 @@ export function useTable<
({}) as TSelected,
): ReactTable {
const [table] = useState(() => {
- const tableInstance = constructTable(tableOptions) as ReactTable<
- TFeatures,
- TData,
- TSelected
- >
+ const tableInstance = constructTable({
+ ...tableOptions,
+ _features: {
+ coreReativityFeature: constructReactivityBindings(),
+ ...tableOptions._features,
+ },
+ }) as ReactTable
tableInstance.Subscribe = ((props: any) => {
return Subscribe({
@@ -139,22 +142,26 @@ export function useTable<
return tableInstance
})
- // sync table options on every render
- table.setOptions((prev) => ({
- ...prev,
- ...tableOptions,
- }))
+ useEffect(() => {
+ table.setOptions((prev) => ({
+ ...prev,
+ ...tableOptions,
+ }))
+ }, [table, tableOptions])
const state = useSelector(table.store, selector, { compare: shallow })
+ const options = useSelector(table.optionsStore, (options) => options, {
+ compare: shallow,
+ })
// we know this is not the most efficient way to return the table,
// but it is required for the react compiler to work
return useMemo(
() => ({
...table,
- options: tableOptions,
+ options,
state,
}),
- [table, tableOptions, state],
+ [table, options, state],
) as ReactTable
}
diff --git a/packages/solid-table/src/createTable.ts b/packages/solid-table/src/createTable.ts
index 412efe6e7a..573bd34fa5 100644
--- a/packages/solid-table/src/createTable.ts
+++ b/packages/solid-table/src/createTable.ts
@@ -1,10 +1,8 @@
-import {
- constructReactivityFeature,
- constructTable,
-} from '@tanstack/table-core'
-import { createComputed, createSignal, mergeProps, untrack } from 'solid-js'
+import { constructTable } from '@tanstack/table-core'
+import { createComputed, getOwner, mergeProps, untrack } from 'solid-js'
import { shallow, useSelector } from '@tanstack/solid-store'
import { FlexRender } from './FlexRender'
+import { solidReactivity } from './reactivity'
import type { Atom, ReadonlyAtom } from '@tanstack/solid-store'
import type { Accessor, JSX } from 'solid-js'
import type {
@@ -73,17 +71,13 @@ export function createTable<
selector: (state: TableState) => TSelected = () =>
({}) as TSelected,
): SolidTable {
- const [notifier, setNotifier] = createSignal(void 0, { equals: false })
-
- const solidReactivityFeature = constructReactivityFeature({
- stateNotifier: () => notifier(),
- optionsNotifier: () => notifier(),
- })
+ const owner = getOwner()!
const mergedOptions = mergeProps(tableOptions, {
- _features: mergeProps(tableOptions._features, {
- solidReactivityFeature,
- }),
+ _features: {
+ coreReativityFeature: solidReactivity(owner),
+ ...tableOptions._features,
+ },
}) as any
const resolvedOptions = mergeProps(
@@ -104,9 +98,6 @@ export function createTable<
TSelected
>
- const allState = useSelector(table.store)
- const allOptions = useSelector(table.optionsStore)
-
createComputed(() => {
const userState = tableOptions.state
if (userState) {
@@ -122,12 +113,6 @@ export function createTable<
})
})
- createComputed(() => {
- allState()
- allOptions()
- untrack(() => setNotifier(void 0))
- })
-
table.Subscribe = ((props: {
source?: Atom | ReadonlyAtom
selector?: ((state: unknown) => unknown) | undefined
diff --git a/packages/solid-table/src/reactivity.ts b/packages/solid-table/src/reactivity.ts
new file mode 100644
index 0000000000..1b3cb44366
--- /dev/null
+++ b/packages/solid-table/src/reactivity.ts
@@ -0,0 +1,68 @@
+import {
+ batch,
+ createMemo,
+ createSignal,
+ observable,
+ runWithOwner,
+ untrack,
+} from 'solid-js'
+import type { Accessor, Owner, Setter } from 'solid-js'
+import type {
+ TableAtomOptions,
+ TableReactivityBindings,
+} from '@tanstack/table-core/reactivity'
+import type { Atom, Observer, ReadonlyAtom } from '@tanstack/solid-store'
+
+function signalToReadonlyAtom(
+ signal: Accessor,
+ owner: Owner,
+): ReadonlyAtom {
+ return Object.assign(signal, {
+ get: () => signal(),
+ subscribe: (observer: Observer) => {
+ return runWithOwner(owner, () => observable(signal))!.subscribe(observer)
+ },
+ })
+}
+
+function signalToWritableAtom(
+ signalTuple: [Accessor, Setter],
+ owner: Owner,
+): Atom {
+ const [signal, setSignal] = signalTuple
+ return Object.assign(signal, {
+ set: (updater: T | ((prevVal: T) => T)) => {
+ typeof updater === 'function'
+ ? setSignal(updater as unknown as (prev: T) => T)
+ : setSignal(updater as Exclude)
+ },
+ get: () => signal(),
+ subscribe: (observer: Observer) => {
+ return runWithOwner(owner, () => observable(signal))!.subscribe(observer)
+ },
+ })
+}
+
+export function solidReactivity(owner: Owner): TableReactivityBindings {
+ return {
+ createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => {
+ const signal = createMemo(() => fn(), {
+ equals: options?.compare,
+ name: options?.debugName,
+ })
+ return signalToReadonlyAtom(signal, owner)
+ },
+ createWritableAtom: (
+ value: T,
+ options?: TableAtomOptions,
+ ): Atom => {
+ const writableSignal = createSignal(value, {
+ equals: options?.compare,
+ name: options?.debugName,
+ })
+ return signalToWritableAtom(writableSignal, owner)
+ },
+ untrack: untrack,
+ batch: batch,
+ }
+}
diff --git a/packages/svelte-table/src/createTable.svelte.ts b/packages/svelte-table/src/createTable.svelte.ts
index 0171065618..9c24a4a1de 100644
--- a/packages/svelte-table/src/createTable.svelte.ts
+++ b/packages/svelte-table/src/createTable.svelte.ts
@@ -1,10 +1,8 @@
-import {
- constructReactivityFeature,
- constructTable,
-} from '@tanstack/table-core'
-import { shallow, useSelector } from '@tanstack/svelte-store'
+import { constructTable } from '@tanstack/table-core'
+import { useSelector } from '@tanstack/svelte-store'
import { untrack } from 'svelte'
import { mergeObjects } from './merge-objects'
+import { svelteReactivity } from './reactivity.svelte'
import type {
RowData,
Table,
@@ -38,23 +36,15 @@ export function createTable<
selector: (state: TableState) => TSelected = () =>
({}) as TSelected,
): SvelteTable {
- // 1. Create $state-based notifier for reactivity feature
- let notifierValue = $state(0)
-
- // 2. Construct reactivity feature (same pattern as solid/vue/angular)
- const svelteReactivityFeature = constructReactivityFeature({
- stateNotifier: () => notifierValue,
- optionsNotifier: () => notifierValue,
- })
-
- // 3. Merge reactivity feature into options using mergeObjects (preserves getters)
+ // 1. Merge reactivity into options using mergeObjects (preserves getters)
const mergedOptions = mergeObjects(tableOptions, {
- _features: mergeObjects(tableOptions._features, {
- svelteReactivityFeature,
- }),
- }) as any
+ _features: {
+ coreReativityFeature: svelteReactivity(),
+ ...tableOptions._features,
+ },
+ }) as TableOptions
- // 4. Set up resolved options with mergeOptions handler
+ // 2. Set up resolved options with mergeOptions handler
const resolvedOptions = mergeObjects(
{
mergeOptions: (
@@ -67,40 +57,23 @@ export function createTable<
mergedOptions,
) as TableOptions
- // 5. Construct table
+ // 3. Construct table
const table = constructTable(resolvedOptions) as SvelteTable<
TFeatures,
TData,
TSelected
>
- // 6. Subscribe to all state and options via useSelector
- const allState = useSelector(table.store, (state) => state)
- const allOptions = useSelector(table.optionsStore, (options) => options)
-
- // 7. Sync store changes -> notifier.
- // Use $effect.pre so this runs before DOM updates (like Solid's createComputed).
- // Use untrack for the write so the effect only depends on allState/allOptions,
- // not on notifierValue itself (which would cause an infinite loop).
- $effect.pre(() => {
- allState.current
- allOptions.current
- untrack(() => {
- notifierValue++
- })
- })
-
- // 8. Sync options reactively. When controlled state changes (e.g., $state
+ // 4. Sync options reactively. When controlled state changes (e.g., $state
// inside createTableState), the effect re-runs and calls setOptions.
// Use $effect.pre so the table sees updated options BEFORE the DOM renders,
// ensuring getRowModel() returns current data (not stale, one-frame-behind data).
// The reactive reads (state getters, data getter) happen OUTSIDE untrack
- // so they become dependencies. The setOptions call is INSIDE untrack to
- // prevent tracking notifierValue (read via store.state's stateNotifier
- // interceptor inside setOptions), which would cause an infinite loop.
+ // so they become dependencies. The setOptions call is INSIDE untrack so
+ // option writes do not subscribe this effect to table internals.
$effect.pre(() => {
// Read reactive getters to create $effect dependencies on external state
- const state = mergedOptions.state
+ const state: Record | undefined = mergedOptions.state
if (state) {
for (const key in state) {
void state[key]
@@ -110,15 +83,12 @@ export function createTable<
untrack(() => {
table.setOptions((prev) => {
- return mergeObjects(prev, mergedOptions) as TableOptions<
- TFeatures,
- TData
- >
+ return mergeObjects(prev, mergedOptions)
})
})
})
- // 9. State selector
+ // 5. State selector
const stateStore = useSelector(table.store, selector)
Object.defineProperty(table, 'state', {
diff --git a/packages/svelte-table/src/reactivity.svelte.ts b/packages/svelte-table/src/reactivity.svelte.ts
new file mode 100644
index 0000000000..0238b914c2
--- /dev/null
+++ b/packages/svelte-table/src/reactivity.svelte.ts
@@ -0,0 +1,64 @@
+import { flushSync, untrack } from 'svelte'
+import type {
+ TableAtomOptions,
+ TableReactivityBindings,
+} from '@tanstack/table-core/reactivity'
+import type { Atom, Observer, ReadonlyAtom } from '@tanstack/svelte-store'
+
+function observerToCallback(
+ observerOrNext: Observer | ((value: T) => void),
+): (value: T) => void {
+ return typeof observerOrNext === 'function'
+ ? observerOrNext
+ : (value) => observerOrNext.next?.(value)
+}
+
+function subscribeToRune(
+ getValue: () => T,
+ observerOrNext: Observer | ((value: T) => void),
+) {
+ const callback = observerToCallback(observerOrNext)
+ const unsubscribe = $effect.root(() => {
+ $effect(() => {
+ callback(getValue())
+ })
+ })
+
+ return { unsubscribe }
+}
+
+export function svelteReactivity(): TableReactivityBindings {
+ return {
+ createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => {
+ const value = $derived.by(fn)
+
+ return {
+ get: () => value,
+ subscribe: ((observerOrNext: Observer | ((value: T) => void)) => {
+ return subscribeToRune(() => value, observerOrNext)
+ }) as ReadonlyAtom['subscribe'],
+ }
+ },
+ createWritableAtom: (
+ initialValue: T,
+ _options?: TableAtomOptions,
+ ): Atom => {
+ let value = $state(initialValue)
+
+ return {
+ set: (updater: T | ((prevVal: T) => T)) => {
+ value =
+ typeof updater === 'function'
+ ? (updater as (prevVal: T) => T)(value)
+ : updater
+ },
+ get: () => value,
+ subscribe: ((observerOrNext: Observer | ((value: T) => void)) => {
+ return subscribeToRune(() => value, observerOrNext)
+ }) as Atom['subscribe'],
+ }
+ },
+ untrack: untrack,
+ batch: (fn) => flushSync(fn),
+ }
+}
diff --git a/packages/table-core/package.json b/packages/table-core/package.json
index 5263f3d45a..0425f26c60 100644
--- a/packages/table-core/package.json
+++ b/packages/table-core/package.json
@@ -38,6 +38,10 @@
"import": "./dist/flex-render.js",
"require": "./dist/flex-render.cjs"
},
+ "./reactivity": {
+ "import": "./dist/reactivity.js",
+ "require": "./dist/reactivity.cjs"
+ },
"./static-functions": {
"import": "./dist/static-functions.js",
"require": "./dist/static-functions.cjs"
diff --git a/packages/table-core/src/core/coreFeatures.ts b/packages/table-core/src/core/coreFeatures.ts
index 22d11f5762..656ff949de 100644
--- a/packages/table-core/src/core/coreFeatures.ts
+++ b/packages/table-core/src/core/coreFeatures.ts
@@ -4,8 +4,10 @@ import { coreHeadersFeature } from './headers/coreHeadersFeature'
import { coreRowModelsFeature } from './row-models/coreRowModelsFeature'
import { coreRowsFeature } from './rows/coreRowsFeature'
import { coreTablesFeature } from './table/coreTablesFeature'
+import type { TableReactivityBindings } from '../reactivity'
export interface CoreFeatures {
+ coreReativityFeature?: TableReactivityBindings
coreCellsFeature: typeof coreCellsFeature
coreColumnsFeature: typeof coreColumnsFeature
coreHeadersFeature: typeof coreHeadersFeature
diff --git a/packages/table-core/src/core/reactivity/constructReactivityBindings.ts b/packages/table-core/src/core/reactivity/constructReactivityBindings.ts
new file mode 100644
index 0000000000..2c94853904
--- /dev/null
+++ b/packages/table-core/src/core/reactivity/constructReactivityBindings.ts
@@ -0,0 +1,19 @@
+import { batch, createAtom } from '@tanstack/store'
+import type { TableReactivityBindings } from './coreReactivityFeature.types'
+
+export function constructReactivityBindings(): TableReactivityBindings {
+ return {
+ batch: batch,
+ untrack: (fn) => fn(),
+ createReadonlyAtom: (fn, options) => {
+ return createAtom(() => fn(), {
+ compare: options?.compare,
+ })
+ },
+ createWritableAtom: (value, options) => {
+ return createAtom(value, {
+ compare: options?.compare,
+ })
+ },
+ }
+}
diff --git a/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts b/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts
new file mode 100644
index 0000000000..8e323c1c4c
--- /dev/null
+++ b/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts
@@ -0,0 +1,40 @@
+import type { Atom, AtomOptions, ReadonlyAtom } from '@tanstack/store'
+
+export interface TableAtomOptions extends AtomOptions {
+ /**
+ * A debug name for the atom, useful for debugging.
+ */
+ debugName: string
+}
+
+/**
+ * Framework reactivity bindings used by table-core.
+ *
+ * Adapters (React, Solid, Vue, etc.) provide concrete implementations so
+ * core features can create derived/writable atoms and integrate with their
+ * scheduling primitives.
+ */
+export interface TableReactivityBindings {
+ /**
+ * Creates a writable atom with an initial value.
+ */
+ createWritableAtom: (
+ initialValue: T,
+ options?: TableAtomOptions,
+ ) => Atom
+ /**
+ * Creates a readonly/derived atom from a compute function.
+ */
+ createReadonlyAtom: (
+ fn: () => T,
+ options?: TableAtomOptions,
+ ) => ReadonlyAtom
+ /**
+ * Evaluates a function without tracking reactive dependencies.
+ */
+ untrack: (fn: () => T) => T
+ /**
+ * Batches reactive updates to avoid intermediate recomputation.
+ */
+ batch: (fn: () => void) => void
+}
diff --git a/packages/table-core/src/core/reactivity/coreReactivityFeature.utils.ts b/packages/table-core/src/core/reactivity/coreReactivityFeature.utils.ts
new file mode 100644
index 0000000000..54ef1f90dc
--- /dev/null
+++ b/packages/table-core/src/core/reactivity/coreReactivityFeature.utils.ts
@@ -0,0 +1,29 @@
+import type { Atom, ReadonlyAtom, ReadonlyStore, Store } from '@tanstack/store'
+
+/**
+ * Converts a writable atom to the store-compatible shape expected by core.
+ */
+export function atomToStore(atom: Atom): Store
+/**
+ * Converts a readonly atom to a readonly store-compatible shape.
+ */
+export function atomToStore(atom: ReadonlyAtom): ReadonlyStore
+/**
+ * Bridges atom instances to the `Store`/`ReadonlyStore` API by exposing
+ * a `state` getter backed by `atom.get()`, and wiring `setState` for
+ * writable atoms.
+ */
+export function atomToStore(
+ atom: Atom | ReadonlyAtom,
+): Store | ReadonlyStore {
+ const store: Store = atom as Store
+ Object.defineProperty(atom, 'state', {
+ get() {
+ return atom.get()
+ },
+ })
+ if ('set' in atom) {
+ store.setState = atom.set.bind(atom)
+ }
+ return store
+}
diff --git a/packages/table-core/src/core/table/constructTable.ts b/packages/table-core/src/core/table/constructTable.ts
index de0eca24bc..be14a21389 100644
--- a/packages/table-core/src/core/table/constructTable.ts
+++ b/packages/table-core/src/core/table/constructTable.ts
@@ -1,6 +1,6 @@
-import { createAtom, createStore } from '@tanstack/store'
import { coreFeatures } from '../coreFeatures'
import { cloneState } from '../../utils'
+import { atomToStore } from '../reactivity/coreReactivityFeature.utils'
import type { RowData } from '../../types/type-utils'
import type { TableFeature, TableFeatures } from '../../types/TableFeatures'
import type { Table, Table_Internal } from '../../types/Table'
@@ -21,15 +21,18 @@ export function constructTable<
TFeatures extends TableFeatures,
TData extends RowData,
>(tableOptions: TableOptions): Table {
+ const _reactivity = tableOptions._features.coreReativityFeature!
+
const table = {
+ _reactivity,
_features: { ...coreFeatures, ...tableOptions._features },
_rowModels: {},
_rowModelFns: {},
get options() {
- return this.optionsStore.state
+ return this.optionsStore.get()
},
set options(value) {
- this.optionsStore.setState(() => value)
+ this.optionsStore.set(() => value)
},
baseAtoms: {},
atoms: {},
@@ -41,10 +44,10 @@ export function constructTable<
return Object.assign(obj, feature.getDefaultTableOptions?.(table))
}, {}) as TableOptions
- table.optionsStore = createStore({
- ...defaultOptions,
- ...tableOptions,
- })
+ // @ts-ignore - direct set
+ table.optionsStore = _reactivity.createWritableAtom<
+ TableOptions
+ >({ ...defaultOptions, ...tableOptions }, { debugName: 'table/optionsStore' })
table.initialState = getInitialTableState(
table._features,
@@ -57,31 +60,44 @@ export function constructTable<
for (const key of stateKeys) {
// create writable base atom
- table.baseAtoms[key] = createAtom(table.initialState[key]) as any
+ table.baseAtoms[key] = _reactivity.createWritableAtom(
+ table.initialState[key],
+ {
+ debugName: `table/baseAtoms/${key}`,
+ },
+ ) as any
// create readonly derived atom: on each get(), read current options (state, then external atom, then base)
- ;(table.atoms as any)[key] = createAtom(() => {
- // Reading optionsStore.state keeps this reactive to setOptions
- const opts = table.optionsStore.state
- const state = opts.state
- if (key in (state ?? {})) {
- return state![key]
- }
- const externalAtom = opts.atoms?.[key]
- if (externalAtom) {
- return externalAtom.get()
- }
- return table.baseAtoms[key].get()
- })
+ ;(table.atoms as any)[key] = _reactivity.createReadonlyAtom(
+ () => {
+ // Reading optionsStore.get() keeps this reactive to setOptions
+ const opts = table.optionsStore.get()
+ const state = opts.state
+ if (key in (state ?? {})) {
+ return state![key]
+ }
+ const externalAtom = opts.atoms?.[key]
+ if (externalAtom) {
+ return externalAtom.get()
+ }
+ return table.baseAtoms[key].get()
+ },
+ { debugName: `table/atoms/${key}` },
+ )
}
- table.store = createStore(() => {
- const snapshot = {} as TableState
- for (const key of stateKeys) {
- snapshot[key] = table.atoms[key].get()
- }
- return snapshot
- })
+ table.store = atomToStore(
+ _reactivity.createReadonlyAtom(
+ () => {
+ const snapshot = {} as TableState
+ for (const key of stateKeys) {
+ snapshot[key] = table.atoms[key].get()
+ }
+ return snapshot
+ },
+ { debugName: 'table/store' },
+ ),
+ )
if (
process.env.NODE_ENV === 'development' &&
diff --git a/packages/table-core/src/core/table/coreTablesFeature.types.ts b/packages/table-core/src/core/table/coreTablesFeature.types.ts
index 62fde58013..5e0bcab3e3 100644
--- a/packages/table-core/src/core/table/coreTablesFeature.types.ts
+++ b/packages/table-core/src/core/table/coreTablesFeature.types.ts
@@ -1,4 +1,5 @@
-import type { Atom, ReadonlyAtom, ReadonlyStore, Store } from '@tanstack/store'
+import type { TableReactivityBindings } from '../reactivity/coreReactivityFeature.types'
+import type { Atom, ReadonlyAtom, ReadonlyStore } from '@tanstack/store'
import type { CoreFeatures } from '../coreFeatures'
import type { RowModelFns } from '../../types/RowModelFns'
import type { RowData, Updater } from '../../types/type-utils'
@@ -67,11 +68,11 @@ export interface TableOptions_Table<
/**
* The features that you want to enable for the table.
*/
- _features: TFeatures
+ readonly _features: TFeatures
/**
* The row model options that you want to enable for the table.
*/
- _rowModels?: CreateRowModels_All
+ readonly _rowModels?: CreateRowModels_All
/**
* Optionally, provide your own external writable atoms for individual state slices.
* When an atom is provided for a given slice, it takes precedence over `options.state[key]`
@@ -79,35 +80,35 @@ export interface TableOptions_Table<
* still routed through the internal base atom; consumers are responsible for
* mirroring changes back to their external atom via the corresponding `onXChange` callback.
*/
- atoms?: ExternalAtoms
+ readonly atoms?: ExternalAtoms
/**
* Set this option to override any of the `autoReset...` feature options.
*/
- autoResetAll?: boolean
+ readonly autoResetAll?: boolean
/**
* The data for the table to display. When the `data` option changes reference, the table will reprocess the data.
*/
- data: ReadonlyArray
+ readonly data: ReadonlyArray
/**
* Use this option to optionally pass initial state to the table. This state will be used when resetting various table states either automatically by the table (eg. `options.autoResetPageIndex`) or via functions like `table.resetRowSelection()`. Most reset function allow you optionally pass a flag to reset to a blank/default state instead of the initial state.
* Table state will not be reset when this object changes, which also means that the initial state object does not need to be stable.
*/
- initialState?: Partial>
+ readonly initialState?: Partial>
/**
* This option is used to optionally implement the merging of table options.
*/
- mergeOptions?: (
+ readonly mergeOptions?: (
defaultOptions: TableOptions,
options: Partial>,
) => TableOptions
/**
* You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`.
*/
- meta?: TableMeta
+ readonly meta?: TableMeta
/**
* Pass in individual self-managed state to the table.
*/
- state?: Partial>
+ readonly state?: Partial>
}
export interface Table_CoreProperties<
@@ -115,9 +116,9 @@ export interface Table_CoreProperties<
TData extends RowData,
> {
/**
- * The features that are enabled for the table.
+ * Table reactivity bindings for interacting with TanStack Store.
*/
- _features: Partial & TFeatures
+ readonly _reactivity: TableReactivityBindings
/**
* Prototype cache for Cell objects - shared by all cells in this table
*/
@@ -126,6 +127,10 @@ export interface Table_CoreProperties<
* Prototype cache for Column objects - shared by all columns in this table
*/
_columnPrototype?: object
+ /**
+ * The features that are enabled for the table.
+ */
+ readonly _features: Partial & TFeatures
/**
* Prototype cache for Header objects - shared by all headers in this table
*/
@@ -133,43 +138,43 @@ export interface Table_CoreProperties<
/**
* The row model processing functions that are used to process the data by features.
*/
- _rowModelFns: RowModelFns
+ readonly _rowModelFns: RowModelFns
/**
* The row models that are enabled for the table.
*/
- _rowModels: CachedRowModels
+ readonly _rowModels: CachedRowModels
/**
* Prototype cache for Row objects - shared by all rows in this table
*/
_rowPrototype?: object
- /**
- * The internal writable atoms for each `TableState` slice. This is the library's
- * single write surface — all state mutations from features land here.
- */
- baseAtoms: BaseAtoms
/**
* The readonly derived atoms for each `TableState` slice. Each derives from
* its corresponding `baseAtom` plus, optionally, a per-slice external atom or
* external state value (precedence: external atom > external state > base atom).
*/
- atoms: Atoms
+ readonly atoms: Atoms
/**
- * The base store for the table options.
+ * The internal writable atoms for each `TableState` slice. This is the library's
+ * single write surface — all state mutations from features land here.
*/
- optionsStore: Store>
+ readonly baseAtoms: BaseAtoms
/**
* This is the resolved initial state of the table.
*/
- initialState: TableState
+ readonly initialState: TableState
/**
* A read-only reference to the table's current options.
*/
readonly options: TableOptions
+ /**
+ * The base store for the table options.
+ */
+ readonly optionsStore: Atom>
/**
* The readonly flat store for the table state. Derives from `table.atoms`
* only; never reads external state directly.
*/
- store: ReadonlyStore>
+ readonly store: ReadonlyStore>
}
export interface Table_Table<
diff --git a/packages/table-core/src/core/table/coreTablesFeature.utils.ts b/packages/table-core/src/core/table/coreTablesFeature.utils.ts
index 800d08afec..01872f17ed 100644
--- a/packages/table-core/src/core/table/coreTablesFeature.utils.ts
+++ b/packages/table-core/src/core/table/coreTablesFeature.utils.ts
@@ -1,4 +1,3 @@
-import { batch } from '@tanstack/store'
import { cloneState, functionalUpdate } from '../../utils'
import type { RowData, Updater } from '../../types/type-utils'
import type { TableFeatures } from '../../types/TableFeatures'
@@ -10,7 +9,7 @@ export function table_reset<
TData extends RowData,
>(table: Table_Internal): void {
const snap = cloneState(table.initialState)
- batch(() => {
+ table._reactivity.batch(() => {
for (const key of Object.keys(snap) as Array) {
;(table.baseAtoms as any)[key].set(snap[key] as any)
}
@@ -43,5 +42,5 @@ export function table_setOptions<
): void {
const newOptions = functionalUpdate(updater, table.options)
const mergedOptions = table_mergeOptions(table, newOptions)
- table.optionsStore.setState(() => mergedOptions)
+ table.optionsStore.set(() => mergedOptions)
}
diff --git a/packages/table-core/src/features/table-reactivity/tableReactivityFeature.ts b/packages/table-core/src/features/table-reactivity/tableReactivityFeature.ts
deleted file mode 100644
index 62ec2bd0c4..0000000000
--- a/packages/table-core/src/features/table-reactivity/tableReactivityFeature.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import type { ReadonlyStore, Store } from '@tanstack/store'
-import type { TableFeature, TableFeatures } from '../../types/TableFeatures'
-import type { RowData } from '../../types/type-utils'
-
-export interface TableReactivityFeatureConstructors<
- TFeatures extends TableFeatures,
- TData extends RowData,
-> {}
-
-export function constructReactivityFeature<
- TFeatures extends TableFeatures,
- TData extends RowData,
->(bindings: {
- stateNotifier?: () => unknown
- optionsNotifier?: () => unknown
-}): TableFeature> {
- return {
- constructTableAPIs: (table) => {
- table.optionsStore = bindStore(
- table.optionsStore,
- bindings.optionsNotifier,
- )
- table.atoms = bindAtoms(table.atoms, bindings.stateNotifier)
- },
- }
-}
-
-const bindStore = | ReadonlyStore>(
- store: T,
- notifier?: () => unknown,
-): T => {
- const stateDescriptor = Object.getOwnPropertyDescriptor(
- Object.getPrototypeOf(store),
- 'state',
- )!
-
- Object.defineProperty(store, 'state', {
- configurable: true,
- enumerable: true,
- get() {
- notifier?.()
- return stateDescriptor.get!.call(store)
- },
- })
-
- return store
-}
-
-// Wraps an atoms/baseAtoms map so that `.get()` on any individual atom
-// calls the framework notifier first — matching how `bindStore` wraps
-// `store.state`. The proxy also transparently forwards missing slices
-// (atoms for features not registered on this table) as `undefined`.
-const bindAtoms = (atoms: T, notifier?: () => unknown): T => {
- if (!notifier) return atoms
- // Cache wrapped atoms so referential identity is stable per slice.
- const wrappedCache = new Map()
- return new Proxy(atoms, {
- get(target, prop, receiver) {
- const atom = Reflect.get(target, prop, receiver) as unknown
- if (!atom || typeof prop !== 'string' || !isAtomLike(atom)) {
- return atom
- }
- if (wrappedCache.has(prop)) return wrappedCache.get(prop)
- const originalGet = atom.get.bind(atom)
- const wrapped = new Proxy(atom, {
- get(atomTarget, atomProp, atomReceiver) {
- if (atomProp === 'get') {
- return () => {
- notifier()
- return originalGet()
- }
- }
- return Reflect.get(atomTarget, atomProp, atomReceiver)
- },
- })
- wrappedCache.set(prop, wrapped)
- return wrapped
- },
- })
-}
-
-interface AtomLike {
- get: () => unknown
-}
-
-function isAtomLike(value: unknown): value is AtomLike {
- return (
- typeof value === 'object' &&
- value !== null &&
- typeof (value as { get?: unknown }).get === 'function'
- )
-}
diff --git a/packages/table-core/src/index.ts b/packages/table-core/src/index.ts
index 3ed19019b4..06805fe7ff 100755
--- a/packages/table-core/src/index.ts
+++ b/packages/table-core/src/index.ts
@@ -71,9 +71,6 @@ export * from './fns/sortFns'
export * from './features/stockFeatures'
-// tableReactivityFeature
-export * from './features/table-reactivity/tableReactivityFeature'
-
// columnFacetingFeature
export * from './features/column-faceting/columnFacetingFeature'
export * from './features/column-faceting/columnFacetingFeature.types'
diff --git a/packages/table-core/src/reactivity.ts b/packages/table-core/src/reactivity.ts
new file mode 100644
index 0000000000..86ad4e0347
--- /dev/null
+++ b/packages/table-core/src/reactivity.ts
@@ -0,0 +1,3 @@
+export * from './core/reactivity/coreReactivityFeature.types'
+export * from './core/reactivity/constructReactivityBindings'
+export * from './core/reactivity/coreReactivityFeature.utils'
diff --git a/packages/table-core/src/types/Table.ts b/packages/table-core/src/types/Table.ts
index 6c27d25a17..e2be6d1d29 100644
--- a/packages/table-core/src/types/Table.ts
+++ b/packages/table-core/src/types/Table.ts
@@ -1,4 +1,4 @@
-import type { ReadonlyStore } from '@tanstack/store'
+import type { ReadonlyAtom, ReadonlyStore } from '@tanstack/store'
import type { Table_ColumnFaceting } from '../features/column-faceting/columnFacetingFeature.types'
import type { Table_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types'
import type { Table_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types'
diff --git a/packages/table-core/src/types/TableFeatures.ts b/packages/table-core/src/types/TableFeatures.ts
index 85f23d3082..d55702f6e4 100644
--- a/packages/table-core/src/types/TableFeatures.ts
+++ b/packages/table-core/src/types/TableFeatures.ts
@@ -12,13 +12,13 @@ export type ExtractFeatureTypes<
TFeatures extends TableFeatures,
> = UnionToIntersection<
{
- [K in keyof TFeatures]: TFeatures[K] extends TableFeature<
- infer FeatureConstructorOptions
- >
- ? TKey extends keyof FeatureConstructorOptions
- ? FeatureConstructorOptions[TKey]
- : never
- : any
+ [K in keyof TFeatures]: K extends 'coreReativityFeature'
+ ? never
+ : TFeatures[K] extends TableFeature
+ ? TKey extends keyof FeatureConstructorOptions
+ ? FeatureConstructorOptions[TKey]
+ : never
+ : any
}[keyof TFeatures]
>
diff --git a/packages/table-core/tests/helpers/generateTestTable.ts b/packages/table-core/tests/helpers/generateTestTable.ts
index c89144871e..3f47ee2141 100644
--- a/packages/table-core/tests/helpers/generateTestTable.ts
+++ b/packages/table-core/tests/helpers/generateTestTable.ts
@@ -1,6 +1,7 @@
import { constructTable, coreFeatures } from '../../src'
import { generateTestColumnDefs } from '../fixtures/data/generateTestColumnDefs'
import { generateTestData } from '../fixtures/data/generateTestData'
+import { constructReactivityBindings } from '../../src/core/reactivity/constructReactivityBindings'
import type {
Row,
Table,
@@ -31,6 +32,7 @@ export function generateTestTableWithData(
_features: {
...coreFeatures,
...options?._features,
+ coreReativityFeature: constructReactivityBindings(),
},
} as any)
}
@@ -47,6 +49,7 @@ export function generateTestTableFromData(
_features: {
...coreFeatures,
...options?._features,
+ coreReativityFeature: constructReactivityBindings(),
},
} as any)
}
diff --git a/packages/table-core/tests/helpers/rowPinningHelpers.ts b/packages/table-core/tests/helpers/rowPinningHelpers.ts
index a74b25dcc9..8537623555 100644
--- a/packages/table-core/tests/helpers/rowPinningHelpers.ts
+++ b/packages/table-core/tests/helpers/rowPinningHelpers.ts
@@ -2,11 +2,12 @@ import { vi } from 'vitest'
import { getDefaultRowPinningState } from '../../src/features/row-pinning/rowPinningFeature.utils'
import {
constructTable,
- createColumnHelper,
coreFeatures,
+ createColumnHelper,
rowPinningFeature,
} from '../../src'
import { generateTestData } from '../fixtures/data/generateTestData'
+import { constructReactivityBindings } from '../../src/core/reactivity/constructReactivityBindings'
import { generateTestTableWithData } from './generateTestTable'
import type { ColumnDef, RowPinningState, TableOptions } from '../../src'
import type { Person } from '../fixtures/data/types'
@@ -15,6 +16,7 @@ import type { Person } from '../fixtures/data/types'
const _features = {
...coreFeatures,
rowPinningFeature,
+ coreReativityFeature: constructReactivityBindings(),
} as any
type personKeys = keyof Person
diff --git a/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts b/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts
index eee05a687c..c5e4570e71 100644
--- a/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts
+++ b/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts
@@ -12,6 +12,7 @@ import {
createTableWithMockOnPinningChange,
} from '../../../helpers/rowPinningHelpers'
import { generateTestData } from '../../../fixtures/data/generateTestData'
+import { constructReactivityBindings } from '../../../../src/core/reactivity/constructReactivityBindings'
import type { ColumnDef, Row } from '../../../../src'
import type { Person } from '../../../fixtures/data/types'
@@ -19,6 +20,7 @@ import type { Person } from '../../../fixtures/data/types'
const _features = {
...coreFeatures,
rowPinningFeature,
+ coreReativityFeature: constructReactivityBindings(),
}
type personKeys = keyof Person
@@ -169,6 +171,7 @@ describe('table methods', () => {
...coreFeatures,
rowPinningFeature,
rowPaginationFeature,
+ coreReativityFeature: constructReactivityBindings(),
}
const table = constructTable({
@@ -178,7 +181,7 @@ describe('table methods', () => {
},
data,
columns,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
enableRowPinning: true,
renderFallbackValue: '',
initialState: {
@@ -208,6 +211,7 @@ describe('table methods', () => {
...coreFeatures,
rowPinningFeature,
rowPaginationFeature,
+ coreReativityFeature: constructReactivityBindings(),
}
const table = constructTable({
@@ -217,7 +221,7 @@ describe('table methods', () => {
},
data,
columns,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
enableRowPinning: true,
renderFallbackValue: '',
initialState: {
diff --git a/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts b/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts
index 65a510eb19..e5d661d2d3 100644
--- a/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts
+++ b/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts
@@ -1,18 +1,22 @@
import { describe, expect, it } from 'vitest'
import {
constructTable,
+ coreFeatures,
createColumnHelper,
rowSelectionFeature,
} from '../../../../src'
import * as RowSelectionUtils from '../../../../src/features/row-selection/rowSelectionFeature.utils'
import { generateTestData } from '../../../fixtures/data/generateTestData'
+import { constructReactivityBindings } from '../../../../src/core/reactivity/constructReactivityBindings'
import type { Person } from '../../../fixtures/data/types'
-import type { ColumnDef } from '../../../../src'
+import type { ColumnDef, Row } from '../../../../src'
// TODO: bring up to new test structure
const _features = {
+ ...coreFeatures,
rowSelectionFeature,
+ coreReativityFeature: constructReactivityBindings(),
}
type personKeys = keyof Person
@@ -44,7 +48,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {
'0': true,
@@ -73,7 +77,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {
'0': true,
@@ -102,7 +106,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {},
},
@@ -245,7 +249,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {},
},
@@ -269,7 +273,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {
'0.0': true,
@@ -295,7 +299,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {
'0.0': true,
@@ -318,10 +322,11 @@ describe('rowSelectionFeature', () => {
const table = constructTable({
_features,
_rowModels: {},
- enableRowSelection: (row) => row.index === 0, // only first row is selectable (of 2 sub-rows)
+ enableRowSelection: (row: Row) =>
+ row.index === 0, // only first row is selectable (of 2 sub-rows)
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {
'0.0': true, // first sub-row
@@ -346,7 +351,7 @@ describe('rowSelectionFeature', () => {
enableRowSelection: true,
renderFallbackValue: '',
data,
- getSubRows: (row) => row.subRows,
+ getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
initialState: {
rowSelection: {
'0.0.0': true, // first nested sub-row
diff --git a/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts b/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts
index 89c45cc525..89525337d3 100644
--- a/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts
+++ b/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts
@@ -8,6 +8,7 @@ import {
} from '../../../../src'
import { createColumnHelper } from '../../../../src/helpers/columnHelper'
import { generateTestData } from '../../../fixtures/data/generateTestData'
+import { constructReactivityBindings } from '../../../../src/core/reactivity/constructReactivityBindings'
import type { Person } from '../../../fixtures/data/types'
import type { ColumnDef } from '../../../../src'
@@ -42,7 +43,11 @@ describe('#getGroupedRowModel', () => {
data.forEach((p) => (p.age = 123))
const table = constructTable({
- _features: { columnGroupingFeature, ...coreFeatures },
+ _features: {
+ columnGroupingFeature,
+ ...coreFeatures,
+ coreReativityFeature: constructReactivityBindings(),
+ },
_rowModels: {
groupedRowModel: createGroupedRowModel(aggregationFns),
},
diff --git a/packages/table-core/tests/unit/core/columns/constructColumn.test.ts b/packages/table-core/tests/unit/core/columns/constructColumn.test.ts
index 13f1e190cd..cab80dec67 100644
--- a/packages/table-core/tests/unit/core/columns/constructColumn.test.ts
+++ b/packages/table-core/tests/unit/core/columns/constructColumn.test.ts
@@ -2,12 +2,16 @@ import { describe, expect, it } from 'vitest'
import { coreColumnsFeature } from '../../../../src/core/columns/coreColumnsFeature'
import { constructColumn } from '../../../../src/core/columns/constructColumn'
import { constructTable } from '../../../../src'
+import { constructReactivityBindings } from '../../../../src/core/reactivity/constructReactivityBindings'
import type { ColumnDef } from '../../../../src/types/ColumnDef'
describe('constructColumn', () => {
it('should create a column with all core column APIs and properties', () => {
const table = constructTable({
- _features: { coreColumnsFeature },
+ _features: {
+ coreColumnsFeature,
+ coreReativityFeature: constructReactivityBindings(),
+ },
columns: [] as Array,
data: [] as Array,
})
diff --git a/packages/table-core/tests/unit/core/table/constructTable.test.ts b/packages/table-core/tests/unit/core/table/constructTable.test.ts
index 0846fa18bd..cf9a489d95 100644
--- a/packages/table-core/tests/unit/core/table/constructTable.test.ts
+++ b/packages/table-core/tests/unit/core/table/constructTable.test.ts
@@ -1,11 +1,13 @@
import { describe, expect, it } from 'vitest'
import { constructTable, coreFeatures } from '../../../../src'
+import { constructReactivityBindings } from '../../../../src/core/reactivity/constructReactivityBindings'
describe('constructTable', () => {
it('should create a table with all core table APIs and properties', () => {
const table = constructTable({
_features: {
...coreFeatures,
+ coreReativityFeature: constructReactivityBindings(),
},
columns: [],
data: [],
diff --git a/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts b/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts
index 88d66abfd6..e14704da3e 100644
--- a/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts
+++ b/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts
@@ -1,10 +1,14 @@
import { describe, expect, it } from 'vitest'
import { constructTable, stockFeatures } from '../../../../src'
+import { constructReactivityBindings } from '../../../../src/core/reactivity/constructReactivityBindings'
describe('constructTable with stockFeatures', () => {
it('should include all feature states in initial state', () => {
const table = constructTable({
- _features: stockFeatures,
+ _features: {
+ ...stockFeatures,
+ coreReativityFeature: constructReactivityBindings(),
+ },
columns: [],
data: [],
})
diff --git a/packages/table-core/tests/unit/core/tableAtoms.test.ts b/packages/table-core/tests/unit/core/tableAtoms.test.ts
index e3c3312135..b10ba9f200 100644
--- a/packages/table-core/tests/unit/core/tableAtoms.test.ts
+++ b/packages/table-core/tests/unit/core/tableAtoms.test.ts
@@ -2,12 +2,17 @@ import { describe, expect, it, vi } from 'vitest'
import { createAtom } from '@tanstack/store'
import {
constructTable,
+ coreFeatures,
rowPaginationFeature,
rowSelectionFeature,
rowSortingFeature,
} from '../../../src'
-import type { Table_Internal } from '../../../src'
-import type { PaginationState, SortingState } from '../../../src'
+import { constructReactivityBindings } from '../../../src/core/reactivity/constructReactivityBindings'
+import type {
+ PaginationState,
+ SortingState,
+ Table_Internal,
+} from '../../../src'
const _features = {
rowPaginationFeature,
@@ -17,7 +22,11 @@ const _features = {
function makeTable(options: any = {}) {
return constructTable({
- _features,
+ _features: {
+ ...coreFeatures,
+ ..._features,
+ coreReativityFeature: constructReactivityBindings(),
+ },
_rowModels: {},
columns: [],
data: [],
diff --git a/packages/table-core/tsdown.config.ts b/packages/table-core/tsdown.config.ts
index c305d9b999..ff0c1b884d 100644
--- a/packages/table-core/tsdown.config.ts
+++ b/packages/table-core/tsdown.config.ts
@@ -5,6 +5,7 @@ export default defineConfig({
'./src/index.ts',
'./src/static-functions.ts',
'./src/flex-render.ts',
+ './src/reactivity.ts',
],
format: ['esm', 'cjs'],
unbundle: true,
diff --git a/packages/vue-table/src/reactivity.ts b/packages/vue-table/src/reactivity.ts
new file mode 100644
index 0000000000..7c1ba3788c
--- /dev/null
+++ b/packages/vue-table/src/reactivity.ts
@@ -0,0 +1,63 @@
+import { computed, shallowRef, watch } from 'vue'
+import type {
+ TableAtomOptions,
+ TableReactivityBindings,
+} from '@tanstack/table-core/reactivity'
+import type { Atom, Observer, ReadonlyAtom } from '@tanstack/vue-store'
+import type { ComputedRef, ShallowRef } from 'vue'
+
+function observerToCallback(
+ observerOrNext: Observer | ((value: T) => void),
+): (value: T) => void {
+ return typeof observerOrNext === 'function'
+ ? observerOrNext
+ : (value) => observerOrNext.next?.(value)
+}
+
+function refToReadonlyAtom(
+ source: ComputedRef | ShallowRef,
+): ReadonlyAtom {
+ return Object.assign(source, {
+ get: () => source.value,
+ subscribe: ((observerOrNext: Observer | ((value: T) => void)) => {
+ const stop = watch(source, observerToCallback(observerOrNext), {
+ flush: 'sync',
+ })
+ return { unsubscribe: stop }
+ }) as ReadonlyAtom['subscribe'],
+ })
+}
+
+function refToWritableAtom(source: ShallowRef): Atom {
+ return Object.assign(source, {
+ set: (updater: T | ((prevVal: T) => T)) => {
+ source.value =
+ typeof updater === 'function'
+ ? (updater as (prevVal: T) => T)(source.value)
+ : updater
+ },
+ get: () => source.value,
+ subscribe: ((observerOrNext: Observer | ((value: T) => void)) => {
+ const stop = watch(source, observerToCallback(observerOrNext), {
+ flush: 'sync',
+ })
+ return { unsubscribe: stop }
+ }) as Atom['subscribe'],
+ })
+}
+
+export function vueReactivity(): TableReactivityBindings {
+ return {
+ createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => {
+ return refToReadonlyAtom(computed(fn))
+ },
+ createWritableAtom: (
+ value: T,
+ _options?: TableAtomOptions,
+ ): Atom => {
+ return refToWritableAtom(shallowRef(value) as ShallowRef)
+ },
+ untrack: (fn) => fn(),
+ batch: (fn) => fn(),
+ }
+}
diff --git a/packages/vue-table/src/useTable.ts b/packages/vue-table/src/useTable.ts
index 4cb84d7d94..f7ddef6c8b 100644
--- a/packages/vue-table/src/useTable.ts
+++ b/packages/vue-table/src/useTable.ts
@@ -1,10 +1,8 @@
-import { isRef, ref, unref, watch, watchEffect } from 'vue'
-import {
- constructReactivityFeature,
- constructTable,
-} from '@tanstack/table-core'
+import { unref, watch } from 'vue'
+import { constructTable } from '@tanstack/table-core'
import { shallow, useSelector } from '@tanstack/vue-store'
import { mergeProxy } from './merge-proxy'
+import { vueReactivity } from './reactivity'
import type { Atom, ReadonlyAtom } from '@tanstack/vue-store'
import type {
NoInfer,
@@ -106,8 +104,6 @@ export function useTable<
selector: (state: TableState) => TSelected = () =>
({}) as TSelected,
): VueTable {
- const notifier = ref(0)
-
const syncTableOptions = (
table: Table,
options: TableOptionsWithReactiveData,
@@ -118,16 +114,11 @@ export function useTable<
)
}
- const vueReactivityFeature = constructReactivityFeature({
- stateNotifier: () => notifier.value,
- optionsNotifier: () => notifier.value,
- })
-
const mergedOptions = {
...tableOptions,
_features: {
+ coreReativityFeature: vueReactivity(),
...tableOptions._features,
- vueReactivityFeature,
},
}
@@ -152,15 +143,6 @@ export function useTable<
TSelected
>
- const allState = useSelector(table.store, (state) => state)
- const allOptions = useSelector(table.optionsStore, (state) => state)
-
- watchEffect(() => {
- allState.value
- allOptions.value
- notifier.value++
- })
-
watch(
() =>
getReactiveOptionDeps(
diff --git a/packages/vue-table/tests/unit/signals.test.ts b/packages/vue-table/tests/unit/signals.test.ts
new file mode 100644
index 0000000000..49698eb2ae
--- /dev/null
+++ b/packages/vue-table/tests/unit/signals.test.ts
@@ -0,0 +1,22 @@
+import { describe, expect, test } from 'vitest'
+import { nextTick } from 'vue'
+import { vueReactivity } from '../../src/reactivity'
+
+describe('vueReactivity', () => {
+ test('creates writable and readonly atoms from Vue refs', async () => {
+ const reactivity = vueReactivity()
+ const count = reactivity.createWritableAtom(1, { debugName: 'count' })
+ const doubled = reactivity.createReadonlyAtom(() => count.get() * 2, {
+ debugName: 'doubled',
+ })
+
+ expect(count.get()).toBe(1)
+ expect(doubled.get()).toBe(2)
+
+ count.set((value) => value + 1)
+ await nextTick()
+
+ expect(count.get()).toBe(2)
+ expect(doubled.get()).toBe(4)
+ })
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index aa9d0ff920..fa78e6b54e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3715,7 +3715,7 @@ importers:
specifier: ^2.1.1
version: 2.1.1
dayjs:
- specifier: ^1.11.13
+ specifier: ^1.11.20
version: 1.11.20
react:
specifier: ^19.2.5
@@ -4325,8 +4325,8 @@ importers:
specifier: ^19.2.5
version: 19.2.5(react@19.2.5)
zod:
- specifier: ^4.4.1
- version: 4.4.1
+ specifier: ^4.4.2
+ version: 4.4.2
devDependencies:
'@rolldown/plugin-babel':
specifier: ^0.2.3
@@ -4427,8 +4427,8 @@ importers:
specifier: ^6.0.3
version: 6.0.3(rollup@4.60.2)
'@tanstack/router-vite-plugin':
- specifier: ^1.166.46
- version: 1.166.46(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))
+ specifier: ^1.166.47
+ version: 1.166.47(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))
'@types/react':
specifier: ^19.2.14
version: 19.2.14
@@ -5081,8 +5081,8 @@ importers:
specifier: ^1.9.12
version: 1.9.12
zod:
- specifier: ^4.4.1
- version: 4.4.1
+ specifier: ^4.4.2
+ version: 4.4.2
devDependencies:
'@faker-js/faker':
specifier: ^10.4.0
@@ -5144,8 +5144,8 @@ importers:
specifier: ^10.4.0
version: 10.4.0
'@tanstack/router-vite-plugin':
- specifier: ^1.166.46
- version: 1.166.46(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))
+ specifier: ^1.166.47
+ version: 1.166.47(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))
typescript:
specifier: 6.0.3
version: 6.0.3
@@ -6027,8 +6027,8 @@ importers:
specifier: ^9.0.0-alpha.41
version: link:../../../packages/svelte-table
zod:
- specifier: ^4.4.1
- version: 4.4.1
+ specifier: ^4.4.2
+ version: 4.4.2
devDependencies:
'@faker-js/faker':
specifier: ^10.4.0
@@ -7025,8 +7025,8 @@ importers:
specifier: ^3.5.33
version: 3.5.33(typescript@6.0.3)
zod:
- specifier: ^4.4.1
- version: 4.4.1
+ specifier: ^4.4.2
+ version: 4.4.2
devDependencies:
'@types/node':
specifier: ^25.6.0
@@ -7139,6 +7139,9 @@ importers:
packages/preact-table:
dependencies:
+ '@preact/signals':
+ specifier: ^2.9.0
+ version: 2.9.0(preact@10.29.1)
'@tanstack/preact-store':
specifier: ^0.13.0
version: 0.13.0(preact@10.29.1)
@@ -7182,8 +7185,8 @@ importers:
version: link:../table-core
devDependencies:
'@eslint-react/eslint-plugin':
- specifier: ^5.6.6
- version: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ specifier: ^5.7.0
+ version: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@types/react':
specifier: ^19.2.14
version: 19.2.14
@@ -7219,8 +7222,8 @@ importers:
version: 19.2.5(react@19.2.5)
devDependencies:
'@eslint-react/eslint-plugin':
- specifier: ^5.6.6
- version: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ specifier: ^5.7.0
+ version: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@tanstack/table-core':
specifier: workspace:*
version: link:../table-core
@@ -8939,50 +8942,50 @@ packages:
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- '@eslint-react/ast@5.6.6':
- resolution: {integrity: sha512-/JQtRvhfYXs3mUbwXROezatFNR6icnU0nLOagNMseg+zkXsUvaITJyWqcRMz4xXXzvoAGwUjCwiuT+iWAVg5zg==}
+ '@eslint-react/ast@5.7.0':
+ resolution: {integrity: sha512-axxvjF/ExVyhXcyS5IUWtz/jP3mXzDt416tr+rWmlb6RPPqdG8tnyNgPXX0rLXHsC2yjfc7LmRuDwUO61hbG2w==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- '@eslint-react/core@5.6.6':
- resolution: {integrity: sha512-bSswvxQlwXJ2vnPm/OkgNS3gVbRC4nL/ZpuLi67qGFb1/ORk1OilzO0bSMVVdp9j1v0H2cNxq6pOJVPGbS7xsw==}
+ '@eslint-react/core@5.7.0':
+ resolution: {integrity: sha512-PoEXxwa5ob/uuE8y/rXZX047ysd0bsdNwsumqU0fLZmdWjOrV+ZS7tmu83HmqMIRmkHKrKTEisMqFCaNZujKIQ==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- '@eslint-react/eslint-plugin@5.6.6':
- resolution: {integrity: sha512-xxeB32eATjdyBb6WMBQlQc1w5NftahLBhz0jWdbyPKHIpYJZXtJ997tNuOTFnvAayRMjWlzl6tCTfhyInu2Uaw==}
+ '@eslint-react/eslint-plugin@5.7.0':
+ resolution: {integrity: sha512-3JgMd9TudbaUF5AyAY+4xnL5lw3+Nadfh6fIEENc6IXJEQkYKegudfJQtWnUke4Ux2prl34GcVtlJfUP63Uurg==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- '@eslint-react/eslint@5.6.6':
- resolution: {integrity: sha512-LhOKn0QsHukmfwsKEVS/bdnpzT3/XW1Tb8Yx22IiwuK56evx+5szFSCBy7qXSEvjKvgDl1CznujS70IcdpsJvA==}
+ '@eslint-react/eslint@5.7.0':
+ resolution: {integrity: sha512-U0DJvQqTAHok4yjIzSHp2Eg4fTSAH32pAzOYJTpfe2K0dV7XryXgQxYaHlrPRr9nzTeTTdQNTk7JywhsOQRnvQ==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- '@eslint-react/jsx@5.6.6':
- resolution: {integrity: sha512-sJTUmCXEnJ6Fm1Cdu+a/zVuTXQys+9HVSVLKrgxgTp9XMBIl1v5dz+axiIeQ5VxfWxvFQJVdUS7CKGoivu/CRg==}
+ '@eslint-react/jsx@5.7.0':
+ resolution: {integrity: sha512-dUqohdmq8Jvzz7I4DN8uPfMyKNRRaRs2s0EluSq9WiRu8BT64VH11wwLj9HJTTtx4PJDmRuUZClnd7jENz0N6g==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- '@eslint-react/shared@5.6.6':
- resolution: {integrity: sha512-gh3xE3rusNuxUxv0OIVzpPp1mQy5KvKGGZ0oQ44mtZwKiGN25MTaY/HzLqN5SsSudxF/bDr6uKDChPct59s+qQ==}
+ '@eslint-react/shared@5.7.0':
+ resolution: {integrity: sha512-YNI7Mqo4aGbwXOR3mvIL4+RVmiHilQa8btvAu9uHgac8KPqPWng5dtoWVEy2NsaA3lUDq6j0W8AItYb4YsjgIA==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- '@eslint-react/var@5.6.6':
- resolution: {integrity: sha512-i42rRnDCQ2SrNAo0fMRj/X5ycvpsOZ860mhVbj64sqAOSfrgbh0IdMXMazz1bv1wwfR8Q2QD1K+GM08WzvvmpA==}
+ '@eslint-react/var@5.7.0':
+ resolution: {integrity: sha512-aEOcxuXojdKXRKRo2GIko5Je5AAKjwPkNy1czX4IbL3c+HRoQ2dK6UPgRiCXR0lfq3HBv0ArUTN4z4E23ZF+JQ==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
@@ -10378,6 +10381,14 @@ packages:
'@babel/core': 7.x
vite: 2.x || 3.x || 4.x || 5.x || 6.x || 7.x || 8.x
+ '@preact/signals-core@1.14.1':
+ resolution: {integrity: sha512-vxPpfXqrwUe9lpjqfYNjAF/0RF/eFGeLgdJzdmIIZjpOnTmGmAB4BjWone562mJGMRP4frU6iZ6ei3PDsu52Ng==}
+
+ '@preact/signals@2.9.0':
+ resolution: {integrity: sha512-hYrY0KyUqkDgOl1qba/JGn6y81pXnurn21PMaxfcMwdncdZ3M/oVdmpTvEnsGjh48dIwDVc7bjWHqIsngSjYug==}
+ peerDependencies:
+ preact: '>= 10.25.0 || >=11.0.0-0'
+
'@prefresh/babel-plugin@0.5.3':
resolution: {integrity: sha512-57LX2SHs4BX2s1IwCjNzTE2OJeEepRCNf1VTEpbNcUyHfMO68eeOWGDIt4ob9aYlW6PEWZ1SuwNikuoIXANDtQ==}
@@ -11932,8 +11943,8 @@ packages:
resolution: {integrity: sha512-j2OW/UvpjM/DT9tHVmuhWW1k6UOezTRrPqBPZFFmIth0fY7iTPqK+Erqpo8r5yGTRGCbMvOS4sL3H2MldnIZew==}
engines: {node: '>=20.19'}
- '@tanstack/router-plugin@1.167.31':
- resolution: {integrity: sha512-WP+joQGNKXIKDvitX7KydHtTVQyzrnPwqSo2e/IwF5arD31Rwg1arlbze7ZSdEJCOrUhHrBP1/WmqbmeENFTTA==}
+ '@tanstack/router-plugin@1.167.32':
+ resolution: {integrity: sha512-i9BA6GzUCoM20UYZ77orXzHwD5zM0OQTtLuPNbqTTSG38CvR6viRFP/d+QFo2aRNyCvun8PR7zSa49bslSggEQ==}
engines: {node: '>=20.19'}
hasBin: true
peerDependencies:
@@ -11958,8 +11969,8 @@ packages:
resolution: {integrity: sha512-VkY0u7ax/GD0qU6ZLLnfPC+UMxVzxRbvZp4yV4iUSXjgJZ/siAT5/QlLm9FEDJ9QDoC0VD9W7f00tKKreUI7Ng==}
engines: {node: '>=20.19'}
- '@tanstack/router-vite-plugin@1.166.46':
- resolution: {integrity: sha512-m6G5VTzlOvXuVb8p1EEOHs9pZ714Q8UeveVHQ51PX0XiOh4M54i0cRUYTtwa+mRSIComVHOk997SrfFibPNJcw==}
+ '@tanstack/router-vite-plugin@1.166.47':
+ resolution: {integrity: sha512-9/SElKRWMP8qVR7+cU+LZpPu9P0bp+Ph+xf/idde3D6Uid+EieFWjH6WrMx+I3k7fsbsGP/bxFF89Xmi5D0IGg==}
engines: {node: '>=20.19'}
'@tanstack/solid-devtools@0.8.2':
@@ -13561,8 +13572,8 @@ packages:
peerDependencies:
eslint: '>=7'
- eslint-plugin-react-dom@5.6.6:
- resolution: {integrity: sha512-2feT8VFFVUFiW6XGi43+YuF70+sEljA4jdqhOt30urmEfLQzxjlaV1EV2AeQSmIYd8Xp39GnHrTDvePbt79YDg==}
+ eslint-plugin-react-dom@5.7.0:
+ resolution: {integrity: sha512-aA3d27vFUqhfNnmBB9/b8INvBcJcVfIwrpdagBtzr5baHsznw8+VM02lCJeRW2l/0fHBKRctWQn3lRo1fPNCgQ==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
@@ -13574,36 +13585,36 @@ packages:
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0
- eslint-plugin-react-jsx@5.6.6:
- resolution: {integrity: sha512-iCn5FMzerdCERMv4+Orpn7/E3WJnnu10PmAtyqgTrLQgy+UvWIPvEC2qRpnez/9cZsu1AtLL/xtYa+R55jGozg==}
+ eslint-plugin-react-jsx@5.7.0:
+ resolution: {integrity: sha512-tTeXNK1QP6YvfMyTCWg8i1ZHHFM67KKBWBNsayI/WAQ9micZ9m2vprbk/EPFJ/RgWqUgT7swIzt4powxiGqTqw==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- eslint-plugin-react-naming-convention@5.6.6:
- resolution: {integrity: sha512-T9ys5uzp0a4Rg5oh71L52uWyGPzv21adNXb2rB+RO/o+2we7oCv2sxW5hUMu8F3d2zZmDPJtz42ASghaxGOo4w==}
+ eslint-plugin-react-naming-convention@5.7.0:
+ resolution: {integrity: sha512-s71ZdDG8sPlsP0H64Dy4FHgD/11FpsXWhKjkSo1rcTs5i9bONJwxRzUQV/99cTtigYSojaEb/fi/r7plo3ezmw==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- eslint-plugin-react-rsc@5.6.6:
- resolution: {integrity: sha512-tBm5dtr8b755kLP5W/giV/0t4j9SVTEMxvZvVwtY8uD45Jn6TynNIH02jv9fRfuCsNsWehTT4ZEjbopiRPtgmw==}
+ eslint-plugin-react-rsc@5.7.0:
+ resolution: {integrity: sha512-fMZyrb8mW5EiQzrJRjM083+3EwAGgsTBXo7B7LFEUDcjV+CwH98hwjNRqLKN0GYPiGK5XVmMXg19P2sv5kI9MA==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- eslint-plugin-react-web-api@5.6.6:
- resolution: {integrity: sha512-3SRULmUUi/Gt9I655pkNJeB+YVGw+Bc25dWoLPgis+Sfw+H4fjyXyrofcN6SdumcxU5RMiSO2yuw6v8O6Sj3RA==}
+ eslint-plugin-react-web-api@5.7.0:
+ resolution: {integrity: sha512-fiPrh9V/WuRGM+ie0IaLMj9mE/dLhkqZ9PLBJ9MWVH/NMZLigGX5uSDshrR7Hafm/b58XkM9Af3tt0wH99RC5w==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
typescript: '*'
- eslint-plugin-react-x@5.6.6:
- resolution: {integrity: sha512-Szx1VkEEell+b3j99dNHY0OJqCtDldfFaQLS0BmvlUOfV27cn/4yFqal9/0Tq8lU0T4Gvi0iiDhSmxib6KsyPA==}
+ eslint-plugin-react-x@5.7.0:
+ resolution: {integrity: sha512-bt0q1X1eK8fz0wJsBPWQvuNexDzM6jWjADM7qpdVEHm6uYnIiJaW0GIgrLecwt1YCmNyAcdh3kEeNFHEmeXfdw==}
engines: {node: '>=22.0.0'}
peerDependencies:
eslint: ^10.2.1
@@ -16775,8 +16786,8 @@ packages:
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
- zod@4.4.1:
- resolution: {integrity: sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==}
+ zod@4.4.2:
+ resolution: {integrity: sha512-IynmDyxsEsb9RKzO3J9+4SxXnl2FTFSzNBaKKaMV6tsSk0rw9gYw9gs+JFCq/qk2LCZ78KDwyj+Z289TijSkUw==}
snapshots:
@@ -18688,7 +18699,7 @@ snapshots:
'@eslint-community/regexpp@4.12.2': {}
- '@eslint-react/ast@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/ast@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3)
@@ -18699,13 +18710,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint-react/core@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/core@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/jsx': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/var': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/jsx': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/var': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/scope-manager': 8.59.1
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
@@ -18715,21 +18726,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint-react/eslint-plugin@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/eslint-plugin@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
- eslint-plugin-react-dom: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- eslint-plugin-react-jsx: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- eslint-plugin-react-naming-convention: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- eslint-plugin-react-rsc: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- eslint-plugin-react-web-api: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- eslint-plugin-react-x: 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ eslint-plugin-react-dom: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ eslint-plugin-react-jsx: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ eslint-plugin-react-naming-convention: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ eslint-plugin-react-rsc: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ eslint-plugin-react-web-api: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ eslint-plugin-react-x: 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@eslint-react/eslint@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/eslint@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
@@ -18737,12 +18748,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint-react/jsx@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/jsx@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/var': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/var': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
@@ -18751,21 +18762,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint-react/shared@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/shared@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
ts-pattern: 5.9.0
typescript: 6.0.3
- zod: 4.4.1
+ zod: 4.4.2
transitivePeerDependencies:
- supports-color
- '@eslint-react/var@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
+ '@eslint-react/var@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)':
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/scope-manager': 8.59.1
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
@@ -19957,6 +19968,13 @@ snapshots:
- rollup
- supports-color
+ '@preact/signals-core@1.14.1': {}
+
+ '@preact/signals@2.9.0(preact@10.29.1)':
+ dependencies:
+ '@preact/signals-core': 1.14.1
+ preact: 10.29.1
+
'@prefresh/babel-plugin@0.5.3': {}
'@prefresh/core@1.5.9(preact@10.29.1)':
@@ -21457,7 +21475,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@tanstack/router-plugin@1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))':
+ '@tanstack/router-plugin@1.167.32(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))':
dependencies:
'@babel/core': 7.29.0
'@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
@@ -21494,9 +21512,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@tanstack/router-vite-plugin@1.166.46(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))':
+ '@tanstack/router-vite-plugin@1.166.47(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))':
dependencies:
- '@tanstack/router-plugin': 1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))
+ '@tanstack/router-plugin': 1.167.32(@tanstack/react-router@1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite-plugin-solid@2.11.12(@testing-library/jest-dom@6.9.1)(solid-js@1.9.12)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3)))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(less@4.6.4)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.13))(terser@5.46.0)(yaml@2.8.3))(webpack@5.105.2(esbuild@0.28.0))
transitivePeerDependencies:
- '@rsbuild/core'
- '@tanstack/react-router'
@@ -23362,12 +23380,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-dom@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
+ eslint-plugin-react-dom@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/jsx': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/jsx': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
compare-versions: 6.1.1
@@ -23382,18 +23400,18 @@ snapshots:
'@babel/parser': 7.29.2
eslint: 10.3.0(jiti@2.6.1)
hermes-parser: 0.25.1
- zod: 4.4.1
- zod-validation-error: 4.0.2(zod@4.4.1)
+ zod: 4.4.2
+ zod-validation-error: 4.0.2(zod@4.4.2)
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-jsx@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
+ eslint-plugin-react-jsx@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/core': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/jsx': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/core': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/jsx': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
@@ -23401,12 +23419,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-naming-convention@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
+ eslint-plugin-react-naming-convention@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/core': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/var': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/core': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/var': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
@@ -23415,13 +23433,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-rsc@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
+ eslint-plugin-react-rsc@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/core': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/var': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/core': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/var': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
eslint: 10.3.0(jiti@2.6.1)
@@ -23429,13 +23447,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-web-api@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
+ eslint-plugin-react-web-api@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/core': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/var': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/core': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/var': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
'@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
birecord: 0.1.1
@@ -23445,14 +23463,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-x@5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
+ eslint-plugin-react-x@5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3):
dependencies:
- '@eslint-react/ast': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/core': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/eslint': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/jsx': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/shared': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
- '@eslint-react/var': 5.6.6(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/ast': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/core': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/eslint': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/jsx': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/shared': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
+ '@eslint-react/var': 5.7.0(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/scope-manager': 8.59.1
'@typescript-eslint/type-utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3)
'@typescript-eslint/types': 8.59.1
@@ -24270,7 +24288,7 @@ snapshots:
tinyglobby: 0.2.16
unbash: 3.0.0
yaml: 2.8.3
- zod: 4.4.1
+ zod: 4.4.2
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
@@ -27100,12 +27118,12 @@ snapshots:
dependencies:
zod: 3.25.76
- zod-validation-error@4.0.2(zod@4.4.1):
+ zod-validation-error@4.0.2(zod@4.4.2):
dependencies:
- zod: 4.4.1
+ zod: 4.4.2
zod@3.25.76: {}
zod@4.3.6: {}
- zod@4.4.1: {}
+ zod@4.4.2: {}