@tanstack/svelte-table 9.0.0-alpha.50 → 9.0.0-alpha.52
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.
- package/dist/createTable.svelte.d.ts +12 -2
- package/dist/reactivity.svelte.d.ts +3 -3
- package/dist/reactivity.svelte.js +47 -20
- package/package.json +4 -4
- package/skills/svelte/compose-with-tanstack-store/SKILL.md +1 -1
- package/skills/svelte/production-readiness/SKILL.md +1 -1
- package/skills/svelte/table-state/SKILL.md +1 -1
- package/src/createTable.svelte.ts +13 -3
- package/src/reactivity.svelte.ts +53 -20
|
@@ -1,7 +1,17 @@
|
|
|
1
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>> = Table<TFeatures, TData> & {
|
|
2
|
+
export type SvelteTable<TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState<TFeatures>> = Omit<Table<TFeatures, TData>, 'store'> & {
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
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`.
|
|
5
15
|
*
|
|
6
16
|
* @example
|
|
7
17
|
* const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
|
|
@@ -2,8 +2,8 @@ import type { TableReactivityBindings } from '@tanstack/table-core/reactivity';
|
|
|
2
2
|
/**
|
|
3
3
|
* Creates the table-core reactivity bindings used by the Svelte adapter.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Table state atoms are backed by TanStack Store atoms. The options store stays
|
|
6
|
+
* framework-native because row-model APIs read `table.options` directly during
|
|
7
|
+
* render. Readonly table atoms bridge Store dependency tracking into `$derived.by`.
|
|
8
8
|
*/
|
|
9
9
|
export declare function svelteReactivity(): TableReactivityBindings;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
import { batch, createAtom } from '@tanstack/svelte-store';
|
|
3
|
+
const optionsStoreDebugName = 'table/optionsStore';
|
|
2
4
|
function observerToCallback(observerOrNext) {
|
|
3
5
|
return typeof observerOrNext === 'function'
|
|
4
6
|
? observerOrNext
|
|
@@ -14,42 +16,67 @@ function subscribeToRune(getValue, observerOrNext) {
|
|
|
14
16
|
});
|
|
15
17
|
return { unsubscribe };
|
|
16
18
|
}
|
|
19
|
+
function createRuneWritableAtom(initialValue) {
|
|
20
|
+
let value = $state(initialValue);
|
|
21
|
+
return {
|
|
22
|
+
set: (updater) => {
|
|
23
|
+
value =
|
|
24
|
+
typeof updater === 'function'
|
|
25
|
+
? updater(value)
|
|
26
|
+
: updater;
|
|
27
|
+
},
|
|
28
|
+
get: () => value,
|
|
29
|
+
subscribe: ((observerOrNext) => {
|
|
30
|
+
return subscribeToRune(() => value, observerOrNext);
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
17
34
|
/**
|
|
18
35
|
* Creates the table-core reactivity bindings used by the Svelte adapter.
|
|
19
36
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
37
|
+
* Table state atoms are backed by TanStack Store atoms. The options store stays
|
|
38
|
+
* framework-native because row-model APIs read `table.options` directly during
|
|
39
|
+
* render. Readonly table atoms bridge Store dependency tracking into `$derived.by`.
|
|
23
40
|
*/
|
|
24
41
|
export function svelteReactivity() {
|
|
25
42
|
return {
|
|
26
43
|
createOptionsStore: true,
|
|
27
44
|
schedule: (fn) => queueMicrotask(() => fn()),
|
|
28
45
|
createReadonlyAtom: (fn, _options) => {
|
|
29
|
-
const
|
|
46
|
+
const storeAtom = createAtom(() => fn(), {
|
|
47
|
+
compare: _options?.compare,
|
|
48
|
+
});
|
|
49
|
+
let version = $state(0);
|
|
50
|
+
$effect(() => {
|
|
51
|
+
const subscription = storeAtom.subscribe(() => {
|
|
52
|
+
version += 1;
|
|
53
|
+
});
|
|
54
|
+
return () => subscription.unsubscribe();
|
|
55
|
+
});
|
|
56
|
+
const value = $derived.by(() => {
|
|
57
|
+
version;
|
|
58
|
+
return storeAtom.get();
|
|
59
|
+
});
|
|
30
60
|
return {
|
|
31
|
-
get: () =>
|
|
61
|
+
get: () => {
|
|
62
|
+
const currentValue = storeAtom.get();
|
|
63
|
+
value;
|
|
64
|
+
return currentValue;
|
|
65
|
+
},
|
|
32
66
|
subscribe: ((observerOrNext) => {
|
|
33
67
|
return subscribeToRune(() => value, observerOrNext);
|
|
34
68
|
}),
|
|
35
69
|
};
|
|
36
70
|
},
|
|
37
71
|
createWritableAtom: (initialValue, _options) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
: updater;
|
|
45
|
-
},
|
|
46
|
-
get: () => value,
|
|
47
|
-
subscribe: ((observerOrNext) => {
|
|
48
|
-
return subscribeToRune(() => value, observerOrNext);
|
|
49
|
-
}),
|
|
50
|
-
};
|
|
72
|
+
if (_options?.debugName === optionsStoreDebugName) {
|
|
73
|
+
return createRuneWritableAtom(initialValue);
|
|
74
|
+
}
|
|
75
|
+
return createAtom(initialValue, {
|
|
76
|
+
compare: _options?.compare,
|
|
77
|
+
});
|
|
51
78
|
},
|
|
52
79
|
untrack: untrack,
|
|
53
|
-
batch
|
|
80
|
+
batch,
|
|
54
81
|
};
|
|
55
82
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/svelte-table",
|
|
3
|
-
"version": "9.0.0-alpha.
|
|
3
|
+
"version": "9.0.0-alpha.52",
|
|
4
4
|
"description": "Headless UI for building powerful tables & datagrids for Svelte.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@tanstack/svelte-store": "^0.12.0",
|
|
56
|
-
"@tanstack/table-core": "9.0.0-alpha.
|
|
56
|
+
"@tanstack/table-core": "9.0.0-alpha.52"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@sveltejs/package": "^2.5.7",
|
|
60
60
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
61
|
-
"eslint-plugin-svelte": "^3.
|
|
62
|
-
"svelte": "^5.
|
|
61
|
+
"eslint-plugin-svelte": "^3.19.0",
|
|
62
|
+
"svelte": "^5.56.0",
|
|
63
63
|
"svelte-check": "^4.4.8"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
@@ -109,7 +109,7 @@ Read the atom directly. Cheapest path; only reactive when called inside a rune-t
|
|
|
109
109
|
```ts
|
|
110
110
|
const sorting = table.atoms.sorting.get()
|
|
111
111
|
const pagination = table.atoms.pagination.get()
|
|
112
|
-
const flat = table.
|
|
112
|
+
const flat = table.state
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
### Reactive read inside markup — `table.state` selector
|
|
@@ -15,9 +15,19 @@ export type SvelteTable<
|
|
|
15
15
|
TFeatures extends TableFeatures,
|
|
16
16
|
TData extends RowData,
|
|
17
17
|
TSelected = TableState<TFeatures>,
|
|
18
|
-
> = Table<TFeatures, TData> & {
|
|
18
|
+
> = Omit<Table<TFeatures, TData>, 'store'> & {
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* @deprecated Prefer `table.state` for render reads,
|
|
21
|
+
* `table.atoms.<slice>.get()` for slice snapshots, or
|
|
22
|
+
* `useSelector(table.store, selector)` for explicit subscriptions.
|
|
23
|
+
* `table.store.state` is a current-value snapshot and is easy to misuse in
|
|
24
|
+
* render code.
|
|
25
|
+
*/
|
|
26
|
+
readonly store: Table<TFeatures, TData>['store']
|
|
27
|
+
/**
|
|
28
|
+
* The selected state of the table. This state may not match the structure of
|
|
29
|
+
* the full table state because it is selected by the selector function that
|
|
30
|
+
* you pass as the 2nd argument to `createTable`.
|
|
21
31
|
*
|
|
22
32
|
* @example
|
|
23
33
|
* const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
|
|
@@ -82,7 +92,7 @@ export function createTable<
|
|
|
82
92
|
) as TableOptions<TFeatures, TData>
|
|
83
93
|
|
|
84
94
|
// 3. Construct table
|
|
85
|
-
const table = constructTable(resolvedOptions) as SvelteTable<
|
|
95
|
+
const table = constructTable(resolvedOptions) as unknown as SvelteTable<
|
|
86
96
|
TFeatures,
|
|
87
97
|
TData,
|
|
88
98
|
TSelected
|
package/src/reactivity.svelte.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { untrack } from 'svelte'
|
|
2
|
+
import { batch, createAtom } from '@tanstack/svelte-store'
|
|
2
3
|
import type {
|
|
3
4
|
TableAtomOptions,
|
|
4
5
|
TableReactivityBindings,
|
|
5
6
|
} from '@tanstack/table-core/reactivity'
|
|
6
7
|
import type { Atom, Observer, ReadonlyAtom } from '@tanstack/svelte-store'
|
|
7
8
|
|
|
9
|
+
const optionsStoreDebugName = 'table/optionsStore'
|
|
10
|
+
|
|
8
11
|
function observerToCallback<T>(
|
|
9
12
|
observerOrNext: Observer<T> | ((value: T) => void),
|
|
10
13
|
): (value: T) => void {
|
|
@@ -28,22 +31,59 @@ function subscribeToRune<T>(
|
|
|
28
31
|
return { unsubscribe }
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
function createRuneWritableAtom<T>(initialValue: T): Atom<T> {
|
|
35
|
+
let value = $state(initialValue)
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
set: (updater: T | ((prevVal: T) => T)) => {
|
|
39
|
+
value =
|
|
40
|
+
typeof updater === 'function'
|
|
41
|
+
? (updater as (prevVal: T) => T)(value)
|
|
42
|
+
: updater
|
|
43
|
+
},
|
|
44
|
+
get: () => value,
|
|
45
|
+
subscribe: ((observerOrNext: Observer<T> | ((value: T) => void)) => {
|
|
46
|
+
return subscribeToRune(() => value, observerOrNext)
|
|
47
|
+
}) as Atom<T>['subscribe'],
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
31
51
|
/**
|
|
32
52
|
* Creates the table-core reactivity bindings used by the Svelte adapter.
|
|
33
53
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
54
|
+
* Table state atoms are backed by TanStack Store atoms. The options store stays
|
|
55
|
+
* framework-native because row-model APIs read `table.options` directly during
|
|
56
|
+
* render. Readonly table atoms bridge Store dependency tracking into `$derived.by`.
|
|
37
57
|
*/
|
|
38
58
|
export function svelteReactivity(): TableReactivityBindings {
|
|
39
59
|
return {
|
|
40
60
|
createOptionsStore: true,
|
|
41
61
|
schedule: (fn) => queueMicrotask(() => fn()),
|
|
42
62
|
createReadonlyAtom: <T>(fn: () => T, _options?: TableAtomOptions<T>) => {
|
|
43
|
-
const
|
|
63
|
+
const storeAtom = createAtom(() => fn(), {
|
|
64
|
+
compare: _options?.compare,
|
|
65
|
+
})
|
|
66
|
+
let version = $state(0)
|
|
67
|
+
|
|
68
|
+
$effect(() => {
|
|
69
|
+
const subscription = storeAtom.subscribe(() => {
|
|
70
|
+
version += 1
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
return () => subscription.unsubscribe()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const value = $derived.by(() => {
|
|
77
|
+
version
|
|
78
|
+
return storeAtom.get()
|
|
79
|
+
})
|
|
44
80
|
|
|
45
81
|
return {
|
|
46
|
-
get: () =>
|
|
82
|
+
get: () => {
|
|
83
|
+
const currentValue = storeAtom.get()
|
|
84
|
+
value
|
|
85
|
+
return currentValue
|
|
86
|
+
},
|
|
47
87
|
subscribe: ((observerOrNext: Observer<T> | ((value: T) => void)) => {
|
|
48
88
|
return subscribeToRune(() => value, observerOrNext)
|
|
49
89
|
}) as ReadonlyAtom<T>['subscribe'],
|
|
@@ -53,22 +93,15 @@ export function svelteReactivity(): TableReactivityBindings {
|
|
|
53
93
|
initialValue: T,
|
|
54
94
|
_options?: TableAtomOptions<T>,
|
|
55
95
|
): Atom<T> => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
set: (updater: T | ((prevVal: T) => T)) => {
|
|
60
|
-
value =
|
|
61
|
-
typeof updater === 'function'
|
|
62
|
-
? (updater as (prevVal: T) => T)(value)
|
|
63
|
-
: updater
|
|
64
|
-
},
|
|
65
|
-
get: () => value,
|
|
66
|
-
subscribe: ((observerOrNext: Observer<T> | ((value: T) => void)) => {
|
|
67
|
-
return subscribeToRune(() => value, observerOrNext)
|
|
68
|
-
}) as Atom<T>['subscribe'],
|
|
96
|
+
if (_options?.debugName === optionsStoreDebugName) {
|
|
97
|
+
return createRuneWritableAtom(initialValue)
|
|
69
98
|
}
|
|
99
|
+
|
|
100
|
+
return createAtom(initialValue, {
|
|
101
|
+
compare: _options?.compare,
|
|
102
|
+
})
|
|
70
103
|
},
|
|
71
104
|
untrack: untrack,
|
|
72
|
-
batch
|
|
105
|
+
batch,
|
|
73
106
|
}
|
|
74
107
|
}
|