diff --git a/.changeset/quiet-table-devtools.md b/.changeset/quiet-table-devtools.md new file mode 100644 index 0000000000..68a623f6b2 --- /dev/null +++ b/.changeset/quiet-table-devtools.md @@ -0,0 +1,12 @@ +--- +'@tanstack/table-devtools': patch +'@tanstack/react-table-devtools': patch +'@tanstack/preact-table-devtools': patch +'@tanstack/solid-table-devtools': patch +'@tanstack/vue-table-devtools': patch +'@tanstack/angular-table-devtools': patch +--- + +Prevent table state updates from remounting the devtools panel, subscribe only +while the panel is open, cache generated styles by theme, and keep adapter +registration and production entrypoints reactive and stable. diff --git a/_artifacts/domain_map.yaml b/_artifacts/domain_map.yaml index af0cf867f3..9986132ac2 100644 --- a/_artifacts/domain_map.yaml +++ b/_artifacts/domain_map.yaml @@ -102,7 +102,7 @@ custom_feature_depth_contract: - 'assignPrototypeAPIs inside assignCellPrototype for shared cell methods.' - 'assignPrototypeAPIs inside assignHeaderPrototype for shared header methods.' - 'initColumnInstanceData and initRowInstanceData for per-instance mutable data rather than shared methods.' - - 'The table_/column_/row_/cell_/header_ static-name prefixes, self argument difference, optional memoDeps, and absence of per-object assign*APIs utilities.' + - 'The table_/column_/row_/cell_/header_ static-name prefixes, `{ fn }` versus `{ computed, compare? }`, prototype self argument, native dependency tracking, and absence of per-object assign*APIs utilities.' api_discovery_policy: rule: 'For exact exports, option types, state shapes, and instance APIs, inspect dist declarations (.d.ts) in the installed package before inventing an API or relying on memory.' diff --git a/_artifacts/skill_spec.md b/_artifacts/skill_spec.md index 5868132346..1f6c8b546d 100644 --- a/_artifacts/skill_spec.md +++ b/_artifacts/skill_spec.md @@ -124,7 +124,7 @@ Treat stable `data` and `columns` references as a correctness and performance in The custom-features skill must enumerate all 10 public declaration-merge FeatureMaps: table state, table options, table, column definition, column, row, cell, header, row-model functions, and cached row models. Explain that `Plugins` registers the feature key and that declarations add types only; each advertised runtime surface needs matching lifecycle wiring. -Enumerate both API utilities and every installation path: `assignTableAPIs` in `constructTableAPIs`, plus `assignPrototypeAPIs` in `assignColumnPrototype`, `assignRowPrototype`, `assignCellPrototype`, and `assignHeaderPrototype`. Include the static-name prefixes, prototype self argument, optional `memoDeps`, shared-prototype constraint, `initColumnInstanceData`/`initRowInstanceData`, and the fact that per-object `assignColumnAPIs`-style utilities do not exist. Clearly label row-model maps as advanced internal pipeline surfaces requiring explicit runtime/cache wiring. +Enumerate both API utilities and every installation path: `assignTableAPIs` in `constructTableAPIs`, plus `assignPrototypeAPIs` in `assignColumnPrototype`, `assignRowPrototype`, `assignCellPrototype`, and `assignHeaderPrototype`. Include the static-name prefixes, the `{ fn }` versus `{ computed, compare? }` descriptor shapes, the prototype computed self argument, native dependency tracking, the shared-prototype constraint, `initColumnInstanceData`/`initRowInstanceData`, and the fact that per-object `assignColumnAPIs`-style utilities do not exist. Clearly label row-model maps as advanced internal pipeline surfaces requiring explicit runtime/cache wiring. Use one annotated, authoritative feature example for the complete shape. Do not stack a minimal density example, a second FeatureMap example, a third API-installation example, and then repeat their distinction under Common Mistakes. Keep selection guidance and foot-guns as compact prose around the single example. diff --git a/_artifacts/skill_tree.yaml b/_artifacts/skill_tree.yaml index 4d96285789..e397a77bb6 100644 --- a/_artifacts/skill_tree.yaml +++ b/_artifacts/skill_tree.yaml @@ -102,7 +102,7 @@ skills: domain: foundations path: 'packages/table-core/skills/custom-features/SKILL.md' package: 'packages/table-core' - description: 'Author a TanStack Table v9 feature plugin across all 10 FeatureMaps and every table/column/row/cell/header API installation path, including prototypes, memoDeps, instance data, and advanced row-model maps, after checking built-ins and meta.' + description: 'Author a TanStack Table v9 feature plugin across all 10 FeatureMaps and every table/column/row/cell/header API installation path, including prototype and computed APIs, instance data, and advanced row-model maps, after checking built-ins and meta.' requires: ['core', 'table-features', 'typescript'] sources: - 'TanStack/table:docs/framework/react/guide/custom-features.md' diff --git a/docs/framework/ember/reference/functions/createTableHook.md b/docs/framework/ember/reference/functions/createTableHook.md index baf000d03c..2340dacd14 100644 --- a/docs/framework/ember/reference/functions/createTableHook.md +++ b/docs/framework/ember/reference/functions/createTableHook.md @@ -60,22 +60,57 @@ createAppColumnHelper: () => ColumnHelper; ### createAppTable() ```ts -createAppTable: (getTableOptions) => AppEmberTable; +createAppTable: { + (owner, getTableOptions): AppEmberTable; + (getTableOptions): AppEmberTable; +}; ``` -#### Type Parameters +#### Call Signature -##### TData +```ts +(owner, getTableOptions): AppEmberTable; +``` + +##### Type Parameters + +###### TData `TData` *extends* `RowData` -#### Parameters +##### Parameters -##### getTableOptions +###### owner + +`object` + +###### getTableOptions () => `Omit`\<`TableOptions`\<`TFeatures`, `TData`\>, `"features"`\> -#### Returns +##### Returns + +[`AppEmberTable`](../type-aliases/AppEmberTable.md)\<`TFeatures`, `TData`\> + +#### Call Signature + +```ts +(getTableOptions): AppEmberTable; +``` + +##### Type Parameters + +###### TData + +`TData` *extends* `RowData` + +##### Parameters + +###### getTableOptions + +() => `Omit`\<`TableOptions`\<`TFeatures`, `TData`\>, `"features"`\> + +##### Returns [`AppEmberTable`](../type-aliases/AppEmberTable.md)\<`TFeatures`, `TData`\> @@ -89,6 +124,6 @@ const { createAppTable, createAppColumnHelper } = createTableHook({ const columnHelper = createAppColumnHelper() const columns = columnHelper.columns([...]) -// inside a Glimmer component; options stay a thunk so tracked reads are reactive -table = createAppTable(() => ({ columns, data: this.data })) +// inside a Glimmer component; passing `this` binds cleanup to its lifecycle +table = createAppTable(this, () => ({ columns, data: this.data })) ``` diff --git a/docs/framework/ember/reference/functions/useTable.md b/docs/framework/ember/reference/functions/useTable.md index c830fcc13d..cba642ed31 100644 --- a/docs/framework/ember/reference/functions/useTable.md +++ b/docs/framework/ember/reference/functions/useTable.md @@ -5,28 +5,76 @@ title: useTable # Function: useTable() +## Call Signature + +```ts +function useTable(owner, getOptions): Table; +``` + +Defined in: packages/ember-table/declarations/use-table.d.ts:10 + +Creates an Ember-reactive table. + +Pass the containing component (or another Ember destroyable) as the first +argument to tie external-atom subscriptions to its lifecycle. The one-arg +form remains available for standalone tables that do not have an Ember +owner. + +### Type Parameters + +#### TFeatures + +`TFeatures` *extends* `TableFeatures` + +#### TData + +`TData` *extends* `RowData` + +### Parameters + +#### owner + +`object` + +#### getOptions + +() => `TableOptions`\<`TFeatures`, `TData`\> + +### Returns + +`Table`\<`TFeatures`, `TData`\> + +## Call Signature + ```ts function useTable(getOptions): Table; ``` -Defined in: packages/ember-table/declarations/use-table.d.ts:2 +Defined in: packages/ember-table/declarations/use-table.d.ts:11 + +Creates an Ember-reactive table. + +Pass the containing component (or another Ember destroyable) as the first +argument to tie external-atom subscriptions to its lifecycle. The one-arg +form remains available for standalone tables that do not have an Ember +owner. -## Type Parameters +### Type Parameters -### TFeatures +#### TFeatures `TFeatures` *extends* `TableFeatures` -### TData +#### TData `TData` *extends* `RowData` -## Parameters +### Parameters -### getOptions +#### getOptions () => `TableOptions`\<`TFeatures`, `TData`\> -## Returns +### Returns `Table`\<`TFeatures`, `TData`\> diff --git a/docs/framework/lit/guide/table-state.md b/docs/framework/lit/guide/table-state.md index 173ffbe6fe..8af534b542 100644 --- a/docs/framework/lit/guide/table-state.md +++ b/docs/framework/lit/guide/table-state.md @@ -32,9 +32,10 @@ A table instance has a few state surfaces: - `table.baseAtoms` are the internal writable atoms created from the resolved initial state. - `table.atoms` are readonly derived atoms exposed per registered state slice. - `table.store` is a readonly flat TanStack Store derived by putting all of the registered `table.atoms` together. +- `table.optionAtoms` contains stable atoms for individual resolved options, plus the readonly `snapshotVersion` atom for observing aggregate option updates. Ordinary option atoms are writable, while `table.options` is a stable readonly view backed by those atoms. - `table.state` is Lit-only selected state. It is the value returned from the selector passed as the second argument to `tableController.table(...)`. -The Lit adapter provides `litReactivity()` to the table's `coreReactivityFeature`. Readonly and writable atoms are TanStack Store atoms. `TableController` subscribes to `table.store` and `table.optionsStore`; atom or options changes flowing through those stores call `host.requestUpdate()`. +The Lit adapter provides `litReactivity()` to the table's `coreReactivityFeature`. Readonly and writable atoms are TanStack Store atoms. `TableController` stages options so table reads during a render see the current values, publishes that option commit from `hostUpdated()`, and subscribes to `table.store` to request host updates for committed state changes. ### Feature-based State @@ -88,7 +89,7 @@ const tableState = table.store.state const pagination = table.store.state.pagination ``` -These reads are current-value reads. The `TableController` handles host invalidation through its subscriptions to the table store and options store. If the UI needs to stay reactive to table state changes, use `table.state`, `table.subscribe`, or a TanStack Store subscription. +These reads are current-value reads. The `TableController` handles host invalidation through its table-store subscription. If the UI needs to stay reactive to table state changes, use `table.state`, `table.subscribe`, or a TanStack Store subscription. #### Reading Reactive State with TableController diff --git a/docs/framework/lit/reference/classes/SubscribeDirective.md b/docs/framework/lit/reference/classes/SubscribeDirective.md index cba28097d1..c9e90a36a1 100644 --- a/docs/framework/lit/reference/classes/SubscribeDirective.md +++ b/docs/framework/lit/reference/classes/SubscribeDirective.md @@ -129,7 +129,7 @@ AsyncDirective._$initialize disconnected(): void; ``` -Defined in: [packages/lit-table/src/subscribe-directive.ts:141](https://github.com/TanStack/table/blob/main/packages/lit-table/src/subscribe-directive.ts#L141) +Defined in: [packages/lit-table/src/subscribe-directive.ts:150](https://github.com/TanStack/table/blob/main/packages/lit-table/src/subscribe-directive.ts#L150) Cleans up the controller subscription when the directive is removed from the DOM. @@ -151,7 +151,7 @@ AsyncDirective.disconnected reconnected(): void; ``` -Defined in: [packages/lit-table/src/subscribe-directive.ts:146](https://github.com/TanStack/table/blob/main/packages/lit-table/src/subscribe-directive.ts#L146) +Defined in: [packages/lit-table/src/subscribe-directive.ts:155](https://github.com/TanStack/table/blob/main/packages/lit-table/src/subscribe-directive.ts#L155) Restores the controller subscription when the directive is re-attached to the DOM. diff --git a/docs/framework/lit/reference/classes/TableController.md b/docs/framework/lit/reference/classes/TableController.md index 42c62b305e..32bea4b093 100644 --- a/docs/framework/lit/reference/classes/TableController.md +++ b/docs/framework/lit/reference/classes/TableController.md @@ -5,7 +5,7 @@ title: TableController # Class: TableController\ -Defined in: [packages/lit-table/src/TableController.ts:118](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L118) +Defined in: [packages/lit-table/src/TableController.ts:123](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L123) A Lit ReactiveController for TanStack Table integration. @@ -56,7 +56,7 @@ class MyTable extends LitElement { new TableController(host): TableController; ``` -Defined in: [packages/lit-table/src/TableController.ts:132](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L132) +Defined in: [packages/lit-table/src/TableController.ts:145](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L145) #### Parameters @@ -76,7 +76,7 @@ Defined in: [packages/lit-table/src/TableController.ts:132](https://github.com/T host: ReactiveControllerHost; ``` -Defined in: [packages/lit-table/src/TableController.ts:122](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L122) +Defined in: [packages/lit-table/src/TableController.ts:127](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L127) ## Methods @@ -86,7 +86,7 @@ Defined in: [packages/lit-table/src/TableController.ts:122](https://github.com/T hostConnected(): void; ``` -Defined in: [packages/lit-table/src/TableController.ts:238](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L238) +Defined in: [packages/lit-table/src/TableController.ts:260](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L260) Called when the host is connected to the component tree. For custom element hosts, this corresponds to the `connectedCallback()` lifecycle, @@ -110,7 +110,7 @@ ReactiveController.hostConnected hostDisconnected(): void; ``` -Defined in: [packages/lit-table/src/TableController.ts:242](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L242) +Defined in: [packages/lit-table/src/TableController.ts:280](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L280) Called when the host is disconnected from the component tree. For custom element hosts, this corresponds to the `disconnectedCallback()` lifecycle, @@ -129,13 +129,36 @@ ReactiveController.hostDisconnected *** +### hostUpdated() + +```ts +hostUpdated(): void; +``` + +Defined in: [packages/lit-table/src/TableController.ts:267](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L267) + +Called after a host update, just before the host calls firstUpdated and +updated. It is not called in server-side rendering. + +#### Returns + +`void` + +#### Implementation of + +```ts +ReactiveController.hostUpdated +``` + +*** + ### table() ```ts table(tableOptions, selector?): LitTable; ``` -Defined in: [packages/lit-table/src/TableController.ts:152](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L152) +Defined in: [packages/lit-table/src/TableController.ts:165](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L165) Returns the Lit-backed table instance for the current render pass. diff --git a/docs/framework/lit/reference/functions/FlexRender-1.md b/docs/framework/lit/reference/functions/FlexRender-1.md index 26fe947fd8..c061ec9d2d 100644 --- a/docs/framework/lit/reference/functions/FlexRender-1.md +++ b/docs/framework/lit/reference/functions/FlexRender-1.md @@ -6,10 +6,10 @@ title: FlexRender # Function: FlexRender() ```ts -function FlexRender(props): string | TemplateResult | null; +function FlexRender(props): LitRenderable; ``` -Defined in: [packages/lit-table/src/flexRender.ts:90](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L90) +Defined in: [packages/lit-table/src/flexRender.ts:101](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L101) Simplified component wrapper of `flexRender`. Use this utility function to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed. @@ -36,7 +36,7 @@ Only one prop (`cell`, `header`, or `footer`) may be passed. ## Returns -`string` \| `TemplateResult` \| `null` +[`LitRenderable`](../type-aliases/LitRenderable.md) ## Example diff --git a/docs/framework/lit/reference/functions/createTableHook.md b/docs/framework/lit/reference/functions/createTableHook.md index 6167c70940..3272de93ba 100644 --- a/docs/framework/lit/reference/functions/createTableHook.md +++ b/docs/framework/lit/reference/functions/createTableHook.md @@ -9,7 +9,7 @@ title: createTableHook function createTableHook(__namedParameters): CreateTableHookResult; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:503](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L503) +Defined in: [packages/lit-table/src/createTableHook.ts:504](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L504) Creates a custom table hook with pre-bound components for composition. diff --git a/docs/framework/lit/reference/functions/flexRender.md b/docs/framework/lit/reference/functions/flexRender.md index cf133cdc28..883d93927f 100644 --- a/docs/framework/lit/reference/functions/flexRender.md +++ b/docs/framework/lit/reference/functions/flexRender.md @@ -6,10 +6,10 @@ title: flexRender # Function: flexRender() ```ts -function flexRender(Comp, props): string | TemplateResult | null; +function flexRender(Comp, props): LitRenderable; ``` -Defined in: [packages/lit-table/src/flexRender.ts:22](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L22) +Defined in: [packages/lit-table/src/flexRender.ts:37](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L37) Renders a Lit table template value with the provided context props. @@ -27,7 +27,7 @@ convenience wrapper for table cell/header/footer objects. ### Comp -`string` | `TemplateResult` | (`props`) => `string` \| `TemplateResult` | `undefined` +[`LitRenderable`](../type-aliases/LitRenderable.md) | (`props`) => [`LitRenderable`](../type-aliases/LitRenderable.md) ### props @@ -35,7 +35,7 @@ convenience wrapper for table cell/header/footer objects. ## Returns -`string` \| `TemplateResult` \| `null` +[`LitRenderable`](../type-aliases/LitRenderable.md) ## Example diff --git a/docs/framework/lit/reference/index.md b/docs/framework/lit/reference/index.md index e0cabbd6ce..5517c61193 100644 --- a/docs/framework/lit/reference/index.md +++ b/docs/framework/lit/reference/index.md @@ -28,6 +28,7 @@ title: "@tanstack/lit-table" - [ComponentType](type-aliases/ComponentType.md) - [CreateTableHookOptions](type-aliases/CreateTableHookOptions.md) - [FlexRenderProps](type-aliases/FlexRenderProps.md) +- [LitRenderable](type-aliases/LitRenderable.md) - [LitTable](type-aliases/LitTable.md) - [SelectionSource](type-aliases/SelectionSource.md) diff --git a/docs/framework/lit/reference/interfaces/CreateTableHookResult.md b/docs/framework/lit/reference/interfaces/CreateTableHookResult.md index 2c6bc65772..4aea227a2e 100644 --- a/docs/framework/lit/reference/interfaces/CreateTableHookResult.md +++ b/docs/framework/lit/reference/interfaces/CreateTableHookResult.md @@ -5,7 +5,7 @@ title: CreateTableHookResult # Interface: CreateTableHookResult\ -Defined in: [packages/lit-table/src/createTableHook.ts:358](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L358) +Defined in: [packages/lit-table/src/createTableHook.ts:359](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L359) ## Type Parameters @@ -33,7 +33,7 @@ Defined in: [packages/lit-table/src/createTableHook.ts:358](https://github.com/T appFeatures: TFeatures; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:365](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L365) +Defined in: [packages/lit-table/src/createTableHook.ts:366](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L366) The features object that was passed to `createTableHook`. @@ -45,7 +45,7 @@ The features object that was passed to `createTableHook`. createAppColumnHelper: () => AppColumnHelper; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:370](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L370) +Defined in: [packages/lit-table/src/createTableHook.ts:371](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L371) A column helper pre-bound to `TFeatures` and the registered components, so the cell/header/footer render props expose the bound components. @@ -68,7 +68,7 @@ the cell/header/footer render props expose the bound components. useAppTable: (host, tableOptions, selector?) => object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:381](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L381) +Defined in: [packages/lit-table/src/createTableHook.ts:382](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L382) Creates a controller-like object whose `table()` method returns a table with the `App*` wrapper functions, a bound `FlexRender`, and the registered @@ -120,7 +120,7 @@ table: () => AppLitTable(host) => ContextConsumer>, ReactiveControllerHost & HTMLElement>; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:410](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L410) +Defined in: [packages/lit-table/src/createTableHook.ts:411](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L411) Reads the cell instance from a `@lit/context` `ContextConsumer`. lit never provides an extended cell through context, so this is a BARE `Cell`. @@ -149,7 +149,7 @@ provides an extended cell through context, so this is a BARE `Cell`. useHeaderContext: (host) => ContextConsumer>, ReactiveControllerHost & HTMLElement>; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:420](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L420) +Defined in: [packages/lit-table/src/createTableHook.ts:421](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L421) Reads the header instance from a `@lit/context` `ContextConsumer`. lit never provides an extended header through context, so this is a BARE `Header`. @@ -178,7 +178,7 @@ provides an extended header through context, so this is a BARE `Header`. useTableContext: (host) => ContextConsumer>, ReactiveControllerHost & HTMLElement>; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:400](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L400) +Defined in: [packages/lit-table/src/createTableHook.ts:401](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L401) Reads the table provided by the nearest ancestor that called `useAppTable`, via a `@lit/context` `ContextConsumer`. This is the BARE `LitTable` written diff --git a/docs/framework/lit/reference/type-aliases/AppCellContext.md b/docs/framework/lit/reference/type-aliases/AppCellContext.md index 7e013ef7fb..05e996c13c 100644 --- a/docs/framework/lit/reference/type-aliases/AppCellContext.md +++ b/docs/framework/lit/reference/type-aliases/AppCellContext.md @@ -9,7 +9,7 @@ title: AppCellContext type AppCellContext = object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:48](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L48) +Defined in: [packages/lit-table/src/createTableHook.ts:49](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L49) Enhanced CellContext with pre-bound cell components. The `cell` property includes the registered cellComponents. @@ -40,19 +40,19 @@ The `cell` property includes the registered cellComponents. cell: Cell & BoundComponents & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:54](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L54) +Defined in: [packages/lit-table/src/createTableHook.ts:55](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L55) #### Type Declaration ##### FlexRender() ```ts -FlexRender: () => TemplateResult | string | null; +FlexRender: () => LitRenderable; ``` ###### Returns -`TemplateResult` \| `string` \| `null` +[`LitRenderable`](LitRenderable.md) *** @@ -62,7 +62,7 @@ FlexRender: () => TemplateResult | string | null; column: Column; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:58](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L58) +Defined in: [packages/lit-table/src/createTableHook.ts:59](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L59) *** @@ -72,7 +72,7 @@ Defined in: [packages/lit-table/src/createTableHook.ts:58](https://github.com/Ta getValue: CellContext["getValue"]; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:59](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L59) +Defined in: [packages/lit-table/src/createTableHook.ts:60](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L60) *** @@ -82,7 +82,7 @@ Defined in: [packages/lit-table/src/createTableHook.ts:59](https://github.com/Ta renderValue: CellContext["renderValue"]; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:60](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L60) +Defined in: [packages/lit-table/src/createTableHook.ts:61](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L61) *** @@ -92,7 +92,7 @@ Defined in: [packages/lit-table/src/createTableHook.ts:60](https://github.com/Ta row: Row; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:61](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L61) +Defined in: [packages/lit-table/src/createTableHook.ts:62](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L62) *** @@ -102,4 +102,4 @@ Defined in: [packages/lit-table/src/createTableHook.ts:61](https://github.com/Ta table: Table; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:62](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L62) +Defined in: [packages/lit-table/src/createTableHook.ts:63](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L63) diff --git a/docs/framework/lit/reference/type-aliases/AppColumnDefBase.md b/docs/framework/lit/reference/type-aliases/AppColumnDefBase.md index bfc76c591c..44646f83b6 100644 --- a/docs/framework/lit/reference/type-aliases/AppColumnDefBase.md +++ b/docs/framework/lit/reference/type-aliases/AppColumnDefBase.md @@ -9,7 +9,7 @@ title: AppColumnDefBase type AppColumnDefBase = Omit, "cell" | "header" | "footer"> & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:97](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L97) +Defined in: [packages/lit-table/src/createTableHook.ts:98](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L98) Enhanced column definition base with pre-bound components in cell/header/footer contexts. diff --git a/docs/framework/lit/reference/type-aliases/AppColumnDefTemplate.md b/docs/framework/lit/reference/type-aliases/AppColumnDefTemplate.md index 10e2a5e356..94ea5c6c65 100644 --- a/docs/framework/lit/reference/type-aliases/AppColumnDefTemplate.md +++ b/docs/framework/lit/reference/type-aliases/AppColumnDefTemplate.md @@ -9,7 +9,7 @@ title: AppColumnDefTemplate type AppColumnDefTemplate = string | (props) => any; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:90](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L90) +Defined in: [packages/lit-table/src/createTableHook.ts:91](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L91) Template type for column definitions that can be a string or a function. diff --git a/docs/framework/lit/reference/type-aliases/AppColumnHelper.md b/docs/framework/lit/reference/type-aliases/AppColumnHelper.md index 267fff63b1..352dc3f684 100644 --- a/docs/framework/lit/reference/type-aliases/AppColumnHelper.md +++ b/docs/framework/lit/reference/type-aliases/AppColumnHelper.md @@ -9,7 +9,7 @@ title: AppColumnHelper type AppColumnHelper = object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:173](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L173) +Defined in: [packages/lit-table/src/createTableHook.ts:174](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L174) Enhanced column helper with pre-bound components in cell/header/footer contexts. This enables TypeScript to know about the registered components when defining columns. @@ -40,7 +40,7 @@ This enables TypeScript to know about the registered components when defining co accessor: (accessor, column) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:183](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L183) +Defined in: [packages/lit-table/src/createTableHook.ts:184](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L184) Creates a data column definition with an accessor key or function. The cell, header, and footer contexts include pre-bound components. @@ -77,7 +77,7 @@ The cell, header, and footer contexts include pre-bound components. columns: (columns) => ColumnDef[] & [...TColumns]; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:214](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L214) +Defined in: [packages/lit-table/src/createTableHook.ts:215](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L215) Wraps an array of column definitions to preserve each column's individual TValue type. @@ -105,7 +105,7 @@ Wraps an array of column definitions to preserve each column's individual TValue display: (column) => DisplayColumnDef; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:222](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L222) +Defined in: [packages/lit-table/src/createTableHook.ts:223](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L223) Creates a display column definition for non-data columns. The cell, header, and footer contexts include pre-bound components. @@ -128,7 +128,7 @@ The cell, header, and footer contexts include pre-bound components. group: (column) => GroupColumnDef; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:235](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L235) +Defined in: [packages/lit-table/src/createTableHook.ts:236](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L236) Creates a group column definition with nested child columns. The cell, header, and footer contexts include pre-bound components. diff --git a/docs/framework/lit/reference/type-aliases/AppDisplayColumnDef.md b/docs/framework/lit/reference/type-aliases/AppDisplayColumnDef.md index 7f80e00a3a..cf84752256 100644 --- a/docs/framework/lit/reference/type-aliases/AppDisplayColumnDef.md +++ b/docs/framework/lit/reference/type-aliases/AppDisplayColumnDef.md @@ -9,7 +9,7 @@ title: AppDisplayColumnDef type AppDisplayColumnDef = Omit, "cell" | "header" | "footer"> & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:121](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L121) +Defined in: [packages/lit-table/src/createTableHook.ts:122](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L122) Enhanced display column definition with pre-bound components. diff --git a/docs/framework/lit/reference/type-aliases/AppGroupColumnDef.md b/docs/framework/lit/reference/type-aliases/AppGroupColumnDef.md index 69c0e75c2e..70bc3f0507 100644 --- a/docs/framework/lit/reference/type-aliases/AppGroupColumnDef.md +++ b/docs/framework/lit/reference/type-aliases/AppGroupColumnDef.md @@ -9,7 +9,7 @@ title: AppGroupColumnDef type AppGroupColumnDef = Omit, "cell" | "header" | "footer" | "columns"> & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:144](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L144) +Defined in: [packages/lit-table/src/createTableHook.ts:145](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L145) Enhanced group column definition with pre-bound components. @@ -24,7 +24,7 @@ optional cell: AppColumnDefTemplate[]; +optional columns: ReadonlyArray>; ``` ### footer? diff --git a/docs/framework/lit/reference/type-aliases/AppHeaderContext.md b/docs/framework/lit/reference/type-aliases/AppHeaderContext.md index a2da9caa18..46e6eb056b 100644 --- a/docs/framework/lit/reference/type-aliases/AppHeaderContext.md +++ b/docs/framework/lit/reference/type-aliases/AppHeaderContext.md @@ -9,7 +9,7 @@ title: AppHeaderContext type AppHeaderContext = object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:69](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L69) +Defined in: [packages/lit-table/src/createTableHook.ts:70](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L70) Enhanced HeaderContext with pre-bound header components. The `header` property includes the registered headerComponents. @@ -40,7 +40,7 @@ The `header` property includes the registered headerComponents. column: Column; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:75](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L75) +Defined in: [packages/lit-table/src/createTableHook.ts:76](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L76) *** @@ -50,19 +50,19 @@ Defined in: [packages/lit-table/src/createTableHook.ts:75](https://github.com/Ta header: Header & BoundComponents & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:76](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L76) +Defined in: [packages/lit-table/src/createTableHook.ts:77](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L77) #### Type Declaration ##### FlexRender() ```ts -FlexRender: () => TemplateResult | string | null; +FlexRender: () => LitRenderable; ``` ###### Returns -`TemplateResult` \| `string` \| `null` +[`LitRenderable`](LitRenderable.md) *** @@ -72,4 +72,4 @@ FlexRender: () => TemplateResult | string | null; table: Table; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:80](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L80) +Defined in: [packages/lit-table/src/createTableHook.ts:81](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L81) diff --git a/docs/framework/lit/reference/type-aliases/AppLitTable.md b/docs/framework/lit/reference/type-aliases/AppLitTable.md index 2d74a6aa64..040021f8e1 100644 --- a/docs/framework/lit/reference/type-aliases/AppLitTable.md +++ b/docs/framework/lit/reference/type-aliases/AppLitTable.md @@ -9,7 +9,7 @@ title: AppLitTable type AppLitTable = LitTable & NoInfer & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:288](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L288) +Defined in: [packages/lit-table/src/createTableHook.ts:289](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L289) Extended table API returned by useAppTable with all App wrapper functions @@ -18,7 +18,7 @@ Extended table API returned by useAppTable with all App wrapper functions ### AppCell() ```ts -AppCell: (cell, renderFn) => TemplateResult | string; +AppCell: (cell, renderFn) => LitRenderable; ``` Wraps a cell and provides cell context with pre-bound cellComponents. @@ -37,11 +37,11 @@ Wraps a cell and provides cell context with pre-bound cellComponents. ##### renderFn -(`cell`) => `TemplateResult` \| `string` +(`cell`) => [`LitRenderable`](LitRenderable.md) #### Returns -`TemplateResult` \| `string` +[`LitRenderable`](LitRenderable.md) #### Example @@ -52,7 +52,7 @@ ${table.AppCell(cell, (c) => html`${c.FlexRender()}`)} ### AppFooter() ```ts -AppFooter: (header, renderFn) => TemplateResult | string; +AppFooter: (header, renderFn) => LitRenderable; ``` Wraps a footer and provides header context with pre-bound headerComponents. @@ -71,11 +71,11 @@ Wraps a footer and provides header context with pre-bound headerComponents. ##### renderFn -(`header`) => `TemplateResult` \| `string` +(`header`) => [`LitRenderable`](LitRenderable.md) #### Returns -`TemplateResult` \| `string` +[`LitRenderable`](LitRenderable.md) #### Example @@ -86,7 +86,7 @@ ${table.AppFooter(footer, (f) => html`${f.FlexRender()}`)} ### AppHeader() ```ts -AppHeader: (header, renderFn) => TemplateResult | string; +AppHeader: (header, renderFn) => LitRenderable; ``` Wraps a header and provides header context with pre-bound headerComponents. @@ -105,11 +105,11 @@ Wraps a header and provides header context with pre-bound headerComponents. ##### renderFn -(`header`) => `TemplateResult` \| `string` +(`header`) => [`LitRenderable`](LitRenderable.md) #### Returns -`TemplateResult` \| `string` +[`LitRenderable`](LitRenderable.md) #### Example diff --git a/docs/framework/lit/reference/type-aliases/BoundComponents.md b/docs/framework/lit/reference/type-aliases/BoundComponents.md index 6e602b3638..07e84c5124 100644 --- a/docs/framework/lit/reference/type-aliases/BoundComponents.md +++ b/docs/framework/lit/reference/type-aliases/BoundComponents.md @@ -9,7 +9,7 @@ title: BoundComponents type BoundComponents = { [TKey in keyof TComponents]: () => ReturnType }; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:34](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L34) +Defined in: [packages/lit-table/src/createTableHook.ts:35](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L35) ## Type Parameters diff --git a/docs/framework/lit/reference/type-aliases/ComponentType.md b/docs/framework/lit/reference/type-aliases/ComponentType.md index 37cb672734..8bb2f9aa9f 100644 --- a/docs/framework/lit/reference/type-aliases/ComponentType.md +++ b/docs/framework/lit/reference/type-aliases/ComponentType.md @@ -9,7 +9,7 @@ title: ComponentType type ComponentType = (props) => any; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:32](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L32) +Defined in: [packages/lit-table/src/createTableHook.ts:33](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L33) ## Type Parameters diff --git a/docs/framework/lit/reference/type-aliases/CreateTableHookOptions.md b/docs/framework/lit/reference/type-aliases/CreateTableHookOptions.md index cc8073add5..d918364ed1 100644 --- a/docs/framework/lit/reference/type-aliases/CreateTableHookOptions.md +++ b/docs/framework/lit/reference/type-aliases/CreateTableHookOptions.md @@ -9,7 +9,7 @@ title: CreateTableHookOptions type CreateTableHookOptions = Omit, "columns" | "data" | "store" | "state" | "initialState"> & object; ``` -Defined in: [packages/lit-table/src/createTableHook.ts:253](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L253) +Defined in: [packages/lit-table/src/createTableHook.ts:254](https://github.com/TanStack/table/blob/main/packages/lit-table/src/createTableHook.ts#L254) Options for creating a table hook with pre-bound components and default table options. Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. diff --git a/docs/framework/lit/reference/type-aliases/FlexRenderProps.md b/docs/framework/lit/reference/type-aliases/FlexRenderProps.md index 39711fc8c5..6449a0df72 100644 --- a/docs/framework/lit/reference/type-aliases/FlexRenderProps.md +++ b/docs/framework/lit/reference/type-aliases/FlexRenderProps.md @@ -24,7 +24,7 @@ type FlexRenderProps = }; ``` -Defined in: [packages/lit-table/src/flexRender.ts:56](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L56) +Defined in: [packages/lit-table/src/flexRender.ts:67](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L67) Simplified component wrapper of `flexRender`. Use this utility function to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed. diff --git a/docs/framework/lit/reference/type-aliases/LitRenderable.md b/docs/framework/lit/reference/type-aliases/LitRenderable.md new file mode 100644 index 0000000000..f471ca81ba --- /dev/null +++ b/docs/framework/lit/reference/type-aliases/LitRenderable.md @@ -0,0 +1,24 @@ +--- +id: LitRenderable +title: LitRenderable +--- + +# Type Alias: LitRenderable + +```ts +type LitRenderable = + | TemplateResult + | DirectiveResult + | Node + | string + | number + | bigint + | boolean + | null + | undefined + | typeof nothing + | typeof noChange +| Iterable; +``` + +Defined in: [packages/lit-table/src/flexRender.ts:11](https://github.com/TanStack/table/blob/main/packages/lit-table/src/flexRender.ts#L11) diff --git a/docs/framework/lit/reference/type-aliases/LitTable.md b/docs/framework/lit/reference/type-aliases/LitTable.md index ac6715de90..64a961162f 100644 --- a/docs/framework/lit/reference/type-aliases/LitTable.md +++ b/docs/framework/lit/reference/type-aliases/LitTable.md @@ -9,7 +9,7 @@ title: LitTable type LitTable = Omit, "store"> & object; ``` -Defined in: [packages/lit-table/src/TableController.ts:21](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L21) +Defined in: [packages/lit-table/src/TableController.ts:26](https://github.com/TanStack/table/blob/main/packages/lit-table/src/TableController.ts#L26) The extended table type returned by the Lit adapter. Includes a `Subscribe` method for fine-grained state subscriptions diff --git a/docs/framework/lit/reference/variables/subscribe.md b/docs/framework/lit/reference/variables/subscribe.md index 72c84f206b..bc5793186e 100644 --- a/docs/framework/lit/reference/variables/subscribe.md +++ b/docs/framework/lit/reference/variables/subscribe.md @@ -12,7 +12,7 @@ const subscribe: { }; ``` -Defined in: [packages/lit-table/src/subscribe-directive.ts:182](https://github.com/TanStack/table/blob/main/packages/lit-table/src/subscribe-directive.ts#L182) +Defined in: [packages/lit-table/src/subscribe-directive.ts:194](https://github.com/TanStack/table/blob/main/packages/lit-table/src/subscribe-directive.ts#L194) A Lit directive that subscribes to a source (Store or Atom) and efficiently updates only the wrapped template diff --git a/docs/framework/preact/reference/functions/FlexRender-1.md b/docs/framework/preact/reference/functions/FlexRender-1.md index 706c45da04..7f29a39faf 100644 --- a/docs/framework/preact/reference/functions/FlexRender-1.md +++ b/docs/framework/preact/reference/functions/FlexRender-1.md @@ -9,7 +9,7 @@ title: FlexRender function FlexRender(props): ComponentChild; ``` -Defined in: [FlexRender.tsx:98](https://github.com/TanStack/table/blob/main/packages/preact-table/src/FlexRender.tsx#L98) +Defined in: [FlexRender.tsx:101](https://github.com/TanStack/table/blob/main/packages/preact-table/src/FlexRender.tsx#L101) Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed. diff --git a/docs/framework/preact/reference/functions/flexRender.md b/docs/framework/preact/reference/functions/flexRender.md index e4ec898268..3b1cabadbf 100644 --- a/docs/framework/preact/reference/functions/flexRender.md +++ b/docs/framework/preact/reference/functions/flexRender.md @@ -9,7 +9,7 @@ title: flexRender function flexRender(Comp, props): ComponentChild | Element; ``` -Defined in: [FlexRender.tsx:46](https://github.com/TanStack/table/blob/main/packages/preact-table/src/FlexRender.tsx#L46) +Defined in: [FlexRender.tsx:49](https://github.com/TanStack/table/blob/main/packages/preact-table/src/FlexRender.tsx#L49) If rendering headers, cells, or footers with custom markup, use flexRender instead of `cell.getValue()` or `cell.renderValue()`. diff --git a/docs/framework/preact/reference/functions/useTable.md b/docs/framework/preact/reference/functions/useTable.md index 8189a123d8..fb1d1da29d 100644 --- a/docs/framework/preact/reference/functions/useTable.md +++ b/docs/framework/preact/reference/functions/useTable.md @@ -9,7 +9,7 @@ title: useTable function useTable(tableOptions, selector?): PreactTable; ``` -Defined in: [useTable.ts:112](https://github.com/TanStack/table/blob/main/packages/preact-table/src/useTable.ts#L112) +Defined in: [useTable.ts:121](https://github.com/TanStack/table/blob/main/packages/preact-table/src/useTable.ts#L121) Creates a Preact table instance backed by TanStack Store atoms. diff --git a/docs/framework/preact/reference/type-aliases/AppGroupColumnDef.md b/docs/framework/preact/reference/type-aliases/AppGroupColumnDef.md index 837a3c58ae..69491cc742 100644 --- a/docs/framework/preact/reference/type-aliases/AppGroupColumnDef.md +++ b/docs/framework/preact/reference/type-aliases/AppGroupColumnDef.md @@ -24,7 +24,7 @@ optional cell: AppColumnDefTemplate[]; +optional columns: ReadonlyArray>; ``` ### footer? diff --git a/docs/framework/preact/reference/type-aliases/FlexRenderProps.md b/docs/framework/preact/reference/type-aliases/FlexRenderProps.md index cfb08d16a6..6d9cc3ebb6 100644 --- a/docs/framework/preact/reference/type-aliases/FlexRenderProps.md +++ b/docs/framework/preact/reference/type-aliases/FlexRenderProps.md @@ -24,7 +24,7 @@ type FlexRenderProps = }; ``` -Defined in: [FlexRender.tsx:64](https://github.com/TanStack/table/blob/main/packages/preact-table/src/FlexRender.tsx#L64) +Defined in: [FlexRender.tsx:67](https://github.com/TanStack/table/blob/main/packages/preact-table/src/FlexRender.tsx#L67) Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed. diff --git a/docs/framework/preact/reference/type-aliases/PreactTable.md b/docs/framework/preact/reference/type-aliases/PreactTable.md index a3c552c4ca..af6038701b 100644 --- a/docs/framework/preact/reference/type-aliases/PreactTable.md +++ b/docs/framework/preact/reference/type-aliases/PreactTable.md @@ -9,7 +9,7 @@ title: PreactTable type PreactTable = Omit, "store"> & object; ``` -Defined in: [useTable.ts:19](https://github.com/TanStack/table/blob/main/packages/preact-table/src/useTable.ts#L19) +Defined in: [useTable.ts:27](https://github.com/TanStack/table/blob/main/packages/preact-table/src/useTable.ts#L27) ## Type Declaration diff --git a/docs/framework/preact/reference/type-aliases/SubscribePropsWithSourceIdentity.md b/docs/framework/preact/reference/type-aliases/SubscribePropsWithSourceIdentity.md index 347a1565da..9c28cb587d 100644 --- a/docs/framework/preact/reference/type-aliases/SubscribePropsWithSourceIdentity.md +++ b/docs/framework/preact/reference/type-aliases/SubscribePropsWithSourceIdentity.md @@ -12,7 +12,7 @@ type SubscribePropsWithSourceIdentity = object; Defined in: [Subscribe.ts:42](https://github.com/TanStack/table/blob/main/packages/preact-table/src/Subscribe.ts#L42) Subscribe to the full value of a source (e.g. `table.atoms.rowSelection` or -`table.optionsStore`). Omitting `selector` is equivalent to the identity +`table.optionAtoms.data`). Omitting `selector` is equivalent to the identity selector — children receive `TSourceValue`. ## Type Parameters diff --git a/docs/framework/react/reference/index/functions/useTable.md b/docs/framework/react/reference/index/functions/useTable.md index 7c8a4a1bd6..2aeae10d7a 100644 --- a/docs/framework/react/reference/index/functions/useTable.md +++ b/docs/framework/react/reference/index/functions/useTable.md @@ -9,7 +9,7 @@ title: useTable function useTable(tableOptions, selector?): ReactTable; ``` -Defined in: [useTable.ts:141](https://github.com/TanStack/table/blob/main/packages/react-table/src/useTable.ts#L141) +Defined in: [useTable.ts:150](https://github.com/TanStack/table/blob/main/packages/react-table/src/useTable.ts#L150) Creates a React table instance backed by TanStack Store atoms. diff --git a/docs/framework/react/reference/index/type-aliases/AppGroupColumnDef.md b/docs/framework/react/reference/index/type-aliases/AppGroupColumnDef.md index f5b71eab3b..dbc86d42a4 100644 --- a/docs/framework/react/reference/index/type-aliases/AppGroupColumnDef.md +++ b/docs/framework/react/reference/index/type-aliases/AppGroupColumnDef.md @@ -24,7 +24,7 @@ optional cell: AppColumnDefTemplate[]; +optional columns: ReadonlyArray>; ``` ### footer? diff --git a/docs/framework/react/reference/index/type-aliases/ReactTable.md b/docs/framework/react/reference/index/type-aliases/ReactTable.md index ba687dfb15..b8b448527c 100644 --- a/docs/framework/react/reference/index/type-aliases/ReactTable.md +++ b/docs/framework/react/reference/index/type-aliases/ReactTable.md @@ -9,7 +9,7 @@ title: ReactTable type ReactTable = Omit, "store"> & object; ``` -Defined in: [useTable.ts:21](https://github.com/TanStack/table/blob/main/packages/react-table/src/useTable.ts#L21) +Defined in: [useTable.ts:29](https://github.com/TanStack/table/blob/main/packages/react-table/src/useTable.ts#L29) ## Type Declaration diff --git a/docs/framework/react/reference/index/type-aliases/SubscribePropsWithSourceIdentity.md b/docs/framework/react/reference/index/type-aliases/SubscribePropsWithSourceIdentity.md index 311890ced1..dd0b58b1f5 100644 --- a/docs/framework/react/reference/index/type-aliases/SubscribePropsWithSourceIdentity.md +++ b/docs/framework/react/reference/index/type-aliases/SubscribePropsWithSourceIdentity.md @@ -12,7 +12,7 @@ type SubscribePropsWithSourceIdentity = object; Defined in: [Subscribe.ts:44](https://github.com/TanStack/table/blob/main/packages/react-table/src/Subscribe.ts#L44) Subscribe to the full value of a source (e.g. `table.atoms.rowSelection` or -`table.optionsStore`). Omitting `selector` is equivalent to the identity +`table.optionAtoms.data`). Omitting `selector` is equivalent to the identity selector — children receive `TSourceValue`. ## Type Parameters diff --git a/docs/framework/solid/reference/functions/createTable.md b/docs/framework/solid/reference/functions/createTable.md index a1c36de618..02136dce64 100644 --- a/docs/framework/solid/reference/functions/createTable.md +++ b/docs/framework/solid/reference/functions/createTable.md @@ -9,7 +9,7 @@ title: createTable function createTable(tableOptions): SolidTable; ``` -Defined in: [createTable.ts:61](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTable.ts#L61) +Defined in: [createTable.ts:56](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTable.ts#L56) Creates a Solid table instance backed by Solid-aware TanStack Store atoms. diff --git a/docs/framework/solid/reference/functions/createTableHook.md b/docs/framework/solid/reference/functions/createTableHook.md index b98e83ae7c..0638d6f940 100644 --- a/docs/framework/solid/reference/functions/createTableHook.md +++ b/docs/framework/solid/reference/functions/createTableHook.md @@ -9,7 +9,7 @@ title: createTableHook function createTableHook(__namedParameters): CreateTableHookResult; ``` -Defined in: [createTableHook.tsx:572](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L572) +Defined in: [createTableHook.tsx:573](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L573) Creates a custom table hook with pre-bound components for composition. diff --git a/docs/framework/solid/reference/interfaces/AppCellComponent.md b/docs/framework/solid/reference/interfaces/AppCellComponent.md index 36c2b4f784..3e59c43cb3 100644 --- a/docs/framework/solid/reference/interfaces/AppCellComponent.md +++ b/docs/framework/solid/reference/interfaces/AppCellComponent.md @@ -5,7 +5,7 @@ title: AppCellComponent # Interface: AppCellComponent()\ -Defined in: [createTableHook.tsx:312](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L312) +Defined in: [createTableHook.tsx:313](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L313) Component type for AppCell - wraps a cell and provides cell context. @@ -27,7 +27,7 @@ Component type for AppCell - wraps a cell and provides cell context. AppCellComponent(props): Element; ``` -Defined in: [createTableHook.tsx:317](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L317) +Defined in: [createTableHook.tsx:318](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L318) Component type for AppCell - wraps a cell and provides cell context. diff --git a/docs/framework/solid/reference/interfaces/AppCellProps.md b/docs/framework/solid/reference/interfaces/AppCellProps.md index b58addcd4e..35dfe1aa6f 100644 --- a/docs/framework/solid/reference/interfaces/AppCellProps.md +++ b/docs/framework/solid/reference/interfaces/AppCellProps.md @@ -5,7 +5,7 @@ title: AppCellProps # Interface: AppCellProps\ -Defined in: [createTableHook.tsx:280](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L280) +Defined in: [createTableHook.tsx:281](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L281) Props for AppCell component. @@ -35,7 +35,7 @@ Props for AppCell component. cell: Cell; ``` -Defined in: [createTableHook.tsx:286](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L286) +Defined in: [createTableHook.tsx:287](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L287) *** @@ -45,7 +45,7 @@ Defined in: [createTableHook.tsx:286](https://github.com/TanStack/table/blob/mai children: (cell) => Element; ``` -Defined in: [createTableHook.tsx:287](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L287) +Defined in: [createTableHook.tsx:288](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L288) #### Parameters diff --git a/docs/framework/solid/reference/interfaces/AppHeaderComponent.md b/docs/framework/solid/reference/interfaces/AppHeaderComponent.md index 70e2e344c0..d98fe0b707 100644 --- a/docs/framework/solid/reference/interfaces/AppHeaderComponent.md +++ b/docs/framework/solid/reference/interfaces/AppHeaderComponent.md @@ -5,7 +5,7 @@ title: AppHeaderComponent # Interface: AppHeaderComponent()\ -Defined in: [createTableHook.tsx:325](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L325) +Defined in: [createTableHook.tsx:326](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L326) Component type for AppHeader/AppFooter - wraps a header and provides header context. @@ -27,7 +27,7 @@ Component type for AppHeader/AppFooter - wraps a header and provides header cont AppHeaderComponent(props): Element; ``` -Defined in: [createTableHook.tsx:330](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L330) +Defined in: [createTableHook.tsx:331](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L331) Component type for AppHeader/AppFooter - wraps a header and provides header context. diff --git a/docs/framework/solid/reference/interfaces/AppHeaderProps.md b/docs/framework/solid/reference/interfaces/AppHeaderProps.md index 248070d61c..5ed7f890d7 100644 --- a/docs/framework/solid/reference/interfaces/AppHeaderProps.md +++ b/docs/framework/solid/reference/interfaces/AppHeaderProps.md @@ -5,7 +5,7 @@ title: AppHeaderProps # Interface: AppHeaderProps\ -Defined in: [createTableHook.tsx:296](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L296) +Defined in: [createTableHook.tsx:297](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L297) Props for AppHeader/AppFooter component. @@ -35,7 +35,7 @@ Props for AppHeader/AppFooter component. children: (header) => Element; ``` -Defined in: [createTableHook.tsx:303](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L303) +Defined in: [createTableHook.tsx:304](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L304) #### Parameters @@ -55,4 +55,4 @@ Defined in: [createTableHook.tsx:303](https://github.com/TanStack/table/blob/mai header: Header; ``` -Defined in: [createTableHook.tsx:302](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L302) +Defined in: [createTableHook.tsx:303](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L303) diff --git a/docs/framework/solid/reference/interfaces/AppTableComponent.md b/docs/framework/solid/reference/interfaces/AppTableComponent.md index ac2f7c6e56..1e14d7e009 100644 --- a/docs/framework/solid/reference/interfaces/AppTableComponent.md +++ b/docs/framework/solid/reference/interfaces/AppTableComponent.md @@ -5,7 +5,7 @@ title: AppTableComponent # Interface: AppTableComponent()\<_TFeatures\> -Defined in: [createTableHook.tsx:338](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L338) +Defined in: [createTableHook.tsx:339](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L339) Component type for AppTable - root wrapper with optional Subscribe @@ -19,7 +19,7 @@ Component type for AppTable - root wrapper with optional Subscribe AppTableComponent(props): Element; ``` -Defined in: [createTableHook.tsx:339](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L339) +Defined in: [createTableHook.tsx:340](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L340) Component type for AppTable - root wrapper with optional Subscribe diff --git a/docs/framework/solid/reference/interfaces/AppTableProps.md b/docs/framework/solid/reference/interfaces/AppTableProps.md index 2f2714e551..d4bd747fa1 100644 --- a/docs/framework/solid/reference/interfaces/AppTableProps.md +++ b/docs/framework/solid/reference/interfaces/AppTableProps.md @@ -5,7 +5,7 @@ title: AppTableProps # Interface: AppTableProps -Defined in: [createTableHook.tsx:273](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L273) +Defined in: [createTableHook.tsx:274](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L274) ## Properties @@ -15,4 +15,4 @@ Defined in: [createTableHook.tsx:273](https://github.com/TanStack/table/blob/mai children: Element; ``` -Defined in: [createTableHook.tsx:274](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L274) +Defined in: [createTableHook.tsx:275](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L275) diff --git a/docs/framework/solid/reference/interfaces/CreateTableHookResult.md b/docs/framework/solid/reference/interfaces/CreateTableHookResult.md index 660ab4153b..9c2a0af301 100644 --- a/docs/framework/solid/reference/interfaces/CreateTableHookResult.md +++ b/docs/framework/solid/reference/interfaces/CreateTableHookResult.md @@ -5,7 +5,7 @@ title: CreateTableHookResult # Interface: CreateTableHookResult\ -Defined in: [createTableHook.tsx:406](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L406) +Defined in: [createTableHook.tsx:407](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L407) ## Type Parameters @@ -33,7 +33,7 @@ Defined in: [createTableHook.tsx:406](https://github.com/TanStack/table/blob/mai appFeatures: TFeatures; ``` -Defined in: [createTableHook.tsx:413](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L413) +Defined in: [createTableHook.tsx:414](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L414) The features object that was passed to `createTableHook`. @@ -45,7 +45,7 @@ The features object that was passed to `createTableHook`. createAppColumnHelper: () => AppColumnHelper; ``` -Defined in: [createTableHook.tsx:418](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L418) +Defined in: [createTableHook.tsx:419](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L419) A column helper pre-bound to `TFeatures` and the registered components, so the cell/header/footer render props expose the bound components. @@ -68,7 +68,7 @@ the cell/header/footer render props expose the bound components. createAppTable: (tableOptions) => AppSolidTable; ``` -Defined in: [createTableHook.tsx:428](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L428) +Defined in: [createTableHook.tsx:429](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L429) Creates a table with the `App*` wrapper components and registered `tableComponents` attached. `TData` is inferred from the `data` option. @@ -97,7 +97,7 @@ Creates a table with the `App*` wrapper components and registered useCellContext: () => Cell_Core & ExtractFeatureMapTypes & TCellComponents & object; ``` -Defined in: [createTableHook.tsx:453](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L453) +Defined in: [createTableHook.tsx:454](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L454) Reads the cell provided by the nearest ``, extended with your `cellComponents` and a context-bound `FlexRender`. @@ -120,7 +120,7 @@ Reads the cell provided by the nearest ``, extended with your useHeaderContext: () => Header_Core & ExtractFeatureMapTypes & THeaderComponents & object; ``` -Defined in: [createTableHook.tsx:464](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L464) +Defined in: [createTableHook.tsx:465](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L465) Reads the header provided by the nearest `` / ``, extended with your `headerComponents` and a @@ -144,7 +144,7 @@ context-bound `FlexRender`. useTableContext: () => AppSolidTable; ``` -Defined in: [createTableHook.tsx:442](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L442) +Defined in: [createTableHook.tsx:443](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L443) Reads the table provided by the nearest ``. This is the same extended instance `createAppTable` returns, so the `App*` components and your diff --git a/docs/framework/solid/reference/type-aliases/AppCellContext.md b/docs/framework/solid/reference/type-aliases/AppCellContext.md index 6d75083acc..3d5fb1e6f2 100644 --- a/docs/framework/solid/reference/type-aliases/AppCellContext.md +++ b/docs/framework/solid/reference/type-aliases/AppCellContext.md @@ -9,7 +9,7 @@ title: AppCellContext type AppCellContext = object; ``` -Defined in: [createTableHook.tsx:40](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L40) +Defined in: [createTableHook.tsx:41](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L41) Enhanced CellContext with pre-bound cell components. The `cell` property includes the registered cellComponents. @@ -40,7 +40,7 @@ The `cell` property includes the registered cellComponents. cell: Cell & TCellComponents & object; ``` -Defined in: [createTableHook.tsx:46](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L46) +Defined in: [createTableHook.tsx:47](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L47) #### Type Declaration @@ -62,7 +62,7 @@ FlexRender: () => JSXElement; column: Column; ``` -Defined in: [createTableHook.tsx:48](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L48) +Defined in: [createTableHook.tsx:49](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L49) *** @@ -72,7 +72,7 @@ Defined in: [createTableHook.tsx:48](https://github.com/TanStack/table/blob/main getValue: CellContext["getValue"]; ``` -Defined in: [createTableHook.tsx:49](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L49) +Defined in: [createTableHook.tsx:50](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L50) *** @@ -82,7 +82,7 @@ Defined in: [createTableHook.tsx:49](https://github.com/TanStack/table/blob/main renderValue: CellContext["renderValue"]; ``` -Defined in: [createTableHook.tsx:50](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L50) +Defined in: [createTableHook.tsx:51](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L51) *** @@ -92,7 +92,7 @@ Defined in: [createTableHook.tsx:50](https://github.com/TanStack/table/blob/main row: Row; ``` -Defined in: [createTableHook.tsx:51](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L51) +Defined in: [createTableHook.tsx:52](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L52) *** @@ -102,4 +102,4 @@ Defined in: [createTableHook.tsx:51](https://github.com/TanStack/table/blob/main table: Table; ``` -Defined in: [createTableHook.tsx:52](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L52) +Defined in: [createTableHook.tsx:53](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L53) diff --git a/docs/framework/solid/reference/type-aliases/AppColumnDefBase.md b/docs/framework/solid/reference/type-aliases/AppColumnDefBase.md index 23941c40bc..d1be49650b 100644 --- a/docs/framework/solid/reference/type-aliases/AppColumnDefBase.md +++ b/docs/framework/solid/reference/type-aliases/AppColumnDefBase.md @@ -9,7 +9,7 @@ title: AppColumnDefBase type AppColumnDefBase = Omit, "cell" | "header" | "footer"> & object; ``` -Defined in: [createTableHook.tsx:85](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L85) +Defined in: [createTableHook.tsx:86](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L86) Enhanced column definition base with pre-bound components in cell/header/footer contexts. diff --git a/docs/framework/solid/reference/type-aliases/AppColumnDefTemplate.md b/docs/framework/solid/reference/type-aliases/AppColumnDefTemplate.md index 6cf56656da..7988901aef 100644 --- a/docs/framework/solid/reference/type-aliases/AppColumnDefTemplate.md +++ b/docs/framework/solid/reference/type-aliases/AppColumnDefTemplate.md @@ -9,7 +9,7 @@ title: AppColumnDefTemplate type AppColumnDefTemplate = string | (props) => any; ``` -Defined in: [createTableHook.tsx:78](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L78) +Defined in: [createTableHook.tsx:79](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L79) Template type for column definitions that can be a string or a function. diff --git a/docs/framework/solid/reference/type-aliases/AppColumnHelper.md b/docs/framework/solid/reference/type-aliases/AppColumnHelper.md index 7a58d5c2b9..be559da935 100644 --- a/docs/framework/solid/reference/type-aliases/AppColumnHelper.md +++ b/docs/framework/solid/reference/type-aliases/AppColumnHelper.md @@ -9,7 +9,7 @@ title: AppColumnHelper type AppColumnHelper = object; ``` -Defined in: [createTableHook.tsx:161](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L161) +Defined in: [createTableHook.tsx:162](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L162) Enhanced column helper with pre-bound components in cell/header/footer contexts. This enables TypeScript to know about the registered components when defining columns. @@ -40,7 +40,7 @@ This enables TypeScript to know about the registered components when defining co accessor: (accessor, column) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef; ``` -Defined in: [createTableHook.tsx:171](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L171) +Defined in: [createTableHook.tsx:172](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L172) Creates a data column definition with an accessor key or function. The cell, header, and footer contexts include pre-bound components. @@ -77,7 +77,7 @@ The cell, header, and footer contexts include pre-bound components. columns: (columns) => ColumnDef[] & [...TColumns]; ``` -Defined in: [createTableHook.tsx:202](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L202) +Defined in: [createTableHook.tsx:203](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L203) Wraps an array of column definitions to preserve each column's individual TValue type. @@ -105,7 +105,7 @@ Wraps an array of column definitions to preserve each column's individual TValue display: (column) => DisplayColumnDef; ``` -Defined in: [createTableHook.tsx:210](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L210) +Defined in: [createTableHook.tsx:211](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L211) Creates a display column definition for non-data columns. The cell, header, and footer contexts include pre-bound components. @@ -128,7 +128,7 @@ The cell, header, and footer contexts include pre-bound components. group: (column) => GroupColumnDef; ``` -Defined in: [createTableHook.tsx:223](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L223) +Defined in: [createTableHook.tsx:224](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L224) Creates a group column definition with nested child columns. The cell, header, and footer contexts include pre-bound components. diff --git a/docs/framework/solid/reference/type-aliases/AppDisplayColumnDef.md b/docs/framework/solid/reference/type-aliases/AppDisplayColumnDef.md index 359ad0db24..262b9431d6 100644 --- a/docs/framework/solid/reference/type-aliases/AppDisplayColumnDef.md +++ b/docs/framework/solid/reference/type-aliases/AppDisplayColumnDef.md @@ -9,7 +9,7 @@ title: AppDisplayColumnDef type AppDisplayColumnDef = Omit, "cell" | "header" | "footer"> & object; ``` -Defined in: [createTableHook.tsx:109](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L109) +Defined in: [createTableHook.tsx:110](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L110) Enhanced display column definition with pre-bound components. diff --git a/docs/framework/solid/reference/type-aliases/AppGroupColumnDef.md b/docs/framework/solid/reference/type-aliases/AppGroupColumnDef.md index 53f9d1283f..5335c5af1a 100644 --- a/docs/framework/solid/reference/type-aliases/AppGroupColumnDef.md +++ b/docs/framework/solid/reference/type-aliases/AppGroupColumnDef.md @@ -9,7 +9,7 @@ title: AppGroupColumnDef type AppGroupColumnDef = Omit, "cell" | "header" | "footer" | "columns"> & object; ``` -Defined in: [createTableHook.tsx:132](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L132) +Defined in: [createTableHook.tsx:133](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L133) Enhanced group column definition with pre-bound components. @@ -24,7 +24,7 @@ optional cell: AppColumnDefTemplate[]; +optional columns: ReadonlyArray>; ``` ### footer? diff --git a/docs/framework/solid/reference/type-aliases/AppHeaderContext.md b/docs/framework/solid/reference/type-aliases/AppHeaderContext.md index 78bfb65852..63d80f7fb9 100644 --- a/docs/framework/solid/reference/type-aliases/AppHeaderContext.md +++ b/docs/framework/solid/reference/type-aliases/AppHeaderContext.md @@ -9,7 +9,7 @@ title: AppHeaderContext type AppHeaderContext = object; ``` -Defined in: [createTableHook.tsx:59](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L59) +Defined in: [createTableHook.tsx:60](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L60) Enhanced HeaderContext with pre-bound header components. The `header` property includes the registered headerComponents. @@ -40,7 +40,7 @@ The `header` property includes the registered headerComponents. column: Column; ``` -Defined in: [createTableHook.tsx:65](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L65) +Defined in: [createTableHook.tsx:66](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L66) *** @@ -50,7 +50,7 @@ Defined in: [createTableHook.tsx:65](https://github.com/TanStack/table/blob/main header: Header & THeaderComponents & object; ``` -Defined in: [createTableHook.tsx:66](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L66) +Defined in: [createTableHook.tsx:67](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L67) #### Type Declaration @@ -72,4 +72,4 @@ FlexRender: () => JSXElement; table: Table; ``` -Defined in: [createTableHook.tsx:68](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L68) +Defined in: [createTableHook.tsx:69](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L69) diff --git a/docs/framework/solid/reference/type-aliases/AppSolidTable.md b/docs/framework/solid/reference/type-aliases/AppSolidTable.md index d4248866c1..f68bf59d1e 100644 --- a/docs/framework/solid/reference/type-aliases/AppSolidTable.md +++ b/docs/framework/solid/reference/type-aliases/AppSolidTable.md @@ -9,7 +9,7 @@ title: AppSolidTable type AppSolidTable = SolidTable & NoInfer & object; ``` -Defined in: [createTableHook.tsx:345](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L345) +Defined in: [createTableHook.tsx:346](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L346) Extended table API returned by createAppTable with all App wrapper components diff --git a/docs/framework/solid/reference/type-aliases/ComponentType.md b/docs/framework/solid/reference/type-aliases/ComponentType.md index 21580b21f4..f1dc24b325 100644 --- a/docs/framework/solid/reference/type-aliases/ComponentType.md +++ b/docs/framework/solid/reference/type-aliases/ComponentType.md @@ -9,7 +9,7 @@ title: ComponentType type ComponentType = Component; ``` -Defined in: [createTableHook.tsx:30](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L30) +Defined in: [createTableHook.tsx:31](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L31) ## Type Parameters diff --git a/docs/framework/solid/reference/type-aliases/CreateTableHookOptions.md b/docs/framework/solid/reference/type-aliases/CreateTableHookOptions.md index f84ca25f1d..3e85c3355b 100644 --- a/docs/framework/solid/reference/type-aliases/CreateTableHookOptions.md +++ b/docs/framework/solid/reference/type-aliases/CreateTableHookOptions.md @@ -9,7 +9,7 @@ title: CreateTableHookOptions type CreateTableHookOptions = Omit, "columns" | "data" | "store" | "state" | "initialState"> & object; ``` -Defined in: [createTableHook.tsx:241](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L241) +Defined in: [createTableHook.tsx:242](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTableHook.tsx#L242) Options for creating a table hook with pre-bound components and default table options. Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. diff --git a/docs/framework/solid/reference/type-aliases/SolidTable.md b/docs/framework/solid/reference/type-aliases/SolidTable.md index 981d6d6fcb..ef7a08a3b4 100644 --- a/docs/framework/solid/reference/type-aliases/SolidTable.md +++ b/docs/framework/solid/reference/type-aliases/SolidTable.md @@ -9,7 +9,7 @@ title: SolidTable type SolidTable = Table & object; ``` -Defined in: [createTable.ts:19](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTable.ts#L19) +Defined in: [createTable.ts:14](https://github.com/TanStack/table/blob/main/packages/solid-table/src/createTable.ts#L14) ## Type Declaration diff --git a/docs/framework/svelte/reference/type-aliases/AppGroupColumnDef.md b/docs/framework/svelte/reference/type-aliases/AppGroupColumnDef.md index b02d54e94c..ad1becaec4 100644 --- a/docs/framework/svelte/reference/type-aliases/AppGroupColumnDef.md +++ b/docs/framework/svelte/reference/type-aliases/AppGroupColumnDef.md @@ -24,7 +24,7 @@ optional cell: AppColumnDefTemplate[]; +optional columns: ReadonlyArray>; ``` ### footer? diff --git a/docs/framework/vue/reference/functions/createTableHook.md b/docs/framework/vue/reference/functions/createTableHook.md index f833200ea9..4b02591f82 100644 --- a/docs/framework/vue/reference/functions/createTableHook.md +++ b/docs/framework/vue/reference/functions/createTableHook.md @@ -9,7 +9,7 @@ title: createTableHook function createTableHook(__namedParameters): CreateTableHookResult; ``` -Defined in: [packages/vue-table/src/createTableHook.ts:357](https://github.com/TanStack/table/blob/main/packages/vue-table/src/createTableHook.ts#L357) +Defined in: [packages/vue-table/src/createTableHook.ts:354](https://github.com/TanStack/table/blob/main/packages/vue-table/src/createTableHook.ts#L354) Creates app-scoped Vue table helpers with features, row models, and renderable component maps pre-bound. diff --git a/docs/framework/vue/reference/functions/useTable.md b/docs/framework/vue/reference/functions/useTable.md index 57c660bd7b..54b0713c34 100644 --- a/docs/framework/vue/reference/functions/useTable.md +++ b/docs/framework/vue/reference/functions/useTable.md @@ -9,7 +9,7 @@ title: useTable function useTable(tableOptions): VueTable; ``` -Defined in: [packages/vue-table/src/useTable.ts:77](https://github.com/TanStack/table/blob/main/packages/vue-table/src/useTable.ts#L77) +Defined in: [packages/vue-table/src/useTable.ts:85](https://github.com/TanStack/table/blob/main/packages/vue-table/src/useTable.ts#L85) Creates a Vue table instance backed by Vue-aware TanStack Store atoms. diff --git a/docs/framework/vue/reference/type-aliases/AppGroupColumnDef.md b/docs/framework/vue/reference/type-aliases/AppGroupColumnDef.md index a96c539039..39edad0917 100644 --- a/docs/framework/vue/reference/type-aliases/AppGroupColumnDef.md +++ b/docs/framework/vue/reference/type-aliases/AppGroupColumnDef.md @@ -22,7 +22,7 @@ optional cell: AppColumnDefTemplate[]; +optional columns: ReadonlyArray>; ``` ### footer? diff --git a/docs/framework/vue/reference/type-aliases/VueTable.md b/docs/framework/vue/reference/type-aliases/VueTable.md index afebd3fe2b..ee4645d93a 100644 --- a/docs/framework/vue/reference/type-aliases/VueTable.md +++ b/docs/framework/vue/reference/type-aliases/VueTable.md @@ -9,7 +9,7 @@ title: VueTable type VueTable = Table & object; ``` -Defined in: [packages/vue-table/src/useTable.ts:46](https://github.com/TanStack/table/blob/main/packages/vue-table/src/useTable.ts#L46) +Defined in: [packages/vue-table/src/useTable.ts:54](https://github.com/TanStack/table/blob/main/packages/vue-table/src/useTable.ts#L54) ## Type Declaration diff --git a/docs/framework/vue/reference/variables/FlexRender.md b/docs/framework/vue/reference/variables/FlexRender.md index dd6ce6f32e..ee2ebc729f 100644 --- a/docs/framework/vue/reference/variables/FlexRender.md +++ b/docs/framework/vue/reference/variables/FlexRender.md @@ -36,7 +36,7 @@ const FlexRender: DefineComponent<{ }, any>; ``` -Defined in: [packages/vue-table/src/FlexRender.ts:67](https://github.com/TanStack/table/blob/main/packages/vue-table/src/FlexRender.ts#L67) +Defined in: [packages/vue-table/src/FlexRender.ts:75](https://github.com/TanStack/table/blob/main/packages/vue-table/src/FlexRender.ts#L75) Simplified component for rendering headers, cells, or footers. diff --git a/docs/reference/index/functions/assignPrototypeAPIs.md b/docs/reference/index/functions/assignPrototypeAPIs.md index 254cb4bf22..f57eba76bc 100644 --- a/docs/reference/index/functions/assignPrototypeAPIs.md +++ b/docs/reference/index/functions/assignPrototypeAPIs.md @@ -6,14 +6,14 @@ title: assignPrototypeAPIs # Function: assignPrototypeAPIs() ```ts -function assignPrototypeAPIs( +function assignPrototypeAPIs( feature, prototype, table, apis): void; ``` -Defined in: [utils.ts:434](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L434) +Defined in: [utils.ts:404](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L404) Assigns API methods to a prototype object for memory-efficient method sharing. All instances created with this prototype will share the same method references. @@ -31,14 +31,6 @@ This provides the best of both worlds: shared method code + per-instance caching `TData` *extends* [`RowData`](../type-aliases/RowData.md) -### TDeps - -`TDeps` *extends* readonly `any`[] - -### TDepArgs - -`TDepArgs` - ## Parameters ### feature @@ -55,7 +47,7 @@ keyof `TFeatures` & `string` ### apis -[`PrototypeAPIObject`](../type-aliases/PrototypeAPIObject.md)\<`TDeps`, [`NoInfer`](../type-aliases/NoInfer.md)\<`TDepArgs`\>\> +[`PrototypeAPIObject`](../type-aliases/PrototypeAPIObject.md) ## Returns diff --git a/docs/reference/index/functions/assignTableAPIs.md b/docs/reference/index/functions/assignTableAPIs.md index 9ac2642cd1..6673bff754 100644 --- a/docs/reference/index/functions/assignTableAPIs.md +++ b/docs/reference/index/functions/assignTableAPIs.md @@ -6,13 +6,13 @@ title: assignTableAPIs # Function: assignTableAPIs() ```ts -function assignTableAPIs( +function assignTableAPIs( feature, table, apis): void; ``` -Defined in: [utils.ts:392](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L392) +Defined in: [utils.ts:359](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L359) Assigns Table API methods directly to the table instance. Unlike row/cell/column/header, the table is a singleton so methods are assigned directly. @@ -27,14 +27,6 @@ Unlike row/cell/column/header, the table is a singleton so methods are assigned `TData` *extends* [`RowData`](../type-aliases/RowData.md) -### TDeps - -`TDeps` *extends* readonly `any`[] - -### TDepArgs - -`TDepArgs` - ## Parameters ### feature @@ -47,7 +39,7 @@ keyof `TFeatures` & `string` ### apis -[`APIObject`](../type-aliases/APIObject.md)\<`TDeps`, [`NoInfer`](../type-aliases/NoInfer.md)\<`TDepArgs`\>\> +[`APIObject`](../type-aliases/APIObject.md) ## Returns diff --git a/docs/reference/index/functions/buildHeaderGroups.md b/docs/reference/index/functions/buildHeaderGroups.md index b2806b1812..1390fe78cf 100644 --- a/docs/reference/index/functions/buildHeaderGroups.md +++ b/docs/reference/index/functions/buildHeaderGroups.md @@ -13,7 +13,7 @@ function buildHeaderGroups( headerFamily?): HeaderGroup[]; ``` -Defined in: [core/headers/buildHeaderGroups.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/buildHeaderGroups.ts#L16) +Defined in: [core/headers/buildHeaderGroups.ts:211](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/buildHeaderGroups.ts#L211) Builds the nested header group structure for a table. diff --git a/docs/reference/index/functions/callMemoOrStaticFn.md b/docs/reference/index/functions/callMemoOrStaticFn.md index d887ea78a8..9f1a15c5d6 100644 --- a/docs/reference/index/functions/callMemoOrStaticFn.md +++ b/docs/reference/index/functions/callMemoOrStaticFn.md @@ -13,7 +13,7 @@ function callMemoOrStaticFn( args): TReturn; ``` -Defined in: [utils.ts:480](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L480) +Defined in: [utils.ts:448](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L448) Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in. diff --git a/docs/reference/index/functions/cloneState.md b/docs/reference/index/functions/cloneState.md index d7d74767e1..59a123030b 100644 --- a/docs/reference/index/functions/cloneState.md +++ b/docs/reference/index/functions/cloneState.md @@ -9,7 +9,7 @@ title: cloneState function cloneState(value): T; ``` -Defined in: [utils.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L22) +Defined in: [utils.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L23) Clones table state values while preserving non-plain objects. diff --git a/docs/reference/index/functions/constructTable.md b/docs/reference/index/functions/constructTable.md index 553dc74793..23f0c65301 100644 --- a/docs/reference/index/functions/constructTable.md +++ b/docs/reference/index/functions/constructTable.md @@ -9,7 +9,7 @@ title: constructTable function constructTable(tableOptions): Table; ``` -Defined in: [core/table/constructTable.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L32) +Defined in: [core/table/constructTable.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L37) Constructs a table instance from normalized table internals. diff --git a/docs/reference/index/functions/copyInstancePropertiesWithoutMemos.md b/docs/reference/index/functions/copyInstancePropertiesWithoutMemos.md index 9cc3a2d8b1..4ecb32740f 100644 --- a/docs/reference/index/functions/copyInstancePropertiesWithoutMemos.md +++ b/docs/reference/index/functions/copyInstancePropertiesWithoutMemos.md @@ -9,7 +9,7 @@ title: copyInstancePropertiesWithoutMemos function copyInstancePropertiesWithoutMemos(target, source): TTarget & TSource; ``` -Defined in: [utils.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L58) +Defined in: [utils.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L59) Copies prototype-instance own properties without carrying over lazy memo closures or the per-row cell cache, both of which are bound to the source diff --git a/docs/reference/index/functions/createCoreRowModel.md b/docs/reference/index/functions/createCoreRowModel.md index 669a215a0d..183dbb261d 100644 --- a/docs/reference/index/functions/createCoreRowModel.md +++ b/docs/reference/index/functions/createCoreRowModel.md @@ -9,7 +9,7 @@ title: createCoreRowModel function createCoreRowModel(): (table) => () => RowModel; ``` -Defined in: [core/row-models/createCoreRowModel.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/createCoreRowModel.ts#L16) +Defined in: [core/row-models/createCoreRowModel.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/createCoreRowModel.ts#L17) Creates a memoized core row model factory. diff --git a/docs/reference/index/functions/createGroupedRowModel.md b/docs/reference/index/functions/createGroupedRowModel.md index eaad73d106..150df9c925 100644 --- a/docs/reference/index/functions/createGroupedRowModel.md +++ b/docs/reference/index/functions/createGroupedRowModel.md @@ -9,7 +9,7 @@ title: createGroupedRowModel function createGroupedRowModel(): (table) => () => RowModel; ``` -Defined in: [features/column-grouping/createGroupedRowModel.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts#L26) +Defined in: [features/column-grouping/createGroupedRowModel.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts#L27) Creates a memoized grouped row model factory. diff --git a/docs/reference/index/functions/createSortedRowModel.md b/docs/reference/index/functions/createSortedRowModel.md index e38afade95..78915054b8 100644 --- a/docs/reference/index/functions/createSortedRowModel.md +++ b/docs/reference/index/functions/createSortedRowModel.md @@ -9,7 +9,7 @@ title: createSortedRowModel function createSortedRowModel(): (table) => () => RowModel; ``` -Defined in: [features/row-sorting/createSortedRowModel.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/createSortedRowModel.ts#L24) +Defined in: [features/row-sorting/createSortedRowModel.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/createSortedRowModel.ts#L25) Creates a memoized sorted row model factory. diff --git a/docs/reference/index/functions/expandRows.md b/docs/reference/index/functions/expandRows.md index 1396582c84..7cb61fcce6 100644 --- a/docs/reference/index/functions/expandRows.md +++ b/docs/reference/index/functions/expandRows.md @@ -9,7 +9,7 @@ title: expandRows function expandRows(rowModel): RowModel; ``` -Defined in: [features/row-expanding/createExpandedRowModel.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts#L62) +Defined in: [features/row-expanding/createExpandedRowModel.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts#L56) Expands a row model according to the current expanded row state. diff --git a/docs/reference/index/functions/flattenBy.md b/docs/reference/index/functions/flattenBy.md index e7821f0f7b..0e1418b73b 100644 --- a/docs/reference/index/functions/flattenBy.md +++ b/docs/reference/index/functions/flattenBy.md @@ -9,7 +9,7 @@ title: flattenBy function flattenBy(arr, getChildren): TNode[]; ``` -Defined in: [utils.ts:131](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L131) +Defined in: [utils.ts:132](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L132) Flattens a tree of nodes by recursively reading child nodes. diff --git a/docs/reference/index/functions/functionalUpdate.md b/docs/reference/index/functions/functionalUpdate.md index 1904efc4ca..f52060651f 100644 --- a/docs/reference/index/functions/functionalUpdate.md +++ b/docs/reference/index/functions/functionalUpdate.md @@ -9,7 +9,7 @@ title: functionalUpdate function functionalUpdate(updater, input): T; ``` -Defined in: [utils.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L11) +Defined in: [utils.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L12) Applies a TanStack updater to a value. diff --git a/docs/reference/index/functions/getFunctionNameInfo.md b/docs/reference/index/functions/getFunctionNameInfo.md index 31cca62ba5..fb7dfca046 100644 --- a/docs/reference/index/functions/getFunctionNameInfo.md +++ b/docs/reference/index/functions/getFunctionNameInfo.md @@ -9,7 +9,7 @@ title: getFunctionNameInfo function getFunctionNameInfo(staticFnName, splitBy): object; ``` -Defined in: [utils.ts:375](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L375) +Defined in: [utils.ts:342](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L342) Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`. @@ -21,7 +21,7 @@ Assumes that a function name is in the format of `parentName_fnKey` and returns ### splitBy -`"_"` | `"."` +`"."` | `"_"` ## Returns diff --git a/docs/reference/index/functions/getInitialTableState.md b/docs/reference/index/functions/getInitialTableState.md index 8a55f27c28..43ce34ed6f 100644 --- a/docs/reference/index/functions/getInitialTableState.md +++ b/docs/reference/index/functions/getInitialTableState.md @@ -9,7 +9,7 @@ title: getInitialTableState function getInitialTableState(features, initialState): TableState; ``` -Defined in: [core/table/constructTable.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L17) +Defined in: [core/table/constructTable.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L22) Builds the initial table state from registered features and user initial state. diff --git a/docs/reference/index/functions/hasOwn.md b/docs/reference/index/functions/hasOwn.md index ea58242834..3b1043c852 100644 --- a/docs/reference/index/functions/hasOwn.md +++ b/docs/reference/index/functions/hasOwn.md @@ -9,7 +9,7 @@ title: hasOwn function hasOwn(obj, key): boolean; ``` -Defined in: [utils.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L88) +Defined in: [utils.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L89) Checks whether an object owns a key, including null-prototype dictionaries. diff --git a/docs/reference/index/functions/isFunction.md b/docs/reference/index/functions/isFunction.md index 730cfd7000..4df1d2f57f 100644 --- a/docs/reference/index/functions/isFunction.md +++ b/docs/reference/index/functions/isFunction.md @@ -9,7 +9,7 @@ title: isFunction function isFunction(d): d is T; ``` -Defined in: [utils.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L122) +Defined in: [utils.ts:123](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L123) Returns whether a value is a function. diff --git a/docs/reference/index/functions/makeObjectMap.md b/docs/reference/index/functions/makeObjectMap.md index 8c7dac1846..9704cf36ca 100644 --- a/docs/reference/index/functions/makeObjectMap.md +++ b/docs/reference/index/functions/makeObjectMap.md @@ -9,7 +9,7 @@ title: makeObjectMap function makeObjectMap(): Record; ``` -Defined in: [utils.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L81) +Defined in: [utils.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L82) Creates an object intended only for string-keyed dictionary lookups. diff --git a/docs/reference/index/functions/makeStateUpdater.md b/docs/reference/index/functions/makeStateUpdater.md index b53ce80ad5..bf37c197b1 100644 --- a/docs/reference/index/functions/makeStateUpdater.md +++ b/docs/reference/index/functions/makeStateUpdater.md @@ -9,7 +9,7 @@ title: makeStateUpdater function makeStateUpdater(key, instance): (updater) => void; ``` -Defined in: [utils.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L97) +Defined in: [utils.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L98) Creates a table state updater for a single state slice. diff --git a/docs/reference/index/functions/memo.md b/docs/reference/index/functions/memo.md deleted file mode 100644 index 1737b56562..0000000000 --- a/docs/reference/index/functions/memo.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -id: memo -title: memo ---- - -# Function: memo() - -```ts -function memo(__namedParameters): (depArgs?) => TResult; -``` - -Defined in: [utils.ts:166](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L166) - -Creates a dependency-tracked memoized function for table internals. - -The memo recomputes only when its dependency tuple changes and can emit debug timing information. - -## Type Parameters - -### TDeps - -`TDeps` *extends* readonly `any`[] - -### TDepArgs - -`TDepArgs` - -### TResult - -`TResult` - -## Parameters - -### \_\_namedParameters - -`MemoOptions`\<`TDeps`, `TDepArgs`, `TResult`\> - -## Returns - -```ts -(depArgs?): TResult; -``` - -### Parameters - -#### depArgs? - -`TDepArgs` - -### Returns - -`TResult` diff --git a/docs/reference/index/functions/tableMemo.md b/docs/reference/index/functions/tableMemo.md index 6f742e807b..2360f09e99 100644 --- a/docs/reference/index/functions/tableMemo.md +++ b/docs/reference/index/functions/tableMemo.md @@ -6,14 +6,15 @@ title: tableMemo # Function: tableMemo() ```ts -function tableMemo(__namedParameters): (depArgs?) => TResult; +function tableMemo(__namedParameters): () => TResult; ``` -Defined in: [utils.ts:235](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L235) +Defined in: [utils.ts:180](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L180) Creates a table-aware memoized function. -This wraps `memo` with table debug options and feature metadata so row models and derived APIs can share consistent diagnostics. +The native readonly atom is created on the first public read so eager +framework computeds cannot evaluate during incomplete table construction. ## Type Parameters @@ -21,14 +22,6 @@ This wraps `memo` with table debug options and feature metadata so row models an `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) -### TDeps - -`TDeps` *extends* readonly `any`[] - -### TDepArgs - -`TDepArgs` - ### TResult `TResult` @@ -37,20 +30,14 @@ This wraps `memo` with table debug options and feature metadata so row models an ### \_\_namedParameters -`TableMemoOptions`\<`TFeatures`, `TDeps`, `TDepArgs`, `TResult`\> +`TableMemoOptions`\<`TFeatures`, `TResult`\> ## Returns ```ts -(depArgs?): TResult; +(): TResult; ``` -### Parameters - -#### depArgs? - -`TDepArgs` - ### Returns `TResult` diff --git a/docs/reference/index/index.md b/docs/reference/index/index.md index bab42cfd74..b2c52bbe58 100644 --- a/docs/reference/index/index.md +++ b/docs/reference/index/index.md @@ -15,7 +15,6 @@ title: index - [AggregationValueContext](interfaces/AggregationValueContext.md) - [AggregationValueOptions](interfaces/AggregationValueOptions.md) - [AggregationValueResult](interfaces/AggregationValueResult.md) -- [API](interfaces/API.md) - [CachedRowModel\_All](interfaces/CachedRowModel_All.md) - [CachedRowModel\_Core](interfaces/CachedRowModel_Core.md) - [CachedRowModel\_Expanded](interfaces/CachedRowModel_Expanded.md) @@ -97,7 +96,6 @@ title: index - [PaginationDefaultOptions](interfaces/PaginationDefaultOptions.md) - [PaginationState](interfaces/PaginationState.md) - [Plugins](interfaces/Plugins.md) -- [PrototypeAPI](interfaces/PrototypeAPI.md) - [ResolvedAggregationFn](interfaces/ResolvedAggregationFn.md) - [ResolvedColumnFilter](interfaces/ResolvedColumnFilter.md) - [Row\_ColumnFiltering](interfaces/Row_ColumnFiltering.md) @@ -212,6 +210,7 @@ title: index - [AggregationFnRef](type-aliases/AggregationFnRef.md) - [AggregationResult](type-aliases/AggregationResult.md) - [AggregationResultOf](type-aliases/AggregationResultOf.md) +- [API](type-aliases/API.md) - [APIObject](type-aliases/APIObject.md) - [Atoms](type-aliases/Atoms.md) - [Atoms\_All](type-aliases/Atoms_All.md) @@ -273,6 +272,7 @@ title: index - [OnChangeFn](type-aliases/OnChangeFn.md) - [PartialKeys](type-aliases/PartialKeys.md) - [Prettify](type-aliases/Prettify.md) +- [PrototypeAPI](type-aliases/PrototypeAPI.md) - [PrototypeAPIObject](type-aliases/PrototypeAPIObject.md) - [RequiredKeys](type-aliases/RequiredKeys.md) - [Row](type-aliases/Row.md) @@ -286,8 +286,10 @@ title: index - [StringOrTemplateHeader](type-aliases/StringOrTemplateHeader.md) - [Table](type-aliases/Table.md) - [Table\_RowModels](type-aliases/Table_RowModels.md) +- [TableOptionAtoms](type-aliases/TableOptionAtoms.md) - [TableOptions](type-aliases/TableOptions.md) - [TableOptions\_All](type-aliases/TableOptions_All.md) +- [TableOptionsLive](type-aliases/TableOptionsLive.md) - [TableState](type-aliases/TableState.md) - [TransformDataValueFn](type-aliases/TransformDataValueFn.md) - [TransformFilterValueFn](type-aliases/TransformFilterValueFn.md) @@ -401,7 +403,6 @@ title: index - [isFunction](functions/isFunction.md) - [makeObjectMap](functions/makeObjectMap.md) - [makeStateUpdater](functions/makeStateUpdater.md) -- [memo](functions/memo.md) - [metaHelper](functions/metaHelper.md) - [tableFeatures](functions/tableFeatures.md) - [tableMemo](functions/tableMemo.md) diff --git a/docs/reference/index/interfaces/API.md b/docs/reference/index/interfaces/API.md deleted file mode 100644 index 1b2b683843..0000000000 --- a/docs/reference/index/interfaces/API.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -id: API -title: API ---- - -# Interface: API\<_TDeps, _TDepArgs\> - -Defined in: [utils.ts:362](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L362) - -## Type Parameters - -### _TDeps - -`_TDeps` *extends* `ReadonlyArray`\<`any`\> - -### _TDepArgs - -`_TDepArgs` - -## Properties - -### fn() - -```ts -fn: (...args) => any; -``` - -Defined in: [utils.ts:363](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L363) - -#### Parameters - -##### args - -...`any` - -#### Returns - -`any` - -*** - -### memoDeps()? - -```ts -optional memoDeps: (depArgs?) => any[] | undefined; -``` - -Defined in: [utils.ts:364](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L364) - -#### Parameters - -##### depArgs? - -`any` - -#### Returns - -`any`[] \| `undefined` diff --git a/docs/reference/index/interfaces/Plugins.md b/docs/reference/index/interfaces/Plugins.md index e5f42aeba0..e9a87e052c 100644 --- a/docs/reference/index/interfaces/Plugins.md +++ b/docs/reference/index/interfaces/Plugins.md @@ -21,4 +21,4 @@ features. workerRowModelsFeature: TableFeature; ``` -Defined in: [worker/createTableWorker.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/worker/createTableWorker.ts#L23) +Defined in: [worker/createTableWorker.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/worker/createTableWorker.ts#L24) diff --git a/docs/reference/index/interfaces/PrototypeAPI.md b/docs/reference/index/interfaces/PrototypeAPI.md deleted file mode 100644 index 1c6f7de5c7..0000000000 --- a/docs/reference/index/interfaces/PrototypeAPI.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: PrototypeAPI -title: PrototypeAPI ---- - -# Interface: PrototypeAPI\<_TDeps, _TDepArgs\> - -Defined in: [utils.ts:417](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L417) - -## Type Parameters - -### _TDeps - -`_TDeps` *extends* `ReadonlyArray`\<`any`\> - -### _TDepArgs - -`_TDepArgs` - -## Properties - -### fn() - -```ts -fn: (self, ...args) => any; -``` - -Defined in: [utils.ts:418](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L418) - -#### Parameters - -##### self - -`any` - -##### args - -...`any` - -#### Returns - -`any` - -*** - -### memoDeps()? - -```ts -optional memoDeps: (self, depArgs?) => any[] | undefined; -``` - -Defined in: [utils.ts:419](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L419) - -#### Parameters - -##### self - -`any` - -##### depArgs? - -`any` - -#### Returns - -`any`[] \| `undefined` diff --git a/docs/reference/index/interfaces/TableFeature.md b/docs/reference/index/interfaces/TableFeature.md index b848353d04..7e98039e17 100644 --- a/docs/reference/index/interfaces/TableFeature.md +++ b/docs/reference/index/interfaces/TableFeature.md @@ -322,7 +322,7 @@ override feature defaults. optional initCellInstanceData: (cell) => void; ``` -Defined in: [types/TableFeatures.ts:449](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L449) +Defined in: [types/TableFeatures.ts:452](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L452) Initializes instance-specific data on each cell. @@ -364,7 +364,7 @@ Shared methods should be assigned via `assignCellPrototype` instead. optional initColumnInstanceData: (column) => void; ``` -Defined in: [types/TableFeatures.ts:464](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L464) +Defined in: [types/TableFeatures.ts:467](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L467) Initializes instance-specific data on each column. @@ -405,7 +405,7 @@ methods should be assigned via `assignColumnPrototype` instead. optional initHeaderGroupInstanceData: (headerGroup) => void; ``` -Defined in: [types/TableFeatures.ts:480](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L480) +Defined in: [types/TableFeatures.ts:483](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L483) Initializes instance-specific data on each header group. @@ -443,7 +443,7 @@ visibility, order, or pinning changes), so this reruns on every rebuild. optional initHeaderInstanceData: (header) => void; ``` -Defined in: [types/TableFeatures.ts:497](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L497) +Defined in: [types/TableFeatures.ts:500](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L500) Initializes instance-specific data on each header. @@ -487,7 +487,7 @@ instead. optional initRowInstanceData: (row) => void; ``` -Defined in: [types/TableFeatures.ts:512](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L512) +Defined in: [types/TableFeatures.ts:515](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L515) Initializes instance-specific data on each row. @@ -524,16 +524,19 @@ should be assigned via `assignRowPrototype` instead. optional initTableInstanceData: (table) => void; ``` -Defined in: [types/TableFeatures.ts:434](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L434) +Defined in: [types/TableFeatures.ts:437](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L437) Initializes mutable, non-reactive data owned by this feature on the table instance. This runs once during table construction after options, state atoms, and -the store are available, and before any feature's `constructTableAPIs` -hook runs. Use `constructTableAPIs` exclusively for assigning table -methods. Table resets do not rerun this hook; use -`resetTableInstanceData` to clear transient instance data instead. +the store are available. Features are processed in a single pass in +registration order, with each feature's instance data initialized just +before its own `constructTableAPIs` hook, so this hook may rely on data +and APIs of features registered earlier. Use `constructTableAPIs` +exclusively for assigning table methods. Table resets do not rerun this +hook; use `resetTableInstanceData` to clear transient instance data +instead. #### Type Parameters @@ -563,7 +566,7 @@ methods. Table resets do not rerun this hook; use optional resetTableInstanceData: (table) => void; ``` -Defined in: [types/TableFeatures.ts:525](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L525) +Defined in: [types/TableFeatures.ts:528](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L528) Resets mutable, non-reactive table-instance data owned by this feature. diff --git a/docs/reference/index/interfaces/TableFeatures.md b/docs/reference/index/interfaces/TableFeatures.md index 2c88440ad8..beb66e27de 100644 --- a/docs/reference/index/interfaces/TableFeatures.md +++ b/docs/reference/index/interfaces/TableFeatures.md @@ -745,7 +745,7 @@ When omitted, the global declaration-merged `TableMeta` interface applies. optional workerRowModelsFeature: TableFeature; ``` -Defined in: [worker/createTableWorker.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/worker/createTableWorker.ts#L23) +Defined in: [worker/createTableWorker.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/worker/createTableWorker.ts#L24) #### Inherited from diff --git a/docs/reference/index/interfaces/TableOptions_Core.md b/docs/reference/index/interfaces/TableOptions_Core.md index 47868b0456..98ae45748c 100644 --- a/docs/reference/index/interfaces/TableOptions_Core.md +++ b/docs/reference/index/interfaces/TableOptions_Core.md @@ -32,7 +32,7 @@ options are mixed in. readonly optional atoms: Partial<{ [K in string | number | symbol]: Atom[K]> }>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L109) +Defined in: [core/table/coreTablesFeature.types.ts:148](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L148) 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]` @@ -52,7 +52,7 @@ model for app-managed table state slices. readonly optional autoResetAll: boolean; ``` -Defined in: [core/table/coreTablesFeature.types.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L113) +Defined in: [core/table/coreTablesFeature.types.ts:152](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L152) Set this option to override any of the `autoReset...` feature options. @@ -84,7 +84,7 @@ The array of column defs to use for the table. readonly data: readonly TData[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L117) +Defined in: [core/table/coreTablesFeature.types.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L156) The data for the table to display. When the `data` option changes reference, the table will reprocess the data. @@ -116,7 +116,7 @@ Default column options to use for all column defs supplied to the table. readonly features: TFeatures & ValidateFeatureSlots; ``` -Defined in: [core/table/coreTablesFeature.types.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L101) +Defined in: [core/table/coreTablesFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L140) The feature modules registered on this table instance. @@ -214,7 +214,7 @@ getSubRows: row => row.subRows readonly optional initialState: Partial>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:131](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L131) +Defined in: [core/table/coreTablesFeature.types.ts:170](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L170) Optionally provide starting values for registered table state slices. Feature reset APIs use this value by default, and many reset APIs accept @@ -233,7 +233,7 @@ object later does not reset table state, so it does not need to be stable. readonly optional key: string; ``` -Defined in: [core/table/coreTablesFeature.types.ts:124](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L124) +Defined in: [core/table/coreTablesFeature.types.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L163) Optional key used to identify this table instance. @@ -252,7 +252,7 @@ not required unless the table is passed to devtools. readonly optional mergeOptions: (defaultOptions, options) => TableOptions; ``` -Defined in: [core/table/coreTablesFeature.types.ts:135](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L135) +Defined in: [core/table/coreTablesFeature.types.ts:174](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L174) This option is used to optionally implement the merging of table options. @@ -282,7 +282,7 @@ This option is used to optionally implement the merging of table options. readonly optional meta: ExtractTableMeta; ``` -Defined in: [core/table/coreTablesFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L145) +Defined in: [core/table/coreTablesFeature.types.ts:184](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L184) You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`. @@ -317,7 +317,7 @@ Value used when the desired value is not found in the data. readonly optional state: Partial>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:153](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L153) +Defined in: [core/table/coreTablesFeature.types.ts:192](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L192) Optionally provide externally managed values for individual state slices. diff --git a/docs/reference/index/interfaces/TableOptions_Table.md b/docs/reference/index/interfaces/TableOptions_Table.md index 8bb8f5c2c2..8d472583c1 100644 --- a/docs/reference/index/interfaces/TableOptions_Table.md +++ b/docs/reference/index/interfaces/TableOptions_Table.md @@ -5,7 +5,7 @@ title: TableOptions_Table # Interface: TableOptions\_Table\ -Defined in: [core/table/coreTablesFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L88) +Defined in: [core/table/coreTablesFeature.types.ts:127](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L127) ## Extended by @@ -29,7 +29,7 @@ Defined in: [core/table/coreTablesFeature.types.ts:88](https://github.com/TanSta readonly optional atoms: Partial<{ [K in string | number | symbol]: Atom[K]> }>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L109) +Defined in: [core/table/coreTablesFeature.types.ts:148](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L148) 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]` @@ -45,7 +45,7 @@ model for app-managed table state slices. readonly optional autoResetAll: boolean; ``` -Defined in: [core/table/coreTablesFeature.types.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L113) +Defined in: [core/table/coreTablesFeature.types.ts:152](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L152) Set this option to override any of the `autoReset...` feature options. @@ -57,7 +57,7 @@ Set this option to override any of the `autoReset...` feature options. readonly data: readonly TData[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L117) +Defined in: [core/table/coreTablesFeature.types.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L156) The data for the table to display. When the `data` option changes reference, the table will reprocess the data. @@ -69,7 +69,7 @@ The data for the table to display. When the `data` option changes reference, the readonly features: TFeatures & ValidateFeatureSlots; ``` -Defined in: [core/table/coreTablesFeature.types.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L101) +Defined in: [core/table/coreTablesFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L140) The feature modules registered on this table instance. @@ -87,7 +87,7 @@ slots (`tableMeta`, `columnMeta`). readonly optional initialState: Partial>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:131](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L131) +Defined in: [core/table/coreTablesFeature.types.ts:170](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L170) Optionally provide starting values for registered table state slices. Feature reset APIs use this value by default, and many reset APIs accept @@ -102,7 +102,7 @@ object later does not reset table state, so it does not need to be stable. readonly optional key: string; ``` -Defined in: [core/table/coreTablesFeature.types.ts:124](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L124) +Defined in: [core/table/coreTablesFeature.types.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L163) Optional key used to identify this table instance. @@ -117,7 +117,7 @@ not required unless the table is passed to devtools. readonly optional mergeOptions: (defaultOptions, options) => TableOptions; ``` -Defined in: [core/table/coreTablesFeature.types.ts:135](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L135) +Defined in: [core/table/coreTablesFeature.types.ts:174](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L174) This option is used to optionally implement the merging of table options. @@ -143,7 +143,7 @@ This option is used to optionally implement the merging of table options. readonly optional meta: ExtractTableMeta; ``` -Defined in: [core/table/coreTablesFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L145) +Defined in: [core/table/coreTablesFeature.types.ts:184](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L184) You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`. @@ -158,7 +158,7 @@ Declare its type per-table via the `tableMeta` type-only slot on the readonly optional state: Partial>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:153](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L153) +Defined in: [core/table/coreTablesFeature.types.ts:192](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L192) Optionally provide externally managed values for individual state slices. diff --git a/docs/reference/index/interfaces/TableState_FeatureMap.md b/docs/reference/index/interfaces/TableState_FeatureMap.md index 023c56b255..cb24a3d9e3 100644 --- a/docs/reference/index/interfaces/TableState_FeatureMap.md +++ b/docs/reference/index/interfaces/TableState_FeatureMap.md @@ -155,4 +155,4 @@ Defined in: [types/TableState.ts:31](https://github.com/TanStack/table/blob/main workerRowModelsFeature: TableState_WorkerRowModels; ``` -Defined in: [worker/createTableWorker.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/worker/createTableWorker.ts#L28) +Defined in: [worker/createTableWorker.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/worker/createTableWorker.ts#L29) diff --git a/docs/reference/index/interfaces/Table_Core.md b/docs/reference/index/interfaces/Table_Core.md index 744ad71ce9..39ed7dabde 100644 --- a/docs/reference/index/interfaces/Table_Core.md +++ b/docs/reference/index/interfaces/Table_Core.md @@ -5,7 +5,7 @@ title: Table_Core # Interface: Table\_Core\ -Defined in: [types/Table.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L40) +Defined in: [types/Table.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L41) The core table object that only includes the core table functionality such as column, header, row, and table APIS. No features are included. @@ -26,13 +26,13 @@ No features are included. ## Properties -### \_cellInstanceInitFns? +### \_cellInstanceInitFns ```ts -optional _cellInstanceInitFns: (cell) => void[]; +_cellInstanceInitFns: (cell) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:167](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L167) +Defined in: [core/table/coreTablesFeature.types.ts:206](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L206) Cache of the `initCellInstanceData` functions for features that define one. @@ -72,7 +72,7 @@ Cache of the `initCellInstanceData` functions for features that define one. optional _cellPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L173) +Defined in: [core/table/coreTablesFeature.types.ts:210](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L210) Prototype cache for Cell objects - shared by all cells in this table @@ -82,13 +82,13 @@ Prototype cache for Cell objects - shared by all cells in this table *** -### \_columnInstanceInitFns? +### \_columnInstanceInitFns ```ts -optional _columnInstanceInitFns: (column) => void[]; +_columnInstanceInitFns: (column) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:177](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L177) +Defined in: [core/table/coreTablesFeature.types.ts:214](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L214) Cache of the `initColumnInstanceData` functions for features that define one. @@ -128,7 +128,7 @@ Cache of the `initColumnInstanceData` functions for features that define one. optional _columnPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:183](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L183) +Defined in: [core/table/coreTablesFeature.types.ts:220](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L220) Prototype cache for Column objects - shared by all columns in this table @@ -144,7 +144,7 @@ Prototype cache for Column objects - shared by all columns in this table readonly _features: Partial & TFeatures; ``` -Defined in: [core/table/coreTablesFeature.types.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L187) +Defined in: [core/table/coreTablesFeature.types.ts:224](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L224) The features that are enabled for the table. @@ -154,13 +154,13 @@ The features that are enabled for the table. *** -### \_headerGroupInstanceInitFns? +### \_headerGroupInstanceInitFns ```ts -optional _headerGroupInstanceInitFns: (headerGroup) => void[]; +_headerGroupInstanceInitFns: (headerGroup) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:191](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L191) +Defined in: [core/table/coreTablesFeature.types.ts:228](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L228) Cache of the `initHeaderGroupInstanceData` functions for features that define one. @@ -190,13 +190,13 @@ Cache of the `initHeaderGroupInstanceData` functions for features that define on *** -### \_headerInstanceInitFns? +### \_headerInstanceInitFns ```ts -optional _headerInstanceInitFns: (header) => void[]; +_headerInstanceInitFns: (header) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:197](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L197) +Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) Cache of the `initHeaderInstanceData` functions for features that define one. @@ -236,7 +236,7 @@ Cache of the `initHeaderInstanceData` functions for features that define one. optional _headerPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:203](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L203) +Defined in: [core/table/coreTablesFeature.types.ts:240](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L240) Prototype cache for Header objects - shared by all headers in this table @@ -252,7 +252,7 @@ Prototype cache for Header objects - shared by all headers in this table readonly _reactivity: TableReactivityBindings; ``` -Defined in: [core/table/coreTablesFeature.types.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L163) +Defined in: [core/table/coreTablesFeature.types.ts:202](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L202) Table reactivity bindings for interacting with TanStack Store. @@ -262,13 +262,13 @@ Table reactivity bindings for interacting with TanStack Store. *** -### \_rowInstanceInitFns? +### \_rowInstanceInitFns ```ts -optional _rowInstanceInitFns: (row) => void[]; +_rowInstanceInitFns: (row) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:219](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L219) +Defined in: [core/table/coreTablesFeature.types.ts:256](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L256) Cache of the `initRowInstanceData` functions for features that define one. @@ -304,7 +304,7 @@ Cache of the `initRowInstanceData` functions for features that define one. readonly _rowModelFns: RowModelFns; ``` -Defined in: [core/table/coreTablesFeature.types.ts:207](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L207) +Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) The row model processing functions that are used to process the data by features. @@ -320,7 +320,7 @@ The row model processing functions that are used to process the data by features readonly _rowModels: CachedRowModels; ``` -Defined in: [core/table/coreTablesFeature.types.ts:211](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L211) +Defined in: [core/table/coreTablesFeature.types.ts:248](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L248) The row models that are enabled for the table. @@ -336,7 +336,7 @@ The row models that are enabled for the table. optional _rowPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:215](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L215) +Defined in: [core/table/coreTablesFeature.types.ts:252](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L252) Prototype cache for Row objects - shared by all rows in this table @@ -352,7 +352,7 @@ Prototype cache for Row objects - shared by all rows in this table readonly atoms: Atoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:225](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L225) +Defined in: [core/table/coreTablesFeature.types.ts:262](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L262) The readonly derived atoms for each `TableState` slice. Each derives from its corresponding `baseAtom` plus, optionally, a per-slice external atom or @@ -370,7 +370,7 @@ external state value (precedence: external atom > external state > base atom). readonly baseAtoms: BaseAtoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:230](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L230) +Defined in: [core/table/coreTablesFeature.types.ts:267](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L267) The internal writable atoms for each `TableState` slice. This is the library's single write surface — all state mutations from features land here. @@ -1062,7 +1062,7 @@ Table_RowModels.getSortedRowModel readonly initialState: ExtractFeatureMapTypes; ``` -Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) +Defined in: [core/table/coreTablesFeature.types.ts:271](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L271) This is the resolved initial state of the table. @@ -1072,37 +1072,39 @@ This is the resolved initial state of the table. *** -### options +### optionAtoms ```ts -readonly options: TableOptions; +readonly optionAtoms: TableOptionAtoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:238](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L238) +Defined in: [core/table/coreTablesFeature.types.ts:283](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L283) + +Stable atoms for individual resolved option values. -A read-only reference to the table's current options. +Ordinary options are writable. Construction-static options are readonly. #### Inherited from -[`Table_Table`](Table_Table.md).[`options`](Table_Table.md#options) +[`Table_Table`](Table_Table.md).[`optionAtoms`](Table_Table.md#optionatoms) *** -### optionsStore? +### options ```ts -readonly optional optionsStore: Atom>; +readonly options: TableOptionsLive; ``` -Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) +Defined in: [core/table/coreTablesFeature.types.ts:277](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L277) -Writable atom for table options. Only created when `createOptionsStore` is -true on the active core reactivity bindings. Adapters that opt out keep -options as plain resolved data instead of backing them with an atom. +A stable live view of the table's current resolved options. + +Reading a property reads the matching entry in `optionAtoms`. #### Inherited from -[`Table_Table`](Table_Table.md).[`optionsStore`](Table_Table.md#optionsstore) +[`Table_Table`](Table_Table.md).[`options`](Table_Table.md#options) *** @@ -1112,7 +1114,7 @@ options as plain resolved data instead of backing them with an atom. reset: () => void; ``` -Defined in: [core/table/coreTablesFeature.types.ts:264](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L264) +Defined in: [core/table/coreTablesFeature.types.ts:303](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L303) Resets the table's internal base atoms to `table.initialState`. @@ -1137,7 +1139,7 @@ reset hooks for mutable, transient table-instance data. setOptions: (newOptions) => void; ``` -Defined in: [core/table/coreTablesFeature.types.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L269) +Defined in: [core/table/coreTablesFeature.types.ts:308](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L308) Updates the table options by applying a value or updater to the current resolved options and then merging them through `options.mergeOptions`. @@ -1164,7 +1166,7 @@ resolved options and then merging them through `options.mergeOptions`. readonly store: ReadonlyStore>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:249](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L249) +Defined in: [core/table/coreTablesFeature.types.ts:288](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L288) The readonly flat store for the table state. Derives from `table.atoms` only; never reads external state directly. diff --git a/docs/reference/index/interfaces/Table_CoreProperties.md b/docs/reference/index/interfaces/Table_CoreProperties.md index 322a1130b6..3d39f915fe 100644 --- a/docs/reference/index/interfaces/Table_CoreProperties.md +++ b/docs/reference/index/interfaces/Table_CoreProperties.md @@ -5,7 +5,7 @@ title: Table_CoreProperties # Interface: Table\_CoreProperties\ -Defined in: [core/table/coreTablesFeature.types.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L156) +Defined in: [core/table/coreTablesFeature.types.ts:195](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L195) ## Extended by @@ -23,13 +23,13 @@ Defined in: [core/table/coreTablesFeature.types.ts:156](https://github.com/TanSt ## Properties -### \_cellInstanceInitFns? +### \_cellInstanceInitFns ```ts -optional _cellInstanceInitFns: (cell) => void[]; +_cellInstanceInitFns: (cell) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:167](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L167) +Defined in: [core/table/coreTablesFeature.types.ts:206](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L206) Cache of the `initCellInstanceData` functions for features that define one. @@ -65,19 +65,19 @@ Cache of the `initCellInstanceData` functions for features that define one. optional _cellPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L173) +Defined in: [core/table/coreTablesFeature.types.ts:210](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L210) Prototype cache for Cell objects - shared by all cells in this table *** -### \_columnInstanceInitFns? +### \_columnInstanceInitFns ```ts -optional _columnInstanceInitFns: (column) => void[]; +_columnInstanceInitFns: (column) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:177](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L177) +Defined in: [core/table/coreTablesFeature.types.ts:214](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L214) Cache of the `initColumnInstanceData` functions for features that define one. @@ -113,7 +113,7 @@ Cache of the `initColumnInstanceData` functions for features that define one. optional _columnPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:183](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L183) +Defined in: [core/table/coreTablesFeature.types.ts:220](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L220) Prototype cache for Column objects - shared by all columns in this table @@ -125,19 +125,19 @@ Prototype cache for Column objects - shared by all columns in this table readonly _features: Partial & TFeatures; ``` -Defined in: [core/table/coreTablesFeature.types.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L187) +Defined in: [core/table/coreTablesFeature.types.ts:224](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L224) The features that are enabled for the table. *** -### \_headerGroupInstanceInitFns? +### \_headerGroupInstanceInitFns ```ts -optional _headerGroupInstanceInitFns: (headerGroup) => void[]; +_headerGroupInstanceInitFns: (headerGroup) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:191](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L191) +Defined in: [core/table/coreTablesFeature.types.ts:228](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L228) Cache of the `initHeaderGroupInstanceData` functions for features that define one. @@ -163,13 +163,13 @@ Cache of the `initHeaderGroupInstanceData` functions for features that define on *** -### \_headerInstanceInitFns? +### \_headerInstanceInitFns ```ts -optional _headerInstanceInitFns: (header) => void[]; +_headerInstanceInitFns: (header) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:197](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L197) +Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) Cache of the `initHeaderInstanceData` functions for features that define one. @@ -205,7 +205,7 @@ Cache of the `initHeaderInstanceData` functions for features that define one. optional _headerPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:203](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L203) +Defined in: [core/table/coreTablesFeature.types.ts:240](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L240) Prototype cache for Header objects - shared by all headers in this table @@ -217,19 +217,19 @@ Prototype cache for Header objects - shared by all headers in this table readonly _reactivity: TableReactivityBindings; ``` -Defined in: [core/table/coreTablesFeature.types.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L163) +Defined in: [core/table/coreTablesFeature.types.ts:202](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L202) Table reactivity bindings for interacting with TanStack Store. *** -### \_rowInstanceInitFns? +### \_rowInstanceInitFns ```ts -optional _rowInstanceInitFns: (row) => void[]; +_rowInstanceInitFns: (row) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:219](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L219) +Defined in: [core/table/coreTablesFeature.types.ts:256](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L256) Cache of the `initRowInstanceData` functions for features that define one. @@ -261,7 +261,7 @@ Cache of the `initRowInstanceData` functions for features that define one. readonly _rowModelFns: RowModelFns; ``` -Defined in: [core/table/coreTablesFeature.types.ts:207](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L207) +Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) The row model processing functions that are used to process the data by features. @@ -273,7 +273,7 @@ The row model processing functions that are used to process the data by features readonly _rowModels: CachedRowModels; ``` -Defined in: [core/table/coreTablesFeature.types.ts:211](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L211) +Defined in: [core/table/coreTablesFeature.types.ts:248](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L248) The row models that are enabled for the table. @@ -285,7 +285,7 @@ The row models that are enabled for the table. optional _rowPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:215](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L215) +Defined in: [core/table/coreTablesFeature.types.ts:252](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L252) Prototype cache for Row objects - shared by all rows in this table @@ -297,7 +297,7 @@ Prototype cache for Row objects - shared by all rows in this table readonly atoms: Atoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:225](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L225) +Defined in: [core/table/coreTablesFeature.types.ts:262](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L262) The readonly derived atoms for each `TableState` slice. Each derives from its corresponding `baseAtom` plus, optionally, a per-slice external atom or @@ -311,7 +311,7 @@ external state value (precedence: external atom > external state > base atom). readonly baseAtoms: BaseAtoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:230](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L230) +Defined in: [core/table/coreTablesFeature.types.ts:267](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L267) The internal writable atoms for each `TableState` slice. This is the library's single write surface — all state mutations from features land here. @@ -324,35 +324,37 @@ single write surface — all state mutations from features land here. readonly initialState: ExtractFeatureMapTypes; ``` -Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) +Defined in: [core/table/coreTablesFeature.types.ts:271](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L271) This is the resolved initial state of the table. *** -### options +### optionAtoms ```ts -readonly options: TableOptions; +readonly optionAtoms: TableOptionAtoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:238](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L238) +Defined in: [core/table/coreTablesFeature.types.ts:283](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L283) -A read-only reference to the table's current options. +Stable atoms for individual resolved option values. + +Ordinary options are writable. Construction-static options are readonly. *** -### optionsStore? +### options ```ts -readonly optional optionsStore: Atom>; +readonly options: TableOptionsLive; ``` -Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) +Defined in: [core/table/coreTablesFeature.types.ts:277](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L277) + +A stable live view of the table's current resolved options. -Writable atom for table options. Only created when `createOptionsStore` is -true on the active core reactivity bindings. Adapters that opt out keep -options as plain resolved data instead of backing them with an atom. +Reading a property reads the matching entry in `optionAtoms`. *** @@ -362,7 +364,7 @@ options as plain resolved data instead of backing them with an atom. readonly store: ReadonlyStore>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:249](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L249) +Defined in: [core/table/coreTablesFeature.types.ts:288](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L288) The readonly flat store for the table state. Derives from `table.atoms` only; never reads external state directly. diff --git a/docs/reference/index/interfaces/Table_FeatureMap.md b/docs/reference/index/interfaces/Table_FeatureMap.md index b28da15e01..03feeeddde 100644 --- a/docs/reference/index/interfaces/Table_FeatureMap.md +++ b/docs/reference/index/interfaces/Table_FeatureMap.md @@ -5,7 +5,7 @@ title: Table_FeatureMap # Interface: Table\_FeatureMap\ -Defined in: [types/Table.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L51) +Defined in: [types/Table.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L52) ## Type Parameters @@ -25,7 +25,7 @@ Defined in: [types/Table.ts:51](https://github.com/TanStack/table/blob/main/pack cellSelectionFeature: Table_CellSelection; ``` -Defined in: [types/Table.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L55) +Defined in: [types/Table.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L56) *** @@ -35,7 +35,7 @@ Defined in: [types/Table.ts:55](https://github.com/TanStack/table/blob/main/pack columnFacetingFeature: Table_ColumnFaceting; ``` -Defined in: [types/Table.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L56) +Defined in: [types/Table.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L57) *** @@ -45,7 +45,7 @@ Defined in: [types/Table.ts:56](https://github.com/TanStack/table/blob/main/pack columnFilteringFeature: Table_ColumnFiltering; ``` -Defined in: [types/Table.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L57) +Defined in: [types/Table.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L58) *** @@ -55,7 +55,7 @@ Defined in: [types/Table.ts:57](https://github.com/TanStack/table/blob/main/pack columnGroupingFeature: Table_ColumnGrouping; ``` -Defined in: [types/Table.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L58) +Defined in: [types/Table.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L59) *** @@ -65,7 +65,7 @@ Defined in: [types/Table.ts:58](https://github.com/TanStack/table/blob/main/pack columnOrderingFeature: Table_ColumnOrdering; ``` -Defined in: [types/Table.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L59) +Defined in: [types/Table.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L60) *** @@ -75,7 +75,7 @@ Defined in: [types/Table.ts:59](https://github.com/TanStack/table/blob/main/pack columnPinningFeature: Table_ColumnPinning; ``` -Defined in: [types/Table.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L60) +Defined in: [types/Table.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L61) *** @@ -85,7 +85,7 @@ Defined in: [types/Table.ts:60](https://github.com/TanStack/table/blob/main/pack columnResizingFeature: Table_ColumnResizing; ``` -Defined in: [types/Table.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L61) +Defined in: [types/Table.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L62) *** @@ -95,7 +95,7 @@ Defined in: [types/Table.ts:61](https://github.com/TanStack/table/blob/main/pack columnSizingFeature: Table_ColumnSizing; ``` -Defined in: [types/Table.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L62) +Defined in: [types/Table.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L63) *** @@ -105,7 +105,7 @@ Defined in: [types/Table.ts:62](https://github.com/TanStack/table/blob/main/pack columnVisibilityFeature: Table_ColumnVisibility; ``` -Defined in: [types/Table.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L63) +Defined in: [types/Table.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L64) *** @@ -115,7 +115,7 @@ Defined in: [types/Table.ts:63](https://github.com/TanStack/table/blob/main/pack globalFilteringFeature: Table_GlobalFiltering; ``` -Defined in: [types/Table.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L64) +Defined in: [types/Table.ts:65](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L65) *** @@ -125,7 +125,7 @@ Defined in: [types/Table.ts:64](https://github.com/TanStack/table/blob/main/pack rowExpandingFeature: Table_RowExpanding; ``` -Defined in: [types/Table.ts:65](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L65) +Defined in: [types/Table.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L66) *** @@ -135,7 +135,7 @@ Defined in: [types/Table.ts:65](https://github.com/TanStack/table/blob/main/pack rowPaginationFeature: Table_RowPagination; ``` -Defined in: [types/Table.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L66) +Defined in: [types/Table.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L67) *** @@ -145,7 +145,7 @@ Defined in: [types/Table.ts:66](https://github.com/TanStack/table/blob/main/pack rowPinningFeature: Table_RowPinning; ``` -Defined in: [types/Table.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L67) +Defined in: [types/Table.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L68) *** @@ -155,7 +155,7 @@ Defined in: [types/Table.ts:67](https://github.com/TanStack/table/blob/main/pack rowSelectionFeature: Table_RowSelection; ``` -Defined in: [types/Table.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L68) +Defined in: [types/Table.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L69) *** @@ -165,4 +165,4 @@ Defined in: [types/Table.ts:68](https://github.com/TanStack/table/blob/main/pack rowSortingFeature: Table_RowSorting; ``` -Defined in: [types/Table.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L69) +Defined in: [types/Table.ts:70](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L70) diff --git a/docs/reference/index/interfaces/Table_Internal.md b/docs/reference/index/interfaces/Table_Internal.md index 16398441e5..3f84659ca1 100644 --- a/docs/reference/index/interfaces/Table_Internal.md +++ b/docs/reference/index/interfaces/Table_Internal.md @@ -5,7 +5,7 @@ title: Table_Internal # Interface: Table\_Internal\ -Defined in: [types/Table.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L96) +Defined in: [types/Table.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L97) Internal broad table shape used by feature implementations. @@ -25,13 +25,13 @@ Internal broad table shape used by feature implementations. ## Properties -### \_cellInstanceInitFns? +### \_cellInstanceInitFns ```ts -optional _cellInstanceInitFns: (cell) => void[]; +_cellInstanceInitFns: (cell) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:167](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L167) +Defined in: [core/table/coreTablesFeature.types.ts:206](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L206) Cache of the `initCellInstanceData` functions for features that define one. @@ -73,7 +73,7 @@ Omit._cellInstanceInitFns optional _cellPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L173) +Defined in: [core/table/coreTablesFeature.types.ts:210](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L210) Prototype cache for Cell objects - shared by all cells in this table @@ -83,13 +83,13 @@ Prototype cache for Cell objects - shared by all cells in this table *** -### \_columnInstanceInitFns? +### \_columnInstanceInitFns ```ts -optional _columnInstanceInitFns: (column) => void[]; +_columnInstanceInitFns: (column) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:177](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L177) +Defined in: [core/table/coreTablesFeature.types.ts:214](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L214) Cache of the `initColumnInstanceData` functions for features that define one. @@ -131,7 +131,7 @@ Omit._columnInstanceInitFns optional _columnPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:183](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L183) +Defined in: [core/table/coreTablesFeature.types.ts:220](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L220) Prototype cache for Column objects - shared by all columns in this table @@ -147,7 +147,7 @@ Prototype cache for Column objects - shared by all columns in this table readonly _features: Partial & TFeatures; ``` -Defined in: [core/table/coreTablesFeature.types.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L187) +Defined in: [core/table/coreTablesFeature.types.ts:224](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L224) The features that are enabled for the table. @@ -159,13 +159,13 @@ Omit._features *** -### \_headerGroupInstanceInitFns? +### \_headerGroupInstanceInitFns ```ts -optional _headerGroupInstanceInitFns: (headerGroup) => void[]; +_headerGroupInstanceInitFns: (headerGroup) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:191](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L191) +Defined in: [core/table/coreTablesFeature.types.ts:228](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L228) Cache of the `initHeaderGroupInstanceData` functions for features that define one. @@ -197,13 +197,13 @@ Omit._headerGroupInstanceInitFns *** -### \_headerInstanceInitFns? +### \_headerInstanceInitFns ```ts -optional _headerInstanceInitFns: (header) => void[]; +_headerInstanceInitFns: (header) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:197](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L197) +Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) Cache of the `initHeaderInstanceData` functions for features that define one. @@ -245,7 +245,7 @@ Omit._headerInstanceInitFns optional _headerPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:203](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L203) +Defined in: [core/table/coreTablesFeature.types.ts:240](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L240) Prototype cache for Header objects - shared by all headers in this table @@ -261,7 +261,7 @@ Prototype cache for Header objects - shared by all headers in this table readonly _reactivity: TableReactivityBindings; ``` -Defined in: [core/table/coreTablesFeature.types.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L163) +Defined in: [core/table/coreTablesFeature.types.ts:202](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L202) Table reactivity bindings for interacting with TanStack Store. @@ -271,13 +271,13 @@ Table reactivity bindings for interacting with TanStack Store. *** -### \_rowInstanceInitFns? +### \_rowInstanceInitFns ```ts -optional _rowInstanceInitFns: (row) => void[]; +_rowInstanceInitFns: (row) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:219](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L219) +Defined in: [core/table/coreTablesFeature.types.ts:256](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L256) Cache of the `initRowInstanceData` functions for features that define one. @@ -315,7 +315,7 @@ Omit._rowInstanceInitFns _rowModelFns: RowModelFns_All; ``` -Defined in: [types/Table.ts:107](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L107) +Defined in: [types/Table.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L108) *** @@ -325,7 +325,7 @@ Defined in: [types/Table.ts:107](https://github.com/TanStack/table/blob/main/pac _rowModels: CachedRowModel_All; ``` -Defined in: [types/Table.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L106) +Defined in: [types/Table.ts:107](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L107) *** @@ -335,7 +335,7 @@ Defined in: [types/Table.ts:106](https://github.com/TanStack/table/blob/main/pac optional _rowPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:215](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L215) +Defined in: [core/table/coreTablesFeature.types.ts:252](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L252) Prototype cache for Row objects - shared by all rows in this table @@ -351,7 +351,7 @@ Prototype cache for Row objects - shared by all rows in this table atoms: Atoms & Atoms_All; ``` -Defined in: [types/Table.ts:116](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L116) +Defined in: [types/Table.ts:119](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L119) The readonly derived atoms for each `TableState` slice. Each derives from its corresponding `baseAtom` plus, optionally, a per-slice external atom or @@ -371,7 +371,7 @@ Omit.atoms baseAtoms: BaseAtoms & BaseAtoms_All; ``` -Defined in: [types/Table.ts:115](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L115) +Defined in: [types/Table.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L118) The internal writable atoms for each `TableState` slice. This is the library's single write surface — all state mutations from features land here. @@ -1065,116 +1065,37 @@ Table_RowModels.getSortedRowModel initialState: ExtractFeatureMapTypes & TableState_All; ``` -Defined in: [types/Table.ts:114](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L114) +Defined in: [types/Table.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L117) *** -### options - -```ts -options: object & DebugKeysFor & TableOptions_Core & Partial & TableOptions_ColumnFiltering & TableOptions_ColumnGrouping & TableOptions_ColumnOrdering & TableOptions_ColumnPinning & TableOptions_ColumnResizing & TableOptions_ColumnSizing & TableOptions_ColumnVisibility & TableOptions_GlobalFiltering & TableOptions_RowExpanding & TableOptions_RowPagination & TableOptions_RowPinning & TableOptions_RowSelection & TableOptions_RowSorting> & object; -``` - -Defined in: [types/Table.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L108) - -#### Type Declaration - -##### debugAll? - -```ts -optional debugAll: boolean; -``` - -##### debugCache? - -```ts -optional debugCache: boolean; -``` - -##### debugCells? +### optionAtoms ```ts -optional debugCells: boolean; +readonly optionAtoms: TableOptionAtoms; ``` -##### debugColumns? +Defined in: [core/table/coreTablesFeature.types.ts:283](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L283) -```ts -optional debugColumns: boolean; -``` - -##### debugHeaders? - -```ts -optional debugHeaders: boolean; -``` +Stable atoms for individual resolved option values. -##### debugRows? +Ordinary options are writable. Construction-static options are readonly. -```ts -optional debugRows: boolean; -``` - -##### debugTable? - -```ts -optional debugTable: boolean; -``` - -#### Type Declaration - -##### atoms? - -```ts -optional atoms: Partial<{ - cellSelection?: Atom; - columnFilters?: Atom; - columnOrder?: Atom; - columnPinning?: Atom; - columnResizing?: Atom; - columnSizing?: Atom; - columnVisibility?: Atom; - expanded?: Atom; - globalFilter?: Atom; - grouping?: Atom; - pagination?: Atom; - rowPinning?: Atom; - rowSelection?: Atom; - sorting?: Atom; -}>; -``` - -##### initialState? - -```ts -optional initialState: TableState_All; -``` - -##### state? +#### Inherited from ```ts -optional state: TableState_All; +Omit.optionAtoms ``` *** -### optionsStore? +### options ```ts -readonly optional optionsStore: Atom>; +options: TableOptionsLive & Readonly & Partial & TableOptions_ColumnFiltering & TableOptions_ColumnGrouping & TableOptions_ColumnOrdering & TableOptions_ColumnPinning & TableOptions_ColumnResizing & TableOptions_ColumnSizing & TableOptions_ColumnVisibility & TableOptions_GlobalFiltering & TableOptions_RowExpanding & TableOptions_RowPagination & TableOptions_RowPinning & TableOptions_RowSelection & TableOptions_RowSorting> & object>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) - -Writable atom for table options. Only created when `createOptionsStore` is -true on the active core reactivity bindings. Adapters that opt out keep -options as plain resolved data instead of backing them with an atom. - -#### Inherited from - -```ts -Omit.optionsStore -``` +Defined in: [types/Table.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L109) *** @@ -1184,7 +1105,7 @@ Omit.optionsStore reset: () => void; ``` -Defined in: [core/table/coreTablesFeature.types.ts:264](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L264) +Defined in: [core/table/coreTablesFeature.types.ts:303](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L303) Resets the table's internal base atoms to `table.initialState`. @@ -1211,7 +1132,7 @@ Omit.reset setOptions: (newOptions) => void; ``` -Defined in: [core/table/coreTablesFeature.types.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L269) +Defined in: [core/table/coreTablesFeature.types.ts:308](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L308) Updates the table options by applying a value or updater to the current resolved options and then merging them through `options.mergeOptions`. @@ -1240,4 +1161,4 @@ Omit.setOptions store: ReadonlyStore> & ReadonlyStore; ``` -Defined in: [types/Table.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L117) +Defined in: [types/Table.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L120) diff --git a/docs/reference/index/interfaces/Table_Table.md b/docs/reference/index/interfaces/Table_Table.md index edc13ea2c3..7a49be946a 100644 --- a/docs/reference/index/interfaces/Table_Table.md +++ b/docs/reference/index/interfaces/Table_Table.md @@ -5,7 +5,7 @@ title: Table_Table # Interface: Table\_Table\ -Defined in: [core/table/coreTablesFeature.types.ts:252](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L252) +Defined in: [core/table/coreTablesFeature.types.ts:291](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L291) ## Extends @@ -27,13 +27,13 @@ Defined in: [core/table/coreTablesFeature.types.ts:252](https://github.com/TanSt ## Properties -### \_cellInstanceInitFns? +### \_cellInstanceInitFns ```ts -optional _cellInstanceInitFns: (cell) => void[]; +_cellInstanceInitFns: (cell) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:167](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L167) +Defined in: [core/table/coreTablesFeature.types.ts:206](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L206) Cache of the `initCellInstanceData` functions for features that define one. @@ -73,7 +73,7 @@ Cache of the `initCellInstanceData` functions for features that define one. optional _cellPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L173) +Defined in: [core/table/coreTablesFeature.types.ts:210](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L210) Prototype cache for Cell objects - shared by all cells in this table @@ -83,13 +83,13 @@ Prototype cache for Cell objects - shared by all cells in this table *** -### \_columnInstanceInitFns? +### \_columnInstanceInitFns ```ts -optional _columnInstanceInitFns: (column) => void[]; +_columnInstanceInitFns: (column) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:177](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L177) +Defined in: [core/table/coreTablesFeature.types.ts:214](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L214) Cache of the `initColumnInstanceData` functions for features that define one. @@ -129,7 +129,7 @@ Cache of the `initColumnInstanceData` functions for features that define one. optional _columnPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:183](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L183) +Defined in: [core/table/coreTablesFeature.types.ts:220](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L220) Prototype cache for Column objects - shared by all columns in this table @@ -145,7 +145,7 @@ Prototype cache for Column objects - shared by all columns in this table readonly _features: Partial & TFeatures; ``` -Defined in: [core/table/coreTablesFeature.types.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L187) +Defined in: [core/table/coreTablesFeature.types.ts:224](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L224) The features that are enabled for the table. @@ -155,13 +155,13 @@ The features that are enabled for the table. *** -### \_headerGroupInstanceInitFns? +### \_headerGroupInstanceInitFns ```ts -optional _headerGroupInstanceInitFns: (headerGroup) => void[]; +_headerGroupInstanceInitFns: (headerGroup) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:191](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L191) +Defined in: [core/table/coreTablesFeature.types.ts:228](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L228) Cache of the `initHeaderGroupInstanceData` functions for features that define one. @@ -191,13 +191,13 @@ Cache of the `initHeaderGroupInstanceData` functions for features that define on *** -### \_headerInstanceInitFns? +### \_headerInstanceInitFns ```ts -optional _headerInstanceInitFns: (header) => void[]; +_headerInstanceInitFns: (header) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:197](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L197) +Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) Cache of the `initHeaderInstanceData` functions for features that define one. @@ -237,7 +237,7 @@ Cache of the `initHeaderInstanceData` functions for features that define one. optional _headerPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:203](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L203) +Defined in: [core/table/coreTablesFeature.types.ts:240](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L240) Prototype cache for Header objects - shared by all headers in this table @@ -253,7 +253,7 @@ Prototype cache for Header objects - shared by all headers in this table readonly _reactivity: TableReactivityBindings; ``` -Defined in: [core/table/coreTablesFeature.types.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L163) +Defined in: [core/table/coreTablesFeature.types.ts:202](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L202) Table reactivity bindings for interacting with TanStack Store. @@ -263,13 +263,13 @@ Table reactivity bindings for interacting with TanStack Store. *** -### \_rowInstanceInitFns? +### \_rowInstanceInitFns ```ts -optional _rowInstanceInitFns: (row) => void[]; +_rowInstanceInitFns: (row) => void[]; ``` -Defined in: [core/table/coreTablesFeature.types.ts:219](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L219) +Defined in: [core/table/coreTablesFeature.types.ts:256](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L256) Cache of the `initRowInstanceData` functions for features that define one. @@ -305,7 +305,7 @@ Cache of the `initRowInstanceData` functions for features that define one. readonly _rowModelFns: RowModelFns; ``` -Defined in: [core/table/coreTablesFeature.types.ts:207](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L207) +Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) The row model processing functions that are used to process the data by features. @@ -321,7 +321,7 @@ The row model processing functions that are used to process the data by features readonly _rowModels: CachedRowModels; ``` -Defined in: [core/table/coreTablesFeature.types.ts:211](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L211) +Defined in: [core/table/coreTablesFeature.types.ts:248](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L248) The row models that are enabled for the table. @@ -337,7 +337,7 @@ The row models that are enabled for the table. optional _rowPrototype: object; ``` -Defined in: [core/table/coreTablesFeature.types.ts:215](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L215) +Defined in: [core/table/coreTablesFeature.types.ts:252](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L252) Prototype cache for Row objects - shared by all rows in this table @@ -353,7 +353,7 @@ Prototype cache for Row objects - shared by all rows in this table readonly atoms: Atoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:225](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L225) +Defined in: [core/table/coreTablesFeature.types.ts:262](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L262) The readonly derived atoms for each `TableState` slice. Each derives from its corresponding `baseAtom` plus, optionally, a per-slice external atom or @@ -371,7 +371,7 @@ external state value (precedence: external atom > external state > base atom). readonly baseAtoms: BaseAtoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:230](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L230) +Defined in: [core/table/coreTablesFeature.types.ts:267](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L267) The internal writable atoms for each `TableState` slice. This is the library's single write surface — all state mutations from features land here. @@ -388,7 +388,7 @@ single write surface — all state mutations from features land here. readonly initialState: ExtractFeatureMapTypes; ``` -Defined in: [core/table/coreTablesFeature.types.ts:234](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L234) +Defined in: [core/table/coreTablesFeature.types.ts:271](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L271) This is the resolved initial state of the table. @@ -398,37 +398,39 @@ This is the resolved initial state of the table. *** -### options +### optionAtoms ```ts -readonly options: TableOptions; +readonly optionAtoms: TableOptionAtoms; ``` -Defined in: [core/table/coreTablesFeature.types.ts:238](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L238) +Defined in: [core/table/coreTablesFeature.types.ts:283](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L283) -A read-only reference to the table's current options. +Stable atoms for individual resolved option values. + +Ordinary options are writable. Construction-static options are readonly. #### Inherited from -[`Table_CoreProperties`](Table_CoreProperties.md).[`options`](Table_CoreProperties.md#options) +[`Table_CoreProperties`](Table_CoreProperties.md).[`optionAtoms`](Table_CoreProperties.md#optionatoms) *** -### optionsStore? +### options ```ts -readonly optional optionsStore: Atom>; +readonly options: TableOptionsLive; ``` -Defined in: [core/table/coreTablesFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L244) +Defined in: [core/table/coreTablesFeature.types.ts:277](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L277) + +A stable live view of the table's current resolved options. -Writable atom for table options. Only created when `createOptionsStore` is -true on the active core reactivity bindings. Adapters that opt out keep -options as plain resolved data instead of backing them with an atom. +Reading a property reads the matching entry in `optionAtoms`. #### Inherited from -[`Table_CoreProperties`](Table_CoreProperties.md).[`optionsStore`](Table_CoreProperties.md#optionsstore) +[`Table_CoreProperties`](Table_CoreProperties.md).[`options`](Table_CoreProperties.md#options) *** @@ -438,7 +440,7 @@ options as plain resolved data instead of backing them with an atom. reset: () => void; ``` -Defined in: [core/table/coreTablesFeature.types.ts:264](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L264) +Defined in: [core/table/coreTablesFeature.types.ts:303](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L303) Resets the table's internal base atoms to `table.initialState`. @@ -459,7 +461,7 @@ reset hooks for mutable, transient table-instance data. setOptions: (newOptions) => void; ``` -Defined in: [core/table/coreTablesFeature.types.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L269) +Defined in: [core/table/coreTablesFeature.types.ts:308](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L308) Updates the table options by applying a value or updater to the current resolved options and then merging them through `options.mergeOptions`. @@ -482,7 +484,7 @@ resolved options and then merging them through `options.mergeOptions`. readonly store: ReadonlyStore>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:249](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L249) +Defined in: [core/table/coreTablesFeature.types.ts:288](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L288) The readonly flat store for the table state. Derives from `table.atoms` only; never reads external state directly. diff --git a/docs/reference/index/type-aliases/API.md b/docs/reference/index/type-aliases/API.md new file mode 100644 index 0000000000..74d317a117 --- /dev/null +++ b/docs/reference/index/type-aliases/API.md @@ -0,0 +1,22 @@ +--- +id: API +title: API +--- + +# Type Alias: API + +```ts +type API = + | { + compare?: (previous, next) => boolean; + computed: () => any; + fn?: never; +} + | { + compare?: never; + computed?: never; + fn: (...args) => any; +}; +``` + +Defined in: [utils.ts:325](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L325) diff --git a/docs/reference/index/type-aliases/APIObject.md b/docs/reference/index/type-aliases/APIObject.md index f381bfcaaa..0582876ddc 100644 --- a/docs/reference/index/type-aliases/APIObject.md +++ b/docs/reference/index/type-aliases/APIObject.md @@ -3,20 +3,10 @@ id: APIObject title: APIObject --- -# Type Alias: APIObject\ +# Type Alias: APIObject ```ts -type APIObject = Record>; +type APIObject = Record; ``` -Defined in: [utils.ts:367](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L367) - -## Type Parameters - -### TDeps - -`TDeps` *extends* `ReadonlyArray`\<`any`\> - -### TDepArgs - -`TDepArgs` +Defined in: [utils.ts:337](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L337) diff --git a/docs/reference/index/type-aliases/Atoms_All.md b/docs/reference/index/type-aliases/Atoms_All.md index c965cc6dd6..a058c91dc0 100644 --- a/docs/reference/index/type-aliases/Atoms_All.md +++ b/docs/reference/index/type-aliases/Atoms_All.md @@ -9,4 +9,4 @@ title: Atoms_All type Atoms_All = { [K in keyof TableState_All]?: ReadonlyAtom }; ``` -Defined in: [core/table/coreTablesFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L81) +Defined in: [core/table/coreTablesFeature.types.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L120) diff --git a/docs/reference/index/type-aliases/BaseAtoms_All.md b/docs/reference/index/type-aliases/BaseAtoms_All.md index 9bef86d951..a1ebaeb925 100644 --- a/docs/reference/index/type-aliases/BaseAtoms_All.md +++ b/docs/reference/index/type-aliases/BaseAtoms_All.md @@ -9,7 +9,7 @@ title: BaseAtoms_All type BaseAtoms_All = { [K in keyof TableState_All]?: Atom> }; ``` -Defined in: [core/table/coreTablesFeature.types.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L78) +Defined in: [core/table/coreTablesFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L117) Internal "all features" flat variants of the atom types. `Table_Internal` uses these so feature code (written generically over `TFeatures`) can access diff --git a/docs/reference/index/type-aliases/ExternalAtoms_All.md b/docs/reference/index/type-aliases/ExternalAtoms_All.md index 450fc7a09c..1141246d21 100644 --- a/docs/reference/index/type-aliases/ExternalAtoms_All.md +++ b/docs/reference/index/type-aliases/ExternalAtoms_All.md @@ -9,4 +9,4 @@ title: ExternalAtoms_All type ExternalAtoms_All = Partial<{ [K in keyof TableState_All]: Atom> }>; ``` -Defined in: [core/table/coreTablesFeature.types.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L84) +Defined in: [core/table/coreTablesFeature.types.ts:123](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L123) diff --git a/docs/reference/index/type-aliases/PrototypeAPI.md b/docs/reference/index/type-aliases/PrototypeAPI.md new file mode 100644 index 0000000000..a6cd8c7fbd --- /dev/null +++ b/docs/reference/index/type-aliases/PrototypeAPI.md @@ -0,0 +1,22 @@ +--- +id: PrototypeAPI +title: PrototypeAPI +--- + +# Type Alias: PrototypeAPI + +```ts +type PrototypeAPI = + | { + compare?: (previous, next) => boolean; + computed: (self) => any; + fn?: never; +} + | { + compare?: never; + computed?: never; + fn: (self, ...args) => any; +}; +``` + +Defined in: [utils.ts:383](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L383) diff --git a/docs/reference/index/type-aliases/PrototypeAPIObject.md b/docs/reference/index/type-aliases/PrototypeAPIObject.md index 324eebd46f..1dbd99278f 100644 --- a/docs/reference/index/type-aliases/PrototypeAPIObject.md +++ b/docs/reference/index/type-aliases/PrototypeAPIObject.md @@ -3,20 +3,10 @@ id: PrototypeAPIObject title: PrototypeAPIObject --- -# Type Alias: PrototypeAPIObject\ +# Type Alias: PrototypeAPIObject ```ts -type PrototypeAPIObject = Record>; +type PrototypeAPIObject = Record; ``` -Defined in: [utils.ts:422](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L422) - -## Type Parameters - -### TDeps - -`TDeps` *extends* `ReadonlyArray`\<`any`\> - -### TDepArgs - -`TDepArgs` +Defined in: [utils.ts:395](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L395) diff --git a/docs/reference/index/type-aliases/Table.md b/docs/reference/index/type-aliases/Table.md index 2bbfee87c3..6a1ed5e4a4 100644 --- a/docs/reference/index/type-aliases/Table.md +++ b/docs/reference/index/type-aliases/Table.md @@ -9,7 +9,7 @@ title: Table type Table = Table_Core & ExtractFeatureMapTypes>; ``` -Defined in: [types/Table.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L75) +Defined in: [types/Table.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L76) The table object that includes both the core table functionality and the features that are enabled via the `features` table option. diff --git a/docs/reference/index/type-aliases/TableOptionAtoms.md b/docs/reference/index/type-aliases/TableOptionAtoms.md new file mode 100644 index 0000000000..842f96422c --- /dev/null +++ b/docs/reference/index/type-aliases/TableOptionAtoms.md @@ -0,0 +1,38 @@ +--- +id: TableOptionAtoms +title: TableOptionAtoms +--- + +# Type Alias: TableOptionAtoms\ + +```ts +type TableOptionAtoms = object & { readonly [K in keyof TableOptions as K extends "snapshotVersion" ? never : K]: K extends ConstructStaticOptionKey ? ReadonlyAtom[K]> : Atom[K]> }; +``` + +Defined in: [core/table/coreTablesFeature.types.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L77) + +One atom per currently resolved table option. + +The atom properties themselves are readonly so their identities stay +stable. Ordinary option atoms are writable; construction-static options +remain readonly. + +## Type Declaration + +### snapshotVersion + +```ts +readonly snapshotVersion: ReadonlyAtom; +``` + +Increments once after each atomic update of the resolved options. + +## Type Parameters + +### TFeatures + +`TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) + +### TData + +`TData` *extends* [`RowData`](RowData.md) diff --git a/docs/reference/index/type-aliases/TableOptionsLive.md b/docs/reference/index/type-aliases/TableOptionsLive.md new file mode 100644 index 0000000000..4f6f4de690 --- /dev/null +++ b/docs/reference/index/type-aliases/TableOptionsLive.md @@ -0,0 +1,26 @@ +--- +id: TableOptionsLive +title: TableOptionsLive +--- + +# Type Alias: TableOptionsLive\ + +```ts +type TableOptionsLive = { readonly [K in keyof TableOptions]: TableOptions[K] }; +``` + +Defined in: [core/table/coreTablesFeature.types.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L97) + +The stable readonly options view exposed by `table.options`. + +Every property read is routed to the matching existing option atom. + +## Type Parameters + +### TFeatures + +`TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) + +### TData + +`TData` *extends* [`RowData`](RowData.md) diff --git a/docs/reference/index/variables/cellSelectionFeature.md b/docs/reference/index/variables/cellSelectionFeature.md index 975f8f178f..963e3f0c66 100644 --- a/docs/reference/index/variables/cellSelectionFeature.md +++ b/docs/reference/index/variables/cellSelectionFeature.md @@ -9,6 +9,6 @@ title: cellSelectionFeature const cellSelectionFeature: TableFeature; ``` -Defined in: [features/cell-selection/cellSelectionFeature.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/cell-selection/cellSelectionFeature.ts#L38) +Defined in: [features/cell-selection/cellSelectionFeature.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/cell-selection/cellSelectionFeature.ts#L37) Feature that adds spreadsheet-style cell range selection state and APIs. diff --git a/docs/reference/index/variables/columnPinningFeature.md b/docs/reference/index/variables/columnPinningFeature.md index 080d77d7b1..c046d128cc 100644 --- a/docs/reference/index/variables/columnPinningFeature.md +++ b/docs/reference/index/variables/columnPinningFeature.md @@ -9,7 +9,7 @@ title: columnPinningFeature const columnPinningFeature: TableFeature; ``` -Defined in: [features/column-pinning/columnPinningFeature.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.ts#L51) +Defined in: [features/column-pinning/columnPinningFeature.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.ts#L57) Feature that adds column pinning state and APIs for logical start, center, and end regions. diff --git a/docs/reference/index/variables/columnSizingFeature.md b/docs/reference/index/variables/columnSizingFeature.md index 2863ec9ac4..2467d71021 100644 --- a/docs/reference/index/variables/columnSizingFeature.md +++ b/docs/reference/index/variables/columnSizingFeature.md @@ -9,6 +9,6 @@ title: columnSizingFeature const columnSizingFeature: TableFeature; ``` -Defined in: [features/column-sizing/columnSizingFeature.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.ts#L28) +Defined in: [features/column-sizing/columnSizingFeature.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.ts#L54) Feature that adds column sizing state, defaults, and size measurement APIs. diff --git a/docs/reference/index/variables/rowPinningFeature.md b/docs/reference/index/variables/rowPinningFeature.md index 08769c84b0..8d40cbcb6f 100644 --- a/docs/reference/index/variables/rowPinningFeature.md +++ b/docs/reference/index/variables/rowPinningFeature.md @@ -9,6 +9,6 @@ title: rowPinningFeature const rowPinningFeature: TableFeature; ``` -Defined in: [features/row-pinning/rowPinningFeature.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.ts#L24) +Defined in: [features/row-pinning/rowPinningFeature.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.ts#L29) Feature that adds row pinning state and APIs for top, center, and bottom rows. diff --git a/docs/reference/static-functions/functions/aggregateColumnValue.md b/docs/reference/static-functions/functions/aggregateColumnValue.md index 37f7a9d85b..3d483d0c44 100644 --- a/docs/reference/static-functions/functions/aggregateColumnValue.md +++ b/docs/reference/static-functions/functions/aggregateColumnValue.md @@ -9,7 +9,7 @@ title: aggregateColumnValue function aggregateColumnValue(args): unknown; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:307](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L307) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:337](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L337) Executes every configured aggregation over a depth-selected row frontier. diff --git a/docs/reference/static-functions/functions/cell_getIsAggregated.md b/docs/reference/static-functions/functions/cell_getIsAggregated.md index 11f960b9cb..37c50c34ab 100644 --- a/docs/reference/static-functions/functions/cell_getIsAggregated.md +++ b/docs/reference/static-functions/functions/cell_getIsAggregated.md @@ -9,7 +9,7 @@ title: cell_getIsAggregated function cell_getIsAggregated(cell): boolean; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:450](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L450) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:480](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L480) Implements `cell.getIsAggregated()` for synthetic grouped rows. diff --git a/docs/reference/static-functions/functions/cell_getIsSelected.md b/docs/reference/static-functions/functions/cell_getIsSelected.md index 204ee18839..d2cb2e18c3 100644 --- a/docs/reference/static-functions/functions/cell_getIsSelected.md +++ b/docs/reference/static-functions/functions/cell_getIsSelected.md @@ -14,7 +14,7 @@ Defined in: [features/cell-selection/cellSelectionFeature.utils.ts:396](https:// Checks whether this cell falls inside any selected range. Deliberately not memoized. Registering this through `assignPrototypeAPIs` -with `memoDeps` would allocate a memo closure and dependency array per cell, +with a native computed would allocate a memo closure per cell, which costs more than the handful of integer comparisons it would save. ## Type Parameters diff --git a/docs/reference/static-functions/functions/column_clearSorting.md b/docs/reference/static-functions/functions/column_clearSorting.md index f47ab88d02..8a33162caa 100644 --- a/docs/reference/static-functions/functions/column_clearSorting.md +++ b/docs/reference/static-functions/functions/column_clearSorting.md @@ -9,7 +9,7 @@ title: column_clearSorting function column_clearSorting(column): void; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:471](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L471) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:476](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L476) Removes this column from the sorting state. diff --git a/docs/reference/static-functions/functions/column_getAggregationFns.md b/docs/reference/static-functions/functions/column_getAggregationFns.md index 2974ca4a65..33d9eeb6b6 100644 --- a/docs/reference/static-functions/functions/column_getAggregationFns.md +++ b/docs/reference/static-functions/functions/column_getAggregationFns.md @@ -9,7 +9,7 @@ title: column_getAggregationFns function column_getAggregationFns(column): readonly ResolvedAggregationFn[]; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:201](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L201) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:231](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L231) Resolves and validates a column's scalar or multiple aggregation option. diff --git a/docs/reference/static-functions/functions/column_getAggregationValue.md b/docs/reference/static-functions/functions/column_getAggregationValue.md index 1121ccef2f..1a14f0b3fb 100644 --- a/docs/reference/static-functions/functions/column_getAggregationValue.md +++ b/docs/reference/static-functions/functions/column_getAggregationValue.md @@ -9,7 +9,7 @@ title: column_getAggregationValue function column_getAggregationValue(column, options?): ColumnAggregationValue; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:386](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L386) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:416](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L416) Implements `column.getAggregationValue(options?)` and its default cache. diff --git a/docs/reference/static-functions/functions/column_getAutoAggregationFn.md b/docs/reference/static-functions/functions/column_getAutoAggregationFn.md index ffd34f4af4..1a1646334b 100644 --- a/docs/reference/static-functions/functions/column_getAutoAggregationFn.md +++ b/docs/reference/static-functions/functions/column_getAutoAggregationFn.md @@ -11,7 +11,7 @@ function column_getAutoAggregationFn(column): | undefined; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:159](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L159) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:189](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L189) Resolves the `sum` or `extent` definition inferred from the first core row. diff --git a/docs/reference/static-functions/functions/column_getCanMultiSort.md b/docs/reference/static-functions/functions/column_getCanMultiSort.md index 537236a0b0..423faaa58b 100644 --- a/docs/reference/static-functions/functions/column_getCanMultiSort.md +++ b/docs/reference/static-functions/functions/column_getCanMultiSort.md @@ -9,7 +9,7 @@ title: column_getCanMultiSort function column_getCanMultiSort(column): boolean; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:406](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L406) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:411](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L411) Checks whether this column can be added to a multi-sort state. diff --git a/docs/reference/static-functions/functions/column_getCanSort.md b/docs/reference/static-functions/functions/column_getCanSort.md index 6b74553334..7e46369de3 100644 --- a/docs/reference/static-functions/functions/column_getCanSort.md +++ b/docs/reference/static-functions/functions/column_getCanSort.md @@ -9,7 +9,7 @@ title: column_getCanSort function column_getCanSort(column): boolean; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:383](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L383) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:388](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L388) Checks whether this accessor column can participate in sorting. diff --git a/docs/reference/static-functions/functions/column_getFirstSortDir.md b/docs/reference/static-functions/functions/column_getFirstSortDir.md index b00c455475..2a2e59135e 100644 --- a/docs/reference/static-functions/functions/column_getFirstSortDir.md +++ b/docs/reference/static-functions/functions/column_getFirstSortDir.md @@ -9,7 +9,7 @@ title: column_getFirstSortDir function column_getFirstSortDir(column): "asc" | "desc"; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:327](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L327) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:332](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L332) Resolves the first direction used when this column begins sorting. diff --git a/docs/reference/static-functions/functions/column_getIsSorted.md b/docs/reference/static-functions/functions/column_getIsSorted.md index 52f98c5829..9d306f268d 100644 --- a/docs/reference/static-functions/functions/column_getIsSorted.md +++ b/docs/reference/static-functions/functions/column_getIsSorted.md @@ -9,7 +9,7 @@ title: column_getIsSorted function column_getIsSorted(column): false | SortDirection; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:429](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L429) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:434](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L434) Reads this column's current sort direction. diff --git a/docs/reference/static-functions/functions/column_getNextSortingOrder.md b/docs/reference/static-functions/functions/column_getNextSortingOrder.md index 85be91cfad..51d7c80389 100644 --- a/docs/reference/static-functions/functions/column_getNextSortingOrder.md +++ b/docs/reference/static-functions/functions/column_getNextSortingOrder.md @@ -9,7 +9,7 @@ title: column_getNextSortingOrder function column_getNextSortingOrder(column, multi?): false | "asc" | "desc"; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:350](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L350) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:355](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L355) Resolves the next sort order for this column's toggle cycle. diff --git a/docs/reference/static-functions/functions/column_getSortIndex.md b/docs/reference/static-functions/functions/column_getSortIndex.md index 0470db21d7..75b706409b 100644 --- a/docs/reference/static-functions/functions/column_getSortIndex.md +++ b/docs/reference/static-functions/functions/column_getSortIndex.md @@ -9,7 +9,7 @@ title: column_getSortIndex function column_getSortIndex(column): number; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:450](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L450) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:455](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L455) Finds this column's position in the ordered `state.sorting` array. diff --git a/docs/reference/static-functions/functions/column_getToggleSortingHandler.md b/docs/reference/static-functions/functions/column_getToggleSortingHandler.md index 5e5cbf5296..8d7b9474c2 100644 --- a/docs/reference/static-functions/functions/column_getToggleSortingHandler.md +++ b/docs/reference/static-functions/functions/column_getToggleSortingHandler.md @@ -9,7 +9,7 @@ title: column_getToggleSortingHandler function column_getToggleSortingHandler(column): (e) => void; ``` -Defined in: [features/row-sorting/rowSortingFeature.utils.ts:493](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L493) +Defined in: [features/row-sorting/rowSortingFeature.utils.ts:498](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L498) Creates a header event handler that toggles this column's sorting. diff --git a/docs/reference/static-functions/functions/formatAggregatedCellValue.md b/docs/reference/static-functions/functions/formatAggregatedCellValue.md index 2cfa6f6b1d..9f7fc8be77 100644 --- a/docs/reference/static-functions/functions/formatAggregatedCellValue.md +++ b/docs/reference/static-functions/functions/formatAggregatedCellValue.md @@ -9,7 +9,7 @@ title: formatAggregatedCellValue function formatAggregatedCellValue(value, option): string | null; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:471](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L471) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:501](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L501) Formats the default scalar or keyed aggregated-cell representation. diff --git a/docs/reference/static-functions/functions/getDefaultRowSelectionState.md b/docs/reference/static-functions/functions/getDefaultRowSelectionState.md index 6c48067ffe..caaa1f1eb5 100644 --- a/docs/reference/static-functions/functions/getDefaultRowSelectionState.md +++ b/docs/reference/static-functions/functions/getDefaultRowSelectionState.md @@ -9,7 +9,7 @@ title: getDefaultRowSelectionState function getDefaultRowSelectionState(): RowSelectionState; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L31) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L35) Creates the default row selection state. diff --git a/docs/reference/static-functions/functions/header_getContext.md b/docs/reference/static-functions/functions/header_getContext.md index af131167a8..5e301559c8 100644 --- a/docs/reference/static-functions/functions/header_getContext.md +++ b/docs/reference/static-functions/functions/header_getContext.md @@ -9,7 +9,7 @@ title: header_getContext function header_getContext(header): object; ``` -Defined in: [core/headers/coreHeadersFeature.utils.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L54) +Defined in: [core/headers/coreHeadersFeature.utils.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L62) Builds the render context passed to a column's `header` or `footer` template. diff --git a/docs/reference/static-functions/functions/header_getLeafHeaders.md b/docs/reference/static-functions/functions/header_getLeafHeaders.md index a7458a9c0e..bfc3efec70 100644 --- a/docs/reference/static-functions/functions/header_getLeafHeaders.md +++ b/docs/reference/static-functions/functions/header_getLeafHeaders.md @@ -9,7 +9,7 @@ title: header_getLeafHeaders function header_getLeafHeaders(header): Header[]; ``` -Defined in: [core/headers/coreHeadersFeature.utils.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L25) +Defined in: [core/headers/coreHeadersFeature.utils.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L40) Walks a header tree and collects all descendant leaf headers. diff --git a/docs/reference/static-functions/functions/header_getSize.md b/docs/reference/static-functions/functions/header_getSize.md index fb5d1e0111..2ceb2bc340 100644 --- a/docs/reference/static-functions/functions/header_getSize.md +++ b/docs/reference/static-functions/functions/header_getSize.md @@ -9,7 +9,7 @@ title: header_getSize function header_getSize(header): number; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L269) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:285](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L285) Computes a header's rendered size from its leaf headers. diff --git a/docs/reference/static-functions/functions/header_getStart.md b/docs/reference/static-functions/functions/header_getStart.md index fdaf380548..9b81cd83af 100644 --- a/docs/reference/static-functions/functions/header_getStart.md +++ b/docs/reference/static-functions/functions/header_getStart.md @@ -9,7 +9,7 @@ title: header_getStart function header_getStart(header): number; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:300](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L300) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:304](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L304) Computes a header's offset from the start of its header group. diff --git a/docs/reference/static-functions/functions/isRowSelected.md b/docs/reference/static-functions/functions/isRowSelected.md index 1a07476675..b5ec2aaa5e 100644 --- a/docs/reference/static-functions/functions/isRowSelected.md +++ b/docs/reference/static-functions/functions/isRowSelected.md @@ -9,7 +9,7 @@ title: isRowSelected function isRowSelected(row, rowSelection): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:866](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L866) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:888](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L888) Returns whether a row id is selected in the current row selection state. diff --git a/docs/reference/static-functions/functions/isSubRowSelected.md b/docs/reference/static-functions/functions/isSubRowSelected.md index 2c7e3c5417..44484f9c2c 100644 --- a/docs/reference/static-functions/functions/isSubRowSelected.md +++ b/docs/reference/static-functions/functions/isSubRowSelected.md @@ -9,7 +9,7 @@ title: isSubRowSelected function isSubRowSelected(row): boolean | "some" | "all"; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:883](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L883) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:905](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L905) Returns whether all, some, or none of a row's selectable descendants are selected. diff --git a/docs/reference/static-functions/functions/normalizeAggregationRows.md b/docs/reference/static-functions/functions/normalizeAggregationRows.md index 41d89599a3..8c2805d703 100644 --- a/docs/reference/static-functions/functions/normalizeAggregationRows.md +++ b/docs/reference/static-functions/functions/normalizeAggregationRows.md @@ -9,7 +9,7 @@ title: normalizeAggregationRows function normalizeAggregationRows(rows, maxDepth): Row[]; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L66) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:114](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L114) Selects unique rows at a maximum relative depth in encounter order. Branches that end before the requested depth contribute their deepest row. diff --git a/docs/reference/static-functions/functions/normalizeUniqueAggregationRows.md b/docs/reference/static-functions/functions/normalizeUniqueAggregationRows.md index 572a573135..b31e423341 100644 --- a/docs/reference/static-functions/functions/normalizeUniqueAggregationRows.md +++ b/docs/reference/static-functions/functions/normalizeUniqueAggregationRows.md @@ -9,7 +9,7 @@ title: normalizeUniqueAggregationRows function normalizeUniqueAggregationRows(rows, maxDepth): readonly Row[]; ``` -Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:105](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L105) +Defined in: [features/row-aggregation/rowAggregationFeature.utils.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts#L145) Frontier selection for rows that are distinct nodes of a single row tree — the row models the table builds itself. Skips `normalizeAggregationRows`' diff --git a/docs/reference/static-functions/functions/row_getAllCells.md b/docs/reference/static-functions/functions/row_getAllCells.md index f283936170..bfe970bb85 100644 --- a/docs/reference/static-functions/functions/row_getAllCells.md +++ b/docs/reference/static-functions/functions/row_getAllCells.md @@ -9,7 +9,7 @@ title: row_getAllCells function row_getAllCells(row): Cell[]; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:250](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L250) +Defined in: [core/rows/coreRowsFeature.utils.ts:251](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L251) Constructs one cell for each leaf column in this row. diff --git a/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md b/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md index db2d35d6f0..a7835d0c08 100644 --- a/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md +++ b/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md @@ -9,7 +9,7 @@ title: row_getAllCellsByColumnId function row_getAllCellsByColumnId(row): Record>; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:286](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L286) +Defined in: [core/rows/coreRowsFeature.utils.ts:287](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L287) Builds a lookup map of this row's cells keyed by column id. diff --git a/docs/reference/static-functions/functions/row_getCanMultiSelect.md b/docs/reference/static-functions/functions/row_getCanMultiSelect.md index 9a063c0da0..8ac97a046b 100644 --- a/docs/reference/static-functions/functions/row_getCanMultiSelect.md +++ b/docs/reference/static-functions/functions/row_getCanMultiSelect.md @@ -9,7 +9,7 @@ title: row_getCanMultiSelect function row_getCanMultiSelect(row): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:634](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L634) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:638](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L638) Checks whether this row can be selected alongside other rows. diff --git a/docs/reference/static-functions/functions/row_getCanSelect.md b/docs/reference/static-functions/functions/row_getCanSelect.md index 569ab7a2c4..afc722c2bb 100644 --- a/docs/reference/static-functions/functions/row_getCanSelect.md +++ b/docs/reference/static-functions/functions/row_getCanSelect.md @@ -9,7 +9,7 @@ title: row_getCanSelect function row_getCanSelect(row): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:588](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L588) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:592](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L592) Checks whether this row can be selected. diff --git a/docs/reference/static-functions/functions/row_getCanSelectSubRows.md b/docs/reference/static-functions/functions/row_getCanSelectSubRows.md index 45a929e4f7..982c95824c 100644 --- a/docs/reference/static-functions/functions/row_getCanSelectSubRows.md +++ b/docs/reference/static-functions/functions/row_getCanSelectSubRows.md @@ -9,7 +9,7 @@ title: row_getCanSelectSubRows function row_getCanSelectSubRows(row): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:611](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L611) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:615](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L615) Checks whether selecting this row should also select its subRows. diff --git a/docs/reference/static-functions/functions/row_getDisplayIndex.md b/docs/reference/static-functions/functions/row_getDisplayIndex.md index 45779902cf..7956d512ce 100644 --- a/docs/reference/static-functions/functions/row_getDisplayIndex.md +++ b/docs/reference/static-functions/functions/row_getDisplayIndex.md @@ -9,7 +9,7 @@ title: row_getDisplayIndex function row_getDisplayIndex(row): number; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L14) +Defined in: [core/rows/coreRowsFeature.utils.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L15) Returns this row's zero-based position in the current pre-pagination row model. Rows outside that model return `-1`. diff --git a/docs/reference/static-functions/functions/row_getIsAllSubRowsSelected.md b/docs/reference/static-functions/functions/row_getIsAllSubRowsSelected.md index 99bbc94068..ebef71a0d6 100644 --- a/docs/reference/static-functions/functions/row_getIsAllSubRowsSelected.md +++ b/docs/reference/static-functions/functions/row_getIsAllSubRowsSelected.md @@ -9,7 +9,7 @@ title: row_getIsAllSubRowsSelected function row_getIsAllSubRowsSelected(row): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:570](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L570) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:574](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L574) Checks whether all selectable descendants are selected. diff --git a/docs/reference/static-functions/functions/row_getIsSelected.md b/docs/reference/static-functions/functions/row_getIsSelected.md index a829e0869c..d54e51bfd1 100644 --- a/docs/reference/static-functions/functions/row_getIsSelected.md +++ b/docs/reference/static-functions/functions/row_getIsSelected.md @@ -9,7 +9,7 @@ title: row_getIsSelected function row_getIsSelected(row): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:535](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L535) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:539](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L539) Checks whether this row id is selected in `state.rowSelection`. diff --git a/docs/reference/static-functions/functions/row_getIsSomeSelected.md b/docs/reference/static-functions/functions/row_getIsSomeSelected.md index fa1a80d408..a01212632e 100644 --- a/docs/reference/static-functions/functions/row_getIsSomeSelected.md +++ b/docs/reference/static-functions/functions/row_getIsSomeSelected.md @@ -9,7 +9,7 @@ title: row_getIsSomeSelected function row_getIsSomeSelected(row): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:553](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L553) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:557](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L557) Checks whether some, but not all, selectable descendants are selected. diff --git a/docs/reference/static-functions/functions/row_getLeafRows.md b/docs/reference/static-functions/functions/row_getLeafRows.md index 4ebccfdd82..2472036d84 100644 --- a/docs/reference/static-functions/functions/row_getLeafRows.md +++ b/docs/reference/static-functions/functions/row_getLeafRows.md @@ -9,7 +9,7 @@ title: row_getLeafRows function row_getLeafRows(row): Row[]; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L163) +Defined in: [core/rows/coreRowsFeature.utils.ts:164](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L164) Flattens this row's descendant tree into leaf rows. diff --git a/docs/reference/static-functions/functions/row_getParentRow.md b/docs/reference/static-functions/functions/row_getParentRow.md index 0d576071cc..656422d100 100644 --- a/docs/reference/static-functions/functions/row_getParentRow.md +++ b/docs/reference/static-functions/functions/row_getParentRow.md @@ -11,7 +11,7 @@ function row_getParentRow(row): | undefined; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:199](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L199) +Defined in: [core/rows/coreRowsFeature.utils.ts:200](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L200) Looks up this row's direct parent, if it has one. diff --git a/docs/reference/static-functions/functions/row_getParentRows.md b/docs/reference/static-functions/functions/row_getParentRows.md index 9508797771..8266afb58d 100644 --- a/docs/reference/static-functions/functions/row_getParentRows.md +++ b/docs/reference/static-functions/functions/row_getParentRows.md @@ -9,7 +9,7 @@ title: row_getParentRows function row_getParentRows(row): Row[]; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:223](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L223) +Defined in: [core/rows/coreRowsFeature.utils.ts:224](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L224) Collects this row's ancestor chain from root to direct parent. diff --git a/docs/reference/static-functions/functions/row_getToggleSelectedHandler.md b/docs/reference/static-functions/functions/row_getToggleSelectedHandler.md index 65756af575..fa5dd4a208 100644 --- a/docs/reference/static-functions/functions/row_getToggleSelectedHandler.md +++ b/docs/reference/static-functions/functions/row_getToggleSelectedHandler.md @@ -9,7 +9,7 @@ title: row_getToggleSelectedHandler function row_getToggleSelectedHandler(row, opts?): (e) => void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:660](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L660) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:664](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L664) Creates a checkbox-style handler that selects or deselects this row. diff --git a/docs/reference/static-functions/functions/row_getUniqueValues.md b/docs/reference/static-functions/functions/row_getUniqueValues.md index f9e7fa9d82..32406c9998 100644 --- a/docs/reference/static-functions/functions/row_getUniqueValues.md +++ b/docs/reference/static-functions/functions/row_getUniqueValues.md @@ -9,7 +9,7 @@ title: row_getUniqueValues function row_getUniqueValues(row, columnId): unknown; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L108) +Defined in: [core/rows/coreRowsFeature.utils.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L109) Reads and caches the values used by faceting/grouping for a column. diff --git a/docs/reference/static-functions/functions/row_getValue.md b/docs/reference/static-functions/functions/row_getValue.md index e2a167117d..d8503b4851 100644 --- a/docs/reference/static-functions/functions/row_getValue.md +++ b/docs/reference/static-functions/functions/row_getValue.md @@ -9,7 +9,7 @@ title: row_getValue function row_getValue(row, columnId): unknown; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L78) +Defined in: [core/rows/coreRowsFeature.utils.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L79) Reads and caches this row's value for a column. diff --git a/docs/reference/static-functions/functions/row_renderValue.md b/docs/reference/static-functions/functions/row_renderValue.md index 7ff2291498..b90b7cd53b 100644 --- a/docs/reference/static-functions/functions/row_renderValue.md +++ b/docs/reference/static-functions/functions/row_renderValue.md @@ -9,7 +9,7 @@ title: row_renderValue function row_renderValue(row, columnId): any; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:146](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L146) +Defined in: [core/rows/coreRowsFeature.utils.ts:147](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L147) Returns a renderable row value for a column. diff --git a/docs/reference/static-functions/functions/row_toggleSelected.md b/docs/reference/static-functions/functions/row_toggleSelected.md index b971b2c05d..55d56080ee 100644 --- a/docs/reference/static-functions/functions/row_toggleSelected.md +++ b/docs/reference/static-functions/functions/row_toggleSelected.md @@ -12,7 +12,7 @@ function row_toggleSelected( opts?): void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:502](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L502) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:506](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L506) Selects or deselects this row. diff --git a/docs/reference/static-functions/functions/selectRowsFn.md b/docs/reference/static-functions/functions/selectRowsFn.md index d509066a84..bb7edbbc47 100644 --- a/docs/reference/static-functions/functions/selectRowsFn.md +++ b/docs/reference/static-functions/functions/selectRowsFn.md @@ -9,7 +9,7 @@ title: selectRowsFn function selectRowsFn(rowModel, table): RowModel; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:807](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L807) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:857](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L857) Builds a row model containing rows selected by the current row selection state. diff --git a/docs/reference/static-functions/functions/table_getAllColumns.md b/docs/reference/static-functions/functions/table_getAllColumns.md index 1948b68a8a..c5f73ea4c5 100644 --- a/docs/reference/static-functions/functions/table_getAllColumns.md +++ b/docs/reference/static-functions/functions/table_getAllColumns.md @@ -9,7 +9,7 @@ title: table_getAllColumns function table_getAllColumns(table): Column[]; ``` -Defined in: [core/columns/coreColumnsFeature.utils.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L120) +Defined in: [core/columns/coreColumnsFeature.utils.ts:155](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L155) Normalizes `options.columns` into the table's nested column tree. diff --git a/docs/reference/static-functions/functions/table_getAllFlatColumns.md b/docs/reference/static-functions/functions/table_getAllFlatColumns.md index cba41c9224..97ff3a9a10 100644 --- a/docs/reference/static-functions/functions/table_getAllFlatColumns.md +++ b/docs/reference/static-functions/functions/table_getAllFlatColumns.md @@ -9,7 +9,7 @@ title: table_getAllFlatColumns function table_getAllFlatColumns(table): Column[]; ``` -Defined in: [core/columns/coreColumnsFeature.utils.ts:162](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L162) +Defined in: [core/columns/coreColumnsFeature.utils.ts:175](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L175) Flattens every table column, including group columns and leaf columns. diff --git a/docs/reference/static-functions/functions/table_getAllFlatColumnsById.md b/docs/reference/static-functions/functions/table_getAllFlatColumnsById.md index da8f8ddebd..6d722fb91b 100644 --- a/docs/reference/static-functions/functions/table_getAllFlatColumnsById.md +++ b/docs/reference/static-functions/functions/table_getAllFlatColumnsById.md @@ -9,7 +9,7 @@ title: table_getAllFlatColumnsById function table_getAllFlatColumnsById(table): Record>; ``` -Defined in: [core/columns/coreColumnsFeature.utils.ts:182](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L182) +Defined in: [core/columns/coreColumnsFeature.utils.ts:195](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L195) Builds an id lookup for every flat column in the table. diff --git a/docs/reference/static-functions/functions/table_getAllLeafColumns.md b/docs/reference/static-functions/functions/table_getAllLeafColumns.md index c787e828df..ceaaa9e29c 100644 --- a/docs/reference/static-functions/functions/table_getAllLeafColumns.md +++ b/docs/reference/static-functions/functions/table_getAllLeafColumns.md @@ -9,7 +9,7 @@ title: table_getAllLeafColumns function table_getAllLeafColumns(table): Column[]; ``` -Defined in: [core/columns/coreColumnsFeature.utils.ts:208](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L208) +Defined in: [core/columns/coreColumnsFeature.utils.ts:221](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L221) Collects all terminal leaf columns in their current table order. diff --git a/docs/reference/static-functions/functions/table_getAllLeafColumnsById.md b/docs/reference/static-functions/functions/table_getAllLeafColumnsById.md index 4f394e6701..d2f32eda6f 100644 --- a/docs/reference/static-functions/functions/table_getAllLeafColumnsById.md +++ b/docs/reference/static-functions/functions/table_getAllLeafColumnsById.md @@ -9,7 +9,7 @@ title: table_getAllLeafColumnsById function table_getAllLeafColumnsById(table): Record>; ``` -Defined in: [core/columns/coreColumnsFeature.utils.ts:235](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L235) +Defined in: [core/columns/coreColumnsFeature.utils.ts:248](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L248) Builds an id lookup for terminal leaf columns only. diff --git a/docs/reference/static-functions/functions/table_getCenterTotalSize.md b/docs/reference/static-functions/functions/table_getCenterTotalSize.md index 844253af9a..22f8379b99 100644 --- a/docs/reference/static-functions/functions/table_getCenterTotalSize.md +++ b/docs/reference/static-functions/functions/table_getCenterTotalSize.md @@ -9,7 +9,7 @@ title: table_getCenterTotalSize function table_getCenterTotalSize(table): number; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:424](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L424) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:428](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L428) Sums the rendered size of the center, unpinned header region. diff --git a/docs/reference/static-functions/functions/table_getColumn.md b/docs/reference/static-functions/functions/table_getColumn.md index 84008f7ba7..236e91eba0 100644 --- a/docs/reference/static-functions/functions/table_getColumn.md +++ b/docs/reference/static-functions/functions/table_getColumn.md @@ -11,7 +11,7 @@ function table_getColumn(table, columnId): | undefined; ``` -Defined in: [core/columns/coreColumnsFeature.utils.ts:261](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L261) +Defined in: [core/columns/coreColumnsFeature.utils.ts:274](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L274) Looks up a column by id from the flat column map. diff --git a/docs/reference/static-functions/functions/table_getEndTotalSize.md b/docs/reference/static-functions/functions/table_getEndTotalSize.md index b677204375..021a1eefdb 100644 --- a/docs/reference/static-functions/functions/table_getEndTotalSize.md +++ b/docs/reference/static-functions/functions/table_getEndTotalSize.md @@ -9,7 +9,7 @@ title: table_getEndTotalSize function table_getEndTotalSize(table): number; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:449](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L449) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:453](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L453) Sums the rendered size of the logical end pinned header region. diff --git a/docs/reference/static-functions/functions/table_getFilteredSelectedRowModel.md b/docs/reference/static-functions/functions/table_getFilteredSelectedRowModel.md index d6b450620d..c510d1a588 100644 --- a/docs/reference/static-functions/functions/table_getFilteredSelectedRowModel.md +++ b/docs/reference/static-functions/functions/table_getFilteredSelectedRowModel.md @@ -15,7 +15,7 @@ function table_getFilteredSelectedRowModel(table): }; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:256](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L256) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:260](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L260) Builds a row model containing selected rows from the filtered row model. diff --git a/docs/reference/static-functions/functions/table_getFlatHeaders.md b/docs/reference/static-functions/functions/table_getFlatHeaders.md index 54d1e90cb7..9921e1bd89 100644 --- a/docs/reference/static-functions/functions/table_getFlatHeaders.md +++ b/docs/reference/static-functions/functions/table_getFlatHeaders.md @@ -9,7 +9,7 @@ title: table_getFlatHeaders function table_getFlatHeaders(table): Header[]; ``` -Defined in: [core/headers/coreHeadersFeature.utils.ts:160](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L160) +Defined in: [core/headers/coreHeadersFeature.utils.ts:168](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L168) Flattens every header from every header group into one array. diff --git a/docs/reference/static-functions/functions/table_getFooterGroups.md b/docs/reference/static-functions/functions/table_getFooterGroups.md index dc36974637..5ac22c1c7c 100644 --- a/docs/reference/static-functions/functions/table_getFooterGroups.md +++ b/docs/reference/static-functions/functions/table_getFooterGroups.md @@ -9,7 +9,7 @@ title: table_getFooterGroups function table_getFooterGroups(table): HeaderGroup[]; ``` -Defined in: [core/headers/coreHeadersFeature.utils.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L141) +Defined in: [core/headers/coreHeadersFeature.utils.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L149) Builds footer groups by reversing the current header groups. diff --git a/docs/reference/static-functions/functions/table_getGroupedSelectedRowModel.md b/docs/reference/static-functions/functions/table_getGroupedSelectedRowModel.md index 4f92225830..671cfd070e 100644 --- a/docs/reference/static-functions/functions/table_getGroupedSelectedRowModel.md +++ b/docs/reference/static-functions/functions/table_getGroupedSelectedRowModel.md @@ -15,7 +15,7 @@ function table_getGroupedSelectedRowModel(table): }; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:290](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L290) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:294](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L294) Builds a row model containing selected rows from the grouped row model. diff --git a/docs/reference/static-functions/functions/table_getHeaderGroups.md b/docs/reference/static-functions/functions/table_getHeaderGroups.md index 835a03d284..13288adb9b 100644 --- a/docs/reference/static-functions/functions/table_getHeaderGroups.md +++ b/docs/reference/static-functions/functions/table_getHeaderGroups.md @@ -9,7 +9,7 @@ title: table_getHeaderGroups function table_getHeaderGroups(table): HeaderGroup[]; ``` -Defined in: [core/headers/coreHeadersFeature.utils.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L77) +Defined in: [core/headers/coreHeadersFeature.utils.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L85) Builds visible header groups for the current column tree. diff --git a/docs/reference/static-functions/functions/table_getIsAllPageRowsSelected.md b/docs/reference/static-functions/functions/table_getIsAllPageRowsSelected.md index 14f61bac64..d1c4b9be8f 100644 --- a/docs/reference/static-functions/functions/table_getIsAllPageRowsSelected.md +++ b/docs/reference/static-functions/functions/table_getIsAllPageRowsSelected.md @@ -9,7 +9,7 @@ title: table_getIsAllPageRowsSelected function table_getIsAllPageRowsSelected(table): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:375](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L375) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:379](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L379) Checks whether every selectable row on the current page is selected. diff --git a/docs/reference/static-functions/functions/table_getIsAllRowsSelected.md b/docs/reference/static-functions/functions/table_getIsAllRowsSelected.md index 94407980a9..a5689b40e1 100644 --- a/docs/reference/static-functions/functions/table_getIsAllRowsSelected.md +++ b/docs/reference/static-functions/functions/table_getIsAllRowsSelected.md @@ -9,7 +9,7 @@ title: table_getIsAllRowsSelected function table_getIsAllRowsSelected(table): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:341](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L341) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:345](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L345) Checks whether every selectable filtered row is selected. diff --git a/docs/reference/static-functions/functions/table_getIsSomePageRowsSelected.md b/docs/reference/static-functions/functions/table_getIsSomePageRowsSelected.md index 11b4674ed6..92467aec5e 100644 --- a/docs/reference/static-functions/functions/table_getIsSomePageRowsSelected.md +++ b/docs/reference/static-functions/functions/table_getIsSomePageRowsSelected.md @@ -9,7 +9,7 @@ title: table_getIsSomePageRowsSelected function table_getIsSomePageRowsSelected(table): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:424](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L424) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:428](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L428) Checks whether the current page has a partial selection. diff --git a/docs/reference/static-functions/functions/table_getIsSomeRowsSelected.md b/docs/reference/static-functions/functions/table_getIsSomeRowsSelected.md index a1a03bad8e..e2fbedea1d 100644 --- a/docs/reference/static-functions/functions/table_getIsSomeRowsSelected.md +++ b/docs/reference/static-functions/functions/table_getIsSomeRowsSelected.md @@ -9,7 +9,7 @@ title: table_getIsSomeRowsSelected function table_getIsSomeRowsSelected(table): boolean; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:406](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L406) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:410](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L410) Checks whether selection is partially applied across filtered rows. diff --git a/docs/reference/static-functions/functions/table_getLeafHeaders.md b/docs/reference/static-functions/functions/table_getLeafHeaders.md index ae4bcbcb77..3769db8731 100644 --- a/docs/reference/static-functions/functions/table_getLeafHeaders.md +++ b/docs/reference/static-functions/functions/table_getLeafHeaders.md @@ -9,7 +9,7 @@ title: table_getLeafHeaders function table_getLeafHeaders(table): Header[]; ``` -Defined in: [core/headers/coreHeadersFeature.utils.ts:186](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L186) +Defined in: [core/headers/coreHeadersFeature.utils.ts:194](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L194) Collects only the leaf headers from the current header tree. diff --git a/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md b/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md index 33294beb28..31567a5b61 100644 --- a/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md +++ b/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md @@ -9,7 +9,7 @@ title: table_getMaxSubRowDepth function table_getMaxSubRowDepth(table): number; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:174](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L174) +Defined in: [core/rows/coreRowsFeature.utils.ts:175](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L175) Returns the deepest structural row depth in the core row model. Root rows are depth `0`, their direct sub-rows are depth `1`, and so on. diff --git a/docs/reference/static-functions/functions/table_getPreSelectedRowModel.md b/docs/reference/static-functions/functions/table_getPreSelectedRowModel.md index 1c607f7e44..dc2ef0574c 100644 --- a/docs/reference/static-functions/functions/table_getPreSelectedRowModel.md +++ b/docs/reference/static-functions/functions/table_getPreSelectedRowModel.md @@ -9,7 +9,7 @@ title: table_getPreSelectedRowModel function table_getPreSelectedRowModel(table): RowModel; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:204](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L204) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:208](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L208) Reads the row model before row selection is projected into selected rows. diff --git a/docs/reference/static-functions/functions/table_getRow.md b/docs/reference/static-functions/functions/table_getRow.md index 378ed7708c..0ac600bc6f 100644 --- a/docs/reference/static-functions/functions/table_getRow.md +++ b/docs/reference/static-functions/functions/table_getRow.md @@ -12,7 +12,7 @@ function table_getRow( searchAll?): Row; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:336](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L336) +Defined in: [core/rows/coreRowsFeature.utils.ts:337](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L337) Looks up a row by id from the current or full row model. diff --git a/docs/reference/static-functions/functions/table_getRowId.md b/docs/reference/static-functions/functions/table_getRowId.md index 495363bdc2..9c3b38c6d8 100644 --- a/docs/reference/static-functions/functions/table_getRowId.md +++ b/docs/reference/static-functions/functions/table_getRowId.md @@ -13,7 +13,7 @@ function table_getRowId( parent?): string; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:310](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L310) +Defined in: [core/rows/coreRowsFeature.utils.ts:311](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L311) Resolves the stable id for a row. diff --git a/docs/reference/static-functions/functions/table_getRowsInDisplayOrder.md b/docs/reference/static-functions/functions/table_getRowsInDisplayOrder.md index fdc93bbcde..499d400141 100644 --- a/docs/reference/static-functions/functions/table_getRowsInDisplayOrder.md +++ b/docs/reference/static-functions/functions/table_getRowsInDisplayOrder.md @@ -9,7 +9,7 @@ title: table_getRowsInDisplayOrder function table_getRowsInDisplayOrder(table): Row[]; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L32) +Defined in: [core/rows/coreRowsFeature.utils.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L33) Returns the rows in the current display order after assigning their zero-based display indexes. diff --git a/docs/reference/static-functions/functions/table_getSelectedRowIds.md b/docs/reference/static-functions/functions/table_getSelectedRowIds.md index be1e8f0a50..3da4cd2f4d 100644 --- a/docs/reference/static-functions/functions/table_getSelectedRowIds.md +++ b/docs/reference/static-functions/functions/table_getSelectedRowIds.md @@ -9,7 +9,7 @@ title: table_getSelectedRowIds function table_getSelectedRowIds(table): string[]; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:323](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L323) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:327](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L327) Returns the ids of all selected rows. diff --git a/docs/reference/static-functions/functions/table_getSelectedRowModel.md b/docs/reference/static-functions/functions/table_getSelectedRowModel.md index 6032ad5231..c7a243eaf7 100644 --- a/docs/reference/static-functions/functions/table_getSelectedRowModel.md +++ b/docs/reference/static-functions/functions/table_getSelectedRowModel.md @@ -15,7 +15,7 @@ function table_getSelectedRowModel(table): }; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:222](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L222) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:226](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L226) Builds a row model containing selected rows from the core row model. diff --git a/docs/reference/static-functions/functions/table_getStartTotalSize.md b/docs/reference/static-functions/functions/table_getStartTotalSize.md index ff23939c93..ade24cf29b 100644 --- a/docs/reference/static-functions/functions/table_getStartTotalSize.md +++ b/docs/reference/static-functions/functions/table_getStartTotalSize.md @@ -9,7 +9,7 @@ title: table_getStartTotalSize function table_getStartTotalSize(table): number; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:399](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L399) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:403](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L403) Sums the rendered size of the logical start pinned header region. diff --git a/docs/reference/static-functions/functions/table_getToggleAllPageRowsSelectedHandler.md b/docs/reference/static-functions/functions/table_getToggleAllPageRowsSelectedHandler.md index b5b2fe8fec..bc0f272cf9 100644 --- a/docs/reference/static-functions/functions/table_getToggleAllPageRowsSelectedHandler.md +++ b/docs/reference/static-functions/functions/table_getToggleAllPageRowsSelectedHandler.md @@ -9,7 +9,7 @@ title: table_getToggleAllPageRowsSelectedHandler function table_getToggleAllPageRowsSelectedHandler(table): (e) => void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:472](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L472) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:476](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L476) Creates a checkbox-style handler that selects or deselects current page rows. diff --git a/docs/reference/static-functions/functions/table_getToggleAllRowsSelectedHandler.md b/docs/reference/static-functions/functions/table_getToggleAllRowsSelectedHandler.md index 5278e63fa1..d7c63aa1d6 100644 --- a/docs/reference/static-functions/functions/table_getToggleAllRowsSelectedHandler.md +++ b/docs/reference/static-functions/functions/table_getToggleAllRowsSelectedHandler.md @@ -9,7 +9,7 @@ title: table_getToggleAllRowsSelectedHandler function table_getToggleAllRowsSelectedHandler(table): (e) => void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:449](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L449) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:453](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L453) Creates a checkbox-style handler that selects or deselects all rows. diff --git a/docs/reference/static-functions/functions/table_getTotalSize.md b/docs/reference/static-functions/functions/table_getTotalSize.md index 27413ddc98..d85f2ee5ee 100644 --- a/docs/reference/static-functions/functions/table_getTotalSize.md +++ b/docs/reference/static-functions/functions/table_getTotalSize.md @@ -9,7 +9,7 @@ title: table_getTotalSize function table_getTotalSize(table): number; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:378](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L378) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:382](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L382) Sums the rendered size of the full table header row. diff --git a/docs/reference/static-functions/functions/table_mergeOptions.md b/docs/reference/static-functions/functions/table_mergeOptions.md index d5bec237d7..94f4ab6e7a 100644 --- a/docs/reference/static-functions/functions/table_mergeOptions.md +++ b/docs/reference/static-functions/functions/table_mergeOptions.md @@ -9,7 +9,7 @@ title: table_mergeOptions function table_mergeOptions(table, newOptions): TableOptions; ``` -Defined in: [core/table/coreTablesFeature.utils.ts:86](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L86) +Defined in: [core/table/coreTablesFeature.utils.ts:132](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L132) Merges new table options with the current resolved options. diff --git a/docs/reference/static-functions/functions/table_publishExternalState.md b/docs/reference/static-functions/functions/table_publishExternalState.md new file mode 100644 index 0000000000..d994e056a5 --- /dev/null +++ b/docs/reference/static-functions/functions/table_publishExternalState.md @@ -0,0 +1,54 @@ +--- +id: table_publishExternalState +title: table_publishExternalState +--- + +# Function: table\_publishExternalState() + +```ts +function table_publishExternalState( + table, + state, + compare, + commitToken?): void; +``` + +Defined in: [core/table/coreTablesFeature.utils.ts:70](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L70) + +Publishes captured controlled state after a host framework commits. + +Render-phase adapters stage options without synchronizing base atoms, then +pass the state captured by the committed render here. The commit signal also +invalidates ownership changes when no base atom was written. + +## Type Parameters + +### TFeatures + +`TFeatures` *extends* [`TableFeatures`](../../index/interfaces/TableFeatures.md) + +### TData + +`TData` *extends* [`RowData`](../../index/type-aliases/RowData.md) + +## Parameters + +### table + +[`Table_Internal`](../../index/interfaces/Table_Internal.md)\<`TFeatures`, `TData`\> + +### state + +`Partial`\<[`TableState`](../../index/type-aliases/TableState.md)\<`TFeatures`\>\> | `null` + +### compare + +(`currentState`, `externalState`) => `boolean` + +### commitToken? + +`number` + +## Returns + +`void` diff --git a/docs/reference/static-functions/functions/table_reset.md b/docs/reference/static-functions/functions/table_reset.md index ec07464dc7..a82a796daa 100644 --- a/docs/reference/static-functions/functions/table_reset.md +++ b/docs/reference/static-functions/functions/table_reset.md @@ -9,7 +9,7 @@ title: table_reset function table_reset(table): void; ``` -Defined in: [core/table/coreTablesFeature.utils.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L54) +Defined in: [core/table/coreTablesFeature.utils.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L100) Resets all internal table base atoms to `table.initialState`, then clears transient instance data through registered feature reset hooks. diff --git a/docs/reference/static-functions/functions/table_resetColumnSizing.md b/docs/reference/static-functions/functions/table_resetColumnSizing.md index 0ac96277e3..af979c7427 100644 --- a/docs/reference/static-functions/functions/table_resetColumnSizing.md +++ b/docs/reference/static-functions/functions/table_resetColumnSizing.md @@ -9,7 +9,7 @@ title: table_resetColumnSizing function table_resetColumnSizing(table, defaultState?): void; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:353](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L353) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:357](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L357) Resets `columnSizing` to the configured initial state or feature default. diff --git a/docs/reference/static-functions/functions/table_resetRowSelection.md b/docs/reference/static-functions/functions/table_resetRowSelection.md index 51e0b9ced9..3e345abe23 100644 --- a/docs/reference/static-functions/functions/table_resetRowSelection.md +++ b/docs/reference/static-functions/functions/table_resetRowSelection.md @@ -9,7 +9,7 @@ title: table_resetRowSelection function table_resetRowSelection(table, defaultState?): void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L68) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L72) Resets `rowSelection` to the configured initial state or feature default. diff --git a/docs/reference/static-functions/functions/table_setColumnSizing.md b/docs/reference/static-functions/functions/table_setColumnSizing.md index 921e2596d4..5f024f2bb0 100644 --- a/docs/reference/static-functions/functions/table_setColumnSizing.md +++ b/docs/reference/static-functions/functions/table_setColumnSizing.md @@ -9,7 +9,7 @@ title: table_setColumnSizing function table_setColumnSizing(table, updater): void; ``` -Defined in: [features/column-sizing/columnSizingFeature.utils.ts:331](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L331) +Defined in: [features/column-sizing/columnSizingFeature.utils.ts:335](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L335) Routes a committed column sizing updater through the table's sizing handler. diff --git a/docs/reference/static-functions/functions/table_setOptions.md b/docs/reference/static-functions/functions/table_setOptions.md index 4ca8ba7278..cad789f7b4 100644 --- a/docs/reference/static-functions/functions/table_setOptions.md +++ b/docs/reference/static-functions/functions/table_setOptions.md @@ -6,10 +6,13 @@ title: table_setOptions # Function: table\_setOptions() ```ts -function table_setOptions(table, updater): void; +function table_setOptions( + table, + updater, + options?): number | undefined; ``` -Defined in: [core/table/coreTablesFeature.utils.ts:152](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L152) +Defined in: [core/table/coreTablesFeature.utils.ts:203](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L203) Updates the table options object. @@ -36,12 +39,19 @@ immediately assigned to the table instance. [`Updater`](../../index/type-aliases/Updater.md)\<[`TableOptions`](../../index/type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>\> +### options? + +#### syncExternalState? + +`boolean` + ## Returns -`void` +`number` \| `undefined` ## Example ```ts table_setOptions(table, (old) => old) +table_setOptions(table, (old) => old, { syncExternalState: false }) ``` diff --git a/docs/reference/static-functions/functions/table_setRowSelection.md b/docs/reference/static-functions/functions/table_setRowSelection.md index 3a95259cbf..3821cbcac2 100644 --- a/docs/reference/static-functions/functions/table_setRowSelection.md +++ b/docs/reference/static-functions/functions/table_setRowSelection.md @@ -9,7 +9,7 @@ title: table_setRowSelection function table_setRowSelection(table, updater): void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L46) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L50) Routes a row selection updater through the table's selection change handler. diff --git a/docs/reference/static-functions/functions/table_syncExternalStateToBaseAtoms.md b/docs/reference/static-functions/functions/table_syncExternalStateToBaseAtoms.md index c3a8961ebd..c3c307b743 100644 --- a/docs/reference/static-functions/functions/table_syncExternalStateToBaseAtoms.md +++ b/docs/reference/static-functions/functions/table_syncExternalStateToBaseAtoms.md @@ -6,15 +6,26 @@ title: table_syncExternalStateToBaseAtoms # Function: table\_syncExternalStateToBaseAtoms() ```ts -function table_syncExternalStateToBaseAtoms(table): void; +function table_syncExternalStateToBaseAtoms( + table, + capturedState?, + compare?): void; ``` -Defined in: [core/table/coreTablesFeature.utils.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L18) +Defined in: [core/table/coreTablesFeature.utils.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L29) Synchronizes externally controlled state slices into the table's base atoms. -This keeps legacy `options.state` values reflected in the atom graph so -derived atoms, stores, and table APIs read a consistent snapshot. +This keeps `options.state` values mirrored in the atom graph so derived +atoms, stores, and table APIs read a consistent snapshot. + +Adapters that update options during their host's render phase pass the +state snapshot captured by the committed render as `capturedState` — the +shared options object may already hold values from a newer render that +never commits. Pass `null` to publish nothing (a captured "no controlled +state"); omitting the argument reads the current `table.options.state` +instead. An optional `compare` suppresses semantically unchanged slice +writes; the default remains reference equality. ## Type Parameters @@ -32,6 +43,14 @@ derived atoms, stores, and table APIs read a consistent snapshot. [`Table_Internal`](../../index/interfaces/Table_Internal.md)\<`TFeatures`, `TData`\> +### capturedState? + +`Partial`\<[`TableState`](../../index/type-aliases/TableState.md)\<`TFeatures`\>\> | `null` + +### compare? + +(`currentState`, `externalState`) => `boolean` + ## Returns `void` @@ -40,4 +59,5 @@ derived atoms, stores, and table APIs read a consistent snapshot. ```ts table_syncExternalStateToBaseAtoms(table) +table_syncExternalStateToBaseAtoms(table, capturedState ?? null, shallow) ``` diff --git a/docs/reference/static-functions/functions/table_toggleAllPageRowsSelected.md b/docs/reference/static-functions/functions/table_toggleAllPageRowsSelected.md index d746770b17..200cedde88 100644 --- a/docs/reference/static-functions/functions/table_toggleAllPageRowsSelected.md +++ b/docs/reference/static-functions/functions/table_toggleAllPageRowsSelected.md @@ -12,7 +12,7 @@ function table_toggleAllPageRowsSelected( opts?): void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:155](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L155) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:159](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L159) Selects or deselects every selectable row on the current page. diff --git a/docs/reference/static-functions/functions/table_toggleAllRowsSelected.md b/docs/reference/static-functions/functions/table_toggleAllRowsSelected.md index 975c733b69..e82d81ac46 100644 --- a/docs/reference/static-functions/functions/table_toggleAllRowsSelected.md +++ b/docs/reference/static-functions/functions/table_toggleAllRowsSelected.md @@ -12,7 +12,7 @@ function table_toggleAllRowsSelected( opts?): void; ``` -Defined in: [features/row-selection/rowSelectionFeature.utils.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L98) +Defined in: [features/row-selection/rowSelectionFeature.utils.ts:102](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L102) Selects or deselects every selectable row before grouping. diff --git a/docs/reference/static-functions/index.md b/docs/reference/static-functions/index.md index b5ca28f5cb..930ee30025 100644 --- a/docs/reference/static-functions/index.md +++ b/docs/reference/static-functions/index.md @@ -241,6 +241,7 @@ title: static-functions - [table\_moveCellSelection](functions/table_moveCellSelection.md) - [table\_nextPage](functions/table_nextPage.md) - [table\_previousPage](functions/table_previousPage.md) +- [table\_publishExternalState](functions/table_publishExternalState.md) - [table\_reset](functions/table_reset.md) - [table\_resetCellSelection](functions/table_resetCellSelection.md) - [table\_resetColumnFilters](functions/table_resetColumnFilters.md) diff --git a/packages/alpine-table/src/createTable.ts b/packages/alpine-table/src/createTable.ts index 67b287b6c6..0f002c62c4 100644 --- a/packages/alpine-table/src/createTable.ts +++ b/packages/alpine-table/src/createTable.ts @@ -99,11 +99,11 @@ export function createTable< // inside the effect registers the dependencies, so the effect re-runs when // they change and re-applies the live values via `setOptions`. // - // `setOptions` writes to the options store, not the state store, so a `data` - // (or other option) change does not emit on `table.store` and would not bump + // `setOptions` writes option atoms, not the state store, so a `data` (or + // other option) change does not emit on `table.store` and would not bump // `_ver` on its own. We bump `_ver` here so the template re-pulls derived - // APIs like `getRowModel()`, which recompute from the new options. The effect - // never reads `_ver`, so writing it does not re-trigger this effect. + // APIs like `getRowModel()`. The effect never reads `_ver`, so writing it + // does not re-trigger this effect. let initialized = false Alpine.effect(() => { const state = tableOptions.state as Record | undefined @@ -168,6 +168,21 @@ export function createTable< } const resolvedValue = Reflect.get(target, prop, receiver) + const descriptor = Reflect.getOwnPropertyDescriptor(target, prop) + + // A Proxy must return the exact value of a non-configurable, + // non-writable data property. Core exposes options and optionAtoms this + // way, which also means callback reads preserve their source identity. + // The containing property read still tracks Alpine's version counter. + if ( + descriptor && + !descriptor.configurable && + 'value' in descriptor && + !descriptor.writable + ) { + void reactivity._ver + return resolvedValue + } if (typeof resolvedValue === 'function') { let targetWrappers = wrapperCache.get(target) diff --git a/packages/alpine-table/src/reactivity.ts b/packages/alpine-table/src/reactivity.ts index 2e94e93045..b795beed62 100644 --- a/packages/alpine-table/src/reactivity.ts +++ b/packages/alpine-table/src/reactivity.ts @@ -1,4 +1,5 @@ import { batch, createAtom } from '@tanstack/store' +import { createStableStoreReadonlyAtom } from '@tanstack/table-core/reactivity' import type { TableAtomOptions, TableReactivityBindings, @@ -12,7 +13,6 @@ import type { */ export function alpineReactivity(): TableReactivityBindings { return { - createOptionsStore: true, wrapExternalAtoms: false, addSubscription: () => { throw new Error( @@ -28,7 +28,7 @@ export function alpineReactivity(): TableReactivityBindings { batch, untrack: (fn) => fn(), createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => { - return createAtom(() => fn(), { + return createStableStoreReadonlyAtom(createAtom, fn, { compare: options?.compare, }) }, diff --git a/packages/alpine-table/tests/unit/adapterCoverage.test.ts b/packages/alpine-table/tests/unit/adapterCoverage.test.ts index a60d460bb1..61d796d56c 100644 --- a/packages/alpine-table/tests/unit/adapterCoverage.test.ts +++ b/packages/alpine-table/tests/unit/adapterCoverage.test.ts @@ -225,11 +225,21 @@ describe('Alpine adapter reactivity', () => { }, }) + expect(table.options.onRowSelectionChange).toBe( + table.optionAtoms.onRowSelectionChange!.get(), + ) + table.toggleAllRowsSelected(true) expect(firstHandler).toHaveBeenCalledTimes(1) options.onRowSelectionChange = secondHandler await flushEffects() + + expect(table.options.onRowSelectionChange).toBe(secondHandler) + expect(table.options.onRowSelectionChange).toBe( + table.optionAtoms.onRowSelectionChange!.get(), + ) + table.toggleAllRowsSelected(false) expect(firstHandler).toHaveBeenCalledTimes(1) diff --git a/packages/angular-table/src/injectTable.ts b/packages/angular-table/src/injectTable.ts index 604d5dc348..485b2a97a3 100644 --- a/packages/angular-table/src/injectTable.ts +++ b/packages/angular-table/src/injectTable.ts @@ -105,11 +105,12 @@ export function injectTable< // Explicit type arguments skip generic inference from the spread object // (a type-check hot spot); the spread only adds the angular reactivity // binding to `features`. + const initialOptions = options() const table = constructTable({ - ...options(), + ...initialOptions, features: { coreReactivityFeature: angularReactivity(injector), - ...options().features, + ...initialOptions.features, }, }) diff --git a/packages/angular-table/src/reactivity.ts b/packages/angular-table/src/reactivity.ts index d35e0269ce..6b86e5245a 100644 --- a/packages/angular-table/src/reactivity.ts +++ b/packages/angular-table/src/reactivity.ts @@ -62,17 +62,14 @@ function signalToWritableAtom( /** * Creates the table-core reactivity bindings used by the Angular adapter. * - * Table state atoms are backed by TanStack Store atoms. The options store stays - * framework-native because row-model APIs read `table.options` directly during - * render. Readonly table atoms bridge Store dependency tracking into Angular - * computed signals. + * Table state and option atoms bridge table-core reads into Angular computed + * signals. */ export function angularReactivity(injector: Injector): TableReactivityBindings { const ngZone = injector.get(NgZone) const subscriptions = new Set() return { - createOptionsStore: true, wrapExternalAtoms: true, addSubscription: (subscription) => { subscriptions.add(subscription) diff --git a/packages/ember-table/src/reactivity.ts b/packages/ember-table/src/reactivity.ts index 98355b48b2..99a2a5911c 100644 --- a/packages/ember-table/src/reactivity.ts +++ b/packages/ember-table/src/reactivity.ts @@ -11,7 +11,6 @@ export function emberReactivity(): TableReactivityBindings { const subscriptions = new Set() return { - createOptionsStore: true, wrapExternalAtoms: true, // timing is not important, but the main thing is that the work does *not* @@ -20,8 +19,19 @@ export function emberReactivity(): TableReactivityBindings { batch: (fn) => fn(), untrack, // @cached - createReadonlyAtom: (fn: () => T) => { - return computed(fn) + createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => { + const compare = options?.compare ?? Object.is + let hasStableValue = false + let stableValue: T + + return computed(() => { + const nextValue = fn() + if (!hasStableValue || !compare(stableValue, nextValue)) { + stableValue = nextValue + hasStableValue = true + } + return stableValue + }) }, // @tracked createWritableAtom: (value: T, options?: TableAtomOptions) => { diff --git a/packages/ember-table/src/signal.ts b/packages/ember-table/src/signal.ts index c89373cb2a..f1c7ae275c 100644 --- a/packages/ember-table/src/signal.ts +++ b/packages/ember-table/src/signal.ts @@ -4,7 +4,10 @@ import { tracked, cached } from '@glimmer/tracking' import { untrack } from '@glimmer/validator' export function subscribeNoEffect(): Subscription { - return null as unknown as Subscription + // Glimmer invalidates computed consumers through tags rather than an + // imperative effect API. Still return a valid subscription object so the + // public ReadonlyAtom contract is safe for callers that always unsubscribe. + return { unsubscribe: () => {} } } /** diff --git a/packages/ember-table/src/use-table.ts b/packages/ember-table/src/use-table.ts index e1d02b9cc9..20c070a4c6 100644 --- a/packages/ember-table/src/use-table.ts +++ b/packages/ember-table/src/use-table.ts @@ -12,17 +12,10 @@ import type { } from '@tanstack/table-core' import type { Atom, ReadonlyAtom, ReadonlyStore } from '@tanstack/store' -// Internal table slots used by the pull-based options/state wiring below. +// Internal table slots used by the per-slice state wiring below. // `Table_Internal` is not exported from the table-core build, so the shape is // declared structurally here. -interface TableInternals< - TFeatures extends TableFeatures, - TData extends RowData, -> { - optionsStore?: { - get(): TableOptions - set(value: () => TableOptions): void - } +interface TableInternals { baseAtoms: Record< string, { @@ -33,6 +26,13 @@ interface TableInternals< atoms: Record } +const staticOptionKeys = new Set([ + 'atoms', + 'features', + 'initialState', + 'mergeOptions', +]) + /** * Creates an Ember-reactive table. * @@ -71,6 +71,33 @@ export function useTable< // Untracked to prevent possible "set on same computation as read" errors in Ember. const initialOptions = untrack(() => userOptions.get()) + const imperativeOptionKeys = new Set() + + const mergeOptions = ( + defaultOptions: TableOptions, + newOptions: Partial>, + ) => { + for (const key of Reflect.ownKeys(newOptions)) { + if (staticOptionKeys.has(key)) { + continue + } + + const currentHasKey = Reflect.has(defaultOptions, key) + const nextValue = Reflect.get(newOptions, key, newOptions) as unknown + const currentValue = currentHasKey + ? (Reflect.get(defaultOptions, key, defaultOptions) as unknown) + : undefined + + if (!currentHasKey || !Object.is(currentValue, nextValue)) { + imperativeOptionKeys.add(key) + } + } + + return { + ...defaultOptions, + ...newOptions, + } + } const table = constructTable({ ...initialOptions, @@ -78,80 +105,46 @@ export function useTable< coreReactivityFeature: reactivity, ...initialOptions.features, }, - mergeOptions: ( - defaultOptions: TableOptions, - newOptions: Partial>, - ) => ({ - ...defaultOptions, - ...newOptions, - }), - }) as Table & TableInternals + mergeOptions, + }) as Table & TableInternals + + // Keep Ember-specific getter tracking in the adapter. Core option atoms only + // store resolved values; these wrappers read the latest tracked user option + // until an imperative setOptions/optionAtoms write takes ownership. + for (const key of Reflect.ownKeys(table.optionAtoms)) { + if (key === 'snapshotVersion' || staticOptionKeys.has(key)) { + continue + } - const optionsStore = table.optionsStore! + const coreAtom = table.optionAtoms[ + key as keyof typeof table.optionAtoms + ] as Atom + const trackedAtom = { + get: () => { + if (imperativeOptionKeys.has(key)) { + return coreAtom.get() + } - const liveOptions = computed(() => { - const stored = optionsStore.get() - return { - ...stored, - ...userOptions.get(), - // stored options carry construct-time normalization (the reactivity - // feature, wrapped external atoms) that must win over the raw user - // options. - features: stored.features, - atoms: stored.atoms, + const currentOptions = userOptions.get() + return Reflect.has(currentOptions, key) + ? Reflect.get(currentOptions, key, currentOptions) + : coreAtom.get() + }, + subscribe: coreAtom.subscribe.bind(coreAtom), + set: coreAtom.set.bind(coreAtom), } - }) - - const getLiveOptions = () => liveOptions.get() - /** - * This is to get around core table not using lazy access so we need to re-wrap - * - * Similar to other reactive signal frameworks (solid, angular, svelte) - */ - Object.defineProperty(table, 'options', { - configurable: true, - enumerable: true, - get: getLiveOptions, - set: (value: TableOptions) => { - optionsStore.set(() => value) - }, - }) + Object.defineProperty(table.optionAtoms, key, { + configurable: true, + enumerable: true, + value: trackedAtom, + writable: false, + }) + } const atoms: Record> = table.atoms const stateKeys = Object.keys(table.baseAtoms) - for (const key of stateKeys) { - const baseAtom = (table.baseAtoms as Record>)[ - key - ]! - - /** - * Original atoms could cause effects for top level properties - * - * Core table should migrate to pure derived data which would boost render - * performance for both signal and non-signal frameworks. - */ - atoms[key] = reactivity.createReadonlyAtom( - () => { - const externalAtom = ( - table.options.atoms as Record> | undefined - )?.[key] - if (externalAtom) { - return externalAtom.get() - } - const stateSlice = ( - table.options.state as Record | undefined - )?.[key] - if (stateSlice !== undefined) { - return stateSlice - } - return baseAtom.get() - }, - { debugName: `table/atoms/${key}` }, - ) - } - const stateProxy: TableState = new Proxy( {}, { diff --git a/packages/ember-table/tests/integration/use-table.test.gts b/packages/ember-table/tests/integration/use-table.test.gts index cb06133665..039bb0212b 100644 --- a/packages/ember-table/tests/integration/use-table.test.gts +++ b/packages/ember-table/tests/integration/use-table.test.gts @@ -35,6 +35,23 @@ const keysInclude = (obj: object, key: string): boolean => module('Integration | useTable', function (hooks) { setupRenderingTest(hooks) + test('option atoms return a valid subscription', function (assert) { + const table = useTable(() => ({ + data: makeData(1), + features: stockFeatures, + columns: [], + })) + + const subscription = table.optionAtoms.data.subscribe(() => {}) + + assert.strictEqual( + typeof subscription.unsubscribe, + 'function', + 'callers can always tear down the returned subscription', + ) + subscription.unsubscribe() + }) + test('can initialize with basic no columns or data', async (assert) => { class TableComponent extends Component { @tracked data = [] @@ -123,6 +140,217 @@ module('Integration | useTable', function (hooks) { .exists({ count: 1 }, 'row model re-renders when tracked data changes') }) + test('keeps the central options proxy stable and live', async (assert) => { + class TableComponent extends Component { + @tracked data = makeData(2) + + table = useTable(() => ({ + data: this.data, + features: stockFeatures, + columns: [], + })) + + savedOptions = this.table.options + + get hasSameOptionsReference() { + return this.savedOptions === this.table.options + } + + get savedOptionsDataLength() { + return this.savedOptions.data.length + } + + get optionAtomDataLength() { + return this.table.optionAtoms.data.get().length + } + + shrink = () => { + this.data = makeData(1) + } + + + } + + await render() + + assert + .dom('[data-test-options-identity]') + .hasText('same', 'the adapter leaves core’s stable options proxy intact') + assert + .dom('[data-test-saved-options]') + .hasText('2', 'a saved options reference reads the initial value') + assert + .dom('[data-test-option-atom]') + .hasText('2', 'the option atom reads the initial value') + + await click('[data-test-shrink]') + + assert + .dom('[data-test-options-identity]') + .hasText('same', 'the options proxy identity stays stable after updates') + assert + .dom('[data-test-saved-options]') + .hasText('1', 'the saved options reference remains live') + assert + .dom('[data-test-option-atom]') + .hasText('1', 'the option atom remains live') + }) + + test('imperative option writes override tracked adapter options', async (assert) => { + class TableComponent extends Component { + @tracked data = makeData(3) + + table = useTable(() => ({ + data: this.data, + features: stockFeatures, + columns: [], + })) + + get optionsDataLength() { + return this.table.options.data.length + } + + get optionAtomDataLength() { + return this.table.optionAtoms.data.get().length + } + + setThroughApi = () => { + this.table.setOptions((previous) => ({ + ...previous, + data: makeData(2), + })) + this.data = makeData(5) + } + + setThroughAtom = () => { + this.table.optionAtoms.data.set(makeData(1)) + this.data = makeData(6) + } + + + } + + await render() + + assert.dom('[data-test-options-data]').hasText('3') + assert.dom('[data-test-option-atom-data]').hasText('3') + + await click('[data-test-set-api]') + + assert + .dom('[data-test-options-data]') + .hasText('2', 'setOptions wins over a later tracked option change') + assert.dom('[data-test-option-atom-data]').hasText('2') + + await click('[data-test-set-atom]') + + assert + .dom('[data-test-options-data]') + .hasText('1', 'assignment through the option atom remains visible') + assert.dom('[data-test-option-atom-data]').hasText('1') + }) + + test('setOptions can add option keys after construction', async (assert) => { + class TableComponent extends Component { + @tracked refresh = 0 + + table = useTable(() => ({ + data: makeData(1), + features: stockFeatures, + columns: [], + })) + + get optionValue() { + void this.refresh + return String(this.table.options.debugRows) + } + + get optionAtomValue() { + void this.refresh + return String(this.table.optionAtoms.debugRows?.get()) + } + + get hasOption() { + void this.refresh + return String('debugRows' in this.table.options) + } + + addOption = () => { + this.table.setOptions((previous) => ({ + ...previous, + debugRows: true, + })) + // The key did not exist when the template first rendered, so there was + // no option atom to track yet. The host rerender makes the newly + // created atom visible. + this.refresh++ + } + + + } + + await render() + + assert.dom('[data-test-option-value]').hasText('undefined') + assert.dom('[data-test-option-atom-value]').hasText('undefined') + assert.dom('[data-test-has-option]').hasText('false') + + await click('[data-test-add-option]') + + assert + .dom('[data-test-option-value]') + .hasText('true', 'the live options proxy sees the newly supplied key') + assert + .dom('[data-test-option-atom-value]') + .hasText('true', 'setOptions creates the new option atom') + assert + .dom('[data-test-has-option]') + .hasText('true', 'reflection sees the newly supplied key') + }) + // Ember analog of angular's "in" / "Object.keys" structural tests, expressed // as rendered output since ember's table is a plain object (not a Proxy). test('exposes expected table structure', async (assert) => { diff --git a/packages/lit-table/src/TableController.ts b/packages/lit-table/src/TableController.ts index a3211e74f6..90de69bbb3 100644 --- a/packages/lit-table/src/TableController.ts +++ b/packages/lit-table/src/TableController.ts @@ -137,6 +137,7 @@ export class TableController< private _storeSubscription?: { unsubscribe: () => void } private _capturedState?: Partial> private _capturedSnapshot?: TableState + private _capturedOptionsToken?: number private _hasSelector = false private _latestSelector?: (state: TableState) => unknown private _lastSelected: unknown @@ -165,6 +166,8 @@ export class TableController< tableOptions: TableOptions, selector?: (state: TableState) => TSelected, ): LitTable { + let constructed = false + if (!this._table) { const mergedOptions: TableOptions = { ...tableOptions, @@ -192,18 +195,24 @@ export class TableController< // Set up subscriptions immediately when table is created this._setupSubscriptions() + constructed = true } // Stage current options for same-render table reads. Publication happens - // in hostUpdated() after Lit commits this render. - table_setOptions( - this._table, - (prev) => ({ - ...prev, - ...tableOptions, - }), - { syncExternalState: false }, - ) + // in hostUpdated() after Lit commits this render. Construction already + // installed this render's options, so avoid a redundant first stage: its + // commit would invalidate every render-phase memo after the values that + // produced the committed DOM were already read. + this._capturedOptionsToken = constructed + ? undefined + : table_setOptions( + this._table, + (prev) => ({ + ...prev, + ...tableOptions, + }), + { syncExternalState: false }, + ) this._capturedState = this._table.options.state const renderSnapshot = this._rootSource!.get() @@ -264,6 +273,7 @@ export class TableController< this._table, this._capturedState ?? null, shallow, + this._capturedOptionsToken, ) } diff --git a/packages/lit-table/src/reactivity.ts b/packages/lit-table/src/reactivity.ts index 0aead58a14..9ae3811f18 100644 --- a/packages/lit-table/src/reactivity.ts +++ b/packages/lit-table/src/reactivity.ts @@ -7,13 +7,11 @@ export type LitTableReactivityBindings = RenderPhaseReactivityBindings /** * Creates the table-core reactivity bindings used by the Lit adapter. * - * Lit calls `controller.table(options)` from the host's `render()`, so options - * are plain values synchronized during the update cycle — writing a reactive - * options store there would schedule a second update per interaction. The - * render-phase preset supplies the live readonly-atom facades and the `commit` - * hook; `TableController` publishes its captured controlled state from - * `hostUpdated()`. Store primitives come from `@tanstack/lit-store` so all - * atoms share one store instance with user-provided external atoms. + * Lit calls `controller.table(options)` from the host's `render()`, so option + * atoms are staged without notification during the update cycle. The + * render-phase preset supplies live option facades, cached memo atoms, and the + * commit hook; `TableController` publishes its captured state and option token + * from `hostUpdated()`. Store primitives come from `@tanstack/lit-store`. */ export function litReactivity(): LitTableReactivityBindings { return renderPhaseReactivity({ createAtom, batch }) diff --git a/packages/preact-table/src/Subscribe.ts b/packages/preact-table/src/Subscribe.ts index c8b79480e3..1d6b27d2bc 100644 --- a/packages/preact-table/src/Subscribe.ts +++ b/packages/preact-table/src/Subscribe.ts @@ -36,7 +36,7 @@ export type SubscribePropsWithStore< /** * Subscribe to the full value of a source (e.g. `table.atoms.rowSelection` or - * `table.optionsStore`). Omitting `selector` is equivalent to the identity + * `table.optionAtoms.data`). Omitting `selector` is equivalent to the identity * selector — children receive `TSourceValue`. */ export type SubscribePropsWithSourceIdentity = { diff --git a/packages/preact-table/src/reactivity.ts b/packages/preact-table/src/reactivity.ts index 5fecc253a8..17a9e13e5f 100644 --- a/packages/preact-table/src/reactivity.ts +++ b/packages/preact-table/src/reactivity.ts @@ -7,10 +7,9 @@ export type PreactTableReactivityBindings = RenderPhaseReactivityBindings /** * Creates the table-core reactivity bindings used by the Preact adapter. * - * Preact stores table state in TanStack Store atoms and leaves options as - * plain resolved data because `useTable` synchronizes options during render. - * The render-phase preset supplies the live readonly-atom facades and the - * `commit` hook; the store primitives are passed in from + * Preact synchronizes option atoms during render without publishing them until + * commit. The render-phase preset supplies live option facades, cached memo + * atoms, and the commit hook; the store primitives come from * `@tanstack/preact-store` so all atoms share one store instance with * user-provided external atoms. */ diff --git a/packages/preact-table/src/useTable.ts b/packages/preact-table/src/useTable.ts index 957f0c6fec..9ffe190547 100644 --- a/packages/preact-table/src/useTable.ts +++ b/packages/preact-table/src/useTable.ts @@ -40,8 +40,9 @@ export type PreactTable< /** * A Preact HOC (Higher Order Component) that allows you to subscribe to the table state. * - * Pass `source` to subscribe to a single atom or store (e.g. `table.atoms.rowSelection` - * or `table.optionsStore`) instead of the full `table.store`. + * Pass `source` to subscribe to a single atom or store (e.g. + * `table.atoms.rowSelection` or `table.optionAtoms.data`) instead of the full + * `table.store`. * * @example * ({ rowSelection: state.rowSelection })}> @@ -161,7 +162,7 @@ export function useTable< // Keep options current during render without publishing them to reactive // subscribers. Readonly atoms expose the staged snapshot through live get(). - table_setOptions( + const optionCommitToken = table_setOptions( coreTable, (prev) => ({ ...prev, @@ -177,15 +178,19 @@ export function useTable< useIsomorphicLayoutEffect(() => { rootSource.markCommitted(renderSnapshot) - table_publishExternalState(coreTable, controlledState ?? null, shallow) + table_publishExternalState( + coreTable, + controlledState ?? null, + shallow, + optionCommitToken, + ) }) return useMemo( () => ({ ...table, - options: tableOptions, state, }), - [table, tableOptions, state], + [table, state], ) } diff --git a/packages/preact-table/tests/unit/adapterReactivity.test.tsx b/packages/preact-table/tests/unit/adapterReactivity.test.tsx index 74e92cb42a..a034515001 100644 --- a/packages/preact-table/tests/unit/adapterReactivity.test.tsx +++ b/packages/preact-table/tests/unit/adapterReactivity.test.tsx @@ -130,7 +130,7 @@ describe('Preact adapter reactivity and lifecycle', () => { ) }) - test('updates the paginated row model without invalidating the core row model', () => { + test('updates pagination with broad render-phase memo invalidation', () => { const data = Array.from({ length: 10 }, (_, index) => ({ id: String(index), title: `Title ${index}`, @@ -188,7 +188,10 @@ describe('Preact adapter reactivity and lifecycle', () => { expect(text('Page row IDs')).toBe('0,1,2') expect(coreRowModelCaptor).toHaveBeenCalledTimes(2) expect(rowModelCaptor).toHaveBeenCalledTimes(2) - expect(coreRowModelCaptor.mock.calls[0]![0]).toBe( + // Render-phase adapters intentionally rotate native memo atoms for any + // materially changed staged options source. Per-option revisions/read + // collectors are deliberately not part of this first implementation. + expect(coreRowModelCaptor.mock.calls[0]![0]).not.toBe( coreRowModelCaptor.mock.calls[1]![0], ) expect(rowModelCaptor.mock.calls[0]![0].rows).toHaveLength(5) diff --git a/packages/react-table/src/Subscribe.ts b/packages/react-table/src/Subscribe.ts index b9a9c45445..f799f838ac 100644 --- a/packages/react-table/src/Subscribe.ts +++ b/packages/react-table/src/Subscribe.ts @@ -38,7 +38,7 @@ export type SubscribePropsWithStore< /** * Subscribe to the full value of a source (e.g. `table.atoms.rowSelection` or - * `table.optionsStore`). Omitting `selector` is equivalent to the identity + * `table.optionAtoms.data`). Omitting `selector` is equivalent to the identity * selector — children receive `TSourceValue`. */ export type SubscribePropsWithSourceIdentity = { diff --git a/packages/react-table/src/reactivity.ts b/packages/react-table/src/reactivity.ts index fdc9e174df..492635220d 100644 --- a/packages/react-table/src/reactivity.ts +++ b/packages/react-table/src/reactivity.ts @@ -7,11 +7,11 @@ export type ReactTableReactivityBindings = RenderPhaseReactivityBindings /** * Creates the table-core reactivity bindings used by the React adapter. * - * React stores table state in TanStack Store atoms and leaves options as plain - * resolved data because `useTable` synchronizes options during render. The - * render-phase preset supplies the live readonly-atom facades and the `commit` - * hook; the store primitives are passed in from `@tanstack/react-store` so all - * atoms share one store instance with user-provided external atoms. + * React synchronizes option atoms during render without publishing them until + * commit. The render-phase preset supplies live option facades, cached memo + * atoms, and the commit hook; the store primitives come from + * `@tanstack/react-store` so all atoms share one store instance with + * user-provided external atoms. */ export function reactReactivity(): ReactTableReactivityBindings { return renderPhaseReactivity({ createAtom, batch }) diff --git a/packages/react-table/src/useTable.ts b/packages/react-table/src/useTable.ts index 7e4a839d6e..cee795b58e 100644 --- a/packages/react-table/src/useTable.ts +++ b/packages/react-table/src/useTable.ts @@ -44,8 +44,9 @@ export type ReactTable< * * This is useful for opting into state re-renders for specific parts of the table state. * - * Pass `source` to subscribe to a single atom or store (e.g. `table.atoms.rowSelection` - * or `table.optionsStore`) instead of the full `table.store`. + * Pass `source` to subscribe to a single atom or store (e.g. + * `table.atoms.rowSelection` or `table.optionAtoms.data`) instead of the full + * `table.store`. * * @example * ({ rowSelection: state.rowSelection })}> @@ -190,7 +191,7 @@ export function useTable< // Keep options current during render without publishing them to reactive // subscribers. Readonly atoms expose the staged snapshot through live get(). - table_setOptions( + const optionCommitToken = table_setOptions( coreTable, (prev) => ({ ...prev, @@ -211,7 +212,12 @@ export function useTable< // subscription drops the matching notification. Isolated subscribers // still receive the post-commit store update before paint. rootSource.markCommitted(renderSnapshot) - table_publishExternalState(coreTable, controlledState ?? null, shallow) + table_publishExternalState( + coreTable, + controlledState ?? null, + shallow, + optionCommitToken, + ) }) // we know this is not the most efficient way to return the table, @@ -219,9 +225,8 @@ export function useTable< return useMemo( () => ({ ...table, - options: tableOptions, state, }), - [table, tableOptions, state], + [table, state], ) } diff --git a/packages/react-table/tests/adapterReactivity.test.tsx b/packages/react-table/tests/adapterReactivity.test.tsx index 3fe4e24724..596a47c09f 100644 --- a/packages/react-table/tests/adapterReactivity.test.tsx +++ b/packages/react-table/tests/adapterReactivity.test.tsx @@ -150,7 +150,7 @@ describe('React adapter reactivity and lifecycle', () => { ) }) - test('updates the paginated row model without invalidating the core row model', () => { + test('updates pagination with broad render-phase memo invalidation', () => { const data = Array.from({ length: 10 }, (_, index) => ({ id: String(index), title: `Title ${index}`, @@ -207,7 +207,10 @@ describe('React adapter reactivity and lifecycle', () => { expect(text('Page row IDs')).toBe('0,1,2') expect(coreRowModelCaptor).toHaveBeenCalledTimes(2) expect(rowModelCaptor).toHaveBeenCalledTimes(2) - expect(coreRowModelCaptor.mock.calls[0]![0]).toBe( + // Render-phase adapters intentionally rotate native memo atoms for any + // materially changed staged options source. Per-option revisions/read + // collectors are deliberately not part of this first implementation. + expect(coreRowModelCaptor.mock.calls[0]![0]).not.toBe( coreRowModelCaptor.mock.calls[1]![0], ) expect(rowModelCaptor.mock.calls[0]![0].rows).toHaveLength(5) diff --git a/packages/solid-table/src/createTable.ts b/packages/solid-table/src/createTable.ts index 3a5a91c80d..1e3e0cd445 100644 --- a/packages/solid-table/src/createTable.ts +++ b/packages/solid-table/src/createTable.ts @@ -1,12 +1,7 @@ import { constructTable } from '@tanstack/table-core' -import { - createComputed, - getOwner, - mergeProps, - onCleanup, - untrack, -} from 'solid-js' +import { createComputed, getOwner, onCleanup, untrack } from 'solid-js' import { FlexRender } from './FlexRender' +import { mergeOptionSources } from './merge-options' import { solidReactivity } from './reactivity' import type { JSX } from 'solid-js' import type { @@ -65,20 +60,20 @@ export function createTable< const owner = getOwner()! const reactivity = solidReactivity(owner) - const mergedOptions = mergeProps(tableOptions, { + const mergedOptions = mergeOptionSources(tableOptions, { features: { coreReactivityFeature: reactivity, ...tableOptions.features, }, }) as any - const resolvedOptions = mergeProps( + const resolvedOptions = mergeOptionSources( { mergeOptions: ( defaultOptions: TableOptions, options: TableOptions, ) => { - return mergeProps(defaultOptions, options) + return mergeOptionSources(defaultOptions, options) }, }, mergedOptions, @@ -90,6 +85,12 @@ export function createTable< > createComputed(() => { + // Option atoms store resolved values. Touch every current option while + // tracked so a signal-backed getter re-runs this synchronization. + for (const key of Reflect.ownKeys(mergedOptions)) { + void Reflect.get(mergedOptions, key, mergedOptions) + } + const userState = tableOptions.state if (userState) { for (const key in userState) { @@ -98,9 +99,7 @@ export function createTable< } untrack(() => { - table.setOptions((prev) => { - return mergeProps(prev, mergedOptions) as TableOptions - }) + table.setOptions(() => mergedOptions as TableOptions) }) }) diff --git a/packages/solid-table/src/createTableHook.tsx b/packages/solid-table/src/createTableHook.tsx index f3f37579ce..4c0e2832c9 100644 --- a/packages/solid-table/src/createTableHook.tsx +++ b/packages/solid-table/src/createTableHook.tsx @@ -1,7 +1,8 @@ import { createColumnHelper as coreCreateColumnHelper } from '@tanstack/table-core' -import { createContext, mergeProps, useContext } from 'solid-js' +import { createContext, useContext } from 'solid-js' import { createTable } from './createTable' import { FlexRender } from './FlexRender' +import { mergeOptionSources } from './merge-options' import type { SolidTable } from './createTable' import type { Component, JSXElement } from 'solid-js' import type { @@ -816,7 +817,7 @@ export function createTableHook< THeaderComponents > { // Merge default options with provided options (provided takes precedence) - const mergedProps = mergeProps(defaultTableOptions, tableOptions) + const mergedProps = mergeOptionSources(defaultTableOptions, tableOptions) const table = createTable( mergedProps as TableOptions, ) diff --git a/packages/solid-table/src/merge-options.ts b/packages/solid-table/src/merge-options.ts new file mode 100644 index 0000000000..a791b18348 --- /dev/null +++ b/packages/solid-table/src/merge-options.ts @@ -0,0 +1,93 @@ +function getMergedPrototype(sources: Array): object | null { + let fallback: object | null = Object.prototype + + for (let i = sources.length - 1; i >= 0; i--) { + const prototype = Object.getPrototypeOf(sources[i]!) + fallback = prototype + + // Adapter-owned option fragments are ordinary objects. Prefer a custom + // user prototype when one exists in another source. + if (prototype !== Object.prototype) { + return prototype + } + } + + return fallback +} + +/** + * Lazily merges reactive Solid option sources. + * + * Unlike `mergeProps`, an explicitly present `undefined` wins over an earlier + * value. This is required for clearing optional table options. The proxy also + * keeps accessor reads live and reflects symbols and the user source's + * prototype for the core option controller. + */ +export function mergeOptionSources>( + ...sources: T +): T[number] { + const accessors = new Map unknown>() + + const read = (key: PropertyKey) => { + for (let i = sources.length - 1; i >= 0; i--) { + const source = sources[i]! + if (Reflect.has(source, key)) { + return Reflect.get(source, key, source) + } + } + } + + return new Proxy(Object.create(null), { + defineProperty() { + return false + }, + deleteProperty() { + return false + }, + get(_target, key) { + return read(key) + }, + getOwnPropertyDescriptor(_target, key) { + let descriptor: PropertyDescriptor | undefined + for (let i = sources.length - 1; i >= 0; i--) { + descriptor = Reflect.getOwnPropertyDescriptor(sources[i]!, key) + if (descriptor) break + } + if (!descriptor) return undefined + + let get = accessors.get(key) + if (!get) { + get = () => read(key) + accessors.set(key, get) + } + + return { + configurable: true, + enumerable: descriptor.enumerable ?? false, + get, + } + }, + getPrototypeOf() { + return getMergedPrototype(sources) + }, + has(_target, key) { + return sources.some((source) => Reflect.has(source, key)) + }, + ownKeys() { + const keys = new Set() + for (const source of sources) { + for (const key of Reflect.ownKeys(source)) keys.add(key) + } + return [...keys] + }, + preventExtensions() { + return false + }, + set() { + return false + }, + setPrototypeOf() { + return false + }, + }) as T[number] +} diff --git a/packages/solid-table/src/reactivity.ts b/packages/solid-table/src/reactivity.ts index c71b6b081b..b8b10fe7ed 100644 --- a/packages/solid-table/src/reactivity.ts +++ b/packages/solid-table/src/reactivity.ts @@ -51,15 +51,12 @@ function signalToWritableAtom( /** * Creates the table-core reactivity bindings used by the Solid adapter. * - * Table state atoms are backed by TanStack Store atoms. The options store stays - * framework-native because row-model APIs read `table.options` directly during - * render. Readonly table atoms bridge Store dependency tracking into Solid memos. + * Table state and option atoms bridge table-core reads into Solid signals. */ export function solidReactivity(owner: Owner): TableReactivityBindings { const subscriptions = new Set() return { - createOptionsStore: true, wrapExternalAtoms: true, addSubscription: (subscription) => { subscriptions.add(subscription) @@ -70,10 +67,12 @@ export function solidReactivity(owner: Owner): TableReactivityBindings { }, schedule: (fn) => queueMicrotask(() => fn()), createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => { - const signal = createMemo(() => fn(), { - equals: options?.compare, - name: options?.debugName, - }) + const signal = runWithOwner(owner, () => + createMemo(() => fn(), undefined, { + ...(options?.compare ? { equals: options.compare } : {}), + name: options?.debugName, + }), + )! return signalToReadonlyAtom(signal, owner) }, createWritableAtom: ( @@ -81,7 +80,7 @@ export function solidReactivity(owner: Owner): TableReactivityBindings { options?: TableAtomOptions, ): Atom => { const writableSignal = createSignal(value, { - equals: options?.compare, + ...(options?.compare ? { equals: options.compare } : {}), name: options?.debugName, }) return signalToWritableAtom(writableSignal, owner) diff --git a/packages/solid-table/tests/unit/adapterReactivity.test.ts b/packages/solid-table/tests/unit/adapterReactivity.test.ts index a07f574d7b..543564e7a5 100644 --- a/packages/solid-table/tests/unit/adapterReactivity.test.ts +++ b/packages/solid-table/tests/unit/adapterReactivity.test.ts @@ -300,4 +300,53 @@ describe('Solid adapter lifecycle and option ownership', () => { dispose() }) }) + + test('an existing option can become undefined without falling back to its prior value', () => { + createRoot((dispose) => { + const [enableRowSelection, setEnableRowSelection] = createSignal< + boolean | undefined + >(false) + const [customOption, setCustomOption] = createSignal('first') + const customSymbol = Symbol('custom-option') + const prototype = { inheritedOption: 'from-prototype' } + const options = Object.create( + prototype, + Object.getOwnPropertyDescriptors({ + data: [{ id: '1', title: 'Title' }], + columns: [idColumn, titleColumn], + features: stockFeatures, + getRowId: (row: Data) => row.id, + [customSymbol]: 'symbol-value', + get enableRowSelection() { + return enableRowSelection() + }, + get customOption() { + return customOption() + }, + }), + ) + const table = createTable(options) + + expect(table.options.enableRowSelection).toBe(false) + expect(table.getRowModel().rows[0]!.getCanSelect()).toBe(false) + expect((table.options as any)[customSymbol]).toBe('symbol-value') + expect((table.options as any).customOption).toBe('first') + expect( + Object.getOwnPropertyDescriptor(table.options, 'customOption'), + ).toMatchObject({ + value: 'first', + writable: false, + }) + + setEnableRowSelection(undefined) + setCustomOption('second') + + expect(table.options.enableRowSelection).toBeUndefined() + expect(table.optionAtoms.enableRowSelection!.get()).toBeUndefined() + expect(table.getRowModel().rows[0]!.getCanSelect()).toBe(true) + expect((table.options as any).customOption).toBe('second') + + dispose() + }) + }) }) diff --git a/packages/solid-table/tests/unit/reactivity.test.ts b/packages/solid-table/tests/unit/reactivity.test.ts index a1a3233707..280e9cfb09 100644 --- a/packages/solid-table/tests/unit/reactivity.test.ts +++ b/packages/solid-table/tests/unit/reactivity.test.ts @@ -63,6 +63,57 @@ describe('solidReactivity', () => { dispose() }) }) + + test('readonly atoms pass their comparator to Solid createMemo', () => { + createRoot((dispose) => { + const owner = getOwner()! + const reactivity = solidReactivity(owner) + const count = reactivity.createWritableAtom(0) + const parity = reactivity.createReadonlyAtom( + () => ({ even: count.get() % 2 === 0 }), + { + compare: (previous, next) => previous.even === next.even, + debugName: 'parity', + }, + ) + + const initial = parity.get() + count.set(2) + expect(parity.get()).toBe(initial) + + count.set(3) + expect(parity.get()).not.toBe(initial) + dispose() + }) + }) + + test('atoms retain Solid identity equality when no comparator is provided', () => { + let dispose!: () => void + const { captor, count } = createRoot((rootDispose) => { + dispose = rootDispose + const owner = getOwner()! + const reactivity = solidReactivity(owner) + const count = reactivity.createWritableAtom(0) + const parity = reactivity.createReadonlyAtom(() => count.get() % 2, { + debugName: 'parity', + }) + const captor = vi.fn<(value: number) => void>() + + createEffect(() => captor(parity.get())) + + return { captor, count } + }) + + count.set(2) + expect(captor.mock.calls).toEqual([[0]]) + + count.set(3) + expect(captor.mock.calls).toEqual([[0], [1]]) + + count.set(3) + expect(captor.mock.calls).toEqual([[0], [1]]) + dispose() + }) }) describe('Solid table reactivity integration', () => { diff --git a/packages/svelte-table/src/createTable.svelte.ts b/packages/svelte-table/src/createTable.svelte.ts index fb9d2131bf..cfe3a9ce77 100644 --- a/packages/svelte-table/src/createTable.svelte.ts +++ b/packages/svelte-table/src/createTable.svelte.ts @@ -90,9 +90,16 @@ export function createTable< const nextOptions = flatMerge(mergedOptions) const state = nextOptions.state as Record | undefined if (state) { + const resolvedState: Record = {} for (const key in state) { - void state[key] + resolvedState[key] = state[key] } + Object.defineProperty(nextOptions, 'state', { + configurable: true, + enumerable: true, + value: resolvedState, + writable: true, + }) } untrack(() => { diff --git a/packages/svelte-table/src/merge-objects.ts b/packages/svelte-table/src/merge-objects.ts index 196dd075da..9870cddbc0 100644 --- a/packages/svelte-table/src/merge-objects.ts +++ b/packages/svelte-table/src/merge-objects.ts @@ -16,32 +16,72 @@ export function mergeObjects( source3: W, ): T & U & V & W export function mergeObjects(...sources: any): any { - const target = {} - for (let source of sources) { - if (typeof source === 'function') source = source() - if (source) { - const descriptors = Object.getOwnPropertyDescriptors(source) - for (const key in descriptors) { - if (key in target) continue - Object.defineProperty(target, key, { - enumerable: true, - get() { - for (let i = sources.length - 1; i >= 0; i--) { - let v, - s = sources[i] - if (typeof s === 'function') s = s() - // eslint-disable-next-line prefer-const - v = (s || {})[key] - if (v !== undefined) return v - } - }, - }) + const target = Object.create(getMergedPrototype(sources)) + const keys = new Set() + + for (const unresolvedSource of sources) { + const source = resolveSource(unresolvedSource) + if (source == null) continue + for (const key of Reflect.ownKeys(source)) keys.add(key) + } + + for (const key of keys) { + let enumerable = false + for (let i = sources.length - 1; i >= 0; i--) { + const source = resolveSource(sources[i]) + const descriptor = + source == null + ? undefined + : Reflect.getOwnPropertyDescriptor(source, key) + if (descriptor) { + enumerable = descriptor.enumerable ?? false + break } } + + Object.defineProperty(target, key, { + configurable: true, + enumerable, + get() { + for (let i = sources.length - 1; i >= 0; i--) { + const source = resolveSource(sources[i]) + if (source != null && Reflect.has(source, key)) { + return Reflect.get(source, key, source) + } + } + }, + }) } + return target } +function resolveSource(source: any) { + return typeof source === 'function' ? source() : source +} + +function getMergedPrototype(sources: Array): object | null { + let fallback: object | null = Object.prototype + + for (let i = sources.length - 1; i >= 0; i--) { + const source = resolveSource(sources[i]) + if ( + (typeof source !== 'object' && typeof source !== 'function') || + source === null + ) { + continue + } + + const prototype = Object.getPrototypeOf(source) + fallback = prototype + if (prototype !== Object.prototype) { + return prototype + } + } + + return fallback +} + /** * Merges objects together by eagerly resolving all values into a flat object. * @@ -50,7 +90,7 @@ export function mergeObjects(...sources: any): any { * accumulation that causes O(N) lookups when the result is repeatedly passed * back as a source in subsequent merges (e.g., inside `$effect.pre` loops). * - * Later sources take precedence; `undefined` values do not override. + * Later sources take precedence, including an explicitly present `undefined`. * * @see https://github.com/TanStack/table/issues/6235 */ @@ -64,15 +104,21 @@ export function flatMerge( source3: W, ): T & U & V & W export function flatMerge(...sources: any): any { - const result: Record = {} - for (let source of sources) { - if (typeof source === 'function') source = source() - if (!source) continue + const result = Object.create(getMergedPrototype(sources)) as Record< + PropertyKey, + unknown + > + for (const unresolvedSource of sources) { + const source = resolveSource(unresolvedSource) + if (source == null) continue for (const key of Reflect.ownKeys(source)) { - const value = (source as Record)[key] - if (value !== undefined) { - result[key as string] = value - } + const descriptor = Reflect.getOwnPropertyDescriptor(source, key) + Object.defineProperty(result, key, { + configurable: true, + enumerable: descriptor?.enumerable ?? true, + value: Reflect.get(source, key, source), + writable: true, + }) } } return result diff --git a/packages/svelte-table/src/reactivity.svelte.ts b/packages/svelte-table/src/reactivity.svelte.ts index a251a7452e..031f44d115 100644 --- a/packages/svelte-table/src/reactivity.svelte.ts +++ b/packages/svelte-table/src/reactivity.svelte.ts @@ -1,13 +1,13 @@ import { untrack } from 'svelte' +import { createSubscriber } from 'svelte/reactivity' import { batch, createAtom } from '@tanstack/svelte-store' +import { createStableStoreReadonlyAtom } from '@tanstack/table-core/reactivity' import type { TableAtomOptions, TableReactivityBindings, } from '@tanstack/table-core/reactivity' import type { Atom, Observer, ReadonlyAtom } from '@tanstack/svelte-store' -const optionsStoreDebugName = 'table/optionsStore' - function observerToCallback( observerOrNext: Observer | ((value: T) => void), ): (value: T) => void { @@ -16,50 +16,15 @@ function observerToCallback( : (value) => observerOrNext.next?.(value) } -function subscribeToRune( - getValue: () => T, - observerOrNext: Observer | ((value: T) => void), -) { - const callback = observerToCallback(observerOrNext) - const unsubscribe = $effect.root(() => { - $effect(() => { - const value = getValue() - untrack(() => callback(value)) - }) - }) - - return { unsubscribe } -} - -function createRuneWritableAtom(initialValue: T): 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'], - } -} - /** * Creates the table-core reactivity bindings used by the Svelte adapter. * - * Table state atoms are backed by TanStack Store atoms. The options store stays - * framework-native because row-model APIs read `table.options` directly during - * render. Readonly table atoms bridge Store dependency tracking into + * Table state and option atoms bridge Store dependency tracking into * `$derived.by`, so their `.get()` methods participate in Svelte dependency * tracking when called in templates, `$derived`, or `$effect`. */ export function svelteReactivity(): TableReactivityBindings { return { - createOptionsStore: true, wrapExternalAtoms: false, addSubscription: () => { throw new Error( @@ -73,35 +38,24 @@ export function svelteReactivity(): TableReactivityBindings { }, schedule: (fn) => queueMicrotask(() => fn()), createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => { - const storeAtom = createAtom(() => fn(), { + const storeAtom = createStableStoreReadonlyAtom(createAtom, fn, { compare: _options?.compare, }) - let version = $state(0) - - $effect(() => { + const trackStore = createSubscriber((update) => { const subscription = storeAtom.subscribe(() => { - version += 1 + update() }) return () => subscription.unsubscribe() }) - const value = $derived.by(() => { - version - return storeAtom.get() - }) - return { get: () => { - // Both reads are load-bearing: the Store read preserves dependency - // tracking between table atoms, while touching `value` registers the - // current Svelte reactive scope with the rune-backed bridge. - const currentValue = storeAtom.get() - value - return currentValue + trackStore() + return storeAtom.get() }, subscribe: ((observerOrNext: Observer | ((value: T) => void)) => { - return subscribeToRune(() => value, observerOrNext) + return storeAtom.subscribe(observerToCallback(observerOrNext)) }) as ReadonlyAtom['subscribe'], } }, @@ -109,10 +63,6 @@ export function svelteReactivity(): TableReactivityBindings { initialValue: T, _options?: TableAtomOptions, ): Atom => { - if (_options?.debugName === optionsStoreDebugName) { - return createRuneWritableAtom(initialValue) - } - return createAtom(initialValue, { compare: _options?.compare, }) diff --git a/packages/svelte-table/tests/adapter-lifecycle.test.ts b/packages/svelte-table/tests/adapter-lifecycle.test.ts index ac6d03bae5..e28e3116fb 100644 --- a/packages/svelte-table/tests/adapter-lifecycle.test.ts +++ b/packages/svelte-table/tests/adapter-lifecycle.test.ts @@ -110,6 +110,25 @@ describe('Svelte adapter lifecycle and reactive options', () => { ]) }) + test('an existing optional top-level option can be cleared to undefined', async () => { + render(ReactivityHarness) + + expect(outputText('Row selection option')).toBe('true') + expect(outputText('First row can be selected')).toBe('true') + + await fireEvent.click( + screen.getByRole('button', { name: 'Disable row selection' }), + ) + expect(outputText('Row selection option')).toBe('false') + expect(outputText('First row can be selected')).toBe('false') + + await fireEvent.click( + screen.getByRole('button', { name: 'Clear row-selection option' }), + ) + expect(outputText('Row selection option')).toBe('undefined') + expect(outputText('First row can be selected')).toBe('true') + }) + test('table APIs use the latest rune-backed option callback', async () => { const firstHandler = vi.fn>() const secondHandler = vi.fn>() diff --git a/packages/svelte-table/tests/fixtures/ReactivityHarness.svelte b/packages/svelte-table/tests/fixtures/ReactivityHarness.svelte index 1bfc7834e4..65573aac3c 100644 --- a/packages/svelte-table/tests/fixtures/ReactivityHarness.svelte +++ b/packages/svelte-table/tests/fixtures/ReactivityHarness.svelte @@ -42,7 +42,7 @@ { id: '2', title: 'Two' }, ]) let columns = $state>>([idColumn]) - let enableRowSelection = $state(true) + let enableRowSelection = $state(true) let controlledState = $state<{ rowSelection?: RowSelectionState }>({ rowSelection: { 1: true }, }) @@ -92,6 +92,14 @@ data = [{ id: '4', title: 'Final' }] columns = [titleColumn] } + + function disableRowSelection() { + enableRowSelection = false + } + + function clearRowSelectionOption() { + enableRowSelection = undefined + } {JSON.stringify(selection)} @@ -117,9 +125,14 @@ {String(table.getRowModel().rows[0]?.getCanSelect() ?? false)} +{String(table.options.enableRowSelection)} + + diff --git a/packages/svelte-table/tests/merge-objects.test.ts b/packages/svelte-table/tests/merge-objects.test.ts new file mode 100644 index 0000000000..75c69d3d38 --- /dev/null +++ b/packages/svelte-table/tests/merge-objects.test.ts @@ -0,0 +1,48 @@ +import { describe, expect, test } from 'vitest' +import { flatMerge, mergeObjects } from '../src/merge-objects' + +describe('Svelte option source merging', () => { + test('preserves explicit undefined, symbols, accessors, and a custom prototype', () => { + const customSymbol = Symbol('custom-option') + const prototype = { inheritedOption: 'from-prototype' } + let accessorValue = 'first' + const source = Object.create(prototype) + + Object.defineProperties(source, { + optional: { + configurable: true, + enumerable: true, + value: undefined, + writable: true, + }, + customOption: { + configurable: true, + enumerable: true, + get: () => accessorValue, + }, + [customSymbol]: { + configurable: true, + enumerable: false, + value: 'symbol-value', + }, + }) + + const merged = mergeObjects({ optional: 'fallback' }, source) + + expect(merged.optional).toBeUndefined() + expect(Object.getPrototypeOf(merged)).toBe(prototype) + expect(merged[customSymbol]).toBe('symbol-value') + expect( + Object.getOwnPropertyDescriptor(merged, 'customOption')?.get, + ).toEqual(expect.any(Function)) + + accessorValue = 'second' + expect(merged.customOption).toBe('second') + + const snapshot = flatMerge({ optional: 'fallback' }, source) + expect(snapshot.optional).toBeUndefined() + expect(Object.getPrototypeOf(snapshot)).toBe(prototype) + expect(snapshot[customSymbol]).toBe('symbol-value') + expect(snapshot.customOption).toBe('second') + }) +}) diff --git a/packages/table-core/skills/custom-features/SKILL.md b/packages/table-core/skills/custom-features/SKILL.md index 80737018c4..07ec3b4c43 100644 --- a/packages/table-core/skills/custom-features/SKILL.md +++ b/packages/table-core/skills/custom-features/SKILL.md @@ -226,7 +226,7 @@ export const features = tableFeatures({ densityFeature }) - Table API `fn` receives declared arguments. Prototype API `fn` receives the current object first. - Initialize table-owned mutable data in `initTableInstanceData`, not `constructTableAPIs`; all feature data is initialized before any table API is assigned. - Clear transient table-owned data in `resetTableInstanceData`. Reset state slices through atoms/updaters, and do not expect this hook to reset externally controlled state. -- Add `memoDeps` only for a genuinely derived method. Prototype methods are shared and must not close over per-object mutable data. +- Register a zero-argument derived method as `{ computed: () => result, compare? }` and read its atoms/options inside the computation so native reactivity tracks them. Prototype computed entries receive the current object as `self`. Keep parameterized methods as `{ fn }`; shared prototype methods must not close over per-object mutable data. - There are no `assignColumnAPIs`, `assignRowAPIs`, `assignCellAPIs`, or `assignHeaderAPIs`; use `assignPrototypeAPIs` in the matching hook. - Do not mutate constructed instances ad hoc or use a feature for renderer-only callbacks that belong in meta. diff --git a/packages/table-core/src/core/cells/coreCellsFeature.ts b/packages/table-core/src/core/cells/coreCellsFeature.ts index e79384620d..8b95fe9608 100644 --- a/packages/table-core/src/core/cells/coreCellsFeature.ts +++ b/packages/table-core/src/core/cells/coreCellsFeature.ts @@ -19,8 +19,7 @@ export const coreCellsFeature: TableFeature = { fn: (cell) => cell_renderValue(cell), }, cell_getContext: { - fn: (cell) => cell_getContext(cell), - memoDeps: (cell) => [cell], + computed: (cell) => cell_getContext(cell), }, }) }, diff --git a/packages/table-core/src/core/columns/coreColumnsFeature.ts b/packages/table-core/src/core/columns/coreColumnsFeature.ts index f21a2b3bfc..69f51ad50f 100644 --- a/packages/table-core/src/core/columns/coreColumnsFeature.ts +++ b/packages/table-core/src/core/columns/coreColumnsFeature.ts @@ -19,17 +19,19 @@ export const coreColumnsFeature: TableFeature = { assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('coreColumnsFeature', prototype, table, { column_getFlatColumns: { - fn: (column) => column_getFlatColumns(column), - memoDeps: (column) => [column.table.options.columns], + computed: (column) => { + void column.table.options.columns + return column_getFlatColumns(column) + }, }, column_getLeafColumns: { - fn: (column) => column_getLeafColumns(column), - memoDeps: (column) => [ - column.table.atoms.columnOrder?.get(), - column.table.atoms.grouping?.get(), - column.table.options.columns, - column.table.options.groupedColumnMode, - ], + computed: (column) => { + void column.table.atoms.columnOrder?.get() + void column.table.atoms.grouping?.get() + void column.table.options.columns + void column.table.options.groupedColumnMode + return column_getLeafColumns(column) + }, }, }) }, @@ -37,33 +39,22 @@ export const coreColumnsFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('coreColumnsFeature', table, { table_getDefaultColumnDef: { - fn: () => table_getDefaultColumnDef(table), - memoDeps: () => [table.options.defaultColumn], + computed: () => table_getDefaultColumnDef(table), }, table_getAllColumns: { - fn: () => table_getAllColumns(table), - memoDeps: () => [table.options.columns], + computed: () => table_getAllColumns(table), }, table_getAllFlatColumns: { - fn: () => table_getAllFlatColumns(table), - memoDeps: () => [table.options.columns], + computed: () => table_getAllFlatColumns(table), }, table_getAllFlatColumnsById: { - fn: () => table_getAllFlatColumnsById(table), - memoDeps: () => [table.options.columns], + computed: () => table_getAllFlatColumnsById(table), }, table_getAllLeafColumns: { - fn: () => table_getAllLeafColumns(table), - memoDeps: () => [ - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.columns, - table.options.groupedColumnMode, - ], + computed: () => table_getAllLeafColumns(table), }, table_getAllLeafColumnsById: { - fn: () => table_getAllLeafColumnsById(table), - memoDeps: () => [table.getAllLeafColumns()], + computed: () => table_getAllLeafColumnsById(table), }, table_getColumn: { fn: (columnId) => table_getColumn(table, columnId), diff --git a/packages/table-core/src/core/headers/coreHeadersFeature.ts b/packages/table-core/src/core/headers/coreHeadersFeature.ts index b8c7a214e4..dd1328263f 100644 --- a/packages/table-core/src/core/headers/coreHeadersFeature.ts +++ b/packages/table-core/src/core/headers/coreHeadersFeature.ts @@ -16,12 +16,16 @@ export const coreHeadersFeature: TableFeature = { assignHeaderPrototype: (prototype, table) => { assignPrototypeAPIs('coreHeadersFeature', prototype, table, { header_getLeafHeaders: { - fn: (header) => header_getLeafHeaders(header), - memoDeps: (header) => [header.column.table.options.columns], + computed: (header) => { + void header.column.table.options.columns + return header_getLeafHeaders(header) + }, }, header_getContext: { - fn: (header) => header_getContext(header), - memoDeps: (header) => [header.column.table.options.columns], + computed: (header) => { + void header.column.table.options.columns + return header_getContext(header) + }, }, }) }, @@ -29,27 +33,16 @@ export const coreHeadersFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('coreHeadersFeature', table, { table_getHeaderGroups: { - fn: () => table_getHeaderGroups(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getHeaderGroups(table), }, table_getFooterGroups: { - fn: () => table_getFooterGroups(table), - memoDeps: () => [table.getHeaderGroups()], + computed: () => table_getFooterGroups(table), }, table_getFlatHeaders: { - fn: () => table_getFlatHeaders(table), - memoDeps: () => [table.getHeaderGroups()], + computed: () => table_getFlatHeaders(table), }, table_getLeafHeaders: { - fn: () => table_getLeafHeaders(table), - memoDeps: () => [table.getHeaderGroups()], + computed: () => table_getLeafHeaders(table), }, }) }, diff --git a/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts b/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts index 045d0dd90a..6d5df67dda 100644 --- a/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts +++ b/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts @@ -10,6 +10,14 @@ export interface TableAtomOptions extends AtomOptions { * A debug name for the atom, useful for debugging. */ debugName: string + /** + * Selects an internal render-phase behavior. `memo` retains native computed + * caching between reads; `staged` makes a writable value live to the current + * render while deferring its reactive publication until commit. + * + * @internal + */ + mode?: 'memo' | 'staged' } /** @@ -20,15 +28,30 @@ export interface TableAtomOptions extends AtomOptions { * scheduling primitives. */ export interface TableReactivityBindings { - createOptionsStore: boolean wrapExternalAtoms: boolean + /** + * Advances memo-mode readonly atoms to a newly staged options snapshot. + * + * Render-phase adapters return a token that must only be published after the + * corresponding host render commits. + * + * @internal + */ + stage?: () => number + /** + * Returns the token for the currently staged options snapshot without + * creating a new stage. + * + * @internal + */ + getStageToken?: () => number /** * Invalidates readonly atoms whose compute reads non-reactive inputs (plain * options). Render-phase adapters call this after publishing captured * controlled state from a host commit, including when no base atom changed, * so controlled ownership changes still reach subscribers. */ - commit?: () => void + commit?: (token?: number) => void addSubscription: (subscription: Subscription) => void /** * Creates a writable atom with an initial value. diff --git a/packages/table-core/src/core/reactivity/createStableStoreReadonlyAtom.ts b/packages/table-core/src/core/reactivity/createStableStoreReadonlyAtom.ts new file mode 100644 index 0000000000..0f411ed804 --- /dev/null +++ b/packages/table-core/src/core/reactivity/createStableStoreReadonlyAtom.ts @@ -0,0 +1,46 @@ +import type { AtomOptions, Observer, ReadonlyAtom } from '@tanstack/store' + +type StoreReadonlyAtomFactory = ( + getValue: (previous?: T) => T, + options?: AtomOptions, +) => ReadonlyAtom + +/** + * Creates a TanStack Store computed that can safely return any value. + * + * TanStack Store treats a function passed to `createAtom` as a computed + * resolver and uses `undefined` as its uninitialized computed snapshot. + * Keeping the result inside a stable box therefore lets the computed return + * function-valued or `undefined` values while preserving result equality. + */ +export function createStableStoreReadonlyAtom( + createAtom: StoreReadonlyAtomFactory, + fn: () => T, + options?: AtomOptions, +): ReadonlyAtom { + const compare = options?.compare ?? Object.is + let stableBox: { value: T } | undefined + + const boxedAtom = createAtom(() => { + const nextValue = fn() + + if (!stableBox || !compare(stableBox.value, nextValue)) { + stableBox = { value: nextValue } + } + + return stableBox + }) + + return { + get: () => boxedAtom.get().value, + subscribe: ((observer: Observer | ((value: T) => void)) => { + return boxedAtom.subscribe((box) => { + if (typeof observer === 'function') { + observer(box.value) + } else { + observer.next?.(box.value) + } + }) + }) as ReadonlyAtom['subscribe'], + } +} diff --git a/packages/table-core/src/core/reactivity/renderPhaseReactivity.ts b/packages/table-core/src/core/reactivity/renderPhaseReactivity.ts index 42b30a20f7..ff4dc45a36 100644 --- a/packages/table-core/src/core/reactivity/renderPhaseReactivity.ts +++ b/packages/table-core/src/core/reactivity/renderPhaseReactivity.ts @@ -1,4 +1,5 @@ -import type { Atom, AtomOptions, ReadonlyAtom } from '@tanstack/store' +import { createStableStoreReadonlyAtom } from './createStableStoreReadonlyAtom' +import type { Atom, AtomOptions, Observer, ReadonlyAtom } from '@tanstack/store' import type { TableAtomOptions, TableReactivityBindings, @@ -9,7 +10,9 @@ import type { * during the host framework's render phase, with a guaranteed `commit` hook. */ export interface RenderPhaseReactivityBindings extends TableReactivityBindings { - commit: () => void + stage: () => number + getStageToken: () => number + commit: (token?: number) => void } /** @@ -40,14 +43,12 @@ export interface RenderPhaseReactivityPrimitives { * component render, where store notifications must not fire until the host * commits. * - * Readonly atoms are exposed as live facades. `get()` re-evaluates the - * resolver against the options of the render in progress — a normal computed - * cannot know that plain `options.state` changed — and caches the result - * through the configured comparator so external-store consumers (e.g. React's - * `useSyncExternalStore`) see referentially stable snapshots. `subscribe()` - * goes through a hidden computed that tracks the resolver's real atom - * dependencies plus a commit version, so subscribers are invalidated by - * actual reactive writes and by the adapter's post-commit publication. + * Regular readonly atoms are exposed as live facades. `get()` re-evaluates the + * resolver against the options of the render in progress and caches the result + * through the configured comparator. Memo-mode atoms use a native computed for + * cached table APIs. A materially changed staged options source rotates those + * computeds without notifying subscribers; `subscribe()` observes the current + * computed only after the matching host commit. * * @example * ```ts @@ -62,10 +63,14 @@ export function renderPhaseReactivity( ): RenderPhaseReactivityBindings { const { createAtom, batch } = primitives const commitAtom = createAtom(0) + let stagedVersion = 0 + let committedVersion = 0 + const publishStagedAtoms = new Set<() => void>() return { - createOptionsStore: false, wrapExternalAtoms: false, + stage: () => ++stagedVersion, + getStageToken: () => stagedVersion, addSubscription: () => { throw new Error( 'Feature not supported in current reactivity implementation', @@ -81,6 +86,42 @@ export function renderPhaseReactivity( untrack: (fn) => fn(), createReadonlyAtom: (fn: () => T, atomOptions?: TableAtomOptions) => { const compare = atomOptions?.compare ?? Object.is + + if (atomOptions?.mode === 'memo') { + let memoVersion = -1 + let memoAtom: ReadonlyAtom | undefined + + const createMemoAtom = () => + createStableStoreReadonlyAtom(createAtom, fn, { compare }) + + const getMemoAtom = () => { + if (!memoAtom || memoVersion !== stagedVersion) { + memoVersion = stagedVersion + memoAtom = createMemoAtom() + } + + return memoAtom + } + + const readMemo = () => getMemoAtom().get() + + // Staging rotates the memo used by render reads without publishing + // during render. Subscribers observe it only after the host commit. + const reactiveAtom = createStableStoreReadonlyAtom( + createAtom, + () => { + commitAtom.get() + return readMemo() + }, + { compare }, + ) + + return { + get: readMemo, + subscribe: reactiveAtom.subscribe.bind(reactiveAtom), + } + } + let hasSnapshot = false let snapshot: T @@ -95,7 +136,8 @@ export function renderPhaseReactivity( return snapshot } - const reactiveAtom = createAtom( + const reactiveAtom = createStableStoreReadonlyAtom( + createAtom, () => { commitAtom.get() return getSnapshot() @@ -109,12 +151,77 @@ export function renderPhaseReactivity( } }, createWritableAtom: (value: T, atomOptions?: TableAtomOptions) => { + if (atomOptions?.mode === 'staged') { + const compare = atomOptions.compare ?? Object.is + const publishedVersion = createAtom(0) + let currentValue = value + let dirty = false + + const publish = () => { + if (!dirty) { + return + } + + dirty = false + publishedVersion.set((version) => version + 1) + } + + publishStagedAtoms.add(publish) + + return { + get: () => { + // The value itself is live for the render in progress. Reactive + // consumers only depend on the version published by commit(). + publishedVersion.get() + return currentValue + }, + set: (updater: T | ((previous: T) => T)) => { + const nextValue = + typeof updater === 'function' + ? (updater as (previous: T) => T)(currentValue) + : updater + + if (!compare(currentValue, nextValue)) { + currentValue = nextValue + dirty = true + } + }, + subscribe: ((observer: Observer | ((value: T) => void)) => { + let previous = currentValue + return publishedVersion.subscribe(() => { + const nextValue = currentValue + if (!compare(previous, nextValue)) { + previous = nextValue + if (typeof observer === 'function') { + observer(nextValue) + } else { + observer.next?.(nextValue) + } + } + }) + }) as Atom['subscribe'], + } + } + return createAtom(value, { compare: atomOptions?.compare, }) }, - commit: () => { - commitAtom.set((version) => version + 1) + commit: (token = stagedVersion) => { + // Publish only the newest staged render. Older effects and commits for a + // token that was superseded by an abandoned render must not publish the + // newer staged values under the wrong token. + if (token !== stagedVersion || token <= committedVersion) { + return + } + + committedVersion = token + batch(() => { + for (const publish of publishStagedAtoms) { + publish() + } + commitAtom.set(() => token) + }) }, } } diff --git a/packages/table-core/src/core/row-models/createCoreRowModel.ts b/packages/table-core/src/core/row-models/createCoreRowModel.ts index 99ab2d60ca..67dd50501d 100644 --- a/packages/table-core/src/core/row-models/createCoreRowModel.ts +++ b/packages/table-core/src/core/row-models/createCoreRowModel.ts @@ -1,4 +1,5 @@ import { constructRow } from '../rows/constructRow' +import { row_setSubRows } from '../rows/subRowsTracking' import { makeObjectMap, tableMemo } from '../../utils' import { table_autoResetCellSelection } from '../../features/cell-selection/cellSelectionFeature.utils' import { table_autoResetPageIndex } from '../../features/row-pagination/rowPaginationFeature.utils' @@ -24,8 +25,20 @@ export function createCoreRowModel< feature: 'coreRowModelsFeature', table, fnName: 'table.getCoreRowModel', - memoDeps: () => [table.options.data], - fn: () => _createCoreRowModel(table, table.options.data), + fn: () => { + // `data` was the core row model's sole memo dependency before native + // computeds. Read that slice reactively, then take the other row + // construction callbacks from the already-installed options source. + // This preserves the established contract that a render-created but + // semantically unchanged `getRowId` callback does not rebuild every + // row, while a later data change still uses the latest callbacks. + const data = table.options.data + const { getRowId, getSubRows } = table._reactivity.untrack(() => ({ + getRowId: table.options.getRowId, + getSubRows: table.options.getSubRows, + })) + return _createCoreRowModel(table, data, getRowId, getSubRows) + }, onAfterUpdate: () => { table_autoResetPageIndex(table) // this memo recomputes only when `options.data` changes, which is @@ -40,6 +53,16 @@ function accessRows( table: Table_Internal, rowModel: RowModel, originalRows: ReadonlyArray, + getRowId: + | (( + originalRow: TData, + index: number, + parent?: Row, + ) => string) + | undefined, + getSubRows: + | ((originalRow: TData, index: number) => ReadonlyArray | undefined) + | undefined, depth = 0, parentRow?: Row, ): Array> { @@ -50,7 +73,8 @@ function accessRows( // Make the row const row = constructRow( table, - table.getRowId(originalRow, i, parentRow), + getRowId?.(originalRow, i, parentRow) ?? + (parentRow ? `${parentRow.id}.${i}` : String(i)), originalRow, i, depth, @@ -66,17 +90,22 @@ function accessRows( rows.push(row) // Get the original subrows - if (table.options.getSubRows) { - row.originalSubRows = table.options.getSubRows(originalRow, i) + if (getSubRows) { + row.originalSubRows = getSubRows(originalRow, i) // Then recursively access them if (row.originalSubRows?.length) { - row.subRows = accessRows( - table, - rowModel, - row.originalSubRows, - depth + 1, + row_setSubRows( row, + accessRows( + table, + rowModel, + row.originalSubRows, + getRowId, + getSubRows, + depth + 1, + row, + ), ) } } @@ -91,6 +120,16 @@ function _createCoreRowModel< >( table: Table_Internal, data: ReadonlyArray, + getRowId: + | (( + originalRow: TData, + index: number, + parent?: Row, + ) => string) + | undefined, + getSubRows: + | ((originalRow: TData, index: number) => ReadonlyArray | undefined) + | undefined, ): { rows: Array> flatRows: Array> @@ -102,7 +141,7 @@ function _createCoreRowModel< rowsById: makeObjectMap(), } - rowModel.rows = accessRows(table, rowModel, data) + rowModel.rows = accessRows(table, rowModel, data, getRowId, getSubRows) return rowModel } diff --git a/packages/table-core/src/core/rows/coreRowsFeature.ts b/packages/table-core/src/core/rows/coreRowsFeature.ts index 5c96a05522..e8e8a04d0a 100644 --- a/packages/table-core/src/core/rows/coreRowsFeature.ts +++ b/packages/table-core/src/core/rows/coreRowsFeature.ts @@ -26,16 +26,13 @@ export const coreRowsFeature: TableFeature = { fn: (row) => row_getDisplayIndex(row), }, row_getAllCellsByColumnId: { - fn: (row) => row_getAllCellsByColumnId(row), - memoDeps: (row) => [row.getAllCells()], + computed: (row) => row_getAllCellsByColumnId(row), }, row_getAllCells: { - fn: (row) => row_getAllCells(row), - memoDeps: (row) => [row.table.getAllLeafColumns()], + computed: (row) => row_getAllCells(row), }, row_getLeafRows: { - fn: (row) => row_getLeafRows(row), - memoDeps: (row) => [row.subRows], + computed: (row) => row_getLeafRows(row), }, row_getParentRow: { fn: (row) => row_getParentRow(row), @@ -57,14 +54,7 @@ export const coreRowsFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('coreRowsFeature', table, { table_getRowsInDisplayOrder: { - fn: () => table_getRowsInDisplayOrder(table), - memoDeps: () => [ - table.getPrePaginatedRowModel().rows, - table.options.paginateExpandedRows, - table.options.paginateExpandedRows === false - ? table.atoms.expanded?.get() - : undefined, - ], + computed: () => table_getRowsInDisplayOrder(table), }, table_getRowId: { fn: (originalRow, index, parent) => @@ -75,8 +65,7 @@ export const coreRowsFeature: TableFeature = { table_getRow(table, id, searchAll), }, table_getMaxSubRowDepth: { - fn: () => table_getMaxSubRowDepth(table), - memoDeps: () => [table.getCoreRowModel()], + computed: () => table_getMaxSubRowDepth(table), }, }) }, diff --git a/packages/table-core/src/core/rows/coreRowsFeature.utils.ts b/packages/table-core/src/core/rows/coreRowsFeature.utils.ts index f37ce79828..d6952b7411 100644 --- a/packages/table-core/src/core/rows/coreRowsFeature.utils.ts +++ b/packages/table-core/src/core/rows/coreRowsFeature.utils.ts @@ -1,5 +1,6 @@ import { flattenBy, hasOwn, makeObjectMap } from '../../utils' import { constructCell } from '../cells/constructCell' +import { row_getTrackedSubRows } from './subRowsTracking' import type { Table_Internal } from '../../types/Table' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' @@ -164,7 +165,7 @@ export function row_getLeafRows< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): Array> { - return flattenBy(row.subRows, (d) => d.subRows) + return flattenBy(row_getTrackedSubRows(row), row_getTrackedSubRows) } /** diff --git a/packages/table-core/src/core/rows/subRowsTracking.ts b/packages/table-core/src/core/rows/subRowsTracking.ts new file mode 100644 index 0000000000..83fa06d3ce --- /dev/null +++ b/packages/table-core/src/core/rows/subRowsTracking.ts @@ -0,0 +1,82 @@ +import type { Atom } from '@tanstack/store' +import type { Row } from '../../types/Row' +import type { RowData } from '../../types/type-utils' +import type { TableFeatures } from '../../types/TableFeatures' + +interface SubRowsTrackingState { + current: unknown + versionAtom: Atom +} + +const subRowsTracking = new WeakMap() + +/** + * Reads a row's sub-rows while making replacement of that array observable to + * table computeds. + * + * Most row APIs never need to observe `subRows` directly, so the revision atom + * and accessor are installed only when a computed such as `getLeafRows` first + * asks for a tracked read. The accessor remains enumerable and preserves the + * public mutable `subRows` property while ensuring later direct assignments + * bump the revision atom. + * + * @internal + */ +export function row_getTrackedSubRows< + TFeatures extends TableFeatures, + TData extends RowData, +>(row: Row): Array> { + const tracking = subRowsTracking.get(row) + + if (!tracking) { + const createdTracking: SubRowsTrackingState = { + current: row.subRows, + versionAtom: row.table._reactivity.createWritableAtom(0, { + debugName: `row/${row.id}/subRowsVersion`, + }), + } + subRowsTracking.set(row, createdTracking) + + Object.defineProperty(row, 'subRows', { + configurable: true, + enumerable: true, + get: () => { + createdTracking.versionAtom.get() + return createdTracking.current + }, + set: (next: Array>) => { + if (createdTracking.current === next) return + createdTracking.current = next + createdTracking.versionAtom.set((version) => version + 1) + }, + }) + + createdTracking.versionAtom.get() + return createdTracking.current as Array> + } + + tracking.versionAtom.get() + return tracking.current as Array> +} + +/** + * Replaces a row's sub-row array and publishes the change when the row has + * acquired a tracked sub-row reader. + * + * @internal + */ +export function row_setSubRows< + TFeatures extends TableFeatures, + TData extends RowData, +>(row: Row, subRows: Array>): void { + const tracking = subRowsTracking.get(row) + + if (!tracking) { + row.subRows = subRows + return + } + + if (tracking.current === subRows) return + tracking.current = subRows + tracking.versionAtom.set((version) => version + 1) +} diff --git a/packages/table-core/src/core/table/constructTable.ts b/packages/table-core/src/core/table/constructTable.ts index 100bafd7e7..70a699396f 100644 --- a/packages/table-core/src/core/table/constructTable.ts +++ b/packages/table-core/src/core/table/constructTable.ts @@ -1,8 +1,12 @@ import { shallow } from '@tanstack/store' import { coreFeatures } from '../coreFeatures' -import { cloneState, hasOwn } from '../../utils' +import { cloneState, functionalUpdate, hasOwn } from '../../utils' import { atomToStore } from '../reactivity/coreReactivityFeature.utils' import { table_syncExternalStateToBaseAtoms } from './coreTablesFeature.utils' +import { + createTableOptionAtoms, + getTableOptionsFromAtoms, +} from './tableOptionAtoms' import type { Atom } from '@tanstack/store' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' @@ -79,7 +83,14 @@ export function constructTable< return Object.assign(obj, feature.getDefaultTableOptions?.(table)) }, {}) as TableOptions - const mergedOptions = { ...defaultOptions, ...tableOptions } + const mergedOptions = Object.create( + Object.getPrototypeOf(tableOptions), + Object.assign( + {}, + Object.getOwnPropertyDescriptors(defaultOptions), + Object.getOwnPropertyDescriptors(tableOptions), + ), + ) as TableOptions if (_reactivity.wrapExternalAtoms && mergedOptions.atoms) { for (const [atomKey, _atom] of Object.entries(mergedOptions.atoms)) { @@ -104,24 +115,32 @@ export function constructTable< } } - if (_reactivity.createOptionsStore) { - // @ts-ignore - direct set - table.optionsStore = _reactivity.createWritableAtom< - TableOptions - >(mergedOptions, { debugName: 'table/optionsStore' }) - Object.defineProperty(table, 'options', { - configurable: true, + const optionAtoms = createTableOptionAtoms( + mergedOptions, + _reactivity, + (key, updater) => { + table.setOptions((previous) => ({ + ...previous, + [key]: functionalUpdate(updater, Reflect.get(previous, key, previous)), + })) + }, + ) + const options = getTableOptionsFromAtoms(optionAtoms) + + Object.defineProperties(table, { + optionAtoms: { + configurable: false, enumerable: true, - get() { - return table.optionsStore!.get() - }, - set(value) { - table.optionsStore!.set(() => value) // or your real update shape - }, - }) - } else { - table.options = mergedOptions - } + value: optionAtoms, + writable: false, + }, + options: { + configurable: false, + enumerable: true, + value: options, + writable: false, + }, + }) table.initialState = getInitialTableState( table._features, @@ -134,6 +153,31 @@ export function constructTable< for (let i = 0; i < stateKeys.length; i++) { const key = stateKeys[i]! + const noControlledState = {} + const externalAtomOption = _reactivity.createReadonlyAtom( + () => + ( + table.optionAtoms.atoms?.get() as + | Record> + | undefined + )?.[key], + { + debugName: `table/options/atoms/${key}`, + }, + ) + const controlledStateOption = _reactivity.createReadonlyAtom( + () => { + const controlledState = table.optionAtoms.state?.get() as + | Record + | undefined + return controlledState && hasOwn(controlledState, key) + ? controlledState[key] + : noControlledState + }, + { + debugName: `table/options/state/${key}`, + }, + ) table.baseAtoms[key] = _reactivity.createWritableAtom( table.initialState[key], { @@ -142,9 +186,7 @@ export function constructTable< ) as any ;(table.atoms as any)[key] = _reactivity.createReadonlyAtom( () => { - const options = table.options - const externalAtoms = options.atoms - const externalAtom = externalAtoms?.[key] + const externalAtom = externalAtomOption.get() // Always touch the reactive owner so controlled state still has an // invalidation source when it is published after a framework commit. const reactiveState = externalAtom @@ -156,13 +198,11 @@ export function constructTable< return reactiveState } - const controlledState = options.state as - | Record - | undefined + const controlledState = controlledStateOption.get() - return controlledState && hasOwn(controlledState, key) - ? controlledState[key] - : reactiveState + return controlledState === noControlledState + ? reactiveState + : controlledState }, { debugName: `table/atoms/${key}` }, ) diff --git a/packages/table-core/src/core/table/coreTablesFeature.types.ts b/packages/table-core/src/core/table/coreTablesFeature.types.ts index 715455cc67..cdf8b144f8 100644 --- a/packages/table-core/src/core/table/coreTablesFeature.types.ts +++ b/packages/table-core/src/core/table/coreTablesFeature.types.ts @@ -65,6 +65,47 @@ export type ExternalAtoms = Partial<{ [K in keyof TableState]: Atom[K]> }> +type ConstructStaticOptionKey = 'features' | 'atoms' | 'initialState' + +/** + * One atom per currently resolved table option. + * + * The atom properties themselves are readonly so their identities stay + * stable. Ordinary option atoms are writable; construction-static options + * remain readonly. + */ +export type TableOptionAtoms< + TFeatures extends TableFeatures, + TData extends RowData, +> = { + /** Increments once after each atomic update of the resolved options. */ + readonly snapshotVersion: ReadonlyAtom +} & { + readonly [K in keyof TableOptions< + TFeatures, + TData + > as K extends 'snapshotVersion' + ? never + : K]: K extends ConstructStaticOptionKey + ? ReadonlyAtom[K]> + : Atom[K]> +} + +/** + * The stable readonly options view exposed by `table.options`. + * + * Every property read is routed to the matching existing option atom. + */ +export type TableOptionsLive< + TFeatures extends TableFeatures, + TData extends RowData, +> = { + readonly [K in keyof TableOptions]: TableOptions< + TFeatures, + TData + >[K] +} + /** * Internal "all features" flat variants of the atom types. `Table_Internal` * uses these so feature code (written generically over `TFeatures`) can access @@ -231,15 +272,17 @@ export interface Table_CoreProperties< */ readonly initialState: TableState /** - * A read-only reference to the table's current options. + * A stable live view of the table's current resolved options. + * + * Reading a property reads the matching entry in `optionAtoms`. */ - readonly options: TableOptions + readonly options: TableOptionsLive /** - * Writable atom for table options. Only created when `createOptionsStore` is - * true on the active core reactivity bindings. Adapters that opt out keep - * options as plain resolved data instead of backing them with an atom. + * Stable atoms for individual resolved option values. + * + * Ordinary options are writable. Construction-static options are readonly. */ - readonly optionsStore?: Atom> | undefined + readonly optionAtoms: TableOptionAtoms /** * The readonly flat store for the table state. Derives from `table.atoms` * only; never reads external state directly. diff --git a/packages/table-core/src/core/table/coreTablesFeature.utils.ts b/packages/table-core/src/core/table/coreTablesFeature.utils.ts index 73f3aea4b5..b05855af0b 100644 --- a/packages/table-core/src/core/table/coreTablesFeature.utils.ts +++ b/packages/table-core/src/core/table/coreTablesFeature.utils.ts @@ -1,4 +1,5 @@ import { cloneState, functionalUpdate } from '../../utils' +import { applyTableOptions } from './tableOptionAtoms' import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' @@ -74,10 +75,11 @@ export function table_publishExternalState< currentState, externalState, ) => currentState === externalState, + commitToken?: number, ): void { table._reactivity.batch(() => { table_syncExternalStateToBaseAtoms(table, state, compare) - table._reactivity.commit?.() + table._reactivity.commit?.(commitToken) }) } @@ -132,51 +134,55 @@ export function table_mergeOptions< table: Table_Internal, newOptions: TableOptions, ) { - const { features, atoms, initialState } = table.options + const currentOptions = table.options + const { features, atoms, initialState } = currentOptions + const mergeOptions = currentOptions.mergeOptions // simple merge if no mergeOptions is provided - performant - if (!table.options.mergeOptions) { + if (!mergeOptions) { return { - ...table.options, + ...currentOptions, ...newOptions, features, atoms, initialState, - } + } as TableOptions } // else use the mergeOptions function and preserve getters/setters - const mergedOptions = table.options.mergeOptions( - table.options as TableOptions, - newOptions, - ) - const descriptors: PropertyDescriptorMap = { + // Give custom merge logic a descriptor-preserving snapshot. A merge + // function that mutates its first argument must not mutate the controller's + // installed source before change detection runs. + const currentOptionsSnapshot = Object.create( + Object.getPrototypeOf(currentOptions), + Object.getOwnPropertyDescriptors(currentOptions), + ) as TableOptions + const mergedOptions = mergeOptions(currentOptionsSnapshot, newOptions) + const descriptors = { ...Object.getOwnPropertyDescriptors(mergedOptions), - } - - return Object.defineProperties( - Object.create(Object.getPrototypeOf(mergedOptions)), - { - ...descriptors, - features: { - value: features, - enumerable: true, - configurable: true, - writable: true, - }, - atoms: { - value: atoms, - enumerable: true, - configurable: true, - writable: true, - }, - initialState: { - value: initialState, - enumerable: true, - configurable: true, - writable: true, - }, + features: { + value: features, + enumerable: true, + configurable: true, + writable: true, }, + atoms: { + value: atoms, + enumerable: true, + configurable: true, + writable: true, + }, + initialState: { + value: initialState, + enumerable: true, + configurable: true, + writable: true, + }, + } as Record + + return Object.create( + Object.getPrototypeOf(mergedOptions), + descriptors, ) as TableOptions } @@ -201,19 +207,21 @@ export function table_setOptions< options?: { syncExternalState?: boolean }, -): void { +): number | undefined { const newOptions = functionalUpdate( updater, table.options as TableOptions, ) const mergedOptions = table_mergeOptions(table, newOptions) - if (table.optionsStore) { - table.optionsStore.set(() => mergedOptions) - } else { - table.options = mergedOptions - } + const commitToken = applyTableOptions(table.optionAtoms, mergedOptions) if (options?.syncExternalState !== false) { - table_publishExternalState(table, mergedOptions.state ?? null) + table_publishExternalState( + table, + mergedOptions.state ?? null, + undefined, + commitToken, + ) } + return commitToken } diff --git a/packages/table-core/src/core/table/tableOptionAtoms.ts b/packages/table-core/src/core/table/tableOptionAtoms.ts new file mode 100644 index 0000000000..6d22ef4847 --- /dev/null +++ b/packages/table-core/src/core/table/tableOptionAtoms.ts @@ -0,0 +1,190 @@ +import type { Atom, ReadonlyAtom } from '@tanstack/store' +import type { TableReactivityBindings } from '../reactivity/coreReactivityFeature.types' +import type { RowData, Updater } from '../../types/type-utils' +import type { TableFeatures } from '../../types/TableFeatures' +import type { TableOptions } from '../../types/TableOptions' +import type { + TableOptionAtoms, + TableOptionsLive, +} from './coreTablesFeature.types' + +type OptionKey = string | symbol +type ValueBox = { value: unknown } + +interface TableOptionAtomsInternals { + readonly options: unknown + apply: (options: unknown) => number | undefined +} + +const constructStaticOptionKeys = new Set([ + 'features', + 'atoms', + 'initialState', +]) +const snapshotVersionKey = 'snapshotVersion' +const optionAtomsInternals = new WeakMap() + +/** + * Creates one stable atom for each resolved option and a readonly live view. + * + * Values are boxed so callback-valued options are never interpreted as + * computed functions or atom updaters during initialization. + */ +export function createTableOptionAtoms< + TFeatures extends TableFeatures, + TData extends RowData, +>( + initialOptions: TableOptions, + reactivity: TableReactivityBindings, + setOption: (key: OptionKey, updater: Updater) => void, +): TableOptionAtoms { + const optionAtoms = Object.create(null) as Record< + PropertyKey, + Atom | ReadonlyAtom + > + const optionsTarget = Object.create(null) as Record + const valueAtoms = new Map>() + const snapshotVersionSource = reactivity.createWritableAtom(0, { + debugName: 'table/optionAtoms/snapshotVersion', + mode: 'staged', + }) + + Object.defineProperty(optionAtoms, snapshotVersionKey, { + configurable: false, + enumerable: true, + value: { + get: () => snapshotVersionSource.get(), + subscribe: snapshotVersionSource.subscribe.bind(snapshotVersionSource), + } satisfies ReadonlyAtom, + writable: false, + }) + + const setValue = (key: OptionKey, value: unknown): boolean => { + if (key === snapshotVersionKey) { + throw new Error( + `Table option "${snapshotVersionKey}" is reserved by table.optionAtoms`, + ) + } + + const valueAtom = valueAtoms.get(key) + if (valueAtom) { + if (Object.is(valueAtom.get().value, value)) { + return false + } + + valueAtom.set({ value }) + return true + } + + const newValueAtom = reactivity.createWritableAtom( + { value }, + { + debugName: `table/optionAtoms/${String(key)}`, + mode: 'staged', + }, + ) + const readonlyAtom = reactivity.createReadonlyAtom( + () => newValueAtom.get().value, + { + debugName: `table/options/${String(key)}`, + }, + ) + const publicAtom = constructStaticOptionKeys.has(key) + ? readonlyAtom + : ({ + get: () => readonlyAtom.get(), + subscribe: readonlyAtom.subscribe.bind(readonlyAtom), + set: (updater: Updater) => setOption(key, updater), + } satisfies Atom) + + valueAtoms.set(key, newValueAtom) + Object.defineProperty(optionAtoms, key, { + configurable: true, + enumerable: true, + value: publicAtom, + writable: false, + }) + Object.defineProperty(optionsTarget, key, { + configurable: true, + enumerable: true, + get: () => optionAtoms[key]!.get(), + }) + + return true + } + + for (const key of Reflect.ownKeys(initialOptions)) { + setValue(key, Reflect.get(initialOptions, key, initialOptions)) + } + + const rejectMutation = () => false + const options = new Proxy(optionsTarget, { + getOwnPropertyDescriptor: (target, key) => { + const descriptor = Reflect.getOwnPropertyDescriptor(target, key) + return descriptor + ? { + configurable: true, + enumerable: true, + value: Reflect.get(target, key, target), + writable: false, + } + : undefined + }, + defineProperty: rejectMutation, + deleteProperty: rejectMutation, + preventExtensions: rejectMutation, + set: rejectMutation, + setPrototypeOf: rejectMutation, + }) as TableOptionsLive + + const apply = (nextOptions: TableOptions) => { + const nextKeys = Reflect.ownKeys(nextOptions) + let changed = false + let commitToken: number | undefined + + reactivity.batch(() => { + for (const key of nextKeys) { + changed = + setValue(key, Reflect.get(nextOptions, key, nextOptions)) || changed + } + + if (changed) { + snapshotVersionSource.set((version) => version + 1) + commitToken = reactivity.stage?.() + } else { + commitToken = reactivity.getStageToken?.() + } + }) + + return commitToken + } + + optionAtomsInternals.set(optionAtoms, { + options, + apply: apply as (options: unknown) => number | undefined, + }) + + return optionAtoms as TableOptionAtoms +} + +export function getTableOptionsFromAtoms< + TFeatures extends TableFeatures, + TData extends RowData, +>( + optionAtoms: TableOptionAtoms, +): TableOptionsLive { + return optionAtomsInternals.get(optionAtoms)!.options as TableOptionsLive< + TFeatures, + TData + > +} + +export function applyTableOptions< + TFeatures extends TableFeatures, + TData extends RowData, +>( + optionAtoms: TableOptionAtoms, + nextOptions: TableOptions, +): number | undefined { + return optionAtomsInternals.get(optionAtoms)!.apply(nextOptions) +} diff --git a/packages/table-core/src/features/cell-selection/cellSelectionFeature.ts b/packages/table-core/src/features/cell-selection/cellSelectionFeature.ts index d0d3b7a47b..71fed09077 100644 --- a/packages/table-core/src/features/cell-selection/cellSelectionFeature.ts +++ b/packages/table-core/src/features/cell-selection/cellSelectionFeature.ts @@ -1,7 +1,6 @@ import { assignPrototypeAPIs, assignTableAPIs, - callMemoOrStaticFn, makeStateUpdater, } from '../../utils' import { @@ -127,31 +126,14 @@ export const cellSelectionFeature: TableFeature = { fn: () => table_autoResetCellSelection(table), }, table_getCellSelectionColumnIndexes: { - fn: () => table_getCellSelectionColumnIndexes(table), + computed: () => table_getCellSelectionColumnIndexes(table), // Mirrors columnVisibilityFeature's own deps rather than calling - // getVisibleLeafColumns() here, so the map stays memoized even when + // getVisibleLeafColumns() directly, so the map stays reactive even when // that feature is absent and its static rebuilds on every call. // columnPinning is added because cells render in pinned order. - memoDeps: () => [ - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.grouping?.get(), - table.options.columns, - table.options.groupedColumnMode, - ], }, table_getCellSelectionBounds: { - fn: () => table_getCellSelectionBounds(table), - memoDeps: () => [ - table.atoms.cellSelection?.get(), - table.getRowsInDisplayOrder(), - callMemoOrStaticFn( - table, - 'getCellSelectionColumnIndexes', - table_getCellSelectionColumnIndexes, - ), - ], + computed: () => table_getCellSelectionBounds(table), }, table_selectCellRange: { fn: (range, opts) => table_selectCellRange(table, range, opts), @@ -172,61 +154,19 @@ export const cellSelectionFeature: TableFeature = { fn: (direction) => table_extendCellSelection(table, direction), }, table_getSelectedCellIds: { - fn: () => table_getSelectedCellIds(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCellSelectionBounds', - table_getCellSelectionBounds, - ), - table.getRowsInDisplayOrder(), - table.options.enableCellSelection, - ], + computed: () => table_getSelectedCellIds(table), }, table_getSelectedCellRangesData: { - fn: () => table_getSelectedCellRangesData(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCellSelectionBounds', - table_getCellSelectionBounds, - ), - table.getRowsInDisplayOrder(), - table.options.enableCellSelection, - ], + computed: () => table_getSelectedCellRangesData(table), }, table_getSelectedCellCount: { - fn: () => table_getSelectedCellCount(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCellSelectionBounds', - table_getCellSelectionBounds, - ), - table.getRowsInDisplayOrder(), - table.options.enableCellSelection, - ], + computed: () => table_getSelectedCellCount(table), }, table_getCellSelectionRowIds: { - fn: () => table_getCellSelectionRowIds(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCellSelectionBounds', - table_getCellSelectionBounds, - ), - table.getRowsInDisplayOrder(), - ], + computed: () => table_getCellSelectionRowIds(table), }, table_getCellSelectionColumnIds: { - fn: () => table_getCellSelectionColumnIds(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCellSelectionBounds', - table_getCellSelectionBounds, - ), - ], + computed: () => table_getCellSelectionColumnIds(table), }, }) }, diff --git a/packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts b/packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts index 41b2a0c897..b8635c4df1 100644 --- a/packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts +++ b/packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts @@ -385,7 +385,7 @@ function resolveCellPosition< * Checks whether this cell falls inside any selected range. * * Deliberately not memoized. Registering this through `assignPrototypeAPIs` - * with `memoDeps` would allocate a memo closure and dependency array per cell, + * with a native computed would allocate a memo closure per cell, * which costs more than the handful of integer comparisons it would save. * * @example diff --git a/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts b/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts index 193d1066dc..f22312f086 100644 --- a/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts +++ b/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts @@ -20,35 +20,36 @@ export const columnFacetingFeature: TableFeature = { assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnFacetingFeature', prototype, table, { column_getFacetedRowModel: { - memoDeps: () => [ - table.getPreFilteredRowModel().rows, - table.atoms.columnFilters?.get(), - table.atoms.globalFilter?.get(), - table.getFilteredRowModel().rows, - ], - fn: (column) => column_getFacetedRowModel(column, column.table), + computed: (column) => { + void table.getPreFilteredRowModel().rows + void table.atoms.columnFilters?.get() + void table.atoms.globalFilter?.get() + // Ensure row.columnFilters metadata is populated before faceting. + void table.getFilteredRowModel().rows + return column_getFacetedRowModel(column, column.table) + }, }, column_getFacetedMinMaxValues: { - memoDeps: (column) => [ - callMemoOrStaticFn( + computed: (column) => { + void callMemoOrStaticFn( column, 'getFacetedRowModel', column_getFacetedRowModel, column.table, - ).flatRows, - ], - fn: (column) => column_getFacetedMinMaxValues(column, column.table), + ).flatRows + return column_getFacetedMinMaxValues(column, column.table) + }, }, column_getFacetedUniqueValues: { - memoDeps: (column) => [ - callMemoOrStaticFn( + computed: (column) => { + void callMemoOrStaticFn( column, 'getFacetedRowModel', column_getFacetedRowModel, column.table, - ).flatRows, - ], - fn: (column) => column_getFacetedUniqueValues(column, column.table), + ).flatRows + return column_getFacetedUniqueValues(column, column.table) + }, }, }) }, @@ -56,33 +57,34 @@ export const columnFacetingFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('columnFacetingFeature', table, { table_getGlobalFacetedRowModel: { - memoDeps: () => [ - table.getPreFilteredRowModel().rows, - table.atoms.columnFilters?.get(), - table.atoms.globalFilter?.get(), - table.getFilteredRowModel().rows, - ], - fn: () => table_getGlobalFacetedRowModel(table), + computed: () => { + void table.getPreFilteredRowModel().rows + void table.atoms.columnFilters?.get() + void table.atoms.globalFilter?.get() + // Ensure row.columnFilters metadata is populated before faceting. + void table.getFilteredRowModel().rows + return table_getGlobalFacetedRowModel(table) + }, }, table_getGlobalFacetedMinMaxValues: { - memoDeps: () => [ - callMemoOrStaticFn( + computed: () => { + void callMemoOrStaticFn( table, 'getGlobalFacetedRowModel', table_getGlobalFacetedRowModel, - ).flatRows, - ], - fn: () => table_getGlobalFacetedMinMaxValues(table), + ).flatRows + return table_getGlobalFacetedMinMaxValues(table) + }, }, table_getGlobalFacetedUniqueValues: { - memoDeps: () => [ - callMemoOrStaticFn( + computed: () => { + void callMemoOrStaticFn( table, 'getGlobalFacetedRowModel', table_getGlobalFacetedRowModel, - ).flatRows, - ], - fn: () => table_getGlobalFacetedUniqueValues(table), + ).flatRows + return table_getGlobalFacetedUniqueValues(table) + }, }, }) }, diff --git a/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts b/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts index 3582901275..6f2439aa16 100644 --- a/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts +++ b/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts @@ -25,28 +25,29 @@ export function createFacetedMinMaxValues< const table = _table as unknown as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', - fn: (flatRows) => _createFacetedMinMaxValues(table, columnId, flatRows), fnName: 'table.getFacetedMinMaxValues', - memoDeps: () => { + fn: () => { + let flatRows: Array> + if (columnId === '__global__') { - return [ - callMemoOrStaticFn( - table, - 'getGlobalFacetedRowModel', - table_getGlobalFacetedRowModel, - ).flatRows, - ] - } - const column = table.getColumn(columnId) - if (!column) return [table.getPreFilteredRowModel().flatRows] - return [ - callMemoOrStaticFn( - column, - 'getFacetedRowModel', - column_getFacetedRowModel, + flatRows = callMemoOrStaticFn( table, - ).flatRows, - ] + 'getGlobalFacetedRowModel', + table_getGlobalFacetedRowModel, + ).flatRows + } else { + const column = table.getColumn(columnId) + flatRows = column + ? callMemoOrStaticFn( + column, + 'getFacetedRowModel', + column_getFacetedRowModel, + table, + ).flatRows + : table.getPreFilteredRowModel().flatRows + } + + return _createFacetedMinMaxValues(table, columnId, flatRows) }, table, }) diff --git a/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts b/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts index a2b55d3dc3..4d7a0e5898 100644 --- a/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts +++ b/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts @@ -28,20 +28,22 @@ export function createFacetedRowModel< feature: 'columnFacetingFeature', table, fnName: 'createFacetedRowModel', - memoDeps: () => [ - table.getPreFilteredRowModel(), - table.atoms.columnFilters?.get(), - table.atoms.globalFilter?.get(), - table.getFilteredRowModel(), - ], - fn: (preRowModel, columnFilters, globalFilter) => - _createFacetedRowModel( + fn: () => { + const preRowModel = table.getPreFilteredRowModel() + const columnFilters = table.atoms.columnFilters?.get() + const globalFilter = table.atoms.globalFilter?.get() + + // Filtering populates row.columnFilters metadata consumed below. + table.getFilteredRowModel() + + return _createFacetedRowModel( table, columnId, preRowModel, columnFilters, globalFilter, - ), + ) + }, }) } } diff --git a/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts b/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts index df8cdcd1c3..d04656f49d 100644 --- a/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts +++ b/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts @@ -27,28 +27,29 @@ export function createFacetedUniqueValues< feature: 'columnFacetingFeature', table, fnName: 'table.getFacetedUniqueValues', - memoDeps: () => { + fn: () => { + let flatRows: Array> + if (columnId === '__global__') { - return [ - callMemoOrStaticFn( - table, - 'getGlobalFacetedRowModel', - table_getGlobalFacetedRowModel, - ).flatRows, - ] - } - const column = table.getColumn(columnId) - if (!column) return [table.getPreFilteredRowModel().flatRows] - return [ - callMemoOrStaticFn( - column, - 'getFacetedRowModel', - column_getFacetedRowModel, + flatRows = callMemoOrStaticFn( table, - ).flatRows, - ] + 'getGlobalFacetedRowModel', + table_getGlobalFacetedRowModel, + ).flatRows + } else { + const column = table.getColumn(columnId) + flatRows = column + ? callMemoOrStaticFn( + column, + 'getFacetedRowModel', + column_getFacetedRowModel, + table, + ).flatRows + : table.getPreFilteredRowModel().flatRows + } + + return _createFacetedUniqueValues(table, columnId, flatRows) }, - fn: (flatRows) => _createFacetedUniqueValues(table, columnId, flatRows), }) } } diff --git a/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts b/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts index 79ed4e1bc2..455effd306 100644 --- a/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts +++ b/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts @@ -39,11 +39,6 @@ export function createFilteredRowModel< feature: 'columnFilteringFeature', table, fnName: 'table.getFilteredRowModel', - memoDeps: () => [ - table.getPreFilteredRowModel(), - table.atoms.columnFilters?.get(), - table.atoms.globalFilter?.get(), - ], fn: () => _createFilteredRowModel(table), onAfterUpdate: () => table_autoResetPageIndex(table), }) diff --git a/packages/table-core/src/features/column-filtering/filterRowsUtils.ts b/packages/table-core/src/features/column-filtering/filterRowsUtils.ts index e8a701a7d6..ae112243a0 100644 --- a/packages/table-core/src/features/column-filtering/filterRowsUtils.ts +++ b/packages/table-core/src/features/column-filtering/filterRowsUtils.ts @@ -1,4 +1,5 @@ import { constructRow } from '../../core/rows/constructRow' +import { row_setSubRows } from '../../core/rows/subRowsTracking' import { makeObjectMap } from '../../utils' import type { Row_ColumnFiltering } from './columnFilteringFeature.types' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' @@ -65,7 +66,7 @@ function filterRowModelFromLeafs< newRow.columnFilters = row.columnFilters if (row.subRows.length && depth < maxDepth) { - newRow.subRows = recurseFilterRows(row.subRows, depth + 1) + row_setSubRows(newRow, recurseFilterRows(row.subRows, depth + 1)) row = newRow if (filterRow(row) && !newRow.subRows.length) { @@ -137,7 +138,7 @@ function filterRowModelFromRoot< undefined, row.parentId, ) - newRow.subRows = recurseFilterRows(row.subRows, depth + 1) + row_setSubRows(newRow, recurseFilterRows(row.subRows, depth + 1)) row = newRow } diff --git a/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts b/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts index a0511fb33e..ae9e1c0ddb 100644 --- a/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts +++ b/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts @@ -1,5 +1,6 @@ import { hasOwn, makeObjectMap, tableMemo } from '../../utils' import { constructRow } from '../../core/rows/constructRow' +import { row_setSubRows } from '../../core/rows/subRowsTracking' import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils' import { table_autoResetExpanded } from '../row-expanding/rowExpandingFeature.utils' import { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils' @@ -37,11 +38,6 @@ export function createGroupedRowModel< feature: 'columnGroupingFeature', table, fnName: 'table.getGroupedRowModel', - memoDeps: () => [ - table.atoms.grouping?.get(), - table.getPreGroupedRowModel(), - table.options.columns, - ], fn: () => _createGroupedRowModel(table), onAfterUpdate: () => { const grouping = table.atoms.grouping?.get() @@ -109,7 +105,10 @@ function _createGroupedRowModel< // parent group's loop or the root loop), so only descendants below // the terminal depth are pushed here. if (row.subRows.length) { - row.subRows = groupUpRecursively(row.subRows, depth + 1, row.id) + row_setSubRows( + row, + groupUpRecursively(row.subRows, depth + 1, row.id), + ) for (let i = 0; i < row.subRows.length; i++) { const subRow = row.subRows[i]! groupedFlatRows.push(subRow) diff --git a/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts b/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts index a279a44fc7..0ed143d206 100644 --- a/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts +++ b/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts @@ -49,15 +49,7 @@ export const columnOrderingFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('columnOrderingFeature', table, { table_getColumnIndexes: { - fn: () => table_getColumnIndexes(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getColumnIndexes(table), }, table_setColumnOrder: { fn: (updater) => table_setColumnOrder(table, updater), @@ -66,12 +58,15 @@ export const columnOrderingFeature: TableFeature = { fn: (defaultState) => table_resetColumnOrder(table, defaultState), }, table_getOrderColumnsFn: { - fn: () => table_getOrderColumnsFn(table), - memoDeps: () => [ - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => { + // These values are consumed when the returned ordering function runs, + // but they also determine that function's behavior. Read them while + // resolving the computed so either change replaces the cached + // function, matching the former explicit memo dependency list. + void table.atoms.grouping?.get() + void table.options.groupedColumnMode + return table_getOrderColumnsFn(table) + }, }, }) }, diff --git a/packages/table-core/src/features/column-pinning/columnPinningFeature.ts b/packages/table-core/src/features/column-pinning/columnPinningFeature.ts index e02665e562..2338800b83 100644 --- a/packages/table-core/src/features/column-pinning/columnPinningFeature.ts +++ b/packages/table-core/src/features/column-pinning/columnPinningFeature.ts @@ -4,7 +4,11 @@ import { callMemoOrStaticFn, makeStateUpdater, } from '../../utils' -import { table_getVisibleLeafColumns } from '../column-visibility/columnVisibilityFeature.utils' +import { + column_getIsVisible, + row_getVisibleCellsByColumnId, +} from '../column-visibility/columnVisibilityFeature.utils' +import { buildHeaderGroups } from '../../core/headers/buildHeaderGroups' import { column_getCanPin, column_getIsPinned, @@ -12,8 +16,6 @@ import { column_pin, getDefaultColumnPinningState, row_getCenterVisibleCells, - row_getEndVisibleCells, - row_getStartVisibleCells, table_getCenterFlatHeaders, table_getCenterFooterGroups, table_getCenterHeaderGroups, @@ -22,7 +24,6 @@ import { table_getCenterVisibleLeafColumns, table_getEndFlatHeaders, table_getEndFooterGroups, - table_getEndHeaderGroups, table_getEndLeafColumns, table_getEndLeafHeaders, table_getEndVisibleLeafColumns, @@ -31,15 +32,20 @@ import { table_getPinnedVisibleLeafColumns, table_getStartFlatHeaders, table_getStartFooterGroups, - table_getStartHeaderGroups, table_getStartLeafColumns, table_getStartLeafHeaders, table_getStartVisibleLeafColumns, table_resetColumnPinning, table_setColumnPinning, } from './columnPinningFeature.utils' +import type { ReadonlyAtom } from '@tanstack/store' import type { TableFeature } from '../../types/TableFeatures' +function createLazySelector(create: () => ReadonlyAtom): () => T { + let atom: ReadonlyAtom | undefined + return () => (atom ??= create()).get() +} + /** * Feature that adds column pinning state and APIs for logical start, center, * and end regions. @@ -83,35 +89,110 @@ export const columnPinningFeature: TableFeature = { }, assignRowPrototype: (prototype, table) => { + const readStartPinning = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => table.atoms.columnPinning?.get()?.start, + { + debugName: 'table/selectors/columnPinning/start', + mode: 'memo', + }, + ), + ) + const readEndPinning = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => table.atoms.columnPinning?.get()?.end, + { + debugName: 'table/selectors/columnPinning/end', + mode: 'memo', + }, + ), + ) + assignPrototypeAPIs('columnPinningFeature', prototype, table, { row_getCenterVisibleCells: { - fn: (row) => row_getCenterVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - row.table.atoms.columnPinning?.get(), - row.table.atoms.columnVisibility?.get(), - ], + computed: (row) => row_getCenterVisibleCells(row), }, row_getStartVisibleCells: { - fn: (row) => row_getStartVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - row.table.atoms.columnPinning?.get()?.start, - row.table.atoms.columnVisibility?.get(), - ], + computed: (row) => { + const start = readStartPinning() ?? [] + if (!start.length) return [] + const cellsByColumnId = callMemoOrStaticFn( + row, + 'getVisibleCellsByColumnId', + row_getVisibleCellsByColumnId, + ) + const cells: Array<(typeof cellsByColumnId)[string]> = [] + for (let i = 0; i < start.length; i++) { + const cell = cellsByColumnId[start[i]!] + if (cell) { + ;(cell as any).position = 'start' + cells.push(cell) + } + } + return cells + }, }, row_getEndVisibleCells: { - fn: (row) => row_getEndVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - row.table.atoms.columnPinning?.get()?.end, - row.table.atoms.columnVisibility?.get(), - ], + computed: (row) => { + const end = readEndPinning() ?? [] + if (!end.length) return [] + const cellsByColumnId = callMemoOrStaticFn( + row, + 'getVisibleCellsByColumnId', + row_getVisibleCellsByColumnId, + ) + const cells: Array<(typeof cellsByColumnId)[string]> = [] + for (let i = 0; i < end.length; i++) { + const cell = cellsByColumnId[end[i]!] + if (cell) { + ;(cell as any).position = 'end' + cells.push(cell) + } + } + return cells + }, }, }) }, constructTableAPIs: (table) => { + const readStartPinning = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => table.atoms.columnPinning?.get()?.start, + { + debugName: 'table/selectors/columnPinning/startHeaderGroups', + mode: 'memo', + }, + ), + ) + const readEndPinning = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => table.atoms.columnPinning?.get()?.end, + { + debugName: 'table/selectors/columnPinning/endHeaderGroups', + mode: 'memo', + }, + ), + ) + const buildPinnedHeaderGroups = ( + position: 'start' | 'end', + pinnedColumnIds: ReadonlyArray, + ) => { + const allColumns = table.getAllColumns() + const leafColumnsById = table.getAllLeafColumnsById() + const orderedLeafColumns: typeof allColumns = [] + for (let i = 0; i < pinnedColumnIds.length; i++) { + const column = leafColumnsById[pinnedColumnIds[i]!] + if ( + column && + callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible) + ) { + orderedLeafColumns.push(column) + } + } + return buildHeaderGroups(allColumns, orderedLeafColumns, table, position) + } + assignTableAPIs('columnPinningFeature', table, { table_setColumnPinning: { fn: (updater) => table_setColumnPinning(table, updater), @@ -124,167 +205,59 @@ export const columnPinningFeature: TableFeature = { }, // header groups table_getStartHeaderGroups: { - fn: () => table_getStartHeaderGroups(table), - memoDeps: () => [ - table.getAllColumns(), - callMemoOrStaticFn( - table, - 'getVisibleLeafColumns', - table_getVisibleLeafColumns, - ), - table.atoms.columnPinning?.get()?.start, - table.atoms.columnOrder?.get(), - ], + computed: () => { + table.atoms.columnOrder?.get() + return buildPinnedHeaderGroups('start', readStartPinning() ?? []) + }, }, table_getCenterHeaderGroups: { - fn: () => table_getCenterHeaderGroups(table), - memoDeps: () => [ - table.getAllColumns(), - callMemoOrStaticFn( - table, - 'getVisibleLeafColumns', - table_getVisibleLeafColumns, - ), - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - ], + computed: () => table_getCenterHeaderGroups(table), }, table_getEndHeaderGroups: { - fn: () => table_getEndHeaderGroups(table), - memoDeps: () => [ - table.getAllColumns(), - callMemoOrStaticFn( - table, - 'getVisibleLeafColumns', - table_getVisibleLeafColumns, - ), - table.atoms.columnPinning?.get()?.end, - table.atoms.columnOrder?.get(), - ], + computed: () => { + table.atoms.columnOrder?.get() + return buildPinnedHeaderGroups('end', readEndPinning() ?? []) + }, }, // footer groups table_getStartFooterGroups: { - fn: () => table_getStartFooterGroups(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getStartHeaderGroups', - table_getStartHeaderGroups, - ), - ], + computed: () => table_getStartFooterGroups(table), }, table_getCenterFooterGroups: { - fn: () => table_getCenterFooterGroups(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCenterHeaderGroups', - table_getCenterHeaderGroups, - ), - ], + computed: () => table_getCenterFooterGroups(table), }, table_getEndFooterGroups: { - fn: () => table_getEndFooterGroups(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getEndHeaderGroups', - table_getEndHeaderGroups, - ), - ], + computed: () => table_getEndFooterGroups(table), }, // flat headers table_getStartFlatHeaders: { - fn: () => table_getStartFlatHeaders(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getStartHeaderGroups', - table_getStartHeaderGroups, - ), - ], + computed: () => table_getStartFlatHeaders(table), }, table_getEndFlatHeaders: { - fn: () => table_getEndFlatHeaders(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getEndHeaderGroups', - table_getEndHeaderGroups, - ), - ], + computed: () => table_getEndFlatHeaders(table), }, table_getCenterFlatHeaders: { - fn: () => table_getCenterFlatHeaders(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCenterHeaderGroups', - table_getCenterHeaderGroups, - ), - ], + computed: () => table_getCenterFlatHeaders(table), }, // leaf headers table_getStartLeafHeaders: { - fn: () => table_getStartLeafHeaders(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getStartHeaderGroups', - table_getStartHeaderGroups, - ), - ], + computed: () => table_getStartLeafHeaders(table), }, table_getEndLeafHeaders: { - fn: () => table_getEndLeafHeaders(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getEndHeaderGroups', - table_getEndHeaderGroups, - ), - ], + computed: () => table_getEndLeafHeaders(table), }, table_getCenterLeafHeaders: { - fn: () => table_getCenterLeafHeaders(table), - memoDeps: () => [ - callMemoOrStaticFn( - table, - 'getCenterHeaderGroups', - table_getCenterHeaderGroups, - ), - ], + computed: () => table_getCenterLeafHeaders(table), }, // leaf columns table_getStartLeafColumns: { - fn: () => table_getStartLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getStartLeafColumns(table), }, table_getEndLeafColumns: { - fn: () => table_getEndLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getEndLeafColumns(table), }, table_getCenterLeafColumns: { - fn: () => table_getCenterLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getCenterLeafColumns(table), }, table_getPinnedLeafColumns: { fn: (position) => table_getPinnedLeafColumns(table, position), @@ -292,37 +265,13 @@ export const columnPinningFeature: TableFeature = { }, // visible leaf columns table_getStartVisibleLeafColumns: { - fn: () => table_getStartVisibleLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getStartVisibleLeafColumns(table), }, table_getCenterVisibleLeafColumns: { - fn: () => table_getCenterVisibleLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getCenterVisibleLeafColumns(table), }, table_getEndVisibleLeafColumns: { - fn: () => table_getEndVisibleLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getEndVisibleLeafColumns(table), }, table_getPinnedVisibleLeafColumns: { fn: (position) => table_getPinnedVisibleLeafColumns(table, position), diff --git a/packages/table-core/src/features/column-sizing/columnSizingFeature.ts b/packages/table-core/src/features/column-sizing/columnSizingFeature.ts index 94b7beed48..0ad8c1576f 100644 --- a/packages/table-core/src/features/column-sizing/columnSizingFeature.ts +++ b/packages/table-core/src/features/column-sizing/columnSizingFeature.ts @@ -1,11 +1,11 @@ import { assignPrototypeAPIs, assignTableAPIs, + hasOwn, makeStateUpdater, } from '../../utils' import { column_getAfter, - column_getSize, column_getStart, column_resetSize, getDefaultColumnSizingColumnDef, @@ -20,8 +20,34 @@ import { table_resetColumnSizing, table_setColumnSizing, } from './columnSizingFeature.utils' +import type { ReadonlyAtom } from '@tanstack/store' import type { TableFeature } from '../../types/TableFeatures' +function createLazySelector(create: () => ReadonlyAtom): () => T { + let atom: ReadonlyAtom | undefined + return () => (atom ??= create()).get() +} + +function resolveColumnSize( + column: { + columnDef: { + maxSize?: number + minSize?: number + size?: number + } + }, + columnSize: number | undefined, +): number { + const defaults = getDefaultColumnSizingColumnDef() + return Math.min( + Math.max( + column.columnDef.minSize ?? defaults.minSize, + columnSize ?? column.columnDef.size ?? defaults.size, + ), + column.columnDef.maxSize ?? defaults.maxSize, + ) +} + /** * Feature that adds column sizing state, defaults, and size measurement APIs. */ @@ -44,13 +70,35 @@ export const columnSizingFeature: TableFeature = { }, assignColumnPrototype: (prototype, table) => { + const sizeSelectors = new WeakMap number | undefined>() + const readColumnSize = (column: { id: string }) => { + let readSize = sizeSelectors.get(column) + if (!readSize) { + readSize = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => { + const sizing = table.atoms.columnSizing?.get() + return sizing && hasOwn(sizing, column.id) + ? sizing[column.id] + : undefined + }, + { + debugName: `table/selectors/columnSizing/${column.id}`, + mode: 'memo', + }, + ), + ) + sizeSelectors.set(column, readSize) + } + return readSize() + } + assignPrototypeAPIs('columnSizingFeature', prototype, table, { column_getSize: { - fn: (column) => column_getSize(column), - memoDeps: (column) => [ - table.options.columns, - table.atoms.columnSizing?.get()?.[column.id], // just this column's size state - ], + computed: (column) => { + void table.options.columns + return resolveColumnSize(column, readColumnSize(column)) + }, }, // O(1) lookups into the memoized table-level offsets, so no per-column // memos here @@ -67,27 +115,41 @@ export const columnSizingFeature: TableFeature = { }, assignHeaderPrototype: (prototype, table) => { + const sizeSelectors = new WeakMap number | undefined>() + const readColumnSize = (column: { id: string }) => { + let readSize = sizeSelectors.get(column) + if (!readSize) { + readSize = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => { + const sizing = table.atoms.columnSizing?.get() + return sizing && hasOwn(sizing, column.id) + ? sizing[column.id] + : undefined + }, + { + debugName: `table/selectors/headerColumnSizing/${column.id}`, + mode: 'memo', + }, + ), + ) + sizeSelectors.set(column, readSize) + } + return readSize() + } + assignPrototypeAPIs('columnSizingFeature', prototype, table, { header_getSize: { - fn: (header) => header_getSize(header), - memoDeps: (header) => [ - table.options.columns, - header.column.columns.length > 0 - ? table.atoms.columnSizing?.get() // must be all columns (sum child columns) - : table.atoms.columnSizing?.get()?.[header.column.id], // can just check it's associated column size state - ], + computed: (header) => { + void table.options.columns + if (header.column.columns.length > 0) { + return header_getSize(header) + } + return resolveColumnSize(header.column, readColumnSize(header.column)) + }, }, header_getStart: { - fn: (header) => header_getStart(header), - memoDeps: () => [ - table.options.columns, - table.atoms.columnSizing?.get(), - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: (header) => header_getStart(header), }, }) }, @@ -95,16 +157,7 @@ export const columnSizingFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('columnSizingFeature', table, { table_getColumnOffsets: { - fn: () => table_getColumnOffsets(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnSizing?.get(), - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], + computed: () => table_getColumnOffsets(table), }, table_setColumnSizing: { fn: (updater) => table_setColumnSizing(table, updater), @@ -113,32 +166,16 @@ export const columnSizingFeature: TableFeature = { fn: (defaultState) => table_resetColumnSizing(table, defaultState), }, table_getTotalSize: { - fn: () => table_getTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], + computed: () => table_getTotalSize(table), }, table_getStartTotalSize: { - fn: () => table_getStartTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], + computed: () => table_getStartTotalSize(table), }, table_getCenterTotalSize: { - fn: () => table_getCenterTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], + computed: () => table_getCenterTotalSize(table), }, table_getEndTotalSize: { - fn: () => table_getEndTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], + computed: () => table_getEndTotalSize(table), }, }) }, diff --git a/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts b/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts index 31b6d81b7e..2f90e5c2d5 100644 --- a/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts +++ b/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts @@ -42,12 +42,7 @@ export const columnVisibilityFeature: TableFeature = { assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { column_getIsVisible: { - fn: (column) => column_getIsVisible(column), - memoDeps: (column) => [ - table.options.columns, - table.atoms.columnVisibility?.get(), - column.columns, - ], + computed: (column) => column_getIsVisible(column), }, column_getCanHide: { fn: (column) => column_getCanHide(column), @@ -64,19 +59,10 @@ export const columnVisibilityFeature: TableFeature = { assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { row_getVisibleCells: { - fn: (row) => row_getVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - ], + computed: (row) => row_getVisibleCells(row), }, row_getVisibleCellsByColumnId: { - fn: (row) => row_getVisibleCellsByColumnId(row), - memoDeps: (row) => [ - row.getAllCells(), - table.atoms.columnVisibility?.get(), - ], + computed: (row) => row_getVisibleCellsByColumnId(row), }, }) }, @@ -84,24 +70,10 @@ export const columnVisibilityFeature: TableFeature = { constructTableAPIs: (table) => { assignTableAPIs('columnVisibilityFeature', table, { table_getVisibleFlatColumns: { - fn: () => table_getVisibleFlatColumns(table), - memoDeps: () => [ - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.columns, - table.options.groupedColumnMode, - ], + computed: () => table_getVisibleFlatColumns(table), }, table_getVisibleLeafColumns: { - fn: () => table_getVisibleLeafColumns(table), - memoDeps: () => [ - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.columns, - table.options.groupedColumnMode, - ], + computed: () => table_getVisibleLeafColumns(table), }, table_setColumnVisibility: { fn: (updater) => table_setColumnVisibility(table, updater), diff --git a/packages/table-core/src/features/row-aggregation/rowAggregationFeature.ts b/packages/table-core/src/features/row-aggregation/rowAggregationFeature.ts index 3c69aba06f..0a3c270354 100644 --- a/packages/table-core/src/features/row-aggregation/rowAggregationFeature.ts +++ b/packages/table-core/src/features/row-aggregation/rowAggregationFeature.ts @@ -40,11 +40,11 @@ export const rowAggregationFeature: TableFeature = { fn: (column, options) => column_getAggregationValue(column, options), }, column_getAutoAggregationFn: { - fn: (column) => column_getAutoAggregationFn(column), - memoDeps: (column) => [ - column.table.getCoreRowModel(), - column.table._rowModelFns.aggregationFns, - ], + computed: (column) => { + void column.table.getCoreRowModel() + void column.table._rowModelFns.aggregationFns + return column_getAutoAggregationFn(column) + }, }, }) }, diff --git a/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts b/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts index bf3df84990..4d16b0d347 100644 --- a/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts +++ b/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts @@ -21,12 +21,6 @@ export function createExpandedRowModel< feature: 'rowExpandingFeature', table, fnName: 'table.getExpandedRowModel', - memoDeps: () => [ - table.atoms.expanded?.get(), - table.getPreExpandedRowModel(), - table.options.paginateExpandedRows, - table.options.manualPagination, - ], fn: () => _createExpandedRowModel(table), }) } diff --git a/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts b/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts index bd991529cf..c9463976ad 100644 --- a/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts +++ b/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts @@ -22,13 +22,6 @@ export function createPaginatedRowModel< feature: 'rowPaginationFeature', table, fnName: 'table.getPaginatedRowModel', - memoDeps: () => [ - table.getPrePaginatedRowModel(), - table.atoms.pagination?.get(), - !table.options.paginateExpandedRows - ? table.atoms.expanded?.get() - : undefined, - ], fn: () => _createPaginatedRowModel(table), }) } diff --git a/packages/table-core/src/features/row-pinning/rowPinningFeature.ts b/packages/table-core/src/features/row-pinning/rowPinningFeature.ts index cbd075e2b4..478e9705df 100644 --- a/packages/table-core/src/features/row-pinning/rowPinningFeature.ts +++ b/packages/table-core/src/features/row-pinning/rowPinningFeature.ts @@ -3,21 +3,26 @@ import { assignTableAPIs, makeStateUpdater, } from '../../utils' +import { row_getIsAllParentsExpanded } from '../row-expanding/rowExpandingFeature.utils' import { getDefaultRowPinningState, row_getCanPin, row_getIsPinned, row_getPinnedIndex, row_pin, - table_getBottomRows, table_getCenterRows, table_getIsSomeRowsPinned, - table_getTopRows, table_resetRowPinning, table_setRowPinning, } from './rowPinningFeature.utils' +import type { ReadonlyAtom } from '@tanstack/store' import type { TableFeature } from '../../types/TableFeatures' +function createLazySelector(create: () => ReadonlyAtom): () => T { + let atom: ReadonlyAtom | undefined + return () => (atom ??= create()).get() +} + /** * Feature that adds row pinning state and APIs for top, center, and bottom rows. */ @@ -47,11 +52,7 @@ export const rowPinningFeature: TableFeature = { fn: (row) => row_getIsPinned(row), }, row_getPinnedIndex: { - fn: (row) => row_getPinnedIndex(row), - memoDeps: (row) => [ - row.table.getRowModel().rows, - row.table.atoms.rowPinning?.get(), - ], + computed: (row) => row_getPinnedIndex(row), }, row_pin: { fn: (row, position, includeLeafRows, includeParentRows) => @@ -61,6 +62,51 @@ export const rowPinningFeature: TableFeature = { }, constructTableAPIs: (table) => { + const readTopPinning = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => table.atoms.rowPinning?.get()?.top, + { + debugName: 'table/selectors/rowPinning/top', + mode: 'memo', + }, + ), + ) + const readBottomPinning = createLazySelector(() => + table._reactivity.createReadonlyAtom( + () => table.atoms.rowPinning?.get()?.bottom, + { + debugName: 'table/selectors/rowPinning/bottom', + mode: 'memo', + }, + ), + ) + const getPinnedRows = ( + position: 'top' | 'bottom', + pinnedRowIds: ReadonlyArray, + ) => { + const visibleRows = table.getRowModel().rows + const keepPinnedRows = table.options.keepPinnedRows ?? true + const result: Array = [] + + for (let i = 0; i < pinnedRowIds.length; i++) { + const rowId = pinnedRowIds[i]! + let row + if (keepPinnedRows) { + const fullRow = table.getRow(rowId, true) + if (row_getIsAllParentsExpanded(fullRow)) { + row = fullRow + } + } else { + row = visibleRows.find((candidate) => candidate.id === rowId) + } + if (!row) continue + ;(row as any).position = position + result.push(row) + } + + return result + } + assignTableAPIs('rowPinningFeature', table, { table_setRowPinning: { fn: (updater) => table_setRowPinning(table, updater), @@ -72,25 +118,13 @@ export const rowPinningFeature: TableFeature = { fn: (position) => table_getIsSomeRowsPinned(table, position), }, table_getTopRows: { - fn: () => table_getTopRows(table), - memoDeps: () => [ - table.getRowModel().rows, - table.atoms.rowPinning?.get()?.top, - ], + computed: () => getPinnedRows('top', readTopPinning() ?? []), }, table_getBottomRows: { - fn: () => table_getBottomRows(table), - memoDeps: () => [ - table.getRowModel().rows, - table.atoms.rowPinning?.get()?.bottom, - ], + computed: () => getPinnedRows('bottom', readBottomPinning() ?? []), }, table_getCenterRows: { - fn: () => table_getCenterRows(table), - memoDeps: () => [ - table.getRowModel().rows, - table.atoms.rowPinning?.get(), - ], + computed: () => table_getCenterRows(table), }, }) }, diff --git a/packages/table-core/src/features/row-selection/rowSelectionFeature.ts b/packages/table-core/src/features/row-selection/rowSelectionFeature.ts index e8f4de7735..4dc82c78f6 100644 --- a/packages/table-core/src/features/row-selection/rowSelectionFeature.ts +++ b/packages/table-core/src/features/row-selection/rowSelectionFeature.ts @@ -78,20 +78,10 @@ export const rowSelectionFeature: TableFeature = { fn: (row) => row_getIsSelected(row), }, row_getIsSomeSelected: { - fn: (row) => row_getIsSomeSelected(row), - memoDeps: (row) => [ - row.subRows, - row.table.atoms.rowSelection?.get(), - row.table.options.enableRowSelection, - ], + computed: (row) => row_getIsSomeSelected(row), }, row_getIsAllSubRowsSelected: { - fn: (row) => row_getIsAllSubRowsSelected(row), - memoDeps: (row) => [ - row.subRows, - row.table.atoms.rowSelection?.get(), - row.table.options.enableRowSelection, - ], + computed: (row) => row_getIsAllSubRowsSelected(row), }, row_getCanSelect: { fn: (row) => row_getCanSelect(row), @@ -127,57 +117,28 @@ export const rowSelectionFeature: TableFeature = { fn: () => table_getPreSelectedRowModel(table), }, table_getSelectedRowModel: { - fn: () => table_getSelectedRowModel(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getCoreRowModel(), - ], + computed: () => table_getSelectedRowModel(table), }, table_getFilteredSelectedRowModel: { - fn: () => table_getFilteredSelectedRowModel(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getFilteredRowModel(), - ], + computed: () => table_getFilteredSelectedRowModel(table), }, table_getGroupedSelectedRowModel: { - fn: () => table_getGroupedSelectedRowModel(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getSortedRowModel(), - ], + computed: () => table_getGroupedSelectedRowModel(table), }, table_getSelectedRowIds: { - fn: () => table_getSelectedRowIds(table), - memoDeps: () => [table.atoms.rowSelection?.get()], + computed: () => table_getSelectedRowIds(table), }, table_getIsAllRowsSelected: { - fn: () => table_getIsAllRowsSelected(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getFilteredRowModel(), - table.options.enableRowSelection, - ], + computed: () => table_getIsAllRowsSelected(table), }, table_getIsAllPageRowsSelected: { - fn: () => table_getIsAllPageRowsSelected(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getPaginatedRowModel(), - table.options.enableRowSelection, - ], + computed: () => table_getIsAllPageRowsSelected(table), }, table_getIsSomeRowsSelected: { - fn: () => table_getIsSomeRowsSelected(table), - memoDeps: () => [table.atoms.rowSelection?.get()], + computed: () => table_getIsSomeRowsSelected(table), }, table_getIsSomePageRowsSelected: { - fn: () => table_getIsSomePageRowsSelected(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getPaginatedRowModel(), - table.options.enableRowSelection, - ], + computed: () => table_getIsSomePageRowsSelected(table), }, table_getToggleAllRowsSelectedHandler: { fn: () => table_getToggleAllRowsSelectedHandler(table), diff --git a/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts b/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts index a0c449799e..94fc500e12 100644 --- a/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts +++ b/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts @@ -5,6 +5,10 @@ import { hasOwn, makeObjectMap, } from '../../utils' +import { + row_getTrackedSubRows, + row_setSubRows, +} from '../../core/rows/subRowsTracking' import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' @@ -807,17 +811,18 @@ function selectRowsRecursively< for (let i = 0; i < rows.length; i++) { const row = rows[i]! const isSelected = isRowSelected(row, rowSelection) + const subRows = row_getTrackedSubRows(row) if (isSelected) { selectedFlatRows.push(row) selectedRowsById[row.id] = row } - if (row.subRows.length) { + if (subRows.length) { // Always recurse — selected descendants of unselected parents must // still be collected into flatRows/rowsById. const newSubRows = selectRowsRecursively( - row.subRows, + subRows, rowSelection, selectedFlatRows, selectedRowsById, @@ -827,7 +832,7 @@ function selectRowsRecursively< // Preserve prototype chain so methods like getValue() remain accessible const cloned = Object.create(Object.getPrototypeOf(row)) copyInstancePropertiesWithoutMemos(cloned, row) - cloned.subRows = newSubRows + row_setSubRows(cloned, newSubRows) result.push(cloned) } } else if (isSelected) { @@ -901,15 +906,16 @@ export function isSubRowSelected< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): boolean | 'some' | 'all' { - if (!row.subRows.length) return false + const subRows = row_getTrackedSubRows(row) + if (!subRows.length) return false const rowSelection = row.table.atoms.rowSelection?.get() ?? {} let someSelected = false let allChildrenSelected = true - for (let i = 0; i < row.subRows.length; i++) { - const subRow = row.subRows[i]! + for (let i = 0; i < subRows.length; i++) { + const subRow = subRows[i]! // Bail out early if we know both of these if (someSelected && !allChildrenSelected) { @@ -925,7 +931,7 @@ export function isSubRowSelected< } // Check row selection of nested subrows - if (subRow.subRows.length) { + if (row_getTrackedSubRows(subRow).length) { const subRowChildrenSelected = isSubRowSelected(subRow) if (subRowChildrenSelected === 'all') { someSelected = true diff --git a/packages/table-core/src/features/row-sorting/createSortedRowModel.ts b/packages/table-core/src/features/row-sorting/createSortedRowModel.ts index 2cd9a10eb3..2794a56195 100644 --- a/packages/table-core/src/features/row-sorting/createSortedRowModel.ts +++ b/packages/table-core/src/features/row-sorting/createSortedRowModel.ts @@ -1,4 +1,5 @@ import { copyInstancePropertiesWithoutMemos, tableMemo } from '../../utils' +import { row_setSubRows } from '../../core/rows/subRowsTracking' import { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils' import { column_getCanSort, column_getSortFn } from './rowSortingFeature.utils' import type { Column_Internal } from '../../types/Column' @@ -31,10 +32,6 @@ export function createSortedRowModel< feature: 'rowSortingFeature', table, fnName: 'table.getSortedRowModel', - memoDeps: () => [ - table.atoms.sorting?.get(), - table.getPreSortedRowModel(), - ], fn: () => _createSortedRowModel(table), onAfterUpdate: () => table_autoResetPageIndex(table), }) @@ -166,7 +163,7 @@ function _createSortedRowModel< // Preserve prototype chain so methods like getValue() remain accessible const cloned = Object.create(Object.getPrototypeOf(row)) copyInstancePropertiesWithoutMemos(cloned, row) - cloned.subRows = sortedSubRows.rows + row_setSubRows(cloned, sortedSubRows.rows) sortedData[i] = cloned sortedFlatRows.push(cloned) changed = true diff --git a/packages/table-core/src/reactivity.ts b/packages/table-core/src/reactivity.ts index ca7a98ddbe..3a34207916 100644 --- a/packages/table-core/src/reactivity.ts +++ b/packages/table-core/src/reactivity.ts @@ -1,3 +1,4 @@ export * from './core/reactivity/coreReactivityFeature.types' export * from './core/reactivity/coreReactivityFeature.utils' +export * from './core/reactivity/createStableStoreReadonlyAtom' export * from './core/reactivity/renderPhaseReactivity' diff --git a/packages/table-core/src/store-reactivity-bindings.ts b/packages/table-core/src/store-reactivity-bindings.ts index e463b87c84..8f99bea40a 100644 --- a/packages/table-core/src/store-reactivity-bindings.ts +++ b/packages/table-core/src/store-reactivity-bindings.ts @@ -1,9 +1,10 @@ import { batch, createAtom } from '@tanstack/store' +import { createStableStoreReadonlyAtom } from './core/reactivity/createStableStoreReadonlyAtom' import type { TableReactivityBindings } from './core/reactivity/coreReactivityFeature.types' /** - * TanStack Store–based reactivity for vanilla / non-framework use of `constructTable`, - * with `createOptionsStore: true` so `table.optionsStore` is available for subscriptions. + * TanStack Store–based reactivity for vanilla / non-framework use of + * `constructTable`. * * @example * ```ts @@ -18,7 +19,6 @@ import type { TableReactivityBindings } from './core/reactivity/coreReactivityFe */ export function storeReactivityBindings(): TableReactivityBindings { return { - createOptionsStore: true, wrapExternalAtoms: false, addSubscription: () => { throw new Error( @@ -34,7 +34,7 @@ export function storeReactivityBindings(): TableReactivityBindings { schedule: (fn) => queueMicrotask(fn), untrack: (fn) => fn(), createReadonlyAtom: (fn, options) => { - return createAtom(() => fn(), { + return createStableStoreReadonlyAtom(createAtom, fn, { compare: options?.compare, }) }, diff --git a/packages/table-core/src/types/Table.ts b/packages/table-core/src/types/Table.ts index a47bb20059..dff9136718 100644 --- a/packages/table-core/src/types/Table.ts +++ b/packages/table-core/src/types/Table.ts @@ -29,9 +29,10 @@ import type { BaseAtoms, BaseAtoms_All, ExternalAtoms_All, + TableOptionsLive, Table_Table, } from '../core/table/coreTablesFeature.types' -import type { DebugOptions, TableOptions_All } from './TableOptions' +import type { TableOptions_All } from './TableOptions' /** * The core table object that only includes the core table functionality such as column, header, row, and table APIS. @@ -105,12 +106,14 @@ export interface Table_Internal< Table_Headers { _rowModels: CachedRowModel_All _rowModelFns: RowModelFns_All - options: DebugOptions & - TableOptions_All & { - state?: TableState_All - initialState?: TableState_All - atoms?: ExternalAtoms_All - } + options: TableOptionsLive & + Readonly< + TableOptions_All & { + state?: TableState_All + initialState?: TableState_All + atoms?: ExternalAtoms_All + } + > initialState: TableState & TableState_All baseAtoms: BaseAtoms & BaseAtoms_All atoms: Atoms & Atoms_All diff --git a/packages/table-core/src/utils.ts b/packages/table-core/src/utils.ts index 81cd79b4f7..d4a84c99fb 100755 --- a/packages/table-core/src/utils.ts +++ b/packages/table-core/src/utils.ts @@ -1,7 +1,8 @@ import type { Table_Internal } from './types/Table' -import type { NoInfer, RowData, Updater } from './types/type-utils' +import type { RowData, Updater } from './types/type-utils' import type { TableFeatures } from './types/TableFeatures' import type { TableState, TableState_All } from './types/TableState' +import type { ReadonlyAtom } from '@tanstack/store' /** * Applies a TanStack updater to a value. @@ -149,70 +150,10 @@ export function flattenBy( return flat } -interface MemoOptions, TDepArgs, TResult> { - fn: (...args: NoInfer) => TResult - memoDeps?: (depArgs?: TDepArgs) => [...TDeps] | undefined - onAfterCompare?: (depsChanged: boolean) => void - onAfterUpdate?: (result: TResult) => void - onBeforeCompare?: () => void - onBeforeUpdate?: () => void -} - -/** - * Creates a dependency-tracked memoized function for table internals. - * - * The memo recomputes only when its dependency tuple changes and can emit debug timing information. - */ -export const memo = , TDepArgs, TResult>({ - fn, - memoDeps, - onAfterCompare, - onAfterUpdate, - onBeforeCompare, - onBeforeUpdate, -}: MemoOptions): (( - depArgs?: TDepArgs, -) => TResult) => { - let deps: Array | undefined = [] - let result: TResult | undefined - - const memoizedFn = (depArgs?: TDepArgs): TResult => { - onBeforeCompare?.() - const newDeps = memoDeps?.(depArgs) - let depsChanged = !newDeps || newDeps.length !== deps?.length - if (!depsChanged && newDeps) { - for (let i = 0; i < newDeps.length; i++) { - if (newDeps[i] !== deps![i]) { - depsChanged = true - break - } - } - } - onAfterCompare?.(depsChanged) - - if (!depsChanged) { - return result! - } - - deps = newDeps - - onBeforeUpdate?.() - result = fn(...(newDeps ?? ([] as any))) - onAfterUpdate?.(result) - - return result - } - - return memoizedFn -} - -interface TableMemoOptions< - TFeatures extends TableFeatures, - TDeps extends ReadonlyArray, - TDepArgs, - TResult, -> extends MemoOptions { +interface TableMemoOptions { + compare?: (previous: TResult, next: TResult) => boolean feature?: keyof TFeatures & string + fn: () => TResult fnName: string objectId?: string onAfterUpdate?: () => void @@ -230,144 +171,158 @@ const pad = (str: number | string, num: number) => { /** * Creates a table-aware memoized function. * - * This wraps `memo` with table debug options and feature metadata so row models and derived APIs can share consistent diagnostics. + * The native readonly atom is created on the first public read so eager + * framework computeds cannot evaluate during incomplete table construction. */ -export function tableMemo< - TFeatures extends TableFeatures, - TDeps extends ReadonlyArray, - TDepArgs, - TResult, ->({ +export function tableMemo({ + compare, feature, + fn, fnName, objectId, onAfterUpdate, table, - ...memoOptions -}: TableMemoOptions) { - let beforeCompareTime: number - let afterCompareTime: number - let startCalcTime: number - let endCalcTime: number - let runCount = 0 - let debug: boolean | undefined - let debugCache: boolean | undefined - - if (process.env.NODE_ENV === 'development') { - const { debugAll } = table.options - const { parentName } = getFunctionNameInfo(fnName, '.') - - const debugByParent = - // @ts-expect-error - table.options[ - `debug${(parentName != 'table' ? parentName + 's' : parentName).replace( - parentName, - parentName.charAt(0).toUpperCase() + parentName.slice(1), - )}` - ] - const debugByFeature = feature - ? // @ts-expect-error - table.options[ - `debug${feature.charAt(0).toUpperCase() + feature.slice(1)}` - ] - : false - - debug = debugAll || debugByParent || debugByFeature +}: TableMemoOptions): () => TResult { + let atom: ReadonlyAtom | undefined + let evaluationCount = 0 + let hasStableResult = false + let stableResult: TResult + let debug = false + let debugCache = false + let debugInitialized = false + const isDevelopment = process.env.NODE_ENV === 'development' + + const initializeDebug = () => { + if (!isDevelopment || debugInitialized) { + return + } + debugInitialized = true + + table._reactivity.untrack(() => { + const options = table.options as unknown as Record + const { parentName } = getFunctionNameInfo(fnName, '.') + const debugParent = ( + parentName !== 'table' ? `${parentName}s` : parentName + ).replace( + parentName, + parentName.charAt(0).toUpperCase() + parentName.slice(1), + ) + const debugByParent = options[`debug${debugParent}`] + const debugByFeature = feature + ? options[`debug${feature.charAt(0).toUpperCase() + feature.slice(1)}`] + : false + + debug = Boolean(options.debugAll || debugByParent || debugByFeature) + debugCache = Boolean(options.debugCache) + }) } - function logTime(time: number, depsChanged: boolean) { - const runType = - runCount === 0 + function logTime(time: number, evaluated: boolean) { + const runType = evaluated + ? evaluationCount === 1 ? '(1st run)' - : depsChanged - ? '(rerun #' + runCount + ')' - : '(cache)' - runCount++ + : `(rerun #${evaluationCount - 1})` + : '(cache)' console.groupCollapsed( `%c⏱ ${pad(`${time.toFixed(1)} ms`, 12)} %c${runType}%c ${fnName}%c ${objectId ? `(${fnName.split('.')[0]}Id: ${objectId})` : ''}`, `font-size: .6rem; font-weight: bold; ${ - depsChanged + evaluated ? `color: hsl( ${Math.max(0, Math.min(120 - Math.log10(time) * 60, 120))}deg 100% 31%);` : '' } `, - `color: ${runCount < 2 ? '#FF00FF' : '#FF1493'}`, + `color: ${evaluationCount < 2 ? '#FF00FF' : '#FF1493'}`, 'color: #666', 'color: #87CEEB', ) console.info({ feature, state: table.store.state, - deps: memoOptions.memoDeps?.toString(), }) console.trace() console.groupEnd() } - const onAfterUpdateHandler = () => { - if (!onAfterUpdate) { - return - } + const createAtom = () => { + initializeDebug() + atom = table._reactivity.createReadonlyAtom( + () => { + const startedAt = isDevelopment && debug ? performance.now() : 0 + let result: TResult + try { + const nextResult = fn() + result = + hasStableResult && compare?.(stableResult, nextResult) + ? stableResult + : nextResult + } catch (error) { + // A few native computed implementations clear their dirty flag + // even when evaluation or comparison throws. Drop this instance + // so the next public read can retry instead of returning a stale + // snapshot. + atom = undefined + throw error + } - const { schedule, untrack } = table._reactivity - schedule(() => untrack(() => onAfterUpdate())) - } + stableResult = result + hasStableResult = true + if (isDevelopment) { + evaluationCount++ + } - const debugOptions = - process.env.NODE_ENV === 'development' - ? { - onBeforeCompare: () => { - if (debugCache) { - beforeCompareTime = performance.now() - } - }, - onAfterCompare: (depsChanged: boolean) => { - if (debugCache) { - afterCompareTime = performance.now() - const compareTime = - Math.round((afterCompareTime - beforeCompareTime) * 100) / 100 - if (!depsChanged) { - logTime(compareTime, depsChanged) - } - } - }, - onBeforeUpdate: () => { - if (debug) { - startCalcTime = performance.now() - } - }, - onAfterUpdate: () => { - if (debug) { - endCalcTime = performance.now() - const executionTime = - Math.round((endCalcTime - startCalcTime) * 100) / 100 - logTime(executionTime, true) - } - onAfterUpdateHandler() - }, + if (isDevelopment && debug) { + const executionTime = + Math.round((performance.now() - startedAt) * 100) / 100 + table._reactivity.untrack(() => logTime(executionTime, true)) } - : { - onAfterUpdate: () => { - onAfterUpdateHandler() - }, + + if (onAfterUpdate) { + const { schedule, untrack } = table._reactivity + schedule(() => untrack(onAfterUpdate)) } - return memo({ - ...memoOptions, - ...debugOptions, - }) -} + return result + }, + { + debugName: fnName, + mode: 'memo', + }, + ) + return atom + } + + if (!isDevelopment) { + return () => (atom ?? createAtom()).get() + } + + return () => { + const startedAt = debugCache ? performance.now() : 0 + const beforeEvaluation = evaluationCount + const result = (atom ?? createAtom()).get() + + if (debugCache && evaluationCount === beforeEvaluation) { + const cacheTime = Math.round((performance.now() - startedAt) * 100) / 100 + table._reactivity.untrack(() => logTime(cacheTime, false)) + } -export interface API<_TDeps extends ReadonlyArray, _TDepArgs> { - fn: (...args: any) => any - memoDeps?: (depArgs?: any) => [...any] | undefined + return result + } } -export type APIObject, TDepArgs> = Record< - string, - API -> +export type API = + | { + compare?: (previous: any, next: any) => boolean + computed: () => any + fn?: never + } + | { + compare?: never + computed?: never + fn: (...args: Array) => any + } + +export type APIObject = Record /** * Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`. @@ -392,37 +347,40 @@ export function getFunctionNameInfo( export function assignTableAPIs< TFeatures extends TableFeatures, TData extends RowData, - TDeps extends ReadonlyArray, - TDepArgs, >( feature: keyof TFeatures & string, table: Table_Internal, - apis: APIObject>, + apis: APIObject, ): void { - for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) { + for (const [staticFnName, api] of Object.entries(apis)) { const { fnKey, fnName } = getFunctionNameInfo(staticFnName) - ;(table as Record)[fnKey] = memoDeps - ? tableMemo({ - memoDeps, - fn, - fnName, - table, - feature, - }) - : fn + ;(table as Record)[fnKey] = + 'computed' in api && api.computed + ? tableMemo({ + compare: api.compare, + fn: api.computed, + fnName, + table, + feature, + }) + : api.fn } } -export interface PrototypeAPI<_TDeps extends ReadonlyArray, _TDepArgs> { - fn: (self: any, ...args: any) => any - memoDeps?: (self: any, depArgs?: any) => [...any] | undefined -} +export type PrototypeAPI = + | { + compare?: (previous: any, next: any) => boolean + computed: (self: any) => any + fn?: never + } + | { + compare?: never + computed?: never + fn: (self: any, ...args: Array) => any + } -export type PrototypeAPIObject< - TDeps extends ReadonlyArray, - TDepArgs, -> = Record> +export type PrototypeAPIObject = Record /** * Assigns API methods to a prototype object for memory-efficient method sharing. @@ -434,41 +392,39 @@ export type PrototypeAPIObject< export function assignPrototypeAPIs< TFeatures extends TableFeatures, TData extends RowData, - TDeps extends ReadonlyArray, - TDepArgs, >( feature: keyof TFeatures & string, prototype: Record, table: Table_Internal, - apis: PrototypeAPIObject>, + apis: PrototypeAPIObject, ): void { - for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) { + for (const [staticFnName, api] of Object.entries(apis)) { const { fnKey, fnName } = getFunctionNameInfo(staticFnName) - if (memoDeps) { + if ('computed' in api && api.computed) { // For memoized methods, create a function that lazily initializes // the memo on first access and stores it on the instance const memoKey = `_memo_${fnKey}` - prototype[fnKey] = function (this: any, ...args: Array) { + prototype[fnKey] = function (this: any) { // Lazily create memo on first access for this instance if (!this[memoKey]) { const self = this this[memoKey] = tableMemo({ - memoDeps: (depArgs) => memoDeps(self, depArgs), - fn: (...deps) => fn(self, ...deps), + compare: api.compare, + fn: () => api.computed(self), fnName, objectId: self.id, table, feature, }) } - return this[memoKey](...args) + return this[memoKey]() } } else { // Non-memoized methods just call the static function with `this` prototype[fnKey] = function (this: any, ...args: Array) { - return fn(this, ...args) + return api.fn(this, ...args) } } } diff --git a/packages/table-core/src/worker/createTableWorker.ts b/packages/table-core/src/worker/createTableWorker.ts index 61720ceb42..e9df2be9a6 100644 --- a/packages/table-core/src/worker/createTableWorker.ts +++ b/packages/table-core/src/worker/createTableWorker.ts @@ -13,6 +13,7 @@ import type { TableWorkerStage, TableWorkerStagePayload, } from './tableWorkerProtocol' +import type { Atom } from '@tanstack/store' // Importing anything from this module (e.g. `workerRowModelsFeature`) // registers the plugin key and its state slice with the core type maps, so @@ -71,7 +72,7 @@ export interface TableWorkerBridge { lastState: Record results: { [K in TableWorkerStage]?: TableWorkerDataPayload } /** Bumped per stage only when that stage's payload actually changed. */ - stageVersions: { [K in TableWorkerStage]?: number } + stageVersionAtoms: { [K in TableWorkerStage]?: Atom } } type AnyTable = Table_Internal @@ -156,13 +157,42 @@ export function getTableWorkerBridge( sentStageCount: 0, lastState: {}, results: {}, - stageVersions: {}, + stageVersionAtoms: {}, } tableWorker._bridges.set(table, bridge) } return bridge } +function getOrCreateStageVersionAtom( + table: AnyTable, + bridge: TableWorkerBridge, + stage: TableWorkerStage, +): Atom { + return (bridge.stageVersionAtoms[stage] ??= + table._reactivity.createWritableAtom(0, { + debugName: `table/worker/${stage}/version`, + })) +} + +/** + * Reads the version for one worker stage as a reactive dependency. + * + * The atom is lazy because only registered worker-backed stages need one. + * Unchanged worker payloads deliberately leave the version untouched, keeping + * the rebuilt row-model computed cached. + * + * @internal + */ +export function getTableWorkerStageVersion( + tableWorker: TableWorker, + table: AnyTable, + stage: TableWorkerStage, +): number { + const bridge = getTableWorkerBridge(tableWorker, table) + return getOrCreateStageVersionAtom(table, bridge, stage).get() +} + /** Shallow reference comparison; atoms return stable refs when unchanged. */ function statesEqual( a: Record | null, @@ -234,7 +264,8 @@ function handleResult( >) { if (payload.kind === 'unchanged') continue bridge.results[stage] = payload - bridge.stageVersions[stage] = (bridge.stageVersions[stage] ?? 0) + 1 + const versionAtom = getOrCreateStageVersionAtom(table, bridge, stage) + versionAtom.set((version) => version + 1) anyChanged = true if (stage === 'grouped') groupedChanged = true } diff --git a/packages/table-core/src/worker/createWorkerRowModel.ts b/packages/table-core/src/worker/createWorkerRowModel.ts index 7d2e7395de..91dbc81548 100644 --- a/packages/table-core/src/worker/createWorkerRowModel.ts +++ b/packages/table-core/src/worker/createWorkerRowModel.ts @@ -1,5 +1,9 @@ import { tableMemo } from '../utils' -import { getTableWorkerBridge, syncTableWorker } from './createTableWorker' +import { + getTableWorkerBridge, + getTableWorkerStageVersion, + syncTableWorker, +} from './createTableWorker' import { rebuildRowModel } from './rebuildRowModel' import { tableWorkerPipeline } from './tableWorkerProtocol' import type { RowModel } from '../core/row-models/coreRowModelsFeature.types' @@ -69,14 +73,13 @@ export function createWorkerRowModel( const memoized = tableMemo({ table, fnName: `table.get${capitalize(stage)}RowModel`, - // The per-stage version bumps only when this stage's payload actually - // changed, so stages the worker reported as `unchanged` skip the O(n) - // rebuild entirely (the re-render itself rides the state slice bump). - memoDeps: () => [ - table.getCoreRowModel(), - getTableWorkerBridge(tableWorker, table).stageVersions[stage], - ], fn: () => { + // The per-stage atom bumps only when this stage's payload actually + // changed, so stages the worker reported as `unchanged` skip the O(n) + // rebuild entirely (the re-render itself rides the state slice bump). + table.getCoreRowModel() + getTableWorkerStageVersion(tableWorker, table, stage) + const bridge = getTableWorkerBridge(tableWorker, table) const payload = bridge.results[stage] if (!payload) { 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 fd916d184a..091aa93393 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 @@ -191,6 +191,43 @@ describe('table methods', () => { expect(table.getTopRows()).toHaveLength(1) expect(table.getBottomRows()).toHaveLength(0) // Row 2 is not in visible rows }) + + it('keeps each pinned region cached when only its sibling changes', () => { + const table = makeTable({ + initialState: { + rowPinning: { + top: [ROW[0]], + bottom: [ROW[1]], + }, + }, + }) + const topRows = table.getTopRows() + const bottomRows = table.getBottomRows() + const initial = table.atoms.rowPinning.get() + + table.setRowPinning({ + top: initial.top, + bottom: [ROW[2]], + }) + + expect(table.getTopRows()).toBe(topRows) + + const next = table.atoms.rowPinning.get() + table.setRowPinning({ + top: [ROW[1]], + bottom: next.bottom, + }) + + expect(table.getBottomRows()).not.toBe(bottomRows) + const currentBottomRows = table.getBottomRows() + + table.setRowPinning({ + top: [ROW[0]], + bottom: table.atoms.rowPinning.get().bottom, + }) + + expect(table.getBottomRows()).toBe(currentBottomRows) + }) }) it('should handle keepPinnedRows - true', () => { 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 fec266e5cc..bce4f0174d 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,7 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { aggregationFns, - rowAggregationFeature, columnFilteringFeature, columnGroupingFeature, constructTable, @@ -9,6 +8,7 @@ import { createGroupedRowModel, createSortedRowModel, filterFns, + rowAggregationFeature, rowSelectionFeature, rowSortingFeature, sortFns, @@ -621,6 +621,52 @@ describe('rowSelectionFeature', () => { callsAfterFirst, ) }) + + it('invalidates recursive selection flags when subRows are replaced', () => { + const data = generateTestData(1, 2) + const table = constructTable({ + features, + data, + columns: generateColumnDefs(data), + getSubRows: (originalRow) => originalRow.subRows, + initialState: { + rowSelection: { '0.0': true }, + }, + }) + const parent = table.getRow('0') + + expect(parent.getIsSomeSelected()).toBe(true) + expect(parent.getIsAllSubRowsSelected()).toBe(false) + + parent.subRows = [parent.subRows[0]!] + + expect(parent.getIsSomeSelected()).toBe(false) + expect(parent.getIsAllSubRowsSelected()).toBe(true) + }) + + it('invalidates the selected row model when subRows are replaced', () => { + const data = generateTestData(1, 2) + const table = constructTable({ + features, + data, + columns: generateColumnDefs(data), + getSubRows: (originalRow) => originalRow.subRows, + initialState: { + rowSelection: { '0': true, '0.0': true }, + }, + }) + const parent = table.getRow('0') + const firstSelected = table.getSelectedRowModel() + + expect(firstSelected.flatRows.map((row) => row.id)).toEqual(['0', '0.0']) + + parent.subRows = [] + + const nextSelected = table.getSelectedRowModel() + expect(nextSelected).not.toBe(firstSelected) + expect(nextSelected.flatRows.map((row) => row.id)).toEqual(['0']) + expect(nextSelected.rows[0]!.subRows).toEqual([]) + }) }) describe('selected row models source the correct pipeline models', () => { diff --git a/packages/table-core/tests/unit/core/createStableStoreReadonlyAtom.test.ts b/packages/table-core/tests/unit/core/createStableStoreReadonlyAtom.test.ts new file mode 100644 index 0000000000..4d48534163 --- /dev/null +++ b/packages/table-core/tests/unit/core/createStableStoreReadonlyAtom.test.ts @@ -0,0 +1,13 @@ +import { createAtom } from '@tanstack/store' +import { describe, expect, it, vi } from 'vitest' +import { createStableStoreReadonlyAtom } from '../../../src/reactivity' + +describe('createStableStoreReadonlyAtom', () => { + it('returns a function value without invoking it as a computed resolver', () => { + const value = vi.fn() + const atom = createStableStoreReadonlyAtom(createAtom, () => value) + + expect(atom.get()).toBe(value) + expect(value).not.toHaveBeenCalled() + }) +}) diff --git a/packages/table-core/tests/unit/core/renderPhaseReactivity.test.ts b/packages/table-core/tests/unit/core/renderPhaseReactivity.test.ts index cebfc2fddb..205f8a6e8d 100644 --- a/packages/table-core/tests/unit/core/renderPhaseReactivity.test.ts +++ b/packages/table-core/tests/unit/core/renderPhaseReactivity.test.ts @@ -40,6 +40,184 @@ afterEach(() => { }) describe('renderPhaseReactivity bindings', () => { + it('caches memo-mode reads within a render and refreshes after staging', () => { + const bindings = renderPhaseReactivity({ createAtom, batch }) + const option = bindings.createWritableAtom(1, { + debugName: 'option', + mode: 'staged', + }) + const evaluate = vi.fn(() => option.get() * 2) + const memo = bindings.createReadonlyAtom(evaluate, { + debugName: 'memo', + mode: 'memo', + }) + + expect(memo.get()).toBe(2) + expect(memo.get()).toBe(2) + expect(evaluate).toHaveBeenCalledTimes(1) + + option.set(2) + bindings.stage() + + expect(memo.get()).toBe(4) + expect(memo.get()).toBe(4) + expect(evaluate).toHaveBeenCalledTimes(2) + }) + + it('uses broad memo invalidation for a materially changed staged source', () => { + const bindings = renderPhaseReactivity({ createAtom, batch }) + const dependency = bindings.createWritableAtom(1, { + debugName: 'dependency', + mode: 'staged', + }) + const unrelated = bindings.createWritableAtom('before', { + debugName: 'unrelated', + mode: 'staged', + }) + const evaluate = vi.fn(() => ({ value: dependency.get() })) + const memo = bindings.createReadonlyAtom(evaluate, { + debugName: 'memo', + mode: 'memo', + }) + + const initial = memo.get() + + unrelated.set('after') + bindings.stage() + + expect(memo.get()).not.toBe(initial) + expect(evaluate).toHaveBeenCalledTimes(2) + }) + + it('publishes staged readonly values once for the committed token', () => { + const bindings = renderPhaseReactivity({ createAtom, batch }) + const option = bindings.createWritableAtom(1, { + debugName: 'option', + mode: 'staged', + }) + const projection = bindings.createReadonlyAtom(() => option.get(), { + debugName: 'projection', + }) + const notifications: Array = [] + const subscription = projection.subscribe((value) => { + notifications.push(value) + }) + + option.set(2) + const token = bindings.stage() + + expect(projection.get()).toBe(2) + expect(notifications).toEqual([]) + + bindings.commit(token) + bindings.commit(token) + + expect(notifications).toEqual([2]) + subscription.unsubscribe() + }) + + it('does not publish an abandoned staged value', () => { + const bindings = renderPhaseReactivity({ createAtom, batch }) + const option = bindings.createWritableAtom(1, { + debugName: 'option', + mode: 'staged', + }) + const projection = bindings.createReadonlyAtom(() => option.get(), { + debugName: 'projection', + }) + const notifications: Array = [] + const subscription = projection.subscribe((value) => { + notifications.push(value) + }) + + option.set(2) + const abandonedToken = bindings.stage() + expect(projection.get()).toBe(2) + + option.set(3) + const committedToken = bindings.stage() + expect(projection.get()).toBe(3) + + bindings.commit(committedToken) + bindings.commit(abandonedToken) + + expect(notifications).toEqual([3]) + subscription.unsubscribe() + }) + + it('does not publish newer staged values through an older commit token', () => { + const bindings = renderPhaseReactivity({ createAtom, batch }) + const option = bindings.createWritableAtom(1, { + debugName: 'option', + mode: 'staged', + }) + const projection = bindings.createReadonlyAtom(() => option.get(), { + debugName: 'projection', + }) + const notifications: Array = [] + const subscription = projection.subscribe((value) => { + notifications.push(value) + }) + + option.set(2) + const olderToken = bindings.stage() + option.set(3) + bindings.stage() + + bindings.commit(olderToken) + + expect(notifications).toEqual([]) + subscription.unsubscribe() + }) + + it('gates option atom publication and forwards the captured token', () => { + const { bindings, table, internalTable } = makeDeferredTable() + const nextData = [{ id: 'next' }] + const notifications: Array> = [] + const subscription = table.optionAtoms.data.subscribe((value) => { + notifications.push(value) + }) + const commitSpy = vi.spyOn(bindings, 'commit') + + const token = table_setOptions( + internalTable, + (options) => ({ + ...options, + data: nextData, + }), + { syncExternalState: false }, + ) + + expect(token).toEqual(expect.any(Number)) + expect(table.optionAtoms.data.get()).toBe(nextData) + expect(notifications).toEqual([]) + + table_publishExternalState(internalTable, null, undefined, token) + + expect(commitSpy).toHaveBeenCalledWith(token) + expect(notifications).toEqual([nextData]) + subscription.unsubscribe() + }) + + it('does not stage a source with unchanged option values', () => { + const { bindings, internalTable } = makeDeferredTable() + // The first merge installs construct-static undefined slots. Subsequent + // render merges with the same values should not rotate memo caches. + table_setOptions(internalTable, (options) => ({ ...options }), { + syncExternalState: false, + }) + const stageSpy = vi.spyOn(bindings, 'stage') + + const token = table_setOptions( + internalTable, + (options) => ({ ...options }), + { syncExternalState: false }, + ) + + expect(token).toBe(bindings.getStageToken()) + expect(stageSpy).not.toHaveBeenCalled() + }) + it('invokes the commit hook on publish, including when nothing is published', () => { const { bindings, internalTable } = makeDeferredTable() const commitSpy = vi.spyOn(bindings, 'commit') diff --git a/packages/table-core/tests/unit/core/rows/constructRow.test.ts b/packages/table-core/tests/unit/core/rows/constructRow.test.ts index 69bef711aa..3266fdcc80 100644 --- a/packages/table-core/tests/unit/core/rows/constructRow.test.ts +++ b/packages/table-core/tests/unit/core/rows/constructRow.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { constructTable } from '../../../../src' import { constructRow } from '../../../../src/core/rows/constructRow' +import { row_getLeafRows } from '../../../../src/core/rows/coreRowsFeature.utils' import { testFeatures } from '../../../fixtures/features' import type { Row } from '../../../../src/types/Row' @@ -90,4 +91,56 @@ describe('constructRow', () => { expect(nextLeafRows).not.toBe(firstLeafRows) expect(nextLeafRows).toEqual([leafB, leafA]) }) + + it('tracks nested subRows replacements in a readonly atom', () => { + const table = constructTable({ + features, + columns: [], + data: [], + }) + + const leafA = constructRow(table, 'leaf-a', { firstName: 'A' }, 0, 2, []) + const leafB = constructRow(table, 'leaf-b', { firstName: 'B' }, 0, 2, []) + const branch = constructRow( + table, + 'branch', + { firstName: 'Branch' }, + 0, + 1, + [leafA], + ) + const parent = constructRow( + table, + 'parent', + { firstName: 'Parent' }, + 0, + 0, + [branch], + ) + let evaluations = 0 + const leafRowsAtom = table._reactivity.createReadonlyAtom( + () => { + evaluations++ + return row_getLeafRows(parent) + }, + { debugName: 'test/nestedSubRows' }, + ) + + const firstLeafRows = leafRowsAtom.get() + expect(firstLeafRows).toEqual([branch, leafA]) + expect(leafRowsAtom.get()).toBe(firstLeafRows) + expect(evaluations).toBe(1) + + const sameSubRows = branch.subRows + branch.subRows = sameSubRows + expect(leafRowsAtom.get()).toBe(firstLeafRows) + expect(evaluations).toBe(1) + + branch.subRows = [leafB] + + const nextLeafRows = leafRowsAtom.get() + expect(nextLeafRows).not.toBe(firstLeafRows) + expect(nextLeafRows).toEqual([branch, leafB]) + expect(evaluations).toBe(2) + }) }) diff --git a/packages/table-core/tests/unit/core/table/tableOptionAtoms.test.ts b/packages/table-core/tests/unit/core/table/tableOptionAtoms.test.ts new file mode 100644 index 0000000000..61af32957b --- /dev/null +++ b/packages/table-core/tests/unit/core/table/tableOptionAtoms.test.ts @@ -0,0 +1,211 @@ +import { describe, expect, it, vi } from 'vitest' +import { constructTable } from '../../../../src' +import { testFeatures } from '../../../fixtures/features' + +function makeTable(extraOptions: Record = {}) { + return constructTable({ + features: testFeatures({}), + columns: [], + data: [], + ...extraOptions, + } as any) as any +} + +describe('table option atoms', () => { + it('types table.options readonly and ordinary option atoms writable', () => { + const table = constructTable({ + features: testFeatures({}), + columns: [], + data: [], + }) + + const assertOptionTypes = () => { + table.optionAtoms.data.set([]) + // @ts-expect-error table.options is a readonly projection + table.options.data = [] + // @ts-expect-error construction-only atoms are readonly + table.optionAtoms.features.set(testFeatures({})) + // @ts-expect-error construction-only atoms are readonly + table.optionAtoms.atoms?.set({}) + // @ts-expect-error construction-only atoms are readonly + table.optionAtoms.initialState?.set({}) + // @ts-expect-error aggregate snapshot version is readonly + table.optionAtoms.snapshotVersion.set(1) + } + + expect(assertOptionTypes).toBeTypeOf('function') + expect(table.options.data).toEqual([]) + }) + + it('keeps one readonly live options projection', () => { + const table = makeTable({ customOption: 'initial' }) + const savedOptions = table.options + const nextData = [{ id: 1 }] + + table.setOptions((previous: any) => ({ + ...previous, + customOption: 'updated', + data: nextData, + })) + + expect(table.options).toBe(savedOptions) + expect(savedOptions.customOption).toBe('updated') + expect(savedOptions.data).toBe(nextData) + expect(table.optionsStore).toBeUndefined() + }) + + it('updates writable option atoms and suppresses unrelated notifications', () => { + const table = makeTable({ customOption: 'initial' }) + const listener = vi.fn() + const subscription = table.optionAtoms.data.subscribe(listener) + const nextData = [{ id: 1 }] + + expect(table.optionAtoms.data.get()).toBe(table.options.data) + + table.optionAtoms.customOption.set('updated') + expect(table.options.customOption).toBe('updated') + expect(listener).not.toHaveBeenCalled() + + table.optionAtoms.data.set(nextData) + expect(table.options.data).toBe(nextData) + expect(listener).toHaveBeenCalledOnce() + expect(listener).toHaveBeenLastCalledWith(nextData) + + subscription.unsubscribe() + }) + + it('creates a missing atom when setOptions introduces its option', () => { + const table = makeTable() + + expect(table.optionAtoms.customOption).toBeUndefined() + expect(table.options.customOption).toBeUndefined() + + table.setOptions((previous: any) => ({ + ...previous, + customOption: 'created', + })) + + expect(table.optionAtoms.customOption.get()).toBe('created') + expect(table.options.customOption).toBe('created') + }) + + it('leaves omitted options unchanged and clears them with undefined', () => { + const table = makeTable({ + customOption: 'initial', + mergeOptions: (_current: unknown, next: unknown) => next, + }) + + table.setOptions(() => ({ data: [] })) + + expect(table.options.customOption).toBe('initial') + expect(table.optionAtoms.customOption.get()).toBe('initial') + + table.setOptions(() => ({ customOption: undefined })) + + expect(table.options.customOption).toBeUndefined() + expect(table.optionAtoms.customOption.get()).toBeUndefined() + }) + + it('keeps optionAtoms as a plain object and only proxies table.options', () => { + const symbolOption = Symbol('symbolOption') + const table = makeTable() + + table.setOptions((previous: any) => ({ + ...previous, + customOption: 'custom', + [symbolOption]: 'symbol', + })) + + expect(Object.getPrototypeOf(table.optionAtoms)).toBeNull() + expect(Reflect.ownKeys(table.options)).toEqual( + expect.arrayContaining(['customOption', symbolOption]), + ) + expect( + Object.getOwnPropertyDescriptor(table.options, 'customOption'), + ).toMatchObject({ + configurable: true, + enumerable: true, + value: 'custom', + writable: false, + }) + expect(table.options[symbolOption]).toBe('symbol') + expect(table.optionAtoms[symbolOption].get()).toBe('symbol') + }) + + it('rejects writes through table.options', () => { + const table = makeTable() + + expect(Reflect.set(table.options, 'data', [{ id: 1 }])).toBe(false) + expect(Reflect.deleteProperty(table.options, 'data')).toBe(false) + expect( + Reflect.defineProperty(table.options, 'data', { + configurable: true, + value: [{ id: 1 }], + }), + ).toBe(false) + expect(Reflect.preventExtensions(table.options)).toBe(false) + expect(Reflect.setPrototypeOf(table.options, {})).toBe(false) + expect(table.options.data).toEqual([]) + }) + + it('stores callback-valued options without invoking them', () => { + const callback = vi.fn(() => 'callback result') + const nextCallback = vi.fn(() => 'next callback result') + const table = makeTable({ callbackOption: callback }) + + expect(callback).not.toHaveBeenCalled() + expect(table.options.callbackOption).toBe(callback) + + // Function-valued atoms use the normal Atom updater contract. Wrapping + // returns the callback as a value instead of executing it as an updater. + table.optionAtoms.callbackOption.set(() => nextCallback) + + expect(table.options.callbackOption).toBe(nextCallback) + expect(callback).not.toHaveBeenCalled() + expect(nextCallback).not.toHaveBeenCalled() + }) + + it('publishes multi-option updates atomically through the binding batch', () => { + const table = makeTable({ + firstOption: 'first-before', + secondOption: 'second-before', + }) + const combined = table._reactivity.createReadonlyAtom( + () => + `${table.optionAtoms.firstOption.get()}:${table.optionAtoms.secondOption.get()}`, + { + debugName: 'table/options/combined-test', + }, + ) + const observations: Array = [] + const versions: Array = [] + const subscription = combined.subscribe((value: string) => { + observations.push(value) + }) + const versionSubscription = table.optionAtoms.snapshotVersion.subscribe( + (version: number) => { + versions.push(version) + }, + ) + + expect(table.optionAtoms.snapshotVersion.get()).toBe(0) + + table.setOptions((previous: any) => ({ + ...previous, + firstOption: 'first-after', + secondOption: 'second-after', + })) + + expect(observations).toEqual(['first-after:second-after']) + expect(table.optionAtoms.snapshotVersion.get()).toBe(1) + expect(versions).toEqual([1]) + + table.setOptions((previous: any) => ({ ...previous })) + + expect(table.optionAtoms.snapshotVersion.get()).toBe(1) + expect(versions).toEqual([1]) + + subscription.unsubscribe() + versionSubscription.unsubscribe() + }) +}) diff --git a/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts index c23ed77ce2..7c2fbbe784 100644 --- a/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts @@ -213,6 +213,28 @@ describe('table_resetColumnOrder', () => { }) describe('table_getOrderColumnsFn', () => { + it('recreates the memoized function when grouping behavior changes', () => { + const table = makeTable(3, { + groupedColumnMode: 'reorder', + }) + const getOrderColumnsFn = () => + ( + table as unknown as { getOrderColumnsFn: () => () => unknown } + ).getOrderColumnsFn() + + const initial = getOrderColumnsFn() + + table.setGrouping(['firstName']) + const afterGrouping = getOrderColumnsFn() + expect(afterGrouping).not.toBe(initial) + + table.setOptions((options) => ({ + ...options, + groupedColumnMode: 'remove', + })) + expect(getOrderColumnsFn()).not.toBe(afterGrouping) + }) + it('should return original columns when no column order is specified', () => { const table = makeTable(3) const columns = table.getAllLeafColumns() diff --git a/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts index 67f72ffaaf..e4e943e70a 100644 --- a/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts @@ -13,29 +13,29 @@ import { column_pin, getDefaultColumnPinningState, row_getCenterVisibleCells, - row_getStartVisibleCells, row_getEndVisibleCells, + row_getStartVisibleCells, table_getCenterFlatHeaders, table_getCenterFooterGroups, table_getCenterHeaderGroups, table_getCenterLeafColumns, table_getCenterLeafHeaders, table_getCenterVisibleLeafColumns, + table_getEndFlatHeaders, + table_getEndFooterGroups, + table_getEndHeaderGroups, + table_getEndLeafColumns, + table_getEndLeafHeaders, + table_getEndVisibleLeafColumns, table_getIsSomeColumnsPinned, + table_getPinnedLeafColumns, + table_getPinnedVisibleLeafColumns, table_getStartFlatHeaders, table_getStartFooterGroups, table_getStartHeaderGroups, table_getStartLeafColumns, table_getStartLeafHeaders, table_getStartVisibleLeafColumns, - table_getPinnedLeafColumns, - table_getPinnedVisibleLeafColumns, - table_getEndFlatHeaders, - table_getEndFooterGroups, - table_getEndHeaderGroups, - table_getEndLeafColumns, - table_getEndLeafHeaders, - table_getEndVisibleLeafColumns, table_getVisibleLeafColumns, table_resetColumnPinning, table_setColumnPinning, @@ -501,6 +501,54 @@ describe('row_getEndVisibleCells', () => { }) }) +describe('column pinning selector boundaries', () => { + it('keeps start results cached when only end pinning changes', () => { + const table = makeTable(1, { + initialState: { + columnPinning: { + start: ['firstName'], + end: ['lastName'], + }, + }, + }) + const row = table.getRowModel().rows[0]! + const startCells = row.getStartVisibleCells() + const startHeaderGroups = table.getStartHeaderGroups() + const current = table.atoms.columnPinning.get() + + table.setColumnPinning({ + start: current.start, + end: ['age'], + }) + + expect(row.getStartVisibleCells()).toBe(startCells) + expect(table.getStartHeaderGroups()).toBe(startHeaderGroups) + }) + + it('keeps end results cached when only start pinning changes', () => { + const table = makeTable(1, { + initialState: { + columnPinning: { + start: ['firstName'], + end: ['lastName'], + }, + }, + }) + const row = table.getRowModel().rows[0]! + const endCells = row.getEndVisibleCells() + const endHeaderGroups = table.getEndHeaderGroups() + const current = table.atoms.columnPinning.get() + + table.setColumnPinning({ + start: ['age'], + end: current.end, + }) + + expect(row.getEndVisibleCells()).toBe(endCells) + expect(table.getEndHeaderGroups()).toBe(endHeaderGroups) + }) +}) + describe('table_getStartHeaderGroups', () => { it('should return header groups for start pinned columns', () => { const table = makeTable(1, { diff --git a/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts index 01c8ea8dfd..2a244ea01c 100644 --- a/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts @@ -285,7 +285,7 @@ describe('header_getResizeHandler', () => { enableColumnResizing: false, }) const onColumnResizingChange = vi.fn() - table.options.onColumnResizingChange = onColumnResizingChange + table.optionAtoms.onColumnResizingChange!.set(() => onColumnResizingChange) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) @@ -297,7 +297,7 @@ describe('header_getResizeHandler', () => { it('should ignore multi-touch events', () => { const table = makeTable(1) const onColumnResizingChange = vi.fn() - table.options.onColumnResizingChange = onColumnResizingChange + table.optionAtoms.onColumnResizingChange!.set(() => onColumnResizingChange) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) @@ -314,7 +314,7 @@ describe('header_getResizeHandler', () => { columnResizeMode: 'onChange', }) const onColumnSizingChange = vi.fn() - table.options.onColumnSizingChange = onColumnSizingChange + table.optionAtoms.onColumnSizingChange!.set(() => onColumnSizingChange) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) @@ -336,21 +336,21 @@ describe('header_getResizeHandler', () => { }) let resizingState = getDefaultColumnResizingState() - table.options.onColumnResizingChange = (updater) => { + table.optionAtoms.onColumnResizingChange!.set(() => (updater) => { resizingState = typeof updater === 'function' ? updater(resizingState) : updater ;(table.store.state as any).columnResizing = resizingState - } + }) const sizingUpdates: Array> = [] - table.options.onColumnSizingChange = (updater) => { + table.optionAtoms.onColumnSizingChange!.set(() => (updater) => { if (typeof updater === 'function') { const result = updater(table.atoms.columnSizing.get()) sizingUpdates.push(result) } else { sizingUpdates.push(updater) } - } + }) const zeroSizeColumn = { ...table.getAllColumns()[0], @@ -392,12 +392,12 @@ describe('header_getResizeHandler', () => { let resizingState = getDefaultColumnResizingState() const resizingUpdates: Array = [] - table.options.onColumnResizingChange = (updater) => { + table.optionAtoms.onColumnResizingChange!.set(() => (updater) => { resizingState = typeof updater === 'function' ? updater(resizingState) : updater ;(table.store.state as any).columnResizing = resizingState resizingUpdates.push(resizingState) - } + }) const zeroSizeColumn = { ...table.getAllColumns()[0], @@ -447,7 +447,7 @@ describe('header_getResizeHandler', () => { columnResizeMode: 'onChange', }) const onColumnSizingChange = vi.fn() - table.options.onColumnSizingChange = onColumnSizingChange + table.optionAtoms.onColumnSizingChange!.set(() => onColumnSizingChange) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any, document) @@ -489,13 +489,13 @@ describe('header_getResizeHandler', () => { columnResizeMode: 'onChange', }) const sizingUpdates: Array> = [] - table.options.onColumnSizingChange = (updater) => { + table.optionAtoms.onColumnSizingChange!.set(() => (updater) => { sizingUpdates.push( typeof updater === 'function' ? updater(table.atoms.columnSizing.get()) : updater, ) - } + }) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any, document) @@ -548,13 +548,13 @@ describe('header_getResizeHandler', () => { columnResizeMode: 'onEnd', }) const sizingUpdates: Array> = [] - table.options.onColumnSizingChange = (updater) => { + table.optionAtoms.onColumnSizingChange!.set(() => (updater) => { sizingUpdates.push( typeof updater === 'function' ? updater(table.atoms.columnSizing.get()) : updater, ) - } + }) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any, document) @@ -610,13 +610,13 @@ describe('header_getResizeHandler', () => { columnResizeMode: 'onChange', }) const sizingUpdates: Array> = [] - table.options.onColumnSizingChange = (updater) => { + table.optionAtoms.onColumnSizingChange!.set(() => (updater) => { sizingUpdates.push( typeof updater === 'function' ? updater(table.atoms.columnSizing.get()) : updater, ) - } + }) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any, document) diff --git a/packages/table-core/tests/unit/features/column-sizing/columnSizingFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-sizing/columnSizingFeature.utils.test.ts index f6431f34f5..0f9c724fa3 100644 --- a/packages/table-core/tests/unit/features/column-sizing/columnSizingFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-sizing/columnSizingFeature.utils.test.ts @@ -14,8 +14,8 @@ import { getDefaultColumnSizingState, table_getCenterTotalSize, table_getColumnOffsets, - table_getStartTotalSize, table_getEndTotalSize, + table_getStartTotalSize, table_getTotalSize, table_resetColumnSizing, table_setColumnSizing, @@ -488,6 +488,39 @@ describe('column_getSize', () => { expect(column_getSize(table.getColumn('a')!)).toBe(300) }) + + it('does not reevaluate a leaf column or header for a sibling size change', () => { + const table = makeTable({ + columns: [ + { id: 'a', accessorKey: 'a' }, + { id: 'b', accessorKey: 'b' }, + ], + }) + table.setColumnSizing({ a: 100, b: 150 }) + + const column = table.getColumn('a')! + const header = table.getHeaderGroups()[0]!.headers[0]! + let resolverReads = 0 + Object.defineProperty(column.columnDef, 'minSize', { + configurable: true, + get: () => { + resolverReads++ + return 20 + }, + }) + + expect(column.getSize()).toBe(100) + resolverReads = 0 + table.setColumnSizing({ a: 100, b: 200 }) + expect(column.getSize()).toBe(100) + expect(resolverReads).toBe(0) + + expect(header.getSize()).toBe(100) + resolverReads = 0 + table.setColumnSizing({ a: 100, b: 250 }) + expect(header.getSize()).toBe(100) + expect(resolverReads).toBe(0) + }) }) describe('column_resetSize', () => { diff --git a/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts b/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts index a147c18f24..f1699cd0a7 100644 --- a/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts @@ -373,8 +373,7 @@ describe('row_getCanPin', () => { }) it('should return false when enableRowPinning is false', () => { - const table = makeTable(10) - table.options.enableRowPinning = false + const table = makeTable(10, { enableRowPinning: false }) const row = table.getRow('0') @@ -382,8 +381,7 @@ describe('row_getCanPin', () => { }) it('should return true when enableRowPinning is true', () => { - const table = makeTable(10) - table.options.enableRowPinning = true + const table = makeTable(10, { enableRowPinning: true }) const row = table.getRow('0') @@ -392,9 +390,7 @@ describe('row_getCanPin', () => { it('should use enableRowPinning function when provided', () => { const enableRowPinning = vi.fn((row) => row.id === '1') - const table = makeTable(10) - - table.options.enableRowPinning = enableRowPinning + const table = makeTable(10, { enableRowPinning }) const row0 = table.getRow('0') const row1 = table.getRow('1') diff --git a/packages/table-core/tests/unit/utils.test.ts b/packages/table-core/tests/unit/utils.test.ts index b839d48c7c..b6d67a226b 100644 --- a/packages/table-core/tests/unit/utils.test.ts +++ b/packages/table-core/tests/unit/utils.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test, vi } from 'vitest' +import { createAtom } from '@tanstack/store' +import { afterEach, describe, expect, test, vi } from 'vitest' import { callMemoOrStaticFn, cloneState, @@ -11,46 +12,273 @@ import { } from '../../src/utils' describe('tableMemo', () => { - test('does not schedule after-update work when no callback is provided', () => { - const schedule = vi.fn() + function createMemoTable( + overrides: Record = {}, + options: Record = {}, + ) { + return { + _reactivity: { + addSubscription: vi.fn(), + batch: (fn: () => void) => fn(), + createReadonlyAtom: ( + fn: () => unknown, + atomOptions?: { + compare?: (previous: unknown, next: unknown) => boolean + }, + ) => + createAtom(fn, { + compare: atomOptions?.compare, + }), + createWritableAtom: (value: unknown) => createAtom(value), + schedule: vi.fn((fn: () => void) => fn()), + untrack: (fn: () => unknown) => fn(), + wrapExternalAtoms: false, + ...overrides, + }, + options, + store: { state: {} }, + } as any + } + + afterEach(() => { + vi.restoreAllMocks() + vi.unstubAllEnvs() + }) + + test('is lazy and evaluates exactly once on the first read with an eager computed binding', () => { + const compute = vi.fn(() => 42) + const onAfterUpdate = vi.fn() + const schedule = vi.fn((fn: () => void) => fn()) + const createReadonlyAtom = vi.fn((fn: () => number) => { + const value = fn() + return { + get: () => value, + subscribe: vi.fn(), + } + }) + const table = createMemoTable({ createReadonlyAtom, schedule }) const memoized = tableMemo({ - table: { - options: {}, - _reactivity: { - schedule, - untrack: (fn: () => void) => fn(), - }, - } as any, + table, fnName: 'table.getValue', - fn: (value?: number) => value ?? 0, - memoDeps: (value?: number) => [value], + fn: compute, + onAfterUpdate, }) - expect(memoized(1)).toBe(1) - expect(memoized(2)).toBe(2) + expect(createReadonlyAtom).not.toHaveBeenCalled() + expect(compute).not.toHaveBeenCalled() expect(schedule).not.toHaveBeenCalled() + + expect(memoized()).toBe(42) + expect(createReadonlyAtom).toHaveBeenCalledOnce() + expect(compute).toHaveBeenCalledOnce() + expect(schedule).toHaveBeenCalledOnce() + expect(onAfterUpdate).toHaveBeenCalledOnce() + }) + + test('uses the native computed cache for repeated reads', () => { + const source = createAtom(1) + const compute = vi.fn(() => source.get() * 2) + const onAfterUpdate = vi.fn() + const table = createMemoTable() + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: compute, + onAfterUpdate, + }) + + expect(memoized()).toBe(2) + expect(memoized()).toBe(2) + expect(compute).toHaveBeenCalledOnce() + expect(onAfterUpdate).toHaveBeenCalledOnce() + }) + + test('reevaluates after a native dependency changes', () => { + const source = createAtom(1) + const compute = vi.fn(() => source.get() * 2) + const onAfterUpdate = vi.fn() + const table = createMemoTable() + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: compute, + onAfterUpdate, + }) + + expect(memoized()).toBe(2) + source.set(2) + expect(memoized()).toBe(4) + expect(compute).toHaveBeenCalledTimes(2) + expect(onAfterUpdate).toHaveBeenCalledTimes(2) + }) + + test('schedules after every successful evaluation even when comparison retains the previous result', () => { + const source = createAtom(1) + const compute = vi.fn(() => ({ parity: source.get() % 2 })) + const onAfterUpdate = vi.fn() + const table = createMemoTable() + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: compute, + compare: (previous, next) => previous.parity === next.parity, + onAfterUpdate, + }) + + const first = memoized() + source.set(3) + const second = memoized() + + expect(second).toBe(first) + expect(compute).toHaveBeenCalledTimes(2) + expect(onAfterUpdate).toHaveBeenCalledTimes(2) + }) + + test('applies the result comparator exactly once per reevaluation', () => { + const source = createAtom(1) + const compare = vi.fn( + (previous: { parity: number }, next: { parity: number }) => + previous.parity === next.parity, + ) + const table = createMemoTable() + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: () => ({ parity: source.get() % 2 }), + compare, + }) + + memoized() + source.set(3) + memoized() + + expect(compare).toHaveBeenCalledOnce() }) - test('schedules after-update work when a callback is provided', () => { + test('does not advance or schedule when result comparison throws', () => { + const source = createAtom(1) + const onAfterUpdate = vi.fn() const schedule = vi.fn((fn: () => void) => fn()) + const compare = vi + .fn<(previous: number, next: number) => boolean>() + .mockImplementationOnce(() => { + throw new Error('comparison failed') + }) + .mockReturnValue(false) + const table = createMemoTable({ schedule }) + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: () => source.get(), + compare, + onAfterUpdate, + }) + + expect(memoized()).toBe(1) + source.set(2) + expect(() => memoized()).toThrow('comparison failed') + expect(schedule).toHaveBeenCalledOnce() + expect(onAfterUpdate).toHaveBeenCalledOnce() + + expect(memoized()).toBe(2) + expect(schedule).toHaveBeenCalledTimes(2) + expect(onAfterUpdate).toHaveBeenCalledTimes(2) + }) + + test('does not advance or schedule when the computation throws', () => { + const source = createAtom(0) const onAfterUpdate = vi.fn() + const schedule = vi.fn((fn: () => void) => fn()) + const table = createMemoTable({ schedule }) + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: () => { + source.get() + throw new Error('no value') + }, + onAfterUpdate, + }) + + expect(() => memoized()).toThrow('no value') + expect(schedule).not.toHaveBeenCalled() + expect(onAfterUpdate).not.toHaveBeenCalled() + }) + + test('does not schedule after-update work when no callback is provided', () => { + const schedule = vi.fn() + const table = createMemoTable({ schedule }) + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: () => 1, + }) + + expect(memoized()).toBe(1) + expect(memoized()).toBe(1) + expect(schedule).not.toHaveBeenCalled() + }) + + test('schedules the untracked callback after returning the computed result', () => { + const scheduled: Array<() => void> = [] + const events: Array = [] + const schedule = vi.fn((fn: () => void) => { + events.push('schedule') + scheduled.push(fn) + }) + const untrack = vi.fn((fn: () => void) => { + events.push('untrack') + return fn() + }) + const onAfterUpdate = vi.fn(() => { + events.push('after') + }) + const table = createMemoTable({ schedule, untrack }) const memoized = tableMemo({ - table: { - options: {}, - _reactivity: { - schedule, - untrack: (fn: () => void) => fn(), - }, - } as any, + table, fnName: 'table.getValue', - fn: (value?: number) => value ?? 0, - memoDeps: (value?: number) => [value], + fn: () => { + events.push('compute') + return 1 + }, onAfterUpdate, }) - expect(memoized(1)).toBe(1) - expect(schedule).toHaveBeenCalledTimes(1) - expect(onAfterUpdate).toHaveBeenCalledTimes(1) + expect(memoized()).toBe(1) + events.push('returned') + expect(events).toEqual(['compute', 'schedule', 'returned']) + expect(onAfterUpdate).not.toHaveBeenCalled() + + scheduled[0]!() + expect(events).toEqual([ + 'compute', + 'schedule', + 'returned', + 'untrack', + 'after', + ]) + }) + + test('logs cache hits when debugCache is enabled', () => { + vi.stubEnv('NODE_ENV', 'development') + const groupCollapsed = vi + .spyOn(console, 'groupCollapsed') + .mockImplementation(() => {}) + vi.spyOn(console, 'info').mockImplementation(() => {}) + vi.spyOn(console, 'trace').mockImplementation(() => {}) + vi.spyOn(console, 'groupEnd').mockImplementation(() => {}) + const table = createMemoTable({}, { debugCache: true }) + const memoized = tableMemo({ + table, + fnName: 'table.getValue', + fn: () => 1, + }) + + memoized() + memoized() + + expect(groupCollapsed).toHaveBeenCalledOnce() + expect(groupCollapsed.mock.calls[0]?.[0]).toContain('(cache)') }) }) diff --git a/packages/table-devtools/src/components/FeaturesPanel.tsx b/packages/table-devtools/src/components/FeaturesPanel.tsx index 6c839ff0ae..b4b5076757 100644 --- a/packages/table-devtools/src/components/FeaturesPanel.tsx +++ b/packages/table-devtools/src/components/FeaturesPanel.tsx @@ -158,10 +158,7 @@ export function FeaturesPanel() { (state) => state, ) const tableOptions = useTableStore( - () => { - const tableInstance = table() - return tableInstance?.optionsStore ?? tableInstance?.store - }, + () => table()?.optionAtoms.snapshotVersion, () => table()?.options as unknown, ) diff --git a/packages/table-devtools/src/components/OptionsPanel.tsx b/packages/table-devtools/src/components/OptionsPanel.tsx index e0753c4d0f..08de142edc 100644 --- a/packages/table-devtools/src/components/OptionsPanel.tsx +++ b/packages/table-devtools/src/components/OptionsPanel.tsx @@ -21,10 +21,7 @@ export function OptionsPanel() { const { table } = useTableDevtoolsContext() const tableOptions = useTableStore( - () => { - const tableInstance = table() - return tableInstance?.optionsStore ?? tableInstance?.store - }, + () => table()?.optionAtoms.snapshotVersion, () => { const tableInstance = table() return tableInstance diff --git a/packages/table-devtools/src/components/RowsPanel.tsx b/packages/table-devtools/src/components/RowsPanel.tsx index af45649ae9..79a045892b 100644 --- a/packages/table-devtools/src/components/RowsPanel.tsx +++ b/packages/table-devtools/src/components/RowsPanel.tsx @@ -52,10 +52,7 @@ export function RowsPanel() { (state) => state, ) const tableOptions = useTableStore( - () => { - const tableInstance = table() - return tableInstance?.optionsStore ?? tableInstance?.store - }, + () => table()?.optionAtoms.snapshotVersion, () => table()?.options as unknown, ) diff --git a/packages/table-devtools/src/components/StatePanel.tsx b/packages/table-devtools/src/components/StatePanel.tsx index 0095b61075..026d230c00 100644 --- a/packages/table-devtools/src/components/StatePanel.tsx +++ b/packages/table-devtools/src/components/StatePanel.tsx @@ -29,10 +29,7 @@ export function StatePanel() { (state) => state, ) const tableOptions = useTableStore( - () => { - const tableInstance = table() - return tableInstance?.optionsStore ?? tableInstance?.store - }, + () => table()?.optionAtoms.snapshotVersion, () => table()?.options as unknown, ) diff --git a/packages/table-devtools/src/tableTarget.ts b/packages/table-devtools/src/tableTarget.ts index ab6d4c4a90..6a87d37803 100644 --- a/packages/table-devtools/src/tableTarget.ts +++ b/packages/table-devtools/src/tableTarget.ts @@ -24,7 +24,9 @@ export interface TableDevtoolsTable { state?: Record [key: string]: unknown } - optionsStore?: TableDevtoolsStore + optionAtoms: { + readonly snapshotVersion: Readable + } reset: () => void store: TableDevtoolsStore } diff --git a/packages/vue-table/src/merge-proxy.ts b/packages/vue-table/src/merge-proxy.ts index 94600ac185..10cf8fa79c 100644 --- a/packages/vue-table/src/merge-proxy.ts +++ b/packages/vue-table/src/merge-proxy.ts @@ -1,3 +1,5 @@ +import { isRef } from 'vue' + function trueFn() { return true } @@ -8,8 +10,10 @@ const $SOURCES = Symbol('merge-proxy-sources') // https://github.com/solidjs/solid/blob/c20ca4fd8c36bc0522fedb2c7f38a110b7ee2663/packages/solid/src/render/component.ts#L51-L118 const propTraps: ProxyHandler<{ get: (k: string | number | symbol) => any + getDescriptor: (k: string | number | symbol) => PropertyDescriptor | undefined has: (k: string | number | symbol) => boolean - keys: () => Array + keys: () => Array + prototype: () => object | null sources: Array }> = { get(_, property, receiver) { @@ -23,16 +27,21 @@ const propTraps: ProxyHandler<{ set: trueFn, deleteProperty: trueFn, getOwnPropertyDescriptor(_, property) { + const descriptor = _.getDescriptor(property) + if (!descriptor) return undefined + return { configurable: true, - enumerable: true, + enumerable: descriptor.enumerable ?? false, get() { return _.get(property) }, set: trueFn, - deleteProperty: trueFn, } }, + getPrototypeOf(_) { + return _.prototype() + }, ownKeys(_) { return _.keys() }, @@ -53,7 +62,32 @@ type MergeProxy> = UnboxIntersection< > function resolveSource(s: any) { - return s && typeof s === 'object' && 'value' in s ? s.value : s + return isRef(s) ? s.value : s +} + +function getMergedPrototype(sources: Array): object | null { + let fallback: object | null = Object.prototype + + for (let i = sources.length - 1; i >= 0; i--) { + const source = resolveSource(sources[i]) + if ( + (typeof source !== 'object' && typeof source !== 'function') || + source === null + ) { + continue + } + + const prototype = Object.getPrototypeOf(source) + fallback = prototype + + // Adapter-injected option fragments are ordinary objects. Prefer a + // meaningful user prototype when one is present in another source. + if (prototype !== Object.prototype) { + return prototype + } + } + + return fallback } export function mergeProxy>(...sources: T): MergeProxy @@ -76,21 +110,40 @@ export function mergeProxy(...sources: any): any { sources: flattenedSources, get(property: string | number | symbol) { for (let i = flattenedSources.length - 1; i >= 0; i--) { - const v = resolveSource(flattenedSources[i])[property] - if (v !== undefined) return v + const source = resolveSource(flattenedSources[i]) + if (source != null && Reflect.has(source, property)) { + return Reflect.get(source, property, source) + } + } + }, + getDescriptor(property: string | number | symbol) { + for (let i = flattenedSources.length - 1; i >= 0; i--) { + const source = resolveSource(flattenedSources[i]) + if (source == null) continue + + const descriptor = Reflect.getOwnPropertyDescriptor(source, property) + if (descriptor) return descriptor } + return undefined }, has(property: string | number | symbol) { for (let i = flattenedSources.length - 1; i >= 0; i--) { - if (property in resolveSource(flattenedSources[i])) return true + const source = resolveSource(flattenedSources[i]) + if (source != null && Reflect.has(source, property)) return true } return false }, keys() { - const keys = [] - for (const source of flattenedSources) - keys.push(...Object.keys(resolveSource(source))) - return [...Array.from(new Set(keys))] + const keys = new Set() + for (const unresolvedSource of flattenedSources) { + const source = resolveSource(unresolvedSource) + if (source == null) continue + for (const key of Reflect.ownKeys(source)) keys.add(key) + } + return [...keys] + }, + prototype() { + return getMergedPrototype(flattenedSources) }, }, propTraps, @@ -114,17 +167,36 @@ export function flatMerge( source3: W, ): T & U & V & W export function flatMerge(...sources: any): any { - const result: Record = {} + const result = Object.create(getMergedPrototype(sources)) as Record< + PropertyKey, + unknown + > - for (let source of sources) { + for (let sourceIndex = 0; sourceIndex < sources.length; sourceIndex++) { + let source = sources[sourceIndex] source = resolveSource(source) if (!source) continue for (const key of Reflect.ownKeys(source)) { - const value = (source as Record)[key] - if (value !== undefined) { - result[key] = value + const descriptor = Reflect.getOwnPropertyDescriptor(source, key) + if ( + sourceIndex === sources.length - 1 && + descriptor && + !('value' in descriptor) + ) { + Object.defineProperty(result, key, { + ...descriptor, + configurable: true, + }) + continue } + + Object.defineProperty(result, key, { + configurable: true, + enumerable: descriptor?.enumerable ?? true, + value: Reflect.get(source, key, source), + writable: true, + }) } } diff --git a/packages/vue-table/src/reactivity.ts b/packages/vue-table/src/reactivity.ts index a79bc2937a..c105698faf 100644 --- a/packages/vue-table/src/reactivity.ts +++ b/packages/vue-table/src/reactivity.ts @@ -54,16 +54,12 @@ function refToWritableAtom(source: ShallowRef): Atom { /** * Creates the table-core reactivity bindings used by the Vue adapter. * - * Table state atoms are backed by TanStack Store atoms. The options store stays - * framework-native because row-model APIs read `table.options` directly during - * render. Readonly table atoms bridge Store dependency tracking into Vue computed - * refs. + * Table state and option atoms bridge table-core reads into Vue computed refs. */ export function vueReactivity(): TableReactivityBindings { const subscriptions = new Set() return { - createOptionsStore: true, wrapExternalAtoms: true, addSubscription: (subscription) => { subscriptions.add(subscription) @@ -73,8 +69,21 @@ export function vueReactivity(): TableReactivityBindings { subscriptions.clear() }, schedule: (fn) => queueMicrotask(() => fn()), - createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => { - return refToReadonlyAtom(computed(() => fn())) + createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => { + const compare = options?.compare ?? Object.is + let hasStableValue = false + let stableValue: T + + return refToReadonlyAtom( + computed(() => { + const nextValue = fn() + if (!hasStableValue || !compare(stableValue, nextValue)) { + stableValue = nextValue + hasStableValue = true + } + return stableValue + }), + ) }, createWritableAtom: ( value: T, diff --git a/packages/vue-table/src/useTable.ts b/packages/vue-table/src/useTable.ts index 58d7a7c622..0c126021b4 100644 --- a/packages/vue-table/src/useTable.ts +++ b/packages/vue-table/src/useTable.ts @@ -23,12 +23,20 @@ function getOptionsWithReactiveValues< TFeatures extends TableFeatures, TData extends RowData, >(options: TableOptionsWithReactiveData) { - const resolvedOptions: Record = {} - - for (const key of Object.keys(options)) { - resolvedOptions[key] = unref( - options[key as keyof TableOptionsWithReactiveData], - ) + const resolvedOptions = Object.create( + Object.getPrototypeOf(options), + ) as Record + + for (const key of Reflect.ownKeys(options)) { + const descriptor = Reflect.getOwnPropertyDescriptor(options, key) + const value = unref(Reflect.get(options, key, options)) + Object.defineProperty(resolvedOptions, key, { + configurable: true, + enumerable: descriptor?.enumerable ?? true, + get() { + return value + }, + }) } return mergeProxy(options, resolvedOptions) @@ -38,8 +46,8 @@ function getReactiveOptionDeps< TFeatures extends TableFeatures, TData extends RowData, >(options: TableOptionsWithReactiveData) { - return Object.keys(options).map((key) => - unref(options[key as keyof TableOptionsWithReactiveData]), + return Reflect.ownKeys(options).map((key) => + unref(Reflect.get(options, key, options)), ) } diff --git a/packages/vue-table/tests/unit/adapter-lifecycle.test.ts b/packages/vue-table/tests/unit/adapter-lifecycle.test.ts index e3f35a8c54..d3039d7c5d 100644 --- a/packages/vue-table/tests/unit/adapter-lifecycle.test.ts +++ b/packages/vue-table/tests/unit/adapter-lifecycle.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test, vi } from 'vitest' -import { computed, effectScope, nextTick, ref, watchEffect } from 'vue' +import { computed, effectScope, isRef, nextTick, ref, watchEffect } from 'vue' import { createAtom } from '@tanstack/store' import { stockFeatures } from '@tanstack/table-core' import { useTable } from '../../src/useTable' @@ -240,4 +240,59 @@ describe('Vue adapter lifecycle and reactive options', () => { scope.stop() }) + + test('an existing ref-backed option can be cleared without leaking the Ref', async () => { + const firstHandler = vi.fn>() + const onRowSelectionChange = ref | undefined>( + firstHandler, + ) + const customOption = ref('first') + const customSymbol = Symbol('custom-option') + const prototype = { inheritedOption: 'from-prototype' } + const options = Object.create( + prototype, + Object.getOwnPropertyDescriptors({ + data: [{ id: '1', title: 'First' }], + columns, + features: stockFeatures, + getRowId: (row: Data) => row.id, + onRowSelectionChange, + value: 'custom-value', + [customSymbol]: 'symbol-value', + get customOption() { + return customOption.value + }, + }), + ) + const scope = effectScope() + const table = scope.run(() => + useTable(options), + )! + + expect(table.options.onRowSelectionChange).toBe(firstHandler) + expect(isRef(table.options.onRowSelectionChange)).toBe(false) + expect((table.options as any).value).toBe('custom-value') + expect((table.options as any)[customSymbol]).toBe('symbol-value') + expect((table.options as any).customOption).toBe('first') + expect( + Object.getOwnPropertyDescriptor(table.options, 'customOption'), + ).toMatchObject({ + value: 'first', + writable: false, + }) + + onRowSelectionChange.value = undefined + customOption.value = 'second' + await nextTick() + + expect(table.options.onRowSelectionChange).toBeUndefined() + expect(table.optionAtoms.onRowSelectionChange!.get()).toBeUndefined() + expect(isRef(table.options.onRowSelectionChange)).toBe(false) + expect((table.options as any).customOption).toBe('second') + + table.toggleAllRowsSelected(true) + expect(firstHandler).not.toHaveBeenCalled() + + scope.stop() + }) }) diff --git a/packages/vue-table/tests/unit/signals.test.ts b/packages/vue-table/tests/unit/signals.test.ts index d751381c8c..3116ba4854 100644 --- a/packages/vue-table/tests/unit/signals.test.ts +++ b/packages/vue-table/tests/unit/signals.test.ts @@ -43,4 +43,25 @@ describe('vueReactivity', () => { expect(doubled.get()).toBe(4) }) + + test('readonly atoms preserve identity through their comparator', async () => { + const reactivity = vueReactivity() + const count = reactivity.createWritableAtom(0) + const parity = reactivity.createReadonlyAtom( + () => ({ even: count.get() % 2 === 0 }), + { + compare: (previous, next) => previous.even === next.even, + debugName: 'parity', + }, + ) + + const initial = parity.get() + count.set(2) + await nextTick() + expect(parity.get()).toBe(initial) + + count.set(3) + await nextTick() + expect(parity.get()).not.toBe(initial) + }) })