@tanstack/table-core 9.0.0-alpha.34 → 9.0.0-alpha.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/core/columns/constructColumn.cjs.map +1 -1
  2. package/dist/core/columns/constructColumn.js.map +1 -1
  3. package/dist/core/columns/coreColumnsFeature.utils.cjs.map +1 -1
  4. package/dist/core/columns/coreColumnsFeature.utils.js.map +1 -1
  5. package/dist/core/headers/buildHeaderGroups.cjs.map +1 -1
  6. package/dist/core/headers/buildHeaderGroups.js.map +1 -1
  7. package/dist/core/headers/coreHeadersFeature.utils.cjs.map +1 -1
  8. package/dist/core/headers/coreHeadersFeature.utils.js.map +1 -1
  9. package/dist/core/row-models/createCoreRowModel.cjs.map +1 -1
  10. package/dist/core/row-models/createCoreRowModel.js.map +1 -1
  11. package/dist/core/rows/constructRow.cjs.map +1 -1
  12. package/dist/core/rows/constructRow.js.map +1 -1
  13. package/dist/core/table/constructTable.cjs +2 -1
  14. package/dist/core/table/constructTable.cjs.map +1 -1
  15. package/dist/core/table/constructTable.js +2 -1
  16. package/dist/core/table/constructTable.js.map +1 -1
  17. package/dist/core/table/coreTablesFeature.utils.cjs +1 -1
  18. package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
  19. package/dist/core/table/coreTablesFeature.utils.js +2 -2
  20. package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
  21. package/dist/features/column-faceting/createFacetedMinMaxValues.cjs.map +1 -1
  22. package/dist/features/column-faceting/createFacetedMinMaxValues.js.map +1 -1
  23. package/dist/features/column-faceting/createFacetedRowModel.cjs.map +1 -1
  24. package/dist/features/column-faceting/createFacetedRowModel.js.map +1 -1
  25. package/dist/features/column-faceting/createFacetedUniqueValues.cjs.map +1 -1
  26. package/dist/features/column-faceting/createFacetedUniqueValues.js.map +1 -1
  27. package/dist/features/column-filtering/columnFilteringFeature.utils.cjs +2 -2
  28. package/dist/features/column-filtering/columnFilteringFeature.utils.cjs.map +1 -1
  29. package/dist/features/column-filtering/columnFilteringFeature.utils.js +3 -3
  30. package/dist/features/column-filtering/columnFilteringFeature.utils.js.map +1 -1
  31. package/dist/features/column-filtering/createFilteredRowModel.cjs.map +1 -1
  32. package/dist/features/column-filtering/createFilteredRowModel.js.map +1 -1
  33. package/dist/features/column-filtering/filterRowsUtils.cjs.map +1 -1
  34. package/dist/features/column-filtering/filterRowsUtils.js.map +1 -1
  35. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +2 -2
  36. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
  37. package/dist/features/column-grouping/columnGroupingFeature.utils.js +3 -3
  38. package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
  39. package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
  40. package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
  41. package/dist/features/column-ordering/columnOrderingFeature.utils.cjs +3 -2
  42. package/dist/features/column-ordering/columnOrderingFeature.utils.cjs.map +1 -1
  43. package/dist/features/column-ordering/columnOrderingFeature.utils.js +3 -2
  44. package/dist/features/column-ordering/columnOrderingFeature.utils.js.map +1 -1
  45. package/dist/features/column-pinning/columnPinningFeature.utils.cjs +3 -3
  46. package/dist/features/column-pinning/columnPinningFeature.utils.cjs.map +1 -1
  47. package/dist/features/column-pinning/columnPinningFeature.utils.js +4 -4
  48. package/dist/features/column-pinning/columnPinningFeature.utils.js.map +1 -1
  49. package/dist/features/column-resizing/columnResizingFeature.utils.cjs +4 -3
  50. package/dist/features/column-resizing/columnResizingFeature.utils.cjs.map +1 -1
  51. package/dist/features/column-resizing/columnResizingFeature.utils.js +4 -3
  52. package/dist/features/column-resizing/columnResizingFeature.utils.js.map +1 -1
  53. package/dist/features/column-sizing/columnSizingFeature.utils.cjs +4 -4
  54. package/dist/features/column-sizing/columnSizingFeature.utils.cjs.map +1 -1
  55. package/dist/features/column-sizing/columnSizingFeature.utils.js +5 -5
  56. package/dist/features/column-sizing/columnSizingFeature.utils.js.map +1 -1
  57. package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs +2 -2
  58. package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs.map +1 -1
  59. package/dist/features/column-visibility/columnVisibilityFeature.utils.js +3 -3
  60. package/dist/features/column-visibility/columnVisibilityFeature.utils.js.map +1 -1
  61. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +1 -1
  62. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
  63. package/dist/features/global-filtering/globalFilteringFeature.utils.js +2 -2
  64. package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
  65. package/dist/features/row-expanding/createExpandedRowModel.cjs.map +1 -1
  66. package/dist/features/row-expanding/createExpandedRowModel.js.map +1 -1
  67. package/dist/features/row-expanding/rowExpandingFeature.utils.cjs +3 -2
  68. package/dist/features/row-expanding/rowExpandingFeature.utils.cjs.map +1 -1
  69. package/dist/features/row-expanding/rowExpandingFeature.utils.js +4 -2
  70. package/dist/features/row-expanding/rowExpandingFeature.utils.js.map +1 -1
  71. package/dist/features/row-pagination/createPaginatedRowModel.cjs.map +1 -1
  72. package/dist/features/row-pagination/createPaginatedRowModel.js.map +1 -1
  73. package/dist/features/row-pagination/rowPaginationFeature.utils.cjs +19 -13
  74. package/dist/features/row-pagination/rowPaginationFeature.utils.cjs.map +1 -1
  75. package/dist/features/row-pagination/rowPaginationFeature.utils.js +20 -14
  76. package/dist/features/row-pagination/rowPaginationFeature.utils.js.map +1 -1
  77. package/dist/features/row-pinning/rowPinningFeature.utils.cjs +3 -3
  78. package/dist/features/row-pinning/rowPinningFeature.utils.cjs.map +1 -1
  79. package/dist/features/row-pinning/rowPinningFeature.utils.js +4 -4
  80. package/dist/features/row-pinning/rowPinningFeature.utils.js.map +1 -1
  81. package/dist/features/row-selection/rowSelectionFeature.utils.cjs +3 -2
  82. package/dist/features/row-selection/rowSelectionFeature.utils.cjs.map +1 -1
  83. package/dist/features/row-selection/rowSelectionFeature.utils.js +4 -2
  84. package/dist/features/row-selection/rowSelectionFeature.utils.js.map +1 -1
  85. package/dist/features/row-sorting/createSortedRowModel.cjs.map +1 -1
  86. package/dist/features/row-sorting/createSortedRowModel.js.map +1 -1
  87. package/dist/features/row-sorting/rowSortingFeature.utils.cjs +2 -2
  88. package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
  89. package/dist/features/row-sorting/rowSortingFeature.utils.js +3 -3
  90. package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
  91. package/dist/flex-render.cjs +19 -0
  92. package/dist/flex-render.cjs.map +1 -0
  93. package/dist/flex-render.d.cts +24 -0
  94. package/dist/flex-render.d.ts +24 -0
  95. package/dist/flex-render.js +16 -0
  96. package/dist/flex-render.js.map +1 -0
  97. package/dist/fns/filterFns.cjs.map +1 -1
  98. package/dist/fns/filterFns.js.map +1 -1
  99. package/dist/index.cjs +1 -2
  100. package/dist/index.d.cts +2 -3
  101. package/dist/index.d.ts +2 -3
  102. package/dist/index.js +2 -3
  103. package/dist/utils.cjs +12 -0
  104. package/dist/utils.cjs.map +1 -1
  105. package/dist/utils.d.cts +2 -1
  106. package/dist/utils.d.ts +2 -1
  107. package/dist/utils.js +12 -1
  108. package/dist/utils.js.map +1 -1
  109. package/package.json +5 -1
  110. package/src/core/columns/coreColumnsFeature.utils.ts +1 -1
  111. package/src/core/row-models/createCoreRowModel.ts +1 -1
  112. package/src/core/rows/constructRow.ts +1 -1
  113. package/src/core/table/constructTable.ts +4 -5
  114. package/src/core/table/coreTablesFeature.utils.ts +2 -2
  115. package/src/features/column-faceting/createFacetedMinMaxValues.ts +1 -1
  116. package/src/features/column-faceting/createFacetedRowModel.ts +1 -1
  117. package/src/features/column-faceting/createFacetedUniqueValues.ts +1 -1
  118. package/src/features/column-filtering/columnFilteringFeature.utils.ts +8 -13
  119. package/src/features/column-filtering/createFilteredRowModel.ts +1 -1
  120. package/src/features/column-grouping/columnGroupingFeature.utils.ts +7 -7
  121. package/src/features/column-grouping/createGroupedRowModel.ts +1 -1
  122. package/src/features/column-ordering/columnOrderingFeature.utils.ts +3 -2
  123. package/src/features/column-pinning/columnPinningFeature.utils.ts +6 -4
  124. package/src/features/column-resizing/columnResizingFeature.utils.ts +6 -3
  125. package/src/features/column-sizing/columnSizingFeature.utils.ts +5 -5
  126. package/src/features/column-visibility/columnVisibilityFeature.utils.ts +3 -3
  127. package/src/features/global-filtering/globalFilteringFeature.utils.ts +4 -5
  128. package/src/features/row-expanding/createExpandedRowModel.ts +1 -1
  129. package/src/features/row-expanding/rowExpandingFeature.utils.ts +4 -3
  130. package/src/features/row-pagination/createPaginatedRowModel.ts +1 -1
  131. package/src/features/row-pagination/rowPaginationFeature.utils.ts +20 -16
  132. package/src/features/row-pinning/rowPinningFeature.utils.ts +6 -4
  133. package/src/features/row-selection/rowSelectionFeature.utils.ts +5 -6
  134. package/src/features/row-sorting/createSortedRowModel.ts +3 -4
  135. package/src/features/row-sorting/rowSortingFeature.utils.ts +7 -9
  136. package/src/flex-render.ts +60 -0
  137. package/src/index.ts +0 -1
  138. package/src/utils.ts +24 -0
  139. package/dist/helpers/tableHelper.cjs +0 -21
  140. package/dist/helpers/tableHelper.cjs.map +0 -1
  141. package/dist/helpers/tableHelper.d.cts +0 -30
  142. package/dist/helpers/tableHelper.d.ts +0 -30
  143. package/dist/helpers/tableHelper.js +0 -21
  144. package/dist/helpers/tableHelper.js.map +0 -1
  145. package/src/helpers/tableHelper.ts +0 -61
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { Table, Table_Internal } from './types/Table'\nimport type { NoInfer, RowData, Updater } from './types/type-utils'\nimport type { TableFeatures } from './types/TableFeatures'\nimport type { TableState, TableState_All } from './types/TableState'\n\nexport function functionalUpdate<T>(updater: Updater<T>, input: T): T {\n return typeof updater === 'function'\n ? (updater as (i: T) => T)(input)\n : updater\n}\n\nexport function noop() {}\n\nexport function makeStateUpdater<\n TFeatures extends TableFeatures,\n K extends (string & {}) | keyof TableState_All | keyof TableState<TFeatures>,\n>(key: K, instance: Table<TFeatures, any>) {\n return (updater: Updater<TableState<any>[K & keyof TableState<any>]>) => {\n const externalAtom = (instance.options as any).atoms?.[key]\n const targetAtom = externalAtom ?? (instance.baseAtoms as any)[key]\n targetAtom.set((old: any) => functionalUpdate(updater, old))\n }\n}\n\ntype AnyFunction = (...args: any) => any\n\nexport function isFunction<T extends AnyFunction>(d: any): d is T {\n return d instanceof Function\n}\n\nexport function isNumberArray(d: any): d is Array<number> {\n return Array.isArray(d) && d.every((val) => typeof val === 'number')\n}\n\nexport function flattenBy<TNode>(\n arr: Array<TNode>,\n getChildren: (item: TNode) => Array<TNode>,\n) {\n const flat: Array<TNode> = []\n\n const recurse = (subArr: Array<TNode>) => {\n subArr.forEach((item) => {\n flat.push(item)\n const children = getChildren(item)\n if (children.length) {\n recurse(children)\n }\n })\n }\n\n recurse(arr)\n\n return flat\n}\n\nexport const $internalMemoFnMeta = Symbol('memoFnMeta')\nexport type MemoFnMeta = { originalArgsLength?: number }\n\n/**\n * @internal\n */\nfunction setMemoFnMeta(fn: Function, meta: MemoFnMeta) {\n Object.defineProperty(fn, $internalMemoFnMeta, { value: meta })\n}\n\n/**\n * @internal\n */\nexport function getMemoFnMeta(fn: any): MemoFnMeta | null {\n return (typeof fn === 'function' && fn[$internalMemoFnMeta]) ?? null\n}\n\ninterface MemoOptions<TDeps extends ReadonlyArray<any>, TDepArgs, TResult> {\n fn: (...args: NoInfer<TDeps>) => TResult\n memoDeps?: (depArgs?: TDepArgs) => [...TDeps] | undefined\n onAfterCompare?: (depsChanged: boolean) => void\n onAfterUpdate?: (result: TResult) => void\n onBeforeCompare?: () => void\n onBeforeUpdate?: () => void\n}\n\nexport const memo = <TDeps extends ReadonlyArray<any>, TDepArgs, TResult>({\n fn,\n memoDeps,\n onAfterCompare,\n onAfterUpdate,\n onBeforeCompare,\n onBeforeUpdate,\n}: MemoOptions<TDeps, TDepArgs, TResult>): ((\n depArgs?: TDepArgs,\n) => TResult) => {\n let deps: Array<any> | undefined = []\n let result: TResult | undefined\n\n const memoizedFn = (depArgs?: TDepArgs): TResult => {\n onBeforeCompare?.()\n const newDeps = memoDeps?.(depArgs)\n const depsChanged =\n !newDeps ||\n newDeps.length !== deps?.length ||\n newDeps.some((dep: any, index: number) => deps?.[index] !== dep)\n onAfterCompare?.(depsChanged)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n onBeforeUpdate?.()\n result = fn(...(newDeps ?? ([] as any)))\n onAfterUpdate?.(result)\n\n return result\n }\n\n setMemoFnMeta(memoizedFn, { originalArgsLength: fn.length })\n\n return memoizedFn\n}\n\ninterface TableMemoOptions<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n> extends MemoOptions<TDeps, TDepArgs, TResult> {\n feature?: keyof TFeatures & string\n fnName: string\n objectId?: string\n onAfterUpdate?: () => void\n table: Table_Internal<TFeatures, any>\n}\n\nconst pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n}\n\nexport function tableMemo<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n>({\n feature,\n fnName,\n objectId,\n onAfterUpdate,\n table,\n ...memoOptions\n}: TableMemoOptions<TFeatures, TDeps, TDepArgs, TResult>) {\n let beforeCompareTime: number\n let afterCompareTime: number\n let startCalcTime: number\n let endCalcTime: number\n let runCount = 0\n let debug: boolean | undefined\n let debugCache: boolean | undefined\n\n if (process.env.NODE_ENV === 'development') {\n const { debugCache: _debugCache, debugAll } = table.options\n debugCache = _debugCache\n const { parentName } = getFunctionNameInfo(fnName, '.')\n\n const debugByParent =\n // @ts-expect-error\n table.options[\n `debug${(parentName != 'table' ? parentName + 's' : parentName).replace(\n parentName,\n parentName.charAt(0).toUpperCase() + parentName.slice(1),\n )}`\n ]\n const debugByFeature = feature\n ? // @ts-expect-error\n table.options[\n `debug${feature.charAt(0).toUpperCase() + feature.slice(1)}`\n ]\n : false\n\n debug = debugAll || debugByParent || debugByFeature\n }\n\n function logTime(time: number, depsChanged: boolean) {\n const runType =\n runCount === 0\n ? '(1st run)'\n : depsChanged\n ? '(rerun #' + runCount + ')'\n : '(cache)'\n runCount++\n\n console.groupCollapsed(\n `%c⏱ ${pad(`${time.toFixed(1)} ms`, 12)} %c${runType}%c ${fnName}%c ${objectId ? `(${fnName.split('.')[0]}Id: ${objectId})` : ''}`,\n `font-size: .6rem; font-weight: bold; ${\n depsChanged\n ? `color: hsl(\n ${Math.max(0, Math.min(120 - Math.log10(time) * 60, 120))}deg 100% 31%);`\n : ''\n } `,\n `color: ${runCount < 2 ? '#FF00FF' : '#FF1493'}`,\n 'color: #666',\n 'color: #87CEEB',\n )\n console.info({\n feature,\n state: table.store.state,\n deps: memoOptions.memoDeps?.toString(),\n })\n console.trace()\n console.groupEnd()\n }\n\n const debugOptions =\n process.env.NODE_ENV === 'development'\n ? {\n onBeforeCompare: () => {\n if (debugCache) {\n beforeCompareTime = performance.now()\n }\n },\n onAfterCompare: (depsChanged: boolean) => {\n if (debugCache) {\n afterCompareTime = performance.now()\n const compareTime =\n Math.round((afterCompareTime - beforeCompareTime) * 100) / 100\n if (!depsChanged) {\n logTime(compareTime, depsChanged)\n }\n }\n },\n onBeforeUpdate: () => {\n if (debug) {\n startCalcTime = performance.now()\n }\n },\n onAfterUpdate: () => {\n if (debug) {\n endCalcTime = performance.now()\n const executionTime =\n Math.round((endCalcTime - startCalcTime) * 100) / 100\n logTime(executionTime, true)\n }\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n : {\n onAfterUpdate: () => {\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n\n return memo({\n ...memoOptions,\n ...debugOptions,\n })\n}\n\nexport interface API<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (...args: any) => any\n memoDeps?: (depArgs?: any) => [...any] | undefined\n}\n\nexport type APIObject<TDeps extends ReadonlyArray<any>, TDepArgs> = Record<\n string,\n API<TDeps, TDepArgs>\n>\n\n/**\n * Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`.\n */\nexport function getFunctionNameInfo(\n staticFnName: string,\n splitBy: '_' | '.' = '_',\n) {\n const [parentName, fnKey] = staticFnName.split(splitBy)\n const fnName = `${parentName}.${fnKey}`\n return { fnKey, fnName, parentName } as {\n fnKey: string\n fnName: string\n parentName: string\n }\n}\n\n/**\n * Assigns Table API methods directly to the table instance.\n * Unlike row/cell/column/header, the table is a singleton so methods are assigned directly.\n */\nexport function assignTableAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n table: Table_Internal<TFeatures, TData>,\n apis: APIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n ;(table as Record<string, any>)[fnKey] = memoDeps\n ? tableMemo({\n memoDeps,\n fn,\n fnName,\n table,\n feature,\n })\n : fn\n }\n}\n\nexport interface PrototypeAPI<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (self: any, ...args: any) => any\n memoDeps?: (self: any, depArgs?: any) => [...any] | undefined\n}\n\nexport type PrototypeAPIObject<\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n> = Record<string, PrototypeAPI<TDeps, TDepArgs>>\n\n/**\n * Assigns API methods to a prototype object for memory-efficient method sharing.\n * All instances created with this prototype will share the same method references.\n *\n * For memoized methods, the memo state is lazily created and stored on each instance.\n * This provides the best of both worlds: shared method code + per-instance caching.\n */\nexport function assignPrototypeAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n prototype: Record<string, any>,\n table: Table_Internal<TFeatures, TData>,\n apis: PrototypeAPIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n if (memoDeps) {\n // For memoized methods, create a function that lazily initializes\n // the memo on first access and stores it on the instance\n const memoKey = `_memo_${fnKey}`\n\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n // Lazily create memo on first access for this instance\n if (!this[memoKey]) {\n const self = this\n this[memoKey] = tableMemo({\n memoDeps: () => memoDeps(self),\n fn: (...deps) => fn(self, ...deps),\n fnName,\n objectId: self.id,\n table,\n feature,\n })\n }\n return this[memoKey](...args)\n }\n } else {\n // Non-memoized methods just call the static function with `this`\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n return fn(this, ...args)\n }\n }\n\n setMemoFnMeta(prototype[fnKey], { originalArgsLength: fn.length })\n }\n}\n\n/**\n * Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in.\n */\nexport function callMemoOrStaticFn<\n TObject extends Record<string, any>,\n TStaticFn extends AnyFunction,\n>(\n obj: TObject,\n fnKey: string,\n staticFn: TStaticFn,\n ...args: Parameters<TStaticFn> extends [any, ...infer Rest] ? Rest : never\n): ReturnType<TStaticFn> {\n return (\n (obj[fnKey] as Function | undefined)?.(...args) ?? staticFn(obj, ...args)\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { Table, Table_Internal } from './types/Table'\nimport type { NoInfer, RowData, Updater } from './types/type-utils'\nimport type { TableFeatures } from './types/TableFeatures'\nimport type { TableState, TableState_All } from './types/TableState'\n\nexport function functionalUpdate<T>(updater: Updater<T>, input: T): T {\n return typeof updater === 'function'\n ? (updater as (i: T) => T)(input)\n : updater\n}\n\nexport function cloneState<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map(cloneState) as T\n }\n\n if (value && typeof value === 'object') {\n const proto = Object.getPrototypeOf(value)\n\n if (proto !== Object.prototype && proto !== null) {\n return value\n }\n\n const copy: Record<string, unknown> = {}\n\n for (const key of Object.keys(value)) {\n copy[key] = cloneState((value as Record<string, unknown>)[key])\n }\n\n return copy as T\n }\n\n return value\n}\n\nexport function noop() {}\n\nexport function makeStateUpdater<\n TFeatures extends TableFeatures,\n K extends (string & {}) | keyof TableState_All | keyof TableState<TFeatures>,\n>(key: K, instance: Table<TFeatures, any>) {\n return (updater: Updater<TableState<any>[K & keyof TableState<any>]>) => {\n const externalAtom = (instance.options as any).atoms?.[key]\n const targetAtom = externalAtom ?? (instance.baseAtoms as any)[key]\n targetAtom.set((old: any) => functionalUpdate(updater, old))\n }\n}\n\ntype AnyFunction = (...args: any) => any\n\nexport function isFunction<T extends AnyFunction>(d: any): d is T {\n return d instanceof Function\n}\n\nexport function isNumberArray(d: any): d is Array<number> {\n return Array.isArray(d) && d.every((val) => typeof val === 'number')\n}\n\nexport function flattenBy<TNode>(\n arr: Array<TNode>,\n getChildren: (item: TNode) => Array<TNode>,\n) {\n const flat: Array<TNode> = []\n\n const recurse = (subArr: Array<TNode>) => {\n subArr.forEach((item) => {\n flat.push(item)\n const children = getChildren(item)\n if (children.length) {\n recurse(children)\n }\n })\n }\n\n recurse(arr)\n\n return flat\n}\n\nexport const $internalMemoFnMeta = Symbol('memoFnMeta')\nexport type MemoFnMeta = { originalArgsLength?: number }\n\n/**\n * @internal\n */\nfunction setMemoFnMeta(fn: Function, meta: MemoFnMeta) {\n Object.defineProperty(fn, $internalMemoFnMeta, { value: meta })\n}\n\n/**\n * @internal\n */\nexport function getMemoFnMeta(fn: any): MemoFnMeta | null {\n return (typeof fn === 'function' && fn[$internalMemoFnMeta]) ?? null\n}\n\ninterface MemoOptions<TDeps extends ReadonlyArray<any>, TDepArgs, TResult> {\n fn: (...args: NoInfer<TDeps>) => TResult\n memoDeps?: (depArgs?: TDepArgs) => [...TDeps] | undefined\n onAfterCompare?: (depsChanged: boolean) => void\n onAfterUpdate?: (result: TResult) => void\n onBeforeCompare?: () => void\n onBeforeUpdate?: () => void\n}\n\nexport const memo = <TDeps extends ReadonlyArray<any>, TDepArgs, TResult>({\n fn,\n memoDeps,\n onAfterCompare,\n onAfterUpdate,\n onBeforeCompare,\n onBeforeUpdate,\n}: MemoOptions<TDeps, TDepArgs, TResult>): ((\n depArgs?: TDepArgs,\n) => TResult) => {\n let deps: Array<any> | undefined = []\n let result: TResult | undefined\n\n const memoizedFn = (depArgs?: TDepArgs): TResult => {\n onBeforeCompare?.()\n const newDeps = memoDeps?.(depArgs)\n const depsChanged =\n !newDeps ||\n newDeps.length !== deps?.length ||\n newDeps.some((dep: any, index: number) => deps?.[index] !== dep)\n onAfterCompare?.(depsChanged)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n onBeforeUpdate?.()\n result = fn(...(newDeps ?? ([] as any)))\n onAfterUpdate?.(result)\n\n return result\n }\n\n setMemoFnMeta(memoizedFn, { originalArgsLength: fn.length })\n\n return memoizedFn\n}\n\ninterface TableMemoOptions<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n> extends MemoOptions<TDeps, TDepArgs, TResult> {\n feature?: keyof TFeatures & string\n fnName: string\n objectId?: string\n onAfterUpdate?: () => void\n table: Table_Internal<TFeatures, any>\n}\n\nconst pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n}\n\nexport function tableMemo<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n>({\n feature,\n fnName,\n objectId,\n onAfterUpdate,\n table,\n ...memoOptions\n}: TableMemoOptions<TFeatures, TDeps, TDepArgs, TResult>) {\n let beforeCompareTime: number\n let afterCompareTime: number\n let startCalcTime: number\n let endCalcTime: number\n let runCount = 0\n let debug: boolean | undefined\n let debugCache: boolean | undefined\n\n if (process.env.NODE_ENV === 'development') {\n const { debugCache: _debugCache, debugAll } = table.options\n debugCache = _debugCache\n const { parentName } = getFunctionNameInfo(fnName, '.')\n\n const debugByParent =\n // @ts-expect-error\n table.options[\n `debug${(parentName != 'table' ? parentName + 's' : parentName).replace(\n parentName,\n parentName.charAt(0).toUpperCase() + parentName.slice(1),\n )}`\n ]\n const debugByFeature = feature\n ? // @ts-expect-error\n table.options[\n `debug${feature.charAt(0).toUpperCase() + feature.slice(1)}`\n ]\n : false\n\n debug = debugAll || debugByParent || debugByFeature\n }\n\n function logTime(time: number, depsChanged: boolean) {\n const runType =\n runCount === 0\n ? '(1st run)'\n : depsChanged\n ? '(rerun #' + runCount + ')'\n : '(cache)'\n runCount++\n\n console.groupCollapsed(\n `%c⏱ ${pad(`${time.toFixed(1)} ms`, 12)} %c${runType}%c ${fnName}%c ${objectId ? `(${fnName.split('.')[0]}Id: ${objectId})` : ''}`,\n `font-size: .6rem; font-weight: bold; ${\n depsChanged\n ? `color: hsl(\n ${Math.max(0, Math.min(120 - Math.log10(time) * 60, 120))}deg 100% 31%);`\n : ''\n } `,\n `color: ${runCount < 2 ? '#FF00FF' : '#FF1493'}`,\n 'color: #666',\n 'color: #87CEEB',\n )\n console.info({\n feature,\n state: table.store.state,\n deps: memoOptions.memoDeps?.toString(),\n })\n console.trace()\n console.groupEnd()\n }\n\n const debugOptions =\n process.env.NODE_ENV === 'development'\n ? {\n onBeforeCompare: () => {\n if (debugCache) {\n beforeCompareTime = performance.now()\n }\n },\n onAfterCompare: (depsChanged: boolean) => {\n if (debugCache) {\n afterCompareTime = performance.now()\n const compareTime =\n Math.round((afterCompareTime - beforeCompareTime) * 100) / 100\n if (!depsChanged) {\n logTime(compareTime, depsChanged)\n }\n }\n },\n onBeforeUpdate: () => {\n if (debug) {\n startCalcTime = performance.now()\n }\n },\n onAfterUpdate: () => {\n if (debug) {\n endCalcTime = performance.now()\n const executionTime =\n Math.round((endCalcTime - startCalcTime) * 100) / 100\n logTime(executionTime, true)\n }\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n : {\n onAfterUpdate: () => {\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n\n return memo({\n ...memoOptions,\n ...debugOptions,\n })\n}\n\nexport interface API<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (...args: any) => any\n memoDeps?: (depArgs?: any) => [...any] | undefined\n}\n\nexport type APIObject<TDeps extends ReadonlyArray<any>, TDepArgs> = Record<\n string,\n API<TDeps, TDepArgs>\n>\n\n/**\n * Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`.\n */\nexport function getFunctionNameInfo(\n staticFnName: string,\n splitBy: '_' | '.' = '_',\n) {\n const [parentName, fnKey] = staticFnName.split(splitBy)\n const fnName = `${parentName}.${fnKey}`\n return { fnKey, fnName, parentName } as {\n fnKey: string\n fnName: string\n parentName: string\n }\n}\n\n/**\n * Assigns Table API methods directly to the table instance.\n * Unlike row/cell/column/header, the table is a singleton so methods are assigned directly.\n */\nexport function assignTableAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n table: Table_Internal<TFeatures, TData>,\n apis: APIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n ;(table as Record<string, any>)[fnKey] = memoDeps\n ? tableMemo({\n memoDeps,\n fn,\n fnName,\n table,\n feature,\n })\n : fn\n }\n}\n\nexport interface PrototypeAPI<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (self: any, ...args: any) => any\n memoDeps?: (self: any, depArgs?: any) => [...any] | undefined\n}\n\nexport type PrototypeAPIObject<\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n> = Record<string, PrototypeAPI<TDeps, TDepArgs>>\n\n/**\n * Assigns API methods to a prototype object for memory-efficient method sharing.\n * All instances created with this prototype will share the same method references.\n *\n * For memoized methods, the memo state is lazily created and stored on each instance.\n * This provides the best of both worlds: shared method code + per-instance caching.\n */\nexport function assignPrototypeAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n prototype: Record<string, any>,\n table: Table_Internal<TFeatures, TData>,\n apis: PrototypeAPIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n if (memoDeps) {\n // For memoized methods, create a function that lazily initializes\n // the memo on first access and stores it on the instance\n const memoKey = `_memo_${fnKey}`\n\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n // Lazily create memo on first access for this instance\n if (!this[memoKey]) {\n const self = this\n this[memoKey] = tableMemo({\n memoDeps: () => memoDeps(self),\n fn: (...deps) => fn(self, ...deps),\n fnName,\n objectId: self.id,\n table,\n feature,\n })\n }\n return this[memoKey](...args)\n }\n } else {\n // Non-memoized methods just call the static function with `this`\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n return fn(this, ...args)\n }\n }\n\n setMemoFnMeta(prototype[fnKey], { originalArgsLength: fn.length })\n }\n}\n\n/**\n * Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in.\n */\nexport function callMemoOrStaticFn<\n TObject extends Record<string, any>,\n TStaticFn extends AnyFunction,\n>(\n obj: TObject,\n fnKey: string,\n staticFn: TStaticFn,\n ...args: Parameters<TStaticFn> extends [any, ...infer Rest] ? Rest : never\n): ReturnType<TStaticFn> {\n return (\n (obj[fnKey] as Function | undefined)?.(...args) ?? staticFn(obj, ...args)\n )\n}\n"],"mappings":"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"}
package/dist/utils.d.cts CHANGED
@@ -5,6 +5,7 @@ import { Table, Table_Internal } from "./types/Table.cjs";
5
5
 
6
6
  //#region src/utils.d.ts
7
7
  declare function functionalUpdate<T>(updater: Updater<T>, input: T): T;
8
+ declare function cloneState<T>(value: T): T;
8
9
  declare function noop(): void;
9
10
  declare function makeStateUpdater<TFeatures extends TableFeatures, K extends (string & {}) | keyof TableState_All | keyof TableState<TFeatures>>(key: K, instance: Table<TFeatures, any>): (updater: Updater<TableState<any>[K & keyof TableState<any>]>) => void;
10
11
  type AnyFunction = (...args: any) => any;
@@ -86,5 +87,5 @@ declare function assignPrototypeAPIs<TFeatures extends TableFeatures, TData exte
86
87
  */
87
88
  declare function callMemoOrStaticFn<TObject extends Record<string, any>, TStaticFn extends AnyFunction>(obj: TObject, fnKey: string, staticFn: TStaticFn, ...args: Parameters<TStaticFn> extends [any, ...infer Rest] ? Rest : never): ReturnType<TStaticFn>;
88
89
  //#endregion
89
- export { $internalMemoFnMeta, API, APIObject, MemoFnMeta, PrototypeAPI, PrototypeAPIObject, assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, flattenBy, functionalUpdate, getFunctionNameInfo, getMemoFnMeta, isFunction, isNumberArray, makeStateUpdater, memo, noop, tableMemo };
90
+ export { $internalMemoFnMeta, API, APIObject, MemoFnMeta, PrototypeAPI, PrototypeAPIObject, assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, cloneState, flattenBy, functionalUpdate, getFunctionNameInfo, getMemoFnMeta, isFunction, isNumberArray, makeStateUpdater, memo, noop, tableMemo };
90
91
  //# sourceMappingURL=utils.d.cts.map
package/dist/utils.d.ts CHANGED
@@ -5,6 +5,7 @@ import { Table, Table_Internal } from "./types/Table.js";
5
5
 
6
6
  //#region src/utils.d.ts
7
7
  declare function functionalUpdate<T>(updater: Updater<T>, input: T): T;
8
+ declare function cloneState<T>(value: T): T;
8
9
  declare function noop(): void;
9
10
  declare function makeStateUpdater<TFeatures extends TableFeatures, K extends (string & {}) | keyof TableState_All | keyof TableState<TFeatures>>(key: K, instance: Table<TFeatures, any>): (updater: Updater<TableState<any>[K & keyof TableState<any>]>) => void;
10
11
  type AnyFunction = (...args: any) => any;
@@ -86,5 +87,5 @@ declare function assignPrototypeAPIs<TFeatures extends TableFeatures, TData exte
86
87
  */
87
88
  declare function callMemoOrStaticFn<TObject extends Record<string, any>, TStaticFn extends AnyFunction>(obj: TObject, fnKey: string, staticFn: TStaticFn, ...args: Parameters<TStaticFn> extends [any, ...infer Rest] ? Rest : never): ReturnType<TStaticFn>;
88
89
  //#endregion
89
- export { $internalMemoFnMeta, API, APIObject, MemoFnMeta, PrototypeAPI, PrototypeAPIObject, assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, flattenBy, functionalUpdate, getFunctionNameInfo, getMemoFnMeta, isFunction, isNumberArray, makeStateUpdater, memo, noop, tableMemo };
90
+ export { $internalMemoFnMeta, API, APIObject, MemoFnMeta, PrototypeAPI, PrototypeAPIObject, assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, cloneState, flattenBy, functionalUpdate, getFunctionNameInfo, getMemoFnMeta, isFunction, isNumberArray, makeStateUpdater, memo, noop, tableMemo };
90
91
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -2,6 +2,17 @@
2
2
  function functionalUpdate(updater, input) {
3
3
  return typeof updater === "function" ? updater(input) : updater;
4
4
  }
5
+ function cloneState(value) {
6
+ if (Array.isArray(value)) return value.map(cloneState);
7
+ if (value && typeof value === "object") {
8
+ const proto = Object.getPrototypeOf(value);
9
+ if (proto !== Object.prototype && proto !== null) return value;
10
+ const copy = {};
11
+ for (const key of Object.keys(value)) copy[key] = cloneState(value[key]);
12
+ return copy;
13
+ }
14
+ return value;
15
+ }
5
16
  function noop() {}
6
17
  function makeStateUpdater(key, instance) {
7
18
  return (updater) => {
@@ -188,5 +199,5 @@ function callMemoOrStaticFn(obj, fnKey, staticFn, ...args) {
188
199
  }
189
200
 
190
201
  //#endregion
191
- export { $internalMemoFnMeta, assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, flattenBy, functionalUpdate, getFunctionNameInfo, getMemoFnMeta, isFunction, isNumberArray, makeStateUpdater, memo, noop, tableMemo };
202
+ export { $internalMemoFnMeta, assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, cloneState, flattenBy, functionalUpdate, getFunctionNameInfo, getMemoFnMeta, isFunction, isNumberArray, makeStateUpdater, memo, noop, tableMemo };
192
203
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { Table, Table_Internal } from './types/Table'\nimport type { NoInfer, RowData, Updater } from './types/type-utils'\nimport type { TableFeatures } from './types/TableFeatures'\nimport type { TableState, TableState_All } from './types/TableState'\n\nexport function functionalUpdate<T>(updater: Updater<T>, input: T): T {\n return typeof updater === 'function'\n ? (updater as (i: T) => T)(input)\n : updater\n}\n\nexport function noop() {}\n\nexport function makeStateUpdater<\n TFeatures extends TableFeatures,\n K extends (string & {}) | keyof TableState_All | keyof TableState<TFeatures>,\n>(key: K, instance: Table<TFeatures, any>) {\n return (updater: Updater<TableState<any>[K & keyof TableState<any>]>) => {\n const externalAtom = (instance.options as any).atoms?.[key]\n const targetAtom = externalAtom ?? (instance.baseAtoms as any)[key]\n targetAtom.set((old: any) => functionalUpdate(updater, old))\n }\n}\n\ntype AnyFunction = (...args: any) => any\n\nexport function isFunction<T extends AnyFunction>(d: any): d is T {\n return d instanceof Function\n}\n\nexport function isNumberArray(d: any): d is Array<number> {\n return Array.isArray(d) && d.every((val) => typeof val === 'number')\n}\n\nexport function flattenBy<TNode>(\n arr: Array<TNode>,\n getChildren: (item: TNode) => Array<TNode>,\n) {\n const flat: Array<TNode> = []\n\n const recurse = (subArr: Array<TNode>) => {\n subArr.forEach((item) => {\n flat.push(item)\n const children = getChildren(item)\n if (children.length) {\n recurse(children)\n }\n })\n }\n\n recurse(arr)\n\n return flat\n}\n\nexport const $internalMemoFnMeta = Symbol('memoFnMeta')\nexport type MemoFnMeta = { originalArgsLength?: number }\n\n/**\n * @internal\n */\nfunction setMemoFnMeta(fn: Function, meta: MemoFnMeta) {\n Object.defineProperty(fn, $internalMemoFnMeta, { value: meta })\n}\n\n/**\n * @internal\n */\nexport function getMemoFnMeta(fn: any): MemoFnMeta | null {\n return (typeof fn === 'function' && fn[$internalMemoFnMeta]) ?? null\n}\n\ninterface MemoOptions<TDeps extends ReadonlyArray<any>, TDepArgs, TResult> {\n fn: (...args: NoInfer<TDeps>) => TResult\n memoDeps?: (depArgs?: TDepArgs) => [...TDeps] | undefined\n onAfterCompare?: (depsChanged: boolean) => void\n onAfterUpdate?: (result: TResult) => void\n onBeforeCompare?: () => void\n onBeforeUpdate?: () => void\n}\n\nexport const memo = <TDeps extends ReadonlyArray<any>, TDepArgs, TResult>({\n fn,\n memoDeps,\n onAfterCompare,\n onAfterUpdate,\n onBeforeCompare,\n onBeforeUpdate,\n}: MemoOptions<TDeps, TDepArgs, TResult>): ((\n depArgs?: TDepArgs,\n) => TResult) => {\n let deps: Array<any> | undefined = []\n let result: TResult | undefined\n\n const memoizedFn = (depArgs?: TDepArgs): TResult => {\n onBeforeCompare?.()\n const newDeps = memoDeps?.(depArgs)\n const depsChanged =\n !newDeps ||\n newDeps.length !== deps?.length ||\n newDeps.some((dep: any, index: number) => deps?.[index] !== dep)\n onAfterCompare?.(depsChanged)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n onBeforeUpdate?.()\n result = fn(...(newDeps ?? ([] as any)))\n onAfterUpdate?.(result)\n\n return result\n }\n\n setMemoFnMeta(memoizedFn, { originalArgsLength: fn.length })\n\n return memoizedFn\n}\n\ninterface TableMemoOptions<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n> extends MemoOptions<TDeps, TDepArgs, TResult> {\n feature?: keyof TFeatures & string\n fnName: string\n objectId?: string\n onAfterUpdate?: () => void\n table: Table_Internal<TFeatures, any>\n}\n\nconst pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n}\n\nexport function tableMemo<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n>({\n feature,\n fnName,\n objectId,\n onAfterUpdate,\n table,\n ...memoOptions\n}: TableMemoOptions<TFeatures, TDeps, TDepArgs, TResult>) {\n let beforeCompareTime: number\n let afterCompareTime: number\n let startCalcTime: number\n let endCalcTime: number\n let runCount = 0\n let debug: boolean | undefined\n let debugCache: boolean | undefined\n\n if (process.env.NODE_ENV === 'development') {\n const { debugCache: _debugCache, debugAll } = table.options\n debugCache = _debugCache\n const { parentName } = getFunctionNameInfo(fnName, '.')\n\n const debugByParent =\n // @ts-expect-error\n table.options[\n `debug${(parentName != 'table' ? parentName + 's' : parentName).replace(\n parentName,\n parentName.charAt(0).toUpperCase() + parentName.slice(1),\n )}`\n ]\n const debugByFeature = feature\n ? // @ts-expect-error\n table.options[\n `debug${feature.charAt(0).toUpperCase() + feature.slice(1)}`\n ]\n : false\n\n debug = debugAll || debugByParent || debugByFeature\n }\n\n function logTime(time: number, depsChanged: boolean) {\n const runType =\n runCount === 0\n ? '(1st run)'\n : depsChanged\n ? '(rerun #' + runCount + ')'\n : '(cache)'\n runCount++\n\n console.groupCollapsed(\n `%c⏱ ${pad(`${time.toFixed(1)} ms`, 12)} %c${runType}%c ${fnName}%c ${objectId ? `(${fnName.split('.')[0]}Id: ${objectId})` : ''}`,\n `font-size: .6rem; font-weight: bold; ${\n depsChanged\n ? `color: hsl(\n ${Math.max(0, Math.min(120 - Math.log10(time) * 60, 120))}deg 100% 31%);`\n : ''\n } `,\n `color: ${runCount < 2 ? '#FF00FF' : '#FF1493'}`,\n 'color: #666',\n 'color: #87CEEB',\n )\n console.info({\n feature,\n state: table.store.state,\n deps: memoOptions.memoDeps?.toString(),\n })\n console.trace()\n console.groupEnd()\n }\n\n const debugOptions =\n process.env.NODE_ENV === 'development'\n ? {\n onBeforeCompare: () => {\n if (debugCache) {\n beforeCompareTime = performance.now()\n }\n },\n onAfterCompare: (depsChanged: boolean) => {\n if (debugCache) {\n afterCompareTime = performance.now()\n const compareTime =\n Math.round((afterCompareTime - beforeCompareTime) * 100) / 100\n if (!depsChanged) {\n logTime(compareTime, depsChanged)\n }\n }\n },\n onBeforeUpdate: () => {\n if (debug) {\n startCalcTime = performance.now()\n }\n },\n onAfterUpdate: () => {\n if (debug) {\n endCalcTime = performance.now()\n const executionTime =\n Math.round((endCalcTime - startCalcTime) * 100) / 100\n logTime(executionTime, true)\n }\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n : {\n onAfterUpdate: () => {\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n\n return memo({\n ...memoOptions,\n ...debugOptions,\n })\n}\n\nexport interface API<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (...args: any) => any\n memoDeps?: (depArgs?: any) => [...any] | undefined\n}\n\nexport type APIObject<TDeps extends ReadonlyArray<any>, TDepArgs> = Record<\n string,\n API<TDeps, TDepArgs>\n>\n\n/**\n * Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`.\n */\nexport function getFunctionNameInfo(\n staticFnName: string,\n splitBy: '_' | '.' = '_',\n) {\n const [parentName, fnKey] = staticFnName.split(splitBy)\n const fnName = `${parentName}.${fnKey}`\n return { fnKey, fnName, parentName } as {\n fnKey: string\n fnName: string\n parentName: string\n }\n}\n\n/**\n * Assigns Table API methods directly to the table instance.\n * Unlike row/cell/column/header, the table is a singleton so methods are assigned directly.\n */\nexport function assignTableAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n table: Table_Internal<TFeatures, TData>,\n apis: APIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n ;(table as Record<string, any>)[fnKey] = memoDeps\n ? tableMemo({\n memoDeps,\n fn,\n fnName,\n table,\n feature,\n })\n : fn\n }\n}\n\nexport interface PrototypeAPI<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (self: any, ...args: any) => any\n memoDeps?: (self: any, depArgs?: any) => [...any] | undefined\n}\n\nexport type PrototypeAPIObject<\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n> = Record<string, PrototypeAPI<TDeps, TDepArgs>>\n\n/**\n * Assigns API methods to a prototype object for memory-efficient method sharing.\n * All instances created with this prototype will share the same method references.\n *\n * For memoized methods, the memo state is lazily created and stored on each instance.\n * This provides the best of both worlds: shared method code + per-instance caching.\n */\nexport function assignPrototypeAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n prototype: Record<string, any>,\n table: Table_Internal<TFeatures, TData>,\n apis: PrototypeAPIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n if (memoDeps) {\n // For memoized methods, create a function that lazily initializes\n // the memo on first access and stores it on the instance\n const memoKey = `_memo_${fnKey}`\n\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n // Lazily create memo on first access for this instance\n if (!this[memoKey]) {\n const self = this\n this[memoKey] = tableMemo({\n memoDeps: () => memoDeps(self),\n fn: (...deps) => fn(self, ...deps),\n fnName,\n objectId: self.id,\n table,\n feature,\n })\n }\n return this[memoKey](...args)\n }\n } else {\n // Non-memoized methods just call the static function with `this`\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n return fn(this, ...args)\n }\n }\n\n setMemoFnMeta(prototype[fnKey], { originalArgsLength: fn.length })\n }\n}\n\n/**\n * Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in.\n */\nexport function callMemoOrStaticFn<\n TObject extends Record<string, any>,\n TStaticFn extends AnyFunction,\n>(\n obj: TObject,\n fnKey: string,\n staticFn: TStaticFn,\n ...args: Parameters<TStaticFn> extends [any, ...infer Rest] ? Rest : never\n): ReturnType<TStaticFn> {\n return (\n (obj[fnKey] as Function | undefined)?.(...args) ?? staticFn(obj, ...args)\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { Table, Table_Internal } from './types/Table'\nimport type { NoInfer, RowData, Updater } from './types/type-utils'\nimport type { TableFeatures } from './types/TableFeatures'\nimport type { TableState, TableState_All } from './types/TableState'\n\nexport function functionalUpdate<T>(updater: Updater<T>, input: T): T {\n return typeof updater === 'function'\n ? (updater as (i: T) => T)(input)\n : updater\n}\n\nexport function cloneState<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map(cloneState) as T\n }\n\n if (value && typeof value === 'object') {\n const proto = Object.getPrototypeOf(value)\n\n if (proto !== Object.prototype && proto !== null) {\n return value\n }\n\n const copy: Record<string, unknown> = {}\n\n for (const key of Object.keys(value)) {\n copy[key] = cloneState((value as Record<string, unknown>)[key])\n }\n\n return copy as T\n }\n\n return value\n}\n\nexport function noop() {}\n\nexport function makeStateUpdater<\n TFeatures extends TableFeatures,\n K extends (string & {}) | keyof TableState_All | keyof TableState<TFeatures>,\n>(key: K, instance: Table<TFeatures, any>) {\n return (updater: Updater<TableState<any>[K & keyof TableState<any>]>) => {\n const externalAtom = (instance.options as any).atoms?.[key]\n const targetAtom = externalAtom ?? (instance.baseAtoms as any)[key]\n targetAtom.set((old: any) => functionalUpdate(updater, old))\n }\n}\n\ntype AnyFunction = (...args: any) => any\n\nexport function isFunction<T extends AnyFunction>(d: any): d is T {\n return d instanceof Function\n}\n\nexport function isNumberArray(d: any): d is Array<number> {\n return Array.isArray(d) && d.every((val) => typeof val === 'number')\n}\n\nexport function flattenBy<TNode>(\n arr: Array<TNode>,\n getChildren: (item: TNode) => Array<TNode>,\n) {\n const flat: Array<TNode> = []\n\n const recurse = (subArr: Array<TNode>) => {\n subArr.forEach((item) => {\n flat.push(item)\n const children = getChildren(item)\n if (children.length) {\n recurse(children)\n }\n })\n }\n\n recurse(arr)\n\n return flat\n}\n\nexport const $internalMemoFnMeta = Symbol('memoFnMeta')\nexport type MemoFnMeta = { originalArgsLength?: number }\n\n/**\n * @internal\n */\nfunction setMemoFnMeta(fn: Function, meta: MemoFnMeta) {\n Object.defineProperty(fn, $internalMemoFnMeta, { value: meta })\n}\n\n/**\n * @internal\n */\nexport function getMemoFnMeta(fn: any): MemoFnMeta | null {\n return (typeof fn === 'function' && fn[$internalMemoFnMeta]) ?? null\n}\n\ninterface MemoOptions<TDeps extends ReadonlyArray<any>, TDepArgs, TResult> {\n fn: (...args: NoInfer<TDeps>) => TResult\n memoDeps?: (depArgs?: TDepArgs) => [...TDeps] | undefined\n onAfterCompare?: (depsChanged: boolean) => void\n onAfterUpdate?: (result: TResult) => void\n onBeforeCompare?: () => void\n onBeforeUpdate?: () => void\n}\n\nexport const memo = <TDeps extends ReadonlyArray<any>, TDepArgs, TResult>({\n fn,\n memoDeps,\n onAfterCompare,\n onAfterUpdate,\n onBeforeCompare,\n onBeforeUpdate,\n}: MemoOptions<TDeps, TDepArgs, TResult>): ((\n depArgs?: TDepArgs,\n) => TResult) => {\n let deps: Array<any> | undefined = []\n let result: TResult | undefined\n\n const memoizedFn = (depArgs?: TDepArgs): TResult => {\n onBeforeCompare?.()\n const newDeps = memoDeps?.(depArgs)\n const depsChanged =\n !newDeps ||\n newDeps.length !== deps?.length ||\n newDeps.some((dep: any, index: number) => deps?.[index] !== dep)\n onAfterCompare?.(depsChanged)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n onBeforeUpdate?.()\n result = fn(...(newDeps ?? ([] as any)))\n onAfterUpdate?.(result)\n\n return result\n }\n\n setMemoFnMeta(memoizedFn, { originalArgsLength: fn.length })\n\n return memoizedFn\n}\n\ninterface TableMemoOptions<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n> extends MemoOptions<TDeps, TDepArgs, TResult> {\n feature?: keyof TFeatures & string\n fnName: string\n objectId?: string\n onAfterUpdate?: () => void\n table: Table_Internal<TFeatures, any>\n}\n\nconst pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n}\n\nexport function tableMemo<\n TFeatures extends TableFeatures,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n TResult,\n>({\n feature,\n fnName,\n objectId,\n onAfterUpdate,\n table,\n ...memoOptions\n}: TableMemoOptions<TFeatures, TDeps, TDepArgs, TResult>) {\n let beforeCompareTime: number\n let afterCompareTime: number\n let startCalcTime: number\n let endCalcTime: number\n let runCount = 0\n let debug: boolean | undefined\n let debugCache: boolean | undefined\n\n if (process.env.NODE_ENV === 'development') {\n const { debugCache: _debugCache, debugAll } = table.options\n debugCache = _debugCache\n const { parentName } = getFunctionNameInfo(fnName, '.')\n\n const debugByParent =\n // @ts-expect-error\n table.options[\n `debug${(parentName != 'table' ? parentName + 's' : parentName).replace(\n parentName,\n parentName.charAt(0).toUpperCase() + parentName.slice(1),\n )}`\n ]\n const debugByFeature = feature\n ? // @ts-expect-error\n table.options[\n `debug${feature.charAt(0).toUpperCase() + feature.slice(1)}`\n ]\n : false\n\n debug = debugAll || debugByParent || debugByFeature\n }\n\n function logTime(time: number, depsChanged: boolean) {\n const runType =\n runCount === 0\n ? '(1st run)'\n : depsChanged\n ? '(rerun #' + runCount + ')'\n : '(cache)'\n runCount++\n\n console.groupCollapsed(\n `%c⏱ ${pad(`${time.toFixed(1)} ms`, 12)} %c${runType}%c ${fnName}%c ${objectId ? `(${fnName.split('.')[0]}Id: ${objectId})` : ''}`,\n `font-size: .6rem; font-weight: bold; ${\n depsChanged\n ? `color: hsl(\n ${Math.max(0, Math.min(120 - Math.log10(time) * 60, 120))}deg 100% 31%);`\n : ''\n } `,\n `color: ${runCount < 2 ? '#FF00FF' : '#FF1493'}`,\n 'color: #666',\n 'color: #87CEEB',\n )\n console.info({\n feature,\n state: table.store.state,\n deps: memoOptions.memoDeps?.toString(),\n })\n console.trace()\n console.groupEnd()\n }\n\n const debugOptions =\n process.env.NODE_ENV === 'development'\n ? {\n onBeforeCompare: () => {\n if (debugCache) {\n beforeCompareTime = performance.now()\n }\n },\n onAfterCompare: (depsChanged: boolean) => {\n if (debugCache) {\n afterCompareTime = performance.now()\n const compareTime =\n Math.round((afterCompareTime - beforeCompareTime) * 100) / 100\n if (!depsChanged) {\n logTime(compareTime, depsChanged)\n }\n }\n },\n onBeforeUpdate: () => {\n if (debug) {\n startCalcTime = performance.now()\n }\n },\n onAfterUpdate: () => {\n if (debug) {\n endCalcTime = performance.now()\n const executionTime =\n Math.round((endCalcTime - startCalcTime) * 100) / 100\n logTime(executionTime, true)\n }\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n : {\n onAfterUpdate: () => {\n queueMicrotask(() => onAfterUpdate?.())\n },\n }\n\n return memo({\n ...memoOptions,\n ...debugOptions,\n })\n}\n\nexport interface API<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (...args: any) => any\n memoDeps?: (depArgs?: any) => [...any] | undefined\n}\n\nexport type APIObject<TDeps extends ReadonlyArray<any>, TDepArgs> = Record<\n string,\n API<TDeps, TDepArgs>\n>\n\n/**\n * Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`.\n */\nexport function getFunctionNameInfo(\n staticFnName: string,\n splitBy: '_' | '.' = '_',\n) {\n const [parentName, fnKey] = staticFnName.split(splitBy)\n const fnName = `${parentName}.${fnKey}`\n return { fnKey, fnName, parentName } as {\n fnKey: string\n fnName: string\n parentName: string\n }\n}\n\n/**\n * Assigns Table API methods directly to the table instance.\n * Unlike row/cell/column/header, the table is a singleton so methods are assigned directly.\n */\nexport function assignTableAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n table: Table_Internal<TFeatures, TData>,\n apis: APIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n ;(table as Record<string, any>)[fnKey] = memoDeps\n ? tableMemo({\n memoDeps,\n fn,\n fnName,\n table,\n feature,\n })\n : fn\n }\n}\n\nexport interface PrototypeAPI<TDeps extends ReadonlyArray<any>, TDepArgs> {\n fn: (self: any, ...args: any) => any\n memoDeps?: (self: any, depArgs?: any) => [...any] | undefined\n}\n\nexport type PrototypeAPIObject<\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n> = Record<string, PrototypeAPI<TDeps, TDepArgs>>\n\n/**\n * Assigns API methods to a prototype object for memory-efficient method sharing.\n * All instances created with this prototype will share the same method references.\n *\n * For memoized methods, the memo state is lazily created and stored on each instance.\n * This provides the best of both worlds: shared method code + per-instance caching.\n */\nexport function assignPrototypeAPIs<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TDeps extends ReadonlyArray<any>,\n TDepArgs,\n>(\n feature: keyof TFeatures & string,\n prototype: Record<string, any>,\n table: Table_Internal<TFeatures, TData>,\n apis: PrototypeAPIObject<TDeps, NoInfer<TDepArgs>>,\n): void {\n for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) {\n const { fnKey, fnName } = getFunctionNameInfo(staticFnName)\n\n if (memoDeps) {\n // For memoized methods, create a function that lazily initializes\n // the memo on first access and stores it on the instance\n const memoKey = `_memo_${fnKey}`\n\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n // Lazily create memo on first access for this instance\n if (!this[memoKey]) {\n const self = this\n this[memoKey] = tableMemo({\n memoDeps: () => memoDeps(self),\n fn: (...deps) => fn(self, ...deps),\n fnName,\n objectId: self.id,\n table,\n feature,\n })\n }\n return this[memoKey](...args)\n }\n } else {\n // Non-memoized methods just call the static function with `this`\n prototype[fnKey] = function (this: any, ...args: Array<any>) {\n return fn(this, ...args)\n }\n }\n\n setMemoFnMeta(prototype[fnKey], { originalArgsLength: fn.length })\n }\n}\n\n/**\n * Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in.\n */\nexport function callMemoOrStaticFn<\n TObject extends Record<string, any>,\n TStaticFn extends AnyFunction,\n>(\n obj: TObject,\n fnKey: string,\n staticFn: TStaticFn,\n ...args: Parameters<TStaticFn> extends [any, ...infer Rest] ? Rest : never\n): ReturnType<TStaticFn> {\n return (\n (obj[fnKey] as Function | undefined)?.(...args) ?? staticFn(obj, ...args)\n )\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/table-core",
3
- "version": "9.0.0-alpha.34",
3
+ "version": "9.0.0-alpha.37",
4
4
  "description": "Headless UI for building powerful tables & datagrids for TS/JS.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -34,6 +34,10 @@
34
34
  "import": "./dist/index.js",
35
35
  "require": "./dist/index.cjs"
36
36
  },
37
+ "./flex-render": {
38
+ "import": "./dist/flex-render.js",
39
+ "require": "./dist/flex-render.cjs"
40
+ },
37
41
  "./static-functions": {
38
42
  "import": "./dist/static-functions.js",
39
43
  "require": "./dist/static-functions.cjs"
@@ -100,7 +100,7 @@ export function table_getAllColumns<
100
100
  })
101
101
  }
102
102
 
103
- return recurseColumns(table.options.columns as any)
103
+ return recurseColumns(table.options.columns)
104
104
  }
105
105
 
106
106
  export function table_getAllFlatColumns<
@@ -12,7 +12,7 @@ export function createCoreRowModel<
12
12
  TData extends RowData,
13
13
  >(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {
14
14
  return (_table) => {
15
- const table = _table as Table_Internal<TFeatures, TData>
15
+ const table: Table_Internal<TFeatures, TData> = _table
16
16
  return tableMemo({
17
17
  feature: 'coreRowModelsFeature',
18
18
  table,
@@ -52,7 +52,7 @@ export const constructRow = <
52
52
 
53
53
  // Initialize instance-specific data (e.g., caches) for features that need it
54
54
  for (const feature of Object.values(table._features)) {
55
- feature.initRowInstanceData?.(row as Row<TFeatures, TData>)
55
+ feature.initRowInstanceData?.(row)
56
56
  }
57
57
 
58
58
  return row as Row<TFeatures, TData>
@@ -1,5 +1,6 @@
1
1
  import { createAtom, createStore } from '@tanstack/store'
2
2
  import { coreFeatures } from '../coreFeatures'
3
+ import { cloneState } from '../../utils'
3
4
  import type { RowData } from '../../types/type-utils'
4
5
  import type { TableFeature, TableFeatures } from '../../types/TableFeatures'
5
6
  import type { Table, Table_Internal } from '../../types/Table'
@@ -11,11 +12,9 @@ export function getInitialTableState<TFeatures extends TableFeatures>(
11
12
  initialState: Partial<TableState<TFeatures>> | undefined = {},
12
13
  ): TableState<TFeatures> {
13
14
  Object.values(features).forEach((feature) => {
14
- initialState =
15
- feature.getInitialState?.(initialState as TableState<TFeatures>) ??
16
- initialState
15
+ initialState = feature.getInitialState?.(initialState) ?? initialState
17
16
  })
18
- return structuredClone(initialState) as TableState<TFeatures>
17
+ return cloneState(initialState) as TableState<TFeatures>
19
18
  }
20
19
 
21
20
  export function constructTable<
@@ -82,7 +81,7 @@ export function constructTable<
82
81
  snapshot[key] = table.atoms[key].get()
83
82
  }
84
83
  return snapshot
85
- }) as typeof table.store
84
+ })
86
85
 
87
86
  if (
88
87
  process.env.NODE_ENV === 'development' &&
@@ -1,5 +1,5 @@
1
1
  import { batch } from '@tanstack/store'
2
- import { functionalUpdate } from '../../utils'
2
+ import { cloneState, functionalUpdate } from '../../utils'
3
3
  import type { RowData, Updater } from '../../types/type-utils'
4
4
  import type { TableFeatures } from '../../types/TableFeatures'
5
5
  import type { Table_Internal } from '../../types/Table'
@@ -9,7 +9,7 @@ export function table_reset<
9
9
  TFeatures extends TableFeatures,
10
10
  TData extends RowData,
11
11
  >(table: Table_Internal<TFeatures, TData>): void {
12
- const snap = structuredClone(table.initialState)
12
+ const snap = cloneState(table.initialState)
13
13
  batch(() => {
14
14
  for (const key of Object.keys(snap) as Array<keyof typeof snap>) {
15
15
  ;(table.baseAtoms as any)[key].set(snap[key] as any)
@@ -13,7 +13,7 @@ export function createFacetedMinMaxValues<
13
13
  columnId: string,
14
14
  ) => () => undefined | [number, number] {
15
15
  return (_table, columnId) => {
16
- const table = _table as Table_Internal<TFeatures, TData>
16
+ const table: Table_Internal<TFeatures, TData> = _table
17
17
  return tableMemo({
18
18
  feature: 'columnFacetingFeature',
19
19
  fn: (flatRows) => _createFacetedMinMaxValues(columnId, flatRows),
@@ -18,7 +18,7 @@ export function createFacetedRowModel<
18
18
  columnId: string,
19
19
  ) => () => RowModel<TFeatures, TData> {
20
20
  return (_table, columnId) => {
21
- const table = _table as Table_Internal<TFeatures, TData>
21
+ const table: Table_Internal<TFeatures, TData> = _table
22
22
  return tableMemo({
23
23
  feature: 'columnFacetingFeature',
24
24
  table,
@@ -13,7 +13,7 @@ export function createFacetedUniqueValues<
13
13
  columnId: string,
14
14
  ) => () => Map<any, number> {
15
15
  return (_table, columnId) => {
16
- const table = _table as Table_Internal<TFeatures, TData>
16
+ const table: Table_Internal<TFeatures, TData> = _table
17
17
  return tableMemo({
18
18
  feature: 'columnFacetingFeature',
19
19
  table,
@@ -1,4 +1,4 @@
1
- import { functionalUpdate, isFunction } from '../../utils'
1
+ import { cloneState, functionalUpdate, isFunction } from '../../utils'
2
2
  import type { CellData, RowData, Updater } from '../../types/type-utils'
3
3
  import type { TableFeatures } from '../../types/TableFeatures'
4
4
  import type { Table_Internal } from '../../types/Table'
@@ -9,7 +9,7 @@ import type {
9
9
  } from './columnFilteringFeature.types'
10
10
 
11
11
  export function getDefaultColumnFiltersState(): ColumnFiltersState {
12
- return structuredClone([])
12
+ return []
13
13
  }
14
14
 
15
15
  export function column_getAutoFilterFn<
@@ -17,9 +17,8 @@ export function column_getAutoFilterFn<
17
17
  TData extends RowData,
18
18
  TValue extends CellData = CellData,
19
19
  >(column: Column_Internal<TFeatures, TData, TValue>) {
20
- const filterFns = column.table._rowModelFns.filterFns as
21
- | Record<string, FilterFn<TFeatures, TData>>
22
- | undefined
20
+ const filterFns: Record<string, FilterFn<TFeatures, TData>> | undefined =
21
+ column.table._rowModelFns.filterFns
23
22
 
24
23
  const firstRow = column.table.getCoreRowModel().flatRows[0]
25
24
 
@@ -56,9 +55,8 @@ export function column_getFilterFn<
56
55
  column: Column_Internal<TFeatures, TData, TValue>,
57
56
  ): FilterFn<TFeatures, TData> | undefined {
58
57
  let filterFn = null
59
- const filterFns = column.table._rowModelFns.filterFns as
60
- | Record<string, FilterFn<TFeatures, TData>>
61
- | undefined
58
+ const filterFns: Record<string, FilterFn<TFeatures, TData>> | undefined =
59
+ column.table._rowModelFns.filterFns
62
60
  filterFn = isFunction(column.columnDef.filterFn)
63
61
  ? column.columnDef.filterFn
64
62
  : column.columnDef.filterFn === 'auto'
@@ -188,7 +186,7 @@ export function table_resetColumnFilters<
188
186
  >(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {
189
187
  table_setColumnFilters(
190
188
  table,
191
- defaultState ? [] : (table.initialState.columnFilters ?? []),
189
+ defaultState ? [] : cloneState(table.initialState.columnFilters ?? []),
192
190
  )
193
191
  }
194
192
 
@@ -203,10 +201,7 @@ export function shouldAutoRemoveFilter<
203
201
  ) {
204
202
  return (
205
203
  (filterFn && filterFn.autoRemove
206
- ? filterFn.autoRemove(
207
- value,
208
- column as Column_Internal<TFeatures, TData, unknown>,
209
- )
204
+ ? filterFn.autoRemove(value, column)
210
205
  : false) ||
211
206
  typeof value === 'undefined' ||
212
207
  (typeof value === 'string' && !value)
@@ -26,7 +26,7 @@ export function createFilteredRowModel<
26
26
  filterFns: Record<keyof FilterFns, FilterFn<TFeatures, TData>>,
27
27
  ): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {
28
28
  return (_table) => {
29
- const table = _table as Table_Internal<TFeatures, TData>
29
+ const table: Table_Internal<TFeatures, TData> = _table
30
30
  if (!table._rowModelFns.filterFns) table._rowModelFns.filterFns = filterFns
31
31
  return tableMemo({
32
32
  feature: 'columnFilteringFeature',
@@ -1,4 +1,4 @@
1
- import { isFunction } from '../../utils'
1
+ import { cloneState, isFunction } from '../../utils'
2
2
  import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'
3
3
  import type { Column_Internal } from '../../types/Column'
4
4
  import type { CellData, RowData, Updater } from '../../types/type-utils'
@@ -13,7 +13,7 @@ import type {
13
13
  } from './columnGroupingFeature.types'
14
14
 
15
15
  export function getDefaultGroupingState(): GroupingState {
16
- return structuredClone([])
16
+ return []
17
17
  }
18
18
 
19
19
  export function column_toggleGrouping<
@@ -77,9 +77,9 @@ export function column_getAutoAggregationFn<
77
77
  TData extends RowData,
78
78
  TValue extends CellData = CellData,
79
79
  >(column: Column_Internal<TFeatures, TData, TValue>) {
80
- const aggregationFns = column.table._rowModelFns.aggregationFns as
80
+ const aggregationFns:
81
81
  | Record<string, AggregationFn<TFeatures, TData>>
82
- | undefined
82
+ | undefined = column.table._rowModelFns.aggregationFns
83
83
 
84
84
  const firstRow = column.table.getCoreRowModel().flatRows[0]
85
85
 
@@ -99,9 +99,9 @@ export function column_getAggregationFn<
99
99
  TData extends RowData,
100
100
  TValue extends CellData = CellData,
101
101
  >(column: Column_Internal<TFeatures, TData, TValue>) {
102
- const aggregationFns = column.table._rowModelFns.aggregationFns as
102
+ const aggregationFns:
103
103
  | Record<string, AggregationFn<TFeatures, TData>>
104
- | undefined
104
+ | undefined = column.table._rowModelFns.aggregationFns
105
105
 
106
106
  return isFunction(column.columnDef.aggregationFn)
107
107
  ? column.columnDef.aggregationFn
@@ -123,7 +123,7 @@ export function table_resetGrouping<
123
123
  >(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {
124
124
  table_setGrouping(
125
125
  table,
126
- defaultState ? [] : (table.initialState.grouping ?? []),
126
+ defaultState ? [] : cloneState(table.initialState.grouping ?? []),
127
127
  )
128
128
  }
129
129
 
@@ -26,7 +26,7 @@ export function createGroupedRowModel<
26
26
  aggregationFns: Record<keyof AggregationFns, AggregationFn<TFeatures, TData>>,
27
27
  ): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {
28
28
  return (_table) => {
29
- const table = _table as Table_Internal<TFeatures, TData>
29
+ const table: Table_Internal<TFeatures, TData> = _table
30
30
  if (!table._rowModelFns.aggregationFns)
31
31
  table._rowModelFns.aggregationFns = aggregationFns
32
32
  return tableMemo({
@@ -1,4 +1,5 @@
1
1
  import { table_getPinnedVisibleLeafColumns } from '../column-pinning/columnPinningFeature.utils'
2
+ import { cloneState } from '../../utils'
2
3
  import type { GroupingState } from '../column-grouping/columnGroupingFeature.types'
3
4
  import type { CellData, RowData, Updater } from '../../types/type-utils'
4
5
  import type { TableFeatures } from '../../types/TableFeatures'
@@ -8,7 +9,7 @@ import type { ColumnPinningPosition } from '../column-pinning/columnPinningFeatu
8
9
  import type { ColumnOrderState } from './columnOrderingFeature.types'
9
10
 
10
11
  export function getDefaultColumnOrderState(): ColumnOrderState {
11
- return structuredClone([])
12
+ return []
12
13
  }
13
14
 
14
15
  export function column_getIndex<
@@ -60,7 +61,7 @@ export function table_resetColumnOrder<
60
61
  >(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {
61
62
  table_setColumnOrder(
62
63
  table,
63
- defaultState ? [] : (table.initialState.columnOrder ?? []),
64
+ defaultState ? [] : cloneState(table.initialState.columnOrder ?? []),
64
65
  )
65
66
  }
66
67
 
@@ -4,7 +4,7 @@ import {
4
4
  table_getVisibleLeafColumns,
5
5
  } from '../column-visibility/columnVisibilityFeature.utils'
6
6
  import { buildHeaderGroups } from '../../core/headers/buildHeaderGroups'
7
- import { callMemoOrStaticFn } from '../../utils'
7
+ import { callMemoOrStaticFn, cloneState } from '../../utils'
8
8
  import type { HeaderGroup } from '../../types/HeaderGroup'
9
9
  import type { Cell } from '../../types/Cell'
10
10
  import type { Row } from '../../types/Row'
@@ -20,10 +20,10 @@ import type {
20
20
  // State
21
21
 
22
22
  export function getDefaultColumnPinningState(): ColumnPinningState {
23
- return structuredClone({
23
+ return {
24
24
  left: [],
25
25
  right: [],
26
- })
26
+ }
27
27
  }
28
28
 
29
29
  // Column APIs
@@ -192,7 +192,9 @@ export function table_resetColumnPinning<
192
192
  table,
193
193
  defaultState
194
194
  ? getDefaultColumnPinningState()
195
- : (table.initialState.columnPinning ?? getDefaultColumnPinningState()),
195
+ : cloneState(
196
+ table.initialState.columnPinning ?? getDefaultColumnPinningState(),
197
+ ),
196
198
  )
197
199
  }
198
200
 
@@ -4,6 +4,7 @@ import {
4
4
  table_setColumnSizing,
5
5
  } from '../column-sizing/columnSizingFeature.utils'
6
6
  import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'
7
+ import { cloneState } from '../../utils'
7
8
  import type { CellData, RowData, Updater } from '../../types/type-utils'
8
9
  import type { TableFeatures } from '../../types/TableFeatures'
9
10
  import type { Table_Internal } from '../../types/Table'
@@ -13,14 +14,14 @@ import type { ColumnSizingState } from '../column-sizing/columnSizingFeature.typ
13
14
  import type { columnResizingState } from './columnResizingFeature.types'
14
15
 
15
16
  export function getDefaultColumnResizingState(): columnResizingState {
16
- return structuredClone({
17
+ return {
17
18
  startOffset: null,
18
19
  startSize: null,
19
20
  deltaOffset: null,
20
21
  deltaPercentage: null,
21
22
  isResizingColumn: false,
22
23
  columnSizingStart: [],
23
- })
24
+ }
24
25
  }
25
26
 
26
27
  export function column_getCanResize<
@@ -239,7 +240,9 @@ export function table_resetHeaderSizeInfo<
239
240
  table,
240
241
  defaultState
241
242
  ? getDefaultColumnResizingState()
242
- : (table.initialState.columnResizing ?? getDefaultColumnResizingState()),
243
+ : cloneState(
244
+ table.initialState.columnResizing ?? getDefaultColumnResizingState(),
245
+ ),
243
246
  )
244
247
  }
245
248
 
@@ -5,7 +5,7 @@ import {
5
5
  table_getRightHeaderGroups,
6
6
  } from '../column-pinning/columnPinningFeature.utils'
7
7
  import { column_getIndex } from '../column-ordering/columnOrderingFeature.utils'
8
- import { callMemoOrStaticFn } from '../../utils'
8
+ import { callMemoOrStaticFn, cloneState } from '../../utils'
9
9
  import type { ColumnPinningPosition } from '../column-pinning/columnPinningFeature.types'
10
10
  import type { CellData, RowData, Updater } from '../../types/type-utils'
11
11
  import type { TableFeatures } from '../../types/TableFeatures'
@@ -15,15 +15,15 @@ import type { Column_Internal } from '../../types/Column'
15
15
  import type { ColumnSizingState } from './columnSizingFeature.types'
16
16
 
17
17
  export function getDefaultColumnSizingState(): ColumnSizingState {
18
- return structuredClone({})
18
+ return {}
19
19
  }
20
20
 
21
21
  export function getDefaultColumnSizingColumnDef() {
22
- return structuredClone({
22
+ return {
23
23
  size: 150,
24
24
  minSize: 20,
25
25
  maxSize: Number.MAX_SAFE_INTEGER,
26
- })
26
+ }
27
27
  }
28
28
 
29
29
  export function column_getSize<
@@ -150,7 +150,7 @@ export function table_resetColumnSizing<
150
150
  >(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {
151
151
  table_setColumnSizing(
152
152
  table,
153
- defaultState ? {} : (table.initialState.columnSizing ?? {}),
153
+ defaultState ? {} : cloneState(table.initialState.columnSizing ?? {}),
154
154
  )
155
155
  }
156
156
 
@@ -1,4 +1,4 @@
1
- import { callMemoOrStaticFn } from '../../utils'
1
+ import { callMemoOrStaticFn, cloneState } from '../../utils'
2
2
  import type { CellData, RowData, Updater } from '../../types/type-utils'
3
3
  import type { TableFeatures } from '../../types/TableFeatures'
4
4
  import type { Table_Internal } from '../../types/Table'
@@ -8,7 +8,7 @@ import type { ColumnVisibilityState } from './columnVisibilityFeature.types'
8
8
  import type { Row } from '../../types/Row'
9
9
 
10
10
  export function getDefaultColumnVisibilityState(): ColumnVisibilityState {
11
- return structuredClone({})
11
+ return {}
12
12
  }
13
13
 
14
14
  export function column_toggleVisibility<
@@ -125,7 +125,7 @@ export function table_resetColumnVisibility<
125
125
  >(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {
126
126
  table_setColumnVisibility(
127
127
  table,
128
- defaultState ? {} : (table.initialState.columnVisibility ?? {}),
128
+ defaultState ? {} : cloneState(table.initialState.columnVisibility ?? {}),
129
129
  )
130
130
  }
131
131