@tanstack/svelte-table 9.0.0-beta.59 → 9.0.0-beta.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,47 +1,38 @@
1
- import type { RowData, Table, TableFeatures, TableOptions, TableState } from '@tanstack/table-core';
2
- export type SvelteTable<TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState<TFeatures>> = Omit<Table<TFeatures, TData>, 'store'> & {
3
- /**
4
- * @deprecated Prefer `table.state` for render reads,
5
- * `table.atoms.<slice>.get()` for slice snapshots, or
6
- * `useSelector(table.store, selector)` for explicit subscriptions.
7
- * `table.store.state` is a current-value snapshot and is easy to misuse in
8
- * render code.
9
- */
10
- readonly store: Table<TFeatures, TData>['store'];
11
- /**
12
- * The selected state of the table. This state may not match the structure of
13
- * the full table state because it is selected by the selector function that
14
- * you pass as the 2nd argument to `createTable`.
15
- *
16
- * @example
17
- * const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
18
- *
19
- * console.log(table.state.globalFilter)
20
- */
21
- readonly state: Readonly<TSelected>;
22
- };
1
+ import type { RowData, Table, TableFeatures, TableOptions } from '@tanstack/table-core';
2
+ /**
3
+ * A Svelte-aware TanStack Table instance.
4
+ *
5
+ * Table APIs and `table.atoms.<slice>.get()` reads participate in Svelte
6
+ * dependency tracking when used in templates, `$derived`, or `$effect`.
7
+ */
8
+ export type SvelteTable<TFeatures extends TableFeatures, TData extends RowData> = Table<TFeatures, TData>;
23
9
  /**
24
10
  * Creates a Svelte 5 table instance backed by rune-aware TanStack Store atoms.
25
11
  *
26
- * The optional selector projects from `table.store`; the selected value is
27
- * exposed on `table.state`. The adapter syncs options in `$effect.pre`, so
28
- * reactive option getters and external `$state` values are applied before DOM
29
- * updates read table APIs such as `getRowModel()`.
12
+ * Read a specific state slice with `table.atoms.<slice>.get()` and read the
13
+ * complete state with `table.store.get()`. Those reads participate in Svelte
14
+ * dependency tracking when they run in a template, `$derived`, or `$effect`.
15
+ * The adapter syncs options in `$effect.pre`, so reactive option getters and
16
+ * external `$state` values are applied before DOM updates read table APIs such
17
+ * as `getRowModel()`.
30
18
  *
31
19
  * @example
32
20
  * ```svelte
33
21
  * <script lang="ts">
34
- * const table = createTable(
35
- * {
36
- * features,
37
- * columns,
38
- * data,
22
+ * const table = createTable({
23
+ * features,
24
+ * columns,
25
+ * get data() {
26
+ * return data
39
27
  * },
40
- * (state) => ({ pagination: state.pagination }),
41
- * )
28
+ * })
29
+ *
30
+ * const pagination = $derived(table.atoms.pagination.get())
31
+ * const stateJson = $derived(JSON.stringify(table.store.get(), null, 2))
42
32
  * </script>
43
33
  *
44
- * {table.state.pagination.pageIndex}
34
+ * <span>Page {pagination.pageIndex + 1}</span>
35
+ * <pre>{stateJson}</pre>
45
36
  * ```
46
37
  */
47
- export declare function createTable<TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState<TFeatures>>(tableOptions: TableOptions<TFeatures, TData>, selector?: (state: TableState<TFeatures>) => TSelected): SvelteTable<TFeatures, TData, TSelected>;
38
+ export declare function createTable<TFeatures extends TableFeatures, TData extends RowData>(tableOptions: TableOptions<TFeatures, TData>): SvelteTable<TFeatures, TData>;
@@ -1,33 +1,37 @@
1
1
  import { constructTable } from '@tanstack/table-core';
2
- import { useSelector } from '@tanstack/svelte-store';
3
2
  import { untrack } from 'svelte';
4
3
  import { flatMerge, mergeObjects } from './merge-objects';
5
4
  import { svelteReactivity } from './reactivity.svelte';
6
5
  /**
7
6
  * Creates a Svelte 5 table instance backed by rune-aware TanStack Store atoms.
8
7
  *
9
- * The optional selector projects from `table.store`; the selected value is
10
- * exposed on `table.state`. The adapter syncs options in `$effect.pre`, so
11
- * reactive option getters and external `$state` values are applied before DOM
12
- * updates read table APIs such as `getRowModel()`.
8
+ * Read a specific state slice with `table.atoms.<slice>.get()` and read the
9
+ * complete state with `table.store.get()`. Those reads participate in Svelte
10
+ * dependency tracking when they run in a template, `$derived`, or `$effect`.
11
+ * The adapter syncs options in `$effect.pre`, so reactive option getters and
12
+ * external `$state` values are applied before DOM updates read table APIs such
13
+ * as `getRowModel()`.
13
14
  *
14
15
  * @example
15
16
  * ```svelte
16
17
  * <script lang="ts">
17
- * const table = createTable(
18
- * {
19
- * features,
20
- * columns,
21
- * data,
18
+ * const table = createTable({
19
+ * features,
20
+ * columns,
21
+ * get data() {
22
+ * return data
22
23
  * },
23
- * (state) => ({ pagination: state.pagination }),
24
- * )
24
+ * })
25
+ *
26
+ * const pagination = $derived(table.atoms.pagination.get())
27
+ * const stateJson = $derived(JSON.stringify(table.store.get(), null, 2))
25
28
  * </script>
26
29
  *
27
- * {table.state.pagination.pageIndex}
30
+ * <span>Page {pagination.pageIndex + 1}</span>
31
+ * <pre>{stateJson}</pre>
28
32
  * ```
29
33
  */
30
- export function createTable(tableOptions, selector) {
34
+ export function createTable(tableOptions) {
31
35
  // 1. Merge reactivity into options using mergeObjects (preserves getters)
32
36
  const mergedOptions = mergeObjects(tableOptions, {
33
37
  features: {
@@ -66,14 +70,5 @@ export function createTable(tableOptions, selector) {
66
70
  });
67
71
  });
68
72
  });
69
- // 5. State selector
70
- const stateStore = useSelector(table.store, selector);
71
- Object.defineProperty(table, 'state', {
72
- get() {
73
- return stateStore.current;
74
- },
75
- configurable: true,
76
- enumerable: true,
77
- });
78
73
  return table;
79
74
  }
@@ -1,7 +1,7 @@
1
1
  import FlexRenderSvelte from './FlexRender.svelte';
2
2
  import type { SvelteTable } from './createTable.svelte';
3
3
  import type { Component, Snippet } from 'svelte';
4
- import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, Cell, CellContext, CellData, Column, ColumnDef, DeepKeys, DeepValue, DisplayColumnDef, GroupColumnDef, Header, IdentifiedColumnDef, NoInfer, Row, RowData, Table, TableFeatures, TableOptions, TableState } from '@tanstack/table-core';
4
+ import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, Cell, CellContext, CellData, Column, ColumnDef, DeepKeys, DeepValue, DisplayColumnDef, GroupColumnDef, Header, IdentifiedColumnDef, NoInfer, Row, RowData, Table, TableFeatures, TableOptions } from '@tanstack/table-core';
5
5
  export type ComponentType<T extends Record<string, any>> = Component<T>;
6
6
  /**
7
7
  * Enhanced CellContext with pre-bound cell components.
@@ -112,9 +112,10 @@ export type CreateTableHookOptions<TFeatures extends TableFeatures, TTableCompon
112
112
  headerComponents?: THeaderComponents;
113
113
  };
114
114
  /**
115
- * Extended table API returned by createAppTable with all App wrapper components.
115
+ * Svelte-aware table returned by `createAppTable`, extended with the registered
116
+ * table components and the `App*` context wrappers.
116
117
  */
117
- export type AppSvelteTable<TFeatures extends TableFeatures, TData extends RowData, TSelected, TTableComponents extends Record<string, ComponentType<any>>, TCellComponents extends Record<string, ComponentType<any>>, THeaderComponents extends Record<string, ComponentType<any>>> = SvelteTable<TFeatures, TData, TSelected> & NoInfer<TTableComponents> & {
118
+ export type AppSvelteTable<TFeatures extends TableFeatures, TData extends RowData, TTableComponents extends Record<string, ComponentType<any>>, TCellComponents extends Record<string, ComponentType<any>>, THeaderComponents extends Record<string, ComponentType<any>>> = SvelteTable<TFeatures, TData> & NoInfer<TTableComponents> & {
118
119
  /**
119
120
  * Root wrapper component that provides table context.
120
121
  * @example
@@ -200,20 +201,18 @@ export interface CreateTableHookResult<TFeatures extends TableFeatures, TTableCo
200
201
  /**
201
202
  * Creates a table with the `App*` wrapper components and registered
202
203
  * `tableComponents` attached. `TData` is inferred from the `data` option.
204
+ *
205
+ * Read table state with `table.atoms.<slice>.get()` or `table.store.get()`.
206
+ * These reads participate in Svelte dependency tracking inside templates,
207
+ * `$derived`, and `$effect`.
203
208
  */
204
- createAppTable: <TData extends RowData, TSelected = TableState<TFeatures>>(tableOptions: Omit<TableOptions<TFeatures, TData>, 'features'>, selector?: (state: TableState<TFeatures>) => TSelected) => AppSvelteTable<TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents>;
209
+ createAppTable: <TData extends RowData>(tableOptions: Omit<TableOptions<TFeatures, TData>, 'features'>) => AppSvelteTable<TFeatures, TData, TTableComponents, TCellComponents, THeaderComponents>;
205
210
  /**
206
211
  * Reads the table provided by the nearest `<table.AppTable>`. This is the same
207
212
  * extended instance `createAppTable` returns, so the `App*` components and your
208
213
  * `tableComponents` are available on it.
209
- *
210
- * Pass `TSelected` to match the selector you gave `createAppTable`, so
211
- * `table.state` is typed as the selected slice. It cannot be inferred
212
- * automatically (context does not carry the provider's generics), so it
213
- * defaults to the full table state, which is correct for the common case of
214
- * `createAppTable` without a selector.
215
214
  */
216
- useTableContext: <TData extends RowData = RowData, TSelected = TableState<TFeatures>>() => AppSvelteTable<TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents>;
215
+ useTableContext: <TData extends RowData = RowData>() => AppSvelteTable<TFeatures, TData, TTableComponents, TCellComponents, THeaderComponents>;
217
216
  /**
218
217
  * Reads the cell provided by the nearest `<table.AppCell>`, extended with your
219
218
  * `cellComponents` and a context-bound `FlexRender`.
@@ -109,10 +109,10 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
109
109
  *
110
110
  * TFeatures is already known from the createTableHook call; TData is inferred from the data prop.
111
111
  */
112
- function createAppTable(tableOptions, selector) {
112
+ function createAppTable(tableOptions) {
113
113
  // Merge default options with provided options (provided takes precedence)
114
114
  const mergedTableOptions = mergeObjects(defaultTableOptions, tableOptions);
115
- const table = createTable(mergedTableOptions, selector);
115
+ const table = createTable(mergedTableOptions);
116
116
  // Build cellComponents with FlexRender included
117
117
  const cellComponentsWithFlexRender = {
118
118
  FlexRender: FlexRenderSvelte,
package/dist/index.d.ts CHANGED
@@ -5,5 +5,4 @@ export { createTableHook } from './createTableHook.svelte';
5
5
  export type { AppCellContext, AppColumnDefBase, AppColumnDefTemplate, AppColumnHelper, AppDisplayColumnDef, AppGroupColumnDef, AppHeaderContext, AppSvelteTable, ComponentType, CreateTableHookOptions, CreateTableHookResult, } from './createTableHook.svelte';
6
6
  export { createTableState } from './createTableState.svelte';
7
7
  export { default as FlexRender } from './FlexRender.svelte';
8
- export { subscribeTable, type SubscribeSource } from './subscribe';
9
8
  export { renderComponent, renderSnippet } from './render-component';
package/dist/index.js CHANGED
@@ -3,5 +3,4 @@ export { createTable } from './createTable.svelte';
3
3
  export { createTableHook } from './createTableHook.svelte';
4
4
  export { createTableState } from './createTableState.svelte';
5
5
  export { default as FlexRender } from './FlexRender.svelte';
6
- export { subscribeTable } from './subscribe';
7
6
  export { renderComponent, renderSnippet } from './render-component';
@@ -4,6 +4,8 @@ import type { TableReactivityBindings } from '@tanstack/table-core/reactivity';
4
4
  *
5
5
  * Table state atoms are backed by TanStack Store atoms. The options store stays
6
6
  * framework-native because row-model APIs read `table.options` directly during
7
- * render. Readonly table atoms bridge Store dependency tracking into `$derived.by`.
7
+ * render. Readonly table atoms bridge Store dependency tracking into
8
+ * `$derived.by`, so their `.get()` methods participate in Svelte dependency
9
+ * tracking when called in templates, `$derived`, or `$effect`.
8
10
  */
9
11
  export declare function svelteReactivity(): TableReactivityBindings;
@@ -36,7 +36,9 @@ function createRuneWritableAtom(initialValue) {
36
36
  *
37
37
  * Table state atoms are backed by TanStack Store atoms. The options store stays
38
38
  * framework-native because row-model APIs read `table.options` directly during
39
- * render. Readonly table atoms bridge Store dependency tracking into `$derived.by`.
39
+ * render. Readonly table atoms bridge Store dependency tracking into
40
+ * `$derived.by`, so their `.get()` methods participate in Svelte dependency
41
+ * tracking when called in templates, `$derived`, or `$effect`.
40
42
  */
41
43
  export function svelteReactivity() {
42
44
  return {
@@ -66,6 +68,9 @@ export function svelteReactivity() {
66
68
  });
67
69
  return {
68
70
  get: () => {
71
+ // Both reads are load-bearing: the Store read preserves dependency
72
+ // tracking between table atoms, while touching `value` registers the
73
+ // current Svelte reactive scope with the rune-backed bridge.
69
74
  const currentValue = storeAtom.get();
70
75
  value;
71
76
  return currentValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/svelte-table",
3
- "version": "9.0.0-beta.59",
3
+ "version": "9.0.0-beta.60",
4
4
  "description": "Headless UI for building powerful tables & datagrids for Svelte.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -6,7 +6,7 @@ metadata:
6
6
  type: framework
7
7
  library: '@tanstack/svelte-table'
8
8
  framework: svelte
9
- library_version: '9.0.0-beta.59'
9
+ library_version: '9.0.0-beta.60'
10
10
  requires:
11
11
  - '@tanstack/table-core#core'
12
12
  - getting-started
@@ -6,7 +6,7 @@ metadata:
6
6
  type: framework
7
7
  library: '@tanstack/svelte-table'
8
8
  framework: svelte
9
- library_version: '9.0.0-beta.59'
9
+ library_version: '9.0.0-beta.60'
10
10
  requires:
11
11
  - '@tanstack/table-core#core'
12
12
  - '@tanstack/table-core#table-features'
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: migrate-v8-to-v9
3
3
  description: >
4
- Complete Svelte v8-to-v9 migration reference: Svelte 5, createTable, explicit features and row-model slots, atom/rune state, rendering helpers, prototype methods, type generics, sorting, sizing, selection, and logical pinning.
4
+ Complete Svelte v8-to-v9 migration reference: Svelte 5, createTable, beta.59 selector removal, explicit features and row-model slots, atom/rune state, rendering helpers, prototype methods, type generics, sorting, sizing, selection, and logical pinning.
5
5
  metadata:
6
6
  type: lifecycle
7
7
  library: '@tanstack/svelte-table'
8
8
  framework: svelte
9
- library_version: '9.0.0-beta.59'
9
+ library_version: '9.0.0-beta.60'
10
10
  requires:
11
11
  - '@tanstack/table-core#migrate-v8-to-v9'
12
12
  - getting-started
@@ -50,7 +50,7 @@ const table = createTable({
50
50
 
51
51
  | v8 | v9 |
52
52
  | -------------------------------------------- | ---------------------------------------------------------- |
53
- | `createSvelteTable(options)` | `createTable(options, selector?)` |
53
+ | `createSvelteTable(options)` | `createTable(options)` |
54
54
  | All features bundled | Required `features: tableFeatures({...})` |
55
55
  | `getCoreRowModel()` option | Remove; the core row model is automatic |
56
56
  | `get*RowModel()` table options | `create*RowModel()` slots in `tableFeatures` |
@@ -78,9 +78,10 @@ Factories take no arguments. Register `filterFns`, `sortFns`, and `aggregationFn
78
78
  ## Svelte State Migration
79
79
 
80
80
  - Reactive option inputs must remain live: use getters for rune values such as `data` and controlled state slices.
81
- - `table.getState().sorting` becomes `table.state.sorting`, `table.store.state.sorting`, or the narrow `table.atoms.sorting.get()`.
82
- - `table.state` contains all registered state by default. Pass a second-argument selector to `createTable` only to narrow its reactive surface.
83
- - `subscribeTable(table.atoms.pagination, selector?)` exposes `.current` for fine-grained template subscriptions.
81
+ - `table.getState().sorting` becomes the narrow `table.atoms.sorting.get()` read. Use `table.store.get()` when code intentionally needs the complete state.
82
+ - Table atom, store, and API reads become reactive inside templates, `$derived`, `$derived.by`, and `$effect`; use native `$derived` values for projections.
83
+ - Starting in beta.59, remove second-argument selectors from `createTable` and `createAppTable`, replace `table.state`, and remove `subscribeTable` / `SubscribeSource` imports.
84
+ - `SvelteTable` now has two generic parameters, `AppSvelteTable` has five, and `useTableContext` no longer accepts a selected-state generic.
84
85
  - For Svelte-owned controlled slices, use `createTableState` and matching `onSortingChange`, `onPaginationChange`, and other per-slice callbacks.
85
86
  - For shared ownership, provide atoms created by `@tanstack/svelte-store` through `atoms`. Never provide both `atoms.pagination` and `state.pagination`.
86
87
  - Subscribe to `table.store` to observe every state change. Do not port the removed top-level `onStateChange`.
@@ -173,6 +174,10 @@ Register both the feature and its `create*RowModel()` slot. Leaving `get*RowMode
173
174
 
174
175
  Use `get data() { return data }`; a one-time `data` snapshot does not remain reactive.
175
176
 
177
+ ### HIGH: Keeping beta.58 Svelte selectors
178
+
179
+ Remove second arguments from `createTable` and `createAppTable`, replace selected `table.state` reads with `table.atoms.<slice>.get()` or `table.store.get()`, and remove `subscribeTable`, `SubscribeSource`, and selected-state generic parameters. Beta.59 intentionally has no compatibility layer for these APIs.
180
+
176
181
  ### HIGH: Destructuring instance methods
177
182
 
178
183
  Keep calls bound to row/cell/column/header instances; shallow copies do not contain prototype methods.
@@ -184,6 +189,7 @@ Keep calls bound to row/cell/column/header instances; shallow copies do not cont
184
189
  - [ ] Explicit features, row models, and function registries are in `tableFeatures`.
185
190
  - [ ] `getCoreRowModel` and the separate `rowModels` shape are removed.
186
191
  - [ ] Reactive inputs and controlled slices use getters/runes; state reads use v9 surfaces.
192
+ - [ ] Svelte creation selectors, `table.state`, `subscribeTable`, `SubscribeSource`, and selected-state generic parameters are removed.
187
193
  - [ ] `onStateChange` is replaced; atom/state ownership does not overlap.
188
194
  - [ ] Rendering uses `FlexRender`, `renderComponent`, or `renderSnippet`.
189
195
  - [ ] Prototype method calls, pinning, sizing/resizing, sorting, row, and selection semantics are audited.
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: table-state
3
3
  description: >
4
- Use Svelte 5 rune-backed table.atoms/store and selected table.state, reactive option getters, controlled $state slices, value-or-updater callbacks, external atoms, and auto-reset behavior without snapshot mismatches.
4
+ Use Svelte 5 rune-aware table atoms and stores, $derived projections, reactive option getters, controlled $state or createTableState slices, external atoms, and auto-reset behavior without broad invalidation or snapshot mismatches.
5
5
  metadata:
6
6
  type: framework
7
7
  library: '@tanstack/svelte-table'
8
8
  framework: svelte
9
- library_version: '9.0.0-beta.59'
9
+ library_version: '9.0.0-beta.60'
10
10
  requires:
11
11
  - '@tanstack/table-core#core'
12
12
  - getting-started
@@ -15,6 +15,7 @@ sources:
15
15
  - 'TanStack/table:docs/framework/svelte/guide/pagination.md'
16
16
  - 'TanStack/table:examples/svelte/basic-external-state'
17
17
  - 'TanStack/table:packages/svelte-table/src/createTable.svelte.ts'
18
+ - 'TanStack/table:packages/svelte-table/src/createTableState.svelte.ts'
18
19
  ---
19
20
 
20
21
  This skill builds on `@tanstack/table-core#core` and `getting-started`. Read them first for table ownership and Svelte construction.
@@ -26,13 +27,14 @@ TanStack Table is primarily a state coordinator. Keep state internal unless anot
26
27
  - `table.baseAtoms` are internal writable atoms initialized from resolved initial state.
27
28
  - `table.atoms` are readonly derived atoms for the active owner of each registered slice.
28
29
  - `table.store` is the readonly flat store assembled from those atoms.
29
- - `table.state` is only the result selected by the second `createTable` argument.
30
30
 
31
- Svelte 5 backs these surfaces with runes and synchronizes reactive options before DOM updates. Only registered features create state and types. If pagination is missing, register `rowPaginationFeature`; do not add a cast or an ad hoc state field. Keep `features` and `columns` stable and pass changing `data` through a getter.
31
+ The Svelte adapter bridges TanStack Store dependency tracking into Svelte runes. `table.atoms.<slice>.get()`, `table.store.get()`, and table APIs become reactive when called in a template, `$derived`, `$derived.by`, or `$effect`. Outside those contexts they return current snapshots.
32
+
33
+ Only registered features create state and types. If pagination is missing, register `rowPaginationFeature`; do not add a cast or ad hoc state field. Keep `features` and `columns` stable and pass changing `data` through a getter.
32
34
 
33
35
  ## Setup
34
36
 
35
- Keep state internal unless another subsystem needs to own it. Select only render state that the component needs.
37
+ Keep state internal unless another subsystem needs to own it. Read only the state slices a component needs.
36
38
 
37
39
  ```svelte
38
40
  <script lang="ts">
@@ -45,25 +47,36 @@ Keep state internal unless another subsystem needs to own it. Select only render
45
47
  const features = tableFeatures({ rowPaginationFeature })
46
48
  const columns = [{ accessorKey: 'name' }]
47
49
  let data = $state([{ name: 'Ada' }])
48
- const table = createTable(
49
- {
50
- features,
51
- columns,
52
- get data() {
53
- return data
54
- },
50
+
51
+ const table = createTable({
52
+ features,
53
+ columns,
54
+ get data() {
55
+ return data
55
56
  },
56
- (state) => ({ pagination: state.pagination }),
57
- )
57
+ })
58
+
59
+ const pagination = $derived(table.atoms.pagination.get())
58
60
  </script>
59
61
 
60
62
  <button onclick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
61
- Page {table.state.pagination.pageIndex + 1}
63
+ Page {pagination.pageIndex + 1}
62
64
  </button>
63
65
  ```
64
66
 
65
67
  ## Core Patterns
66
68
 
69
+ ### Read narrow or complete state
70
+
71
+ ```ts
72
+ const pagination = $derived(table.atoms.pagination.get())
73
+ const pageIndex = $derived(table.atoms.pagination.get().pageIndex)
74
+ const rows = $derived(table.getRowModel().rows)
75
+ const stateJson = $derived(JSON.stringify(table.store.get(), null, 2))
76
+ ```
77
+
78
+ Use atom reads for normal UI. A `table.store.get()` read intentionally re-runs for any registered state change, so reserve it for debug output, persistence, or computations that need the whole state.
79
+
67
80
  ### Control a slice with value-or-updater semantics
68
81
 
69
82
  ```ts
@@ -75,20 +88,41 @@ const updatePagination = (next: Updater<PaginationState>) => {
75
88
  }
76
89
  ```
77
90
 
78
- Pass `get state() { return { pagination } }` and `onPaginationChange: updatePagination` to `createTable`.
91
+ Pass a getter-backed `state.pagination` and `onPaginationChange: updatePagination` to `createTable`.
79
92
 
80
- ### Subscribe narrowly outside selected table.state
93
+ ### Reduce boilerplate with `createTableState`
81
94
 
82
95
  ```ts
83
- import { subscribeTable } from '@tanstack/svelte-table'
84
-
85
- const pageIndex = subscribeTable(
86
- table.atoms.pagination,
87
- (value) => value.pageIndex,
88
- )
96
+ import {
97
+ createTable,
98
+ createTableState,
99
+ rowPaginationFeature,
100
+ tableFeatures,
101
+ type PaginationState,
102
+ } from '@tanstack/svelte-table'
103
+
104
+ const features = tableFeatures({ rowPaginationFeature })
105
+ const columns = [{ accessorKey: 'name' }]
106
+ const data = [{ name: 'Ada' }]
107
+ const [pagination, setPagination] = createTableState<PaginationState>({
108
+ pageIndex: 0,
109
+ pageSize: 20,
110
+ })
111
+
112
+ const table = createTable({
113
+ features,
114
+ columns,
115
+ data,
116
+ state: {
117
+ get pagination() {
118
+ return pagination()
119
+ },
120
+ },
121
+ onPaginationChange: setPagination,
122
+ })
89
123
  ```
90
124
 
91
- Read `pageIndex.current` in rune-tracked Svelte code. Use feature APIs for writes; `baseAtoms` is a low-level escape hatch.
125
+ For better or worse, this resembles a small React `useState` hook: `pagination()` reads the current rune-backed value, while `setPagination` accepts either a value or a functional updater and can be passed directly to `onPaginationChange`.
92
126
 
93
127
  ## Choose State Ownership
94
128
 
@@ -96,10 +130,12 @@ Use one owner per slice:
96
130
 
97
131
  - Prefer internal state plus feature APIs for table-local interaction.
98
132
  - Use `initialState` for starting/reset values; changing it later does not reset state.
99
- - Prefer a stable external atom in `atoms` for state shared with Query, routing, or another component. Do not also add its change callback.
100
- - Use a `$state` value exposed through a `state` getter plus the matching callback for simple controlled state. Always resolve value-or-updater semantics.
133
+ - Use Svelte `$state`, a getter-backed `state` entry, and the matching callback for normal Svelte-owned controlled state.
134
+ - Use a stable external atom in `atoms` for state shared as a raw TanStack Store atom. Do not also add its change callback.
101
135
 
102
- External atoms win over controlled `state`, which syncs into the internal base atom. Avoid multiple owners. The global v8 `onStateChange` option is gone; subscribe to `table.store` if all state changes must be observed.
136
+ External atoms win over controlled `state`, which syncs into the internal base atom. Avoid multiple owners. The global v8 `onStateChange` option is gone; subscribe to `table.store` if every state change must be observed imperatively.
137
+
138
+ When code outside the table consumes a raw external atom, use `useSelector` from `@tanstack/svelte-store`. Inside table-driven UI, read the rune-aware `table.atoms.<slice>.get()` wrapper.
103
139
 
104
140
  ## Initialize, Update, and Reset
105
141
 
@@ -115,6 +151,26 @@ Feature resets use `table.initialState` unless `true` requests the feature defau
115
151
 
116
152
  ## Common Mistakes
117
153
 
154
+ ### HIGH Keeping removed adapter selectors
155
+
156
+ Wrong:
157
+
158
+ ```ts
159
+ const table = createTable(options, (state) => state.pagination)
160
+ const pageIndex = table.state.pageIndex
161
+ ```
162
+
163
+ Correct:
164
+
165
+ ```ts
166
+ const table = createTable(options)
167
+ const pagination = $derived(table.atoms.pagination.get())
168
+ ```
169
+
170
+ Starting in beta.59, `createTable` and `createAppTable` take only options, `table.state` is absent, and `subscribeTable` and `SubscribeSource` are no longer exported. Use native tracked Svelte reads and `$derived` projections.
171
+
172
+ Source: `docs/framework/svelte/guide/migrating.md`
173
+
118
174
  ### HIGH Controlling without writing back
119
175
 
120
176
  Wrong:
@@ -127,8 +183,10 @@ Correct:
127
183
 
128
184
  ```ts
129
185
  const options = {
130
- get state() {
131
- return { pagination }
186
+ state: {
187
+ get pagination() {
188
+ return pagination
189
+ },
132
190
  },
133
191
  onPaginationChange: updatePagination,
134
192
  }
@@ -138,24 +196,21 @@ A controlled slice is frozen unless every updater is resolved into the owning ru
138
196
 
139
197
  Source: `docs/framework/svelte/guide/table-state.md`
140
198
 
141
- ### HIGH Reading snapshots outside tracking
199
+ ### HIGH Snapshotting outside tracking
142
200
 
143
201
  Wrong:
144
202
 
145
203
  ```ts
146
- const pageIndex = table.store.state.pagination.pageIndex
204
+ const pageIndex = table.store.get().pagination.pageIndex
147
205
  ```
148
206
 
149
- Correct:
207
+ Correct inside a component:
150
208
 
151
209
  ```ts
152
- const pageIndex = subscribeTable(
153
- table.atoms.pagination,
154
- (value) => value.pageIndex,
155
- )
210
+ const pageIndex = $derived(table.atoms.pagination.get().pageIndex)
156
211
  ```
157
212
 
158
- `store.state` is a current snapshot; it does not create a future Svelte update outside a tracked scope.
213
+ The first line is only a current snapshot when it runs outside a template or rune. The second line is a narrow native Svelte derivation.
159
214
 
160
215
  Source: `packages/svelte-table/src/createTable.svelte.ts`
161
216
 
@@ -171,8 +226,10 @@ Correct:
171
226
 
172
227
  ```ts
173
228
  const options = {
174
- get state() {
175
- return { pagination }
229
+ state: {
230
+ get pagination() {
231
+ return pagination
232
+ },
176
233
  },
177
234
  }
178
235
  ```
@@ -202,4 +259,4 @@ Source: `docs/framework/svelte/guide/pagination.md`
202
259
 
203
260
  ## API Discovery
204
261
 
205
- Inspect `node_modules/@tanstack/svelte-table/dist/createTable.svelte.d.ts`, `createTableState.svelte.d.ts`, and `subscribe.d.ts`; inspect registered state slices in the matching core feature source.
262
+ Inspect `node_modules/@tanstack/svelte-table/dist/createTable.svelte.d.ts`, `createTableHook.svelte.d.ts`, and `createTableState.svelte.d.ts`; inspect registered state slices in the matching core feature source.
@@ -6,7 +6,7 @@ metadata:
6
6
  type: composition
7
7
  library: '@tanstack/svelte-table'
8
8
  framework: svelte
9
- library_version: '9.0.0-beta.59'
9
+ library_version: '9.0.0-beta.60'
10
10
  requires:
11
11
  - '@tanstack/table-core#client-vs-server'
12
12
  - getting-started
@@ -52,8 +52,10 @@ const table = createTable({
52
52
  return dataQuery.data?.rowCount ?? 0
53
53
  },
54
54
  manualPagination: true,
55
- get state() {
56
- return { pagination }
55
+ state: {
56
+ get pagination() {
57
+ return pagination
58
+ },
57
59
  },
58
60
  onPaginationChange: (next) => {
59
61
  pagination = typeof next === 'function' ? next(pagination) : next
@@ -6,7 +6,7 @@ metadata:
6
6
  type: composition
7
7
  library: '@tanstack/svelte-table'
8
8
  framework: svelte
9
- library_version: '9.0.0-beta.59'
9
+ library_version: '9.0.0-beta.60'
10
10
  requires:
11
11
  - '@tanstack/table-core#core'
12
12
  - getting-started
@@ -1,24 +0,0 @@
1
- import { useSelector } from '@tanstack/svelte-store';
2
- import type { Atom, ReadonlyAtom, ReadonlyStore, Store } from '@tanstack/svelte-store';
3
- export type SubscribeSource<TValue> = Atom<TValue> | ReadonlyAtom<TValue> | Store<TValue> | ReadonlyStore<TValue>;
4
- /**
5
- * Creates a fine-grained Svelte subscription to a TanStack Store source.
6
- *
7
- * Pass a table atom or store and optionally project it with a selector. The
8
- * returned selector store exposes `.current`, making it useful for reading
9
- * focused table state outside the broad `createTable` selector.
10
- *
11
- * @example
12
- * ```svelte
13
- * <script lang="ts">
14
- * const selected = subscribeTable(
15
- * table.atoms.rowSelection,
16
- * (rowSelection) => rowSelection[row.id],
17
- * )
18
- * </script>
19
- *
20
- * <input type="checkbox" checked={!!selected.current} />
21
- * ```
22
- */
23
- export declare function subscribeTable<TSourceValue>(source: SubscribeSource<TSourceValue>): ReturnType<typeof useSelector<TSourceValue>>;
24
- export declare function subscribeTable<TSourceValue, TSelected>(source: SubscribeSource<TSourceValue>, selector: (state: TSourceValue) => TSelected): ReturnType<typeof useSelector<TSourceValue, TSelected>>;
package/dist/subscribe.js DELETED
@@ -1,4 +0,0 @@
1
- import { shallow, useSelector } from '@tanstack/svelte-store';
2
- export function subscribeTable(source, selector) {
3
- return useSelector(source, selector, { compare: shallow });
4
- }