Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/lit-table/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"build": "tsdown"
},
"dependencies": {
"@tanstack/store": "^0.11.0",
"@tanstack/lit-store": "^0.13.2",
"@tanstack/table-core": "workspace:*"
},
"devDependencies": {
Expand Down
41 changes: 34 additions & 7 deletions packages/lit-table/src/TableController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { constructTable } from '@tanstack/table-core'
import { TanStackStoreSelector } from '@tanstack/lit-store'
import { litReactivity } from './reactivity'
import { FlexRender } from './flexRender'
import type { Atom, ReadonlyAtom, ReadonlyStore, Store } from '@tanstack/store'
import type {
Atom,
ReadonlyAtom,
ReadonlyStore,
Store,
} from '@tanstack/lit-store'
import type {
NoInfer,
RowData,
Expand Down Expand Up @@ -198,23 +204,28 @@ export class TableController<
const tableInstance = this._table

// Attach Subscribe function
const Subscribe = function Subscribe(props: {
const Subscribe = ((props: {
source?: SubscribeSource<unknown>
selector?: (state: unknown) => unknown
children:
| ((state: Readonly<unknown>) => TemplateResult | string)
| TemplateResult
| string
}): TemplateResult | string {
}): TemplateResult | string => {
const source = props.source ?? tableInstance.store
const value = source.get()
const selectedState =
props.selector !== undefined ? props.selector(value) : value

const storeSelector: TanStackStoreSelector<unknown> =
this._getOrCreateSelector(source, props.selector)
Comment on lines +217 to +218
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate TanStackStoreSelector implementation =="
selector_files="$(fd -i 'TanStackStoreSelector.*\.ts$' || true)"
if [ -z "${selector_files}" ]; then
  echo "No TanStackStoreSelector source file found in-repo (may be external package)."
else
  while IFS= read -r f; do
    echo "---- $f ----"
    rg -n -C3 'class\s+TanStackStoreSelector|addController\(|subscribe\(|unsubscribe\(' "$f"
  done <<< "${selector_files}"
fi

echo
echo "== Inspect creation sites in TableController =="
rg -n -C3 '_getOrCreateSelector|new TanStackStoreSelector|storeSelector\.value' packages/lit-table/src/TableController.ts

Repository: TanStack/table

Length of output: 1193


🏁 Script executed:

cat -n packages/lit-table/src/TableController.ts | head -n 320 | tail -n 100

Repository: TanStack/table

Length of output: 3667


🏁 Script executed:

rg -n 'import.*TanStackStoreSelector|from.*TanStackStoreSelector' packages/lit-table/src/TableController.ts

Repository: TanStack/table

Length of output: 120


Cache selector instances; new instance created on every Subscribe call.

Line 279 creates a fresh TanStackStoreSelector on each Subscribe invocation. The TODO comment on line 269 acknowledges this concern. In render-heavy usage, this accumulates controller and subscription instances without cleanup, since hostDisconnected only cleans up the main store subscriptions, not these selector instances.

Implement a two-level cache using WeakMap<source, Map<selector, instance>> to reuse instances per (source, selector) pair. The WeakMap ensures the cache is garbage-collected when sources are no longer referenced.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lit-table/src/TableController.ts` around lines 217 - 218, Cache and
reuse selector instances per source/selector pair to avoid creating a new
TanStackStoreSelector on every Subscribe call: add a private two-level cache
field (e.g., _selectorCache: WeakMap<any, Map<any,
TanStackStoreSelector<unknown>>> ) on TableController, update
_getOrCreateSelector(source, selector) to look up and return an existing
instance from _selectorCache[source].get(selector) or create, store, and return
a new one; ensure keys use the raw selector object/function (handle undefined
selectors consistently). Also update hostDisconnected (or appropriate teardown)
to remove the source entry from _selectorCache so entries can be
garbage-collected when a source is gone.


// TODO: update to newest version of Tanstack Store: https://github.com/TanStack/store/pull/329
const selectedState = storeSelector.value

if (typeof props.children === 'function') {
return props.children(selectedState as Readonly<unknown>)
}

return props.children
} as LitTable<TFeatures, TData, TSelected>['Subscribe']
}) as LitTable<TFeatures, TData, TSelected>['Subscribe']

return {
...this._table,
Expand Down Expand Up @@ -251,4 +262,20 @@ export class TableController<
this._optionsSubscription?.unsubscribe()
this._optionsSubscription = undefined
}

/**
* Get or create a TanStackStoreSelector for the given source and selector.
*
* TODO: check if caching of controllers can improve performance and reduce memory usage.
*
* @param source The atom or store to subscribe to
* @param selector Optional selector function to select a slice of the source state
* @returns A TanStackStoreSelector instance that subscribes to the source and applies the selector
*/
private _getOrCreateSelector = (
source?: SubscribeSource<unknown>,
selector?: (state: unknown) => unknown,
): TanStackStoreSelector<unknown> => {
return new TanStackStoreSelector(this.host, () => source, selector)
}
}
2 changes: 1 addition & 1 deletion packages/lit-table/src/reactivity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { batch, createAtom } from '@tanstack/store'
import { batch, createAtom } from '@tanstack/lit-store'
import type {
TableAtomOptions,
TableReactivityBindings,
Expand Down
16 changes: 13 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.