diff --git a/packages/svelte-table/src/createTable.svelte.ts b/packages/svelte-table/src/createTable.svelte.ts index 50aadfefbc..283b161337 100644 --- a/packages/svelte-table/src/createTable.svelte.ts +++ b/packages/svelte-table/src/createTable.svelte.ts @@ -1,7 +1,7 @@ import { constructTable } from '@tanstack/table-core' import { useSelector } from '@tanstack/svelte-store' import { untrack } from 'svelte' -import { mergeObjects } from './merge-objects' +import { flatMerge, mergeObjects } from './merge-objects' import { svelteReactivity } from './reactivity.svelte' import type { RowData, @@ -75,7 +75,7 @@ export function createTable< defaultOptions: TableOptions, newOptions: Partial>, ) => { - return mergeObjects(defaultOptions, newOptions) + return flatMerge(defaultOptions, newOptions) }, }, mergedOptions, @@ -107,7 +107,7 @@ export function createTable< untrack(() => { table.setOptions((prev) => { - return mergeObjects(prev, mergedOptions) + return flatMerge(prev, mergedOptions) }) }) }) diff --git a/packages/svelte-table/src/merge-objects.ts b/packages/svelte-table/src/merge-objects.ts index ca11d524d3..1dc17f3f47 100644 --- a/packages/svelte-table/src/merge-objects.ts +++ b/packages/svelte-table/src/merge-objects.ts @@ -41,3 +41,43 @@ export function mergeObjects(...sources: any): any { } return target } + +/** + * Merges objects together by eagerly resolving all values into a flat object. + * + * Unlike `mergeObjects`, this does NOT preserve getters — values are read once + * and stored as plain data properties. This prevents the getter-chain + * 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. + * + * @see https://github.com/TanStack/table/issues/6235 + */ +export function flatMerge(source: T): T +export function flatMerge(source: T, source1: U): T & U +export function flatMerge( + source: T, + source1: U, + source2: V, +): T & U & V +export function flatMerge( + source: T, + source1: U, + source2: V, + 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 + for (const key of Reflect.ownKeys(source)) { + const value = (source as Record)[key] + if (value !== undefined) { + result[key as string] = value + } + } + } + return result +}