@tanstack/vue-table 9.0.0-beta.3 → 9.0.0-beta.5

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/src/reactivity.ts CHANGED
@@ -1,20 +1,17 @@
1
- import {
2
- computed,
3
- getCurrentScope,
4
- onScopeDispose,
5
- shallowRef,
6
- watch,
7
- } from 'vue'
8
- import { batch, createAtom } from '@tanstack/vue-store'
1
+ import { computed, shallowRef, watch } from 'vue'
2
+ import { batch } from '@tanstack/store'
9
3
  import type {
10
4
  TableAtomOptions,
11
5
  TableReactivityBindings,
12
6
  } from '@tanstack/table-core/reactivity'
13
- import type { Atom, Observer, ReadonlyAtom } from '@tanstack/vue-store'
7
+ import type {
8
+ Atom,
9
+ Observer,
10
+ ReadonlyAtom,
11
+ Subscription,
12
+ } from '@tanstack/store'
14
13
  import type { ComputedRef, ShallowRef } from 'vue'
15
14
 
16
- const optionsStoreDebugName = 'table/optionsStore'
17
-
18
15
  function observerToCallback<T>(
19
16
  observerOrNext: Observer<T> | ((value: T) => void),
20
17
  ): (value: T) => void {
@@ -64,50 +61,27 @@ function refToWritableAtom<T>(source: ShallowRef<T>): Atom<T> {
64
61
  * refs.
65
62
  */
66
63
  export function vueReactivity(): TableReactivityBindings {
64
+ const subscriptions = new Set<Subscription>()
65
+
67
66
  return {
68
67
  createOptionsStore: true,
69
- wrapExternalAtoms: false,
70
- addSubscription: () => {
71
- throw new Error(
72
- 'Feature not supported in current reactivity implementation',
73
- )
68
+ wrapExternalAtoms: true,
69
+ addSubscription: (subscription) => {
70
+ subscriptions.add(subscription)
74
71
  },
75
72
  unmount: () => {
76
- throw new Error(
77
- 'Feature not supported in current reactivity implementation',
78
- )
73
+ subscriptions.forEach((s) => s.unsubscribe())
74
+ subscriptions.clear()
79
75
  },
80
76
  schedule: (fn) => queueMicrotask(() => fn()),
81
77
  createReadonlyAtom: <T>(fn: () => T, _options?: TableAtomOptions<T>) => {
82
- const storeAtom = createAtom(() => fn(), {
83
- compare: _options?.compare,
84
- })
85
- const version = shallowRef(0)
86
- const subscription = storeAtom.subscribe(() => {
87
- version.value += 1
88
- })
89
- if (getCurrentScope()) {
90
- onScopeDispose(() => subscription.unsubscribe())
91
- }
92
-
93
- return refToReadonlyAtom(
94
- computed(() => {
95
- version.value
96
- return storeAtom.get()
97
- }),
98
- )
78
+ return refToReadonlyAtom(computed(() => fn()))
99
79
  },
100
80
  createWritableAtom: <T>(
101
81
  value: T,
102
82
  _options?: TableAtomOptions<T>,
103
83
  ): Atom<T> => {
104
- if (_options?.debugName === optionsStoreDebugName) {
105
- return refToWritableAtom(shallowRef(value) as ShallowRef<T>)
106
- }
107
-
108
- return createAtom(value, {
109
- compare: _options?.compare,
110
- })
84
+ return refToWritableAtom(shallowRef(value) as ShallowRef<T>)
111
85
  },
112
86
  untrack: (fn) => fn(),
113
87
  batch,
package/src/useTable.ts CHANGED
@@ -1,16 +1,8 @@
1
- import { unref, watch } from 'vue'
1
+ import { getCurrentScope, onScopeDispose, unref, watch } from 'vue'
2
2
  import { constructTable } from '@tanstack/table-core'
3
- import { shallow, useSelector } from '@tanstack/vue-store'
4
3
  import { flatMerge, mergeProxy } from './merge-proxy'
5
4
  import { vueReactivity } from './reactivity'
6
5
  import type {
7
- Atom,
8
- ReadonlyAtom,
9
- ReadonlyStore,
10
- Store,
11
- } from '@tanstack/vue-store'
12
- import type {
13
- NoInfer,
14
6
  RowData,
15
7
  Table,
16
8
  TableFeatures,
@@ -19,12 +11,6 @@ import type {
19
11
  } from '@tanstack/table-core'
20
12
  import type { MaybeRef, VNode } from 'vue'
21
13
 
22
- export type SubscribeSource<TValue> =
23
- | Atom<TValue>
24
- | ReadonlyAtom<TValue>
25
- | Store<TValue>
26
- | ReadonlyStore<TValue>
27
-
28
14
  export type TableOptionsWithReactiveData<
29
15
  TFeatures extends TableFeatures,
30
16
  TData extends RowData,
@@ -61,57 +47,19 @@ function getReactiveOptionDeps<
61
47
  export type VueTable<
62
48
  TFeatures extends TableFeatures,
63
49
  TData extends RowData,
64
- TSelected = TableState<TFeatures>,
65
50
  > = Omit<Table<TFeatures, TData>, 'store'> & {
66
51
  /**
67
- * @deprecated Prefer `table.state` for render reads,
68
- * `table.atoms.<slice>.get()` for slice snapshots, or
69
- * `table.Subscribe` / `useSelector(table.store, selector)` for explicit
70
- * subscriptions. `table.store.state` is a current-value snapshot and is easy
71
- * to misuse in render code.
52
+ * @deprecated Prefer `table.atoms.<slice>.get()` for slice snapshots, or
53
+ * `table.Subscribe` for explicit subscriptions. `table.store.state` is a
54
+ * current-value snapshot and is easy to misuse in render code.
72
55
  */
73
56
  readonly store: Table<TFeatures, TData>['store']
74
- /**
75
- * Store mode: `selector` required. Source mode: pass `source` (atom or store); omit
76
- * `selector` for the whole value (identity), or pass `selector` to project. Split
77
- * overloads so source-only infers `TSourceValue` for `children` (see React `Subscribe`).
78
- */
79
- Subscribe: {
80
- <TSourceValue>(props: {
81
- source: SubscribeSource<TSourceValue>
82
- selector?: undefined
83
- children:
84
- | ((state: Readonly<TSourceValue>) => VNode | Array<VNode>)
85
- | VNode
86
- | Array<VNode>
87
- }): VNode | Array<VNode>
88
- <TSourceValue, TSubSelected>(props: {
89
- source: SubscribeSource<TSourceValue>
90
- selector: (state: TSourceValue) => TSubSelected
91
- children:
92
- | ((state: Readonly<TSubSelected>) => VNode | Array<VNode>)
93
- | VNode
94
- | Array<VNode>
95
- }): VNode | Array<VNode>
96
- <TSubSelected>(props: {
97
- selector: (state: NoInfer<TableState<TFeatures>>) => TSubSelected
98
- children:
99
- | ((state: Readonly<TSubSelected>) => VNode | Array<VNode>)
100
- | VNode
101
- | Array<VNode>
102
- }): VNode | Array<VNode>
103
- }
104
- /**
105
- * The selected state of the table. This state may not match the structure of
106
- * the full table state because it is selected by the selector function that
107
- * you pass as the 2nd argument to `useTable`.
108
- *
109
- * @example
110
- * const table = useTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
111
- *
112
- * console.log(table.state.globalFilter)
57
+ /** Creates a reactive render boundary. The child function reads the table
58
+ * atoms it needs, so Vue only tracks those atom reads.
113
59
  */
114
- readonly state: Readonly<TSelected>
60
+ Subscribe: (props: {
61
+ children: (atoms: Table<TFeatures, TData>['atoms']) => VNode | Array<VNode>
62
+ }) => VNode | Array<VNode>
115
63
  }
116
64
 
117
65
  /**
@@ -119,8 +67,8 @@ export type VueTable<
119
67
  *
120
68
  * Table options may contain Vue refs or computed values. The adapter unwraps
121
69
  * those reactive inputs, watches them with synchronous flushing, and keeps the
122
- * table options in sync. The optional selector projects from `table.store` and
123
- * exposes the selected value on `table.state`.
70
+ * table options in sync. Use `table.Subscribe` or native Vue computed values
71
+ * around `table.atoms.<slice>.get()` for selected reactive reads.
124
72
  *
125
73
  * @example
126
74
  * ```ts
@@ -131,22 +79,17 @@ export type VueTable<
131
79
  * columns,
132
80
  * data,
133
81
  * },
134
- * (state) => ({ pagination: state.pagination }),
135
82
  * )
136
- *
137
- * table.state.pagination
138
83
  * ```
139
84
  */
140
85
  export function useTable<
141
86
  TFeatures extends TableFeatures,
142
87
  TData extends RowData,
143
- TSelected = TableState<TFeatures>,
144
88
  >(
145
89
  tableOptions:
146
90
  | TableOptions<TFeatures, TData>
147
91
  | TableOptionsWithReactiveData<TFeatures, TData>,
148
- selector?: (state: TableState<TFeatures>) => TSelected,
149
- ): VueTable<TFeatures, TData, TSelected> {
92
+ ): VueTable<TFeatures, TData> {
150
93
  const syncTableOptions = (
151
94
  table: Table<TFeatures, TData>,
152
95
  options: TableOptionsWithReactiveData<TFeatures, TData>,
@@ -156,9 +99,11 @@ export function useTable<
156
99
  )
157
100
  }
158
101
 
102
+ const reactivity = vueReactivity()
103
+
159
104
  const mergedOptions = mergeProxy(tableOptions, {
160
105
  features: {
161
- coreReativityFeature: vueReactivity(),
106
+ coreReativityFeature: reactivity,
162
107
  ...(unref(tableOptions.features) ?? {}),
163
108
  },
164
109
  }) as TableOptionsWithReactiveData<TFeatures, TData>
@@ -177,7 +122,11 @@ export function useTable<
177
122
  ) as TableOptions<TFeatures, TData>
178
123
 
179
124
  const coreTable = constructTable(resolvedOptions)
180
- const table = coreTable as unknown as VueTable<TFeatures, TData, TSelected>
125
+ const table = coreTable as unknown as VueTable<TFeatures, TData>
126
+
127
+ if (getCurrentScope()) {
128
+ onScopeDispose(() => reactivity.unmount?.())
129
+ }
181
130
 
182
131
  watch(
183
132
  () => getReactiveOptionDeps(mergedOptions),
@@ -222,30 +171,11 @@ export function useTable<
222
171
  { immediate: true },
223
172
  )
224
173
 
225
- table.Subscribe = ((props: {
226
- source?: SubscribeSource<unknown>
227
- selector?: ((state: unknown) => unknown) | undefined
228
- children:
229
- | ((state: Readonly<unknown>) => VNode | Array<VNode>)
230
- | VNode
231
- | Array<VNode>
174
+ table.Subscribe = (props: {
175
+ children: (atoms: Table<TFeatures, TData>['atoms']) => VNode | Array<VNode>
232
176
  }) => {
233
- const source = props.source ?? table.store
234
- const selected = useSelector(source as never, props.selector as never, {
235
- compare: shallow,
236
- })
237
- if (typeof props.children === 'function') {
238
- return props.children(selected.value as Readonly<unknown>)
239
- }
240
- return props.children
241
- }) as VueTable<TFeatures, TData, TSelected>['Subscribe']
242
-
243
- const stateStore = useSelector(table.store, selector)
244
-
245
- return {
246
- ...table,
247
- get state() {
248
- return stateStore.value
249
- },
177
+ return props.children(table.atoms)
250
178
  }
179
+
180
+ return table
251
181
  }