@tanstack/table-core 9.0.0-beta.12 → 9.0.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/table/coreTablesFeature.utils.cjs +33 -11
- package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
- package/dist/core/table/coreTablesFeature.utils.d.cts +3 -1
- package/dist/core/table/coreTablesFeature.utils.d.ts +3 -1
- package/dist/core/table/coreTablesFeature.utils.js +33 -11
- package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
- package/dist/fns/filterFns.cjs +2 -2
- package/dist/fns/filterFns.cjs.map +1 -1
- package/dist/fns/filterFns.js +2 -2
- package/dist/fns/filterFns.js.map +1 -1
- package/package.json +1 -1
- package/src/core/table/coreTablesFeature.utils.ts +47 -18
- package/src/fns/filterFns.ts +8 -2
|
@@ -49,7 +49,9 @@ function table_reset(table) {
|
|
|
49
49
|
* Merges new table options with the current resolved options.
|
|
50
50
|
*
|
|
51
51
|
* If `options.mergeOptions` is provided, it owns the merge behavior; otherwise
|
|
52
|
-
* options are shallow-merged.
|
|
52
|
+
* options are shallow-merged. Static options that should never change after
|
|
53
|
+
* initialization are restored on a fresh object so framework merge helpers may
|
|
54
|
+
* return readonly getter/proxy objects.
|
|
53
55
|
*
|
|
54
56
|
* @example
|
|
55
57
|
* ```ts
|
|
@@ -57,11 +59,37 @@ function table_reset(table) {
|
|
|
57
59
|
* ```
|
|
58
60
|
*/
|
|
59
61
|
function table_mergeOptions(table, newOptions) {
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
+
const { features, atoms, initialState } = table.options;
|
|
63
|
+
if (!table.options.mergeOptions) return {
|
|
62
64
|
...table.options,
|
|
63
|
-
...newOptions
|
|
65
|
+
...newOptions,
|
|
66
|
+
features,
|
|
67
|
+
atoms,
|
|
68
|
+
initialState
|
|
64
69
|
};
|
|
70
|
+
const mergedOptions = table.options.mergeOptions(table.options, newOptions);
|
|
71
|
+
const descriptors = { ...Object.getOwnPropertyDescriptors(mergedOptions) };
|
|
72
|
+
return Object.defineProperties(Object.create(Object.getPrototypeOf(mergedOptions)), {
|
|
73
|
+
...descriptors,
|
|
74
|
+
features: {
|
|
75
|
+
value: features,
|
|
76
|
+
enumerable: true,
|
|
77
|
+
configurable: true,
|
|
78
|
+
writable: true
|
|
79
|
+
},
|
|
80
|
+
atoms: {
|
|
81
|
+
value: atoms,
|
|
82
|
+
enumerable: true,
|
|
83
|
+
configurable: true,
|
|
84
|
+
writable: true
|
|
85
|
+
},
|
|
86
|
+
initialState: {
|
|
87
|
+
value: initialState,
|
|
88
|
+
enumerable: true,
|
|
89
|
+
configurable: true,
|
|
90
|
+
writable: true
|
|
91
|
+
}
|
|
92
|
+
});
|
|
65
93
|
}
|
|
66
94
|
/**
|
|
67
95
|
* Updates the table options object.
|
|
@@ -75,13 +103,7 @@ function table_mergeOptions(table, newOptions) {
|
|
|
75
103
|
* ```
|
|
76
104
|
*/
|
|
77
105
|
function table_setOptions(table, updater) {
|
|
78
|
-
const
|
|
79
|
-
const { features, atoms, initialState } = table.options;
|
|
80
|
-
const mergedOptions = Object.assign(table_mergeOptions(table, newOptions), {
|
|
81
|
-
features,
|
|
82
|
-
atoms,
|
|
83
|
-
initialState
|
|
84
|
-
});
|
|
106
|
+
const mergedOptions = table_mergeOptions(table, require_utils.functionalUpdate(updater, table.options));
|
|
85
107
|
if (table.optionsStore) table.optionsStore.set(() => mergedOptions);
|
|
86
108
|
else table.options = mergedOptions;
|
|
87
109
|
table_syncExternalStateToBaseAtoms(table);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coreTablesFeature.utils.cjs","names":["cloneState","functionalUpdate"],"sources":["../../../src/core/table/coreTablesFeature.utils.ts"],"sourcesContent":["import { cloneState, functionalUpdate } from '../../utils'\nimport type { RowData, Updater } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { Table_Internal } from '../../types/Table'\nimport type { TableOptions } from '../../types/TableOptions'\n\n/**\n * Synchronizes externally controlled state slices into the table's base atoms.\n *\n * This keeps legacy `options.state` values reflected in the atom graph so\n * derived atoms, stores, and table APIs read a consistent snapshot.\n *\n * @example\n * ```ts\n * table_syncExternalStateToBaseAtoms(table)\n * ```\n */\nexport function table_syncExternalStateToBaseAtoms<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const state = table.options.state\n if (!state) {\n return\n }\n\n table._reactivity.batch(() => {\n for (const key in state) {\n const baseAtom = (table.baseAtoms as Record<string, any>)[key]\n if (!baseAtom) {\n continue\n }\n\n const externalState = state[key as keyof typeof state]\n if (externalState !== baseAtom.get()) {\n baseAtom.set(() => externalState)\n }\n }\n })\n}\n\n/**\n * Resets all internal table base atoms to `table.initialState`.\n *\n * This resets internally owned state slices in a single reactivity batch. Use\n * feature-specific reset APIs when a slice may be externally owned.\n *\n * @example\n * ```ts\n * table_reset(table)\n * ```\n */\nexport function table_reset<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const snap = cloneState(table.initialState)\n table._reactivity.batch(() => {\n const keys = Object.keys(snap) as Array<keyof typeof snap>\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n ;(table.baseAtoms as any)[key].set(snap[key])\n }\n })\n}\n\n/**\n * Merges new table options with the current resolved options.\n *\n * If `options.mergeOptions` is provided, it owns the merge behavior; otherwise\n * options are shallow-merged.\n *\n * @example\n * ```ts\n * const options = table_mergeOptions(table, nextOptions)\n * ```\n */\nexport function table_mergeOptions<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n newOptions: TableOptions<TFeatures, TData>,\n) {\n if (table.options.mergeOptions) {\n return table.options.mergeOptions(\n
|
|
1
|
+
{"version":3,"file":"coreTablesFeature.utils.cjs","names":["cloneState","functionalUpdate"],"sources":["../../../src/core/table/coreTablesFeature.utils.ts"],"sourcesContent":["import { cloneState, functionalUpdate } from '../../utils'\nimport type { RowData, Updater } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { Table_Internal } from '../../types/Table'\nimport type { TableOptions } from '../../types/TableOptions'\n\n/**\n * Synchronizes externally controlled state slices into the table's base atoms.\n *\n * This keeps legacy `options.state` values reflected in the atom graph so\n * derived atoms, stores, and table APIs read a consistent snapshot.\n *\n * @example\n * ```ts\n * table_syncExternalStateToBaseAtoms(table)\n * ```\n */\nexport function table_syncExternalStateToBaseAtoms<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const state = table.options.state\n if (!state) {\n return\n }\n\n table._reactivity.batch(() => {\n for (const key in state) {\n const baseAtom = (table.baseAtoms as Record<string, any>)[key]\n if (!baseAtom) {\n continue\n }\n\n const externalState = state[key as keyof typeof state]\n if (externalState !== baseAtom.get()) {\n baseAtom.set(() => externalState)\n }\n }\n })\n}\n\n/**\n * Resets all internal table base atoms to `table.initialState`.\n *\n * This resets internally owned state slices in a single reactivity batch. Use\n * feature-specific reset APIs when a slice may be externally owned.\n *\n * @example\n * ```ts\n * table_reset(table)\n * ```\n */\nexport function table_reset<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const snap = cloneState(table.initialState)\n table._reactivity.batch(() => {\n const keys = Object.keys(snap) as Array<keyof typeof snap>\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n ;(table.baseAtoms as any)[key].set(snap[key])\n }\n })\n}\n\n/**\n * Merges new table options with the current resolved options.\n *\n * If `options.mergeOptions` is provided, it owns the merge behavior; otherwise\n * options are shallow-merged. Static options that should never change after\n * initialization are restored on a fresh object so framework merge helpers may\n * return readonly getter/proxy objects.\n *\n * @example\n * ```ts\n * const options = table_mergeOptions(table, nextOptions)\n * ```\n */\nexport function table_mergeOptions<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n newOptions: TableOptions<TFeatures, TData>,\n) {\n const { features, atoms, initialState } = table.options\n\n // simple merge if no mergeOptions is provided - performant\n if (!table.options.mergeOptions) {\n return {\n ...table.options,\n ...newOptions,\n features,\n atoms,\n initialState,\n }\n }\n\n // else use the mergeOptions function and preserve getters/setters\n const mergedOptions = table.options.mergeOptions(\n table.options as TableOptions<TFeatures, TData>,\n newOptions,\n )\n const descriptors: PropertyDescriptorMap = {\n ...Object.getOwnPropertyDescriptors(mergedOptions),\n }\n\n return Object.defineProperties(\n Object.create(Object.getPrototypeOf(mergedOptions)),\n {\n ...descriptors,\n features: {\n value: features,\n enumerable: true,\n configurable: true,\n writable: true,\n },\n atoms: {\n value: atoms,\n enumerable: true,\n configurable: true,\n writable: true,\n },\n initialState: {\n value: initialState,\n enumerable: true,\n configurable: true,\n writable: true,\n },\n },\n ) as TableOptions<TFeatures, TData>\n}\n\n/**\n * Updates the table options object.\n *\n * The updater receives the current resolved options and the merged result is\n * immediately assigned to the table instance.\n *\n * @example\n * ```ts\n * table_setOptions(table, (old) => old)\n * ```\n */\nexport function table_setOptions<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n updater: Updater<TableOptions<TFeatures, TData>>,\n): void {\n const newOptions = functionalUpdate(\n updater,\n table.options as TableOptions<TFeatures, TData>,\n )\n const mergedOptions = table_mergeOptions(table, newOptions)\n\n if (table.optionsStore) {\n table.optionsStore.set(() => mergedOptions)\n } else {\n table.options = mergedOptions\n }\n table_syncExternalStateToBaseAtoms(table)\n}\n"],"mappings":";;;;;;;;;;;;;;AAiBA,SAAgB,mCAGd,OAA+C;CAC/C,MAAM,QAAQ,MAAM,QAAQ;CAC5B,IAAI,CAAC,OACH;CAGF,MAAM,YAAY,YAAY;EAC5B,KAAK,MAAM,OAAO,OAAO;GACvB,MAAM,WAAY,MAAM,UAAkC;GAC1D,IAAI,CAAC,UACH;GAGF,MAAM,gBAAgB,MAAM;GAC5B,IAAI,kBAAkB,SAAS,IAAI,GACjC,SAAS,UAAU,aAAa;EAEpC;CACF,CAAC;AACH;;;;;;;;;;;;AAaA,SAAgB,YAGd,OAA+C;CAC/C,MAAM,OAAOA,yBAAW,MAAM,YAAY;CAC1C,MAAM,YAAY,YAAY;EAC5B,MAAM,OAAO,OAAO,KAAK,IAAI;EAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;GAChB,AAAC,MAAM,UAAkB,IAAI,CAAC,IAAI,KAAK,IAAI;EAC9C;CACF,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,mBAId,OACA,YACA;CACA,MAAM,EAAE,UAAU,OAAO,iBAAiB,MAAM;CAGhD,IAAI,CAAC,MAAM,QAAQ,cACjB,OAAO;EACL,GAAG,MAAM;EACT,GAAG;EACH;EACA;EACA;CACF;CAIF,MAAM,gBAAgB,MAAM,QAAQ,aAClC,MAAM,SACN,UACF;CACA,MAAM,cAAqC,EACzC,GAAG,OAAO,0BAA0B,aAAa,EACnD;CAEA,OAAO,OAAO,iBACZ,OAAO,OAAO,OAAO,eAAe,aAAa,CAAC,GAClD;EACE,GAAG;EACH,UAAU;GACR,OAAO;GACP,YAAY;GACZ,cAAc;GACd,UAAU;EACZ;EACA,OAAO;GACL,OAAO;GACP,YAAY;GACZ,cAAc;GACd,UAAU;EACZ;EACA,cAAc;GACZ,OAAO;GACP,YAAY;GACZ,cAAc;GACd,UAAU;EACZ;CACF,CACF;AACF;;;;;;;;;;;;AAaA,SAAgB,iBAId,OACA,SACM;CAKN,MAAM,gBAAgB,mBAAmB,OAJtBC,+BACjB,SACA,MAAM,OAEiD,CAAC;CAE1D,IAAI,MAAM,cACR,MAAM,aAAa,UAAU,aAAa;MAE1C,MAAM,UAAU;CAElB,mCAAmC,KAAK;AAC1C"}
|
|
@@ -32,7 +32,9 @@ declare function table_reset<TFeatures extends TableFeatures, TData extends RowD
|
|
|
32
32
|
* Merges new table options with the current resolved options.
|
|
33
33
|
*
|
|
34
34
|
* If `options.mergeOptions` is provided, it owns the merge behavior; otherwise
|
|
35
|
-
* options are shallow-merged.
|
|
35
|
+
* options are shallow-merged. Static options that should never change after
|
|
36
|
+
* initialization are restored on a fresh object so framework merge helpers may
|
|
37
|
+
* return readonly getter/proxy objects.
|
|
36
38
|
*
|
|
37
39
|
* @example
|
|
38
40
|
* ```ts
|
|
@@ -32,7 +32,9 @@ declare function table_reset<TFeatures extends TableFeatures, TData extends RowD
|
|
|
32
32
|
* Merges new table options with the current resolved options.
|
|
33
33
|
*
|
|
34
34
|
* If `options.mergeOptions` is provided, it owns the merge behavior; otherwise
|
|
35
|
-
* options are shallow-merged.
|
|
35
|
+
* options are shallow-merged. Static options that should never change after
|
|
36
|
+
* initialization are restored on a fresh object so framework merge helpers may
|
|
37
|
+
* return readonly getter/proxy objects.
|
|
36
38
|
*
|
|
37
39
|
* @example
|
|
38
40
|
* ```ts
|
|
@@ -49,7 +49,9 @@ function table_reset(table) {
|
|
|
49
49
|
* Merges new table options with the current resolved options.
|
|
50
50
|
*
|
|
51
51
|
* If `options.mergeOptions` is provided, it owns the merge behavior; otherwise
|
|
52
|
-
* options are shallow-merged.
|
|
52
|
+
* options are shallow-merged. Static options that should never change after
|
|
53
|
+
* initialization are restored on a fresh object so framework merge helpers may
|
|
54
|
+
* return readonly getter/proxy objects.
|
|
53
55
|
*
|
|
54
56
|
* @example
|
|
55
57
|
* ```ts
|
|
@@ -57,11 +59,37 @@ function table_reset(table) {
|
|
|
57
59
|
* ```
|
|
58
60
|
*/
|
|
59
61
|
function table_mergeOptions(table, newOptions) {
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
+
const { features, atoms, initialState } = table.options;
|
|
63
|
+
if (!table.options.mergeOptions) return {
|
|
62
64
|
...table.options,
|
|
63
|
-
...newOptions
|
|
65
|
+
...newOptions,
|
|
66
|
+
features,
|
|
67
|
+
atoms,
|
|
68
|
+
initialState
|
|
64
69
|
};
|
|
70
|
+
const mergedOptions = table.options.mergeOptions(table.options, newOptions);
|
|
71
|
+
const descriptors = { ...Object.getOwnPropertyDescriptors(mergedOptions) };
|
|
72
|
+
return Object.defineProperties(Object.create(Object.getPrototypeOf(mergedOptions)), {
|
|
73
|
+
...descriptors,
|
|
74
|
+
features: {
|
|
75
|
+
value: features,
|
|
76
|
+
enumerable: true,
|
|
77
|
+
configurable: true,
|
|
78
|
+
writable: true
|
|
79
|
+
},
|
|
80
|
+
atoms: {
|
|
81
|
+
value: atoms,
|
|
82
|
+
enumerable: true,
|
|
83
|
+
configurable: true,
|
|
84
|
+
writable: true
|
|
85
|
+
},
|
|
86
|
+
initialState: {
|
|
87
|
+
value: initialState,
|
|
88
|
+
enumerable: true,
|
|
89
|
+
configurable: true,
|
|
90
|
+
writable: true
|
|
91
|
+
}
|
|
92
|
+
});
|
|
65
93
|
}
|
|
66
94
|
/**
|
|
67
95
|
* Updates the table options object.
|
|
@@ -75,13 +103,7 @@ function table_mergeOptions(table, newOptions) {
|
|
|
75
103
|
* ```
|
|
76
104
|
*/
|
|
77
105
|
function table_setOptions(table, updater) {
|
|
78
|
-
const
|
|
79
|
-
const { features, atoms, initialState } = table.options;
|
|
80
|
-
const mergedOptions = Object.assign(table_mergeOptions(table, newOptions), {
|
|
81
|
-
features,
|
|
82
|
-
atoms,
|
|
83
|
-
initialState
|
|
84
|
-
});
|
|
106
|
+
const mergedOptions = table_mergeOptions(table, functionalUpdate(updater, table.options));
|
|
85
107
|
if (table.optionsStore) table.optionsStore.set(() => mergedOptions);
|
|
86
108
|
else table.options = mergedOptions;
|
|
87
109
|
table_syncExternalStateToBaseAtoms(table);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coreTablesFeature.utils.js","names":[],"sources":["../../../src/core/table/coreTablesFeature.utils.ts"],"sourcesContent":["import { cloneState, functionalUpdate } from '../../utils'\nimport type { RowData, Updater } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { Table_Internal } from '../../types/Table'\nimport type { TableOptions } from '../../types/TableOptions'\n\n/**\n * Synchronizes externally controlled state slices into the table's base atoms.\n *\n * This keeps legacy `options.state` values reflected in the atom graph so\n * derived atoms, stores, and table APIs read a consistent snapshot.\n *\n * @example\n * ```ts\n * table_syncExternalStateToBaseAtoms(table)\n * ```\n */\nexport function table_syncExternalStateToBaseAtoms<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const state = table.options.state\n if (!state) {\n return\n }\n\n table._reactivity.batch(() => {\n for (const key in state) {\n const baseAtom = (table.baseAtoms as Record<string, any>)[key]\n if (!baseAtom) {\n continue\n }\n\n const externalState = state[key as keyof typeof state]\n if (externalState !== baseAtom.get()) {\n baseAtom.set(() => externalState)\n }\n }\n })\n}\n\n/**\n * Resets all internal table base atoms to `table.initialState`.\n *\n * This resets internally owned state slices in a single reactivity batch. Use\n * feature-specific reset APIs when a slice may be externally owned.\n *\n * @example\n * ```ts\n * table_reset(table)\n * ```\n */\nexport function table_reset<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const snap = cloneState(table.initialState)\n table._reactivity.batch(() => {\n const keys = Object.keys(snap) as Array<keyof typeof snap>\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n ;(table.baseAtoms as any)[key].set(snap[key])\n }\n })\n}\n\n/**\n * Merges new table options with the current resolved options.\n *\n * If `options.mergeOptions` is provided, it owns the merge behavior; otherwise\n * options are shallow-merged.\n *\n * @example\n * ```ts\n * const options = table_mergeOptions(table, nextOptions)\n * ```\n */\nexport function table_mergeOptions<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n newOptions: TableOptions<TFeatures, TData>,\n) {\n if (table.options.mergeOptions) {\n return table.options.mergeOptions(\n
|
|
1
|
+
{"version":3,"file":"coreTablesFeature.utils.js","names":[],"sources":["../../../src/core/table/coreTablesFeature.utils.ts"],"sourcesContent":["import { cloneState, functionalUpdate } from '../../utils'\nimport type { RowData, Updater } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { Table_Internal } from '../../types/Table'\nimport type { TableOptions } from '../../types/TableOptions'\n\n/**\n * Synchronizes externally controlled state slices into the table's base atoms.\n *\n * This keeps legacy `options.state` values reflected in the atom graph so\n * derived atoms, stores, and table APIs read a consistent snapshot.\n *\n * @example\n * ```ts\n * table_syncExternalStateToBaseAtoms(table)\n * ```\n */\nexport function table_syncExternalStateToBaseAtoms<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const state = table.options.state\n if (!state) {\n return\n }\n\n table._reactivity.batch(() => {\n for (const key in state) {\n const baseAtom = (table.baseAtoms as Record<string, any>)[key]\n if (!baseAtom) {\n continue\n }\n\n const externalState = state[key as keyof typeof state]\n if (externalState !== baseAtom.get()) {\n baseAtom.set(() => externalState)\n }\n }\n })\n}\n\n/**\n * Resets all internal table base atoms to `table.initialState`.\n *\n * This resets internally owned state slices in a single reactivity batch. Use\n * feature-specific reset APIs when a slice may be externally owned.\n *\n * @example\n * ```ts\n * table_reset(table)\n * ```\n */\nexport function table_reset<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>): void {\n const snap = cloneState(table.initialState)\n table._reactivity.batch(() => {\n const keys = Object.keys(snap) as Array<keyof typeof snap>\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n ;(table.baseAtoms as any)[key].set(snap[key])\n }\n })\n}\n\n/**\n * Merges new table options with the current resolved options.\n *\n * If `options.mergeOptions` is provided, it owns the merge behavior; otherwise\n * options are shallow-merged. Static options that should never change after\n * initialization are restored on a fresh object so framework merge helpers may\n * return readonly getter/proxy objects.\n *\n * @example\n * ```ts\n * const options = table_mergeOptions(table, nextOptions)\n * ```\n */\nexport function table_mergeOptions<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n newOptions: TableOptions<TFeatures, TData>,\n) {\n const { features, atoms, initialState } = table.options\n\n // simple merge if no mergeOptions is provided - performant\n if (!table.options.mergeOptions) {\n return {\n ...table.options,\n ...newOptions,\n features,\n atoms,\n initialState,\n }\n }\n\n // else use the mergeOptions function and preserve getters/setters\n const mergedOptions = table.options.mergeOptions(\n table.options as TableOptions<TFeatures, TData>,\n newOptions,\n )\n const descriptors: PropertyDescriptorMap = {\n ...Object.getOwnPropertyDescriptors(mergedOptions),\n }\n\n return Object.defineProperties(\n Object.create(Object.getPrototypeOf(mergedOptions)),\n {\n ...descriptors,\n features: {\n value: features,\n enumerable: true,\n configurable: true,\n writable: true,\n },\n atoms: {\n value: atoms,\n enumerable: true,\n configurable: true,\n writable: true,\n },\n initialState: {\n value: initialState,\n enumerable: true,\n configurable: true,\n writable: true,\n },\n },\n ) as TableOptions<TFeatures, TData>\n}\n\n/**\n * Updates the table options object.\n *\n * The updater receives the current resolved options and the merged result is\n * immediately assigned to the table instance.\n *\n * @example\n * ```ts\n * table_setOptions(table, (old) => old)\n * ```\n */\nexport function table_setOptions<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n updater: Updater<TableOptions<TFeatures, TData>>,\n): void {\n const newOptions = functionalUpdate(\n updater,\n table.options as TableOptions<TFeatures, TData>,\n )\n const mergedOptions = table_mergeOptions(table, newOptions)\n\n if (table.optionsStore) {\n table.optionsStore.set(() => mergedOptions)\n } else {\n table.options = mergedOptions\n }\n table_syncExternalStateToBaseAtoms(table)\n}\n"],"mappings":";;;;;;;;;;;;;;AAiBA,SAAgB,mCAGd,OAA+C;CAC/C,MAAM,QAAQ,MAAM,QAAQ;CAC5B,IAAI,CAAC,OACH;CAGF,MAAM,YAAY,YAAY;EAC5B,KAAK,MAAM,OAAO,OAAO;GACvB,MAAM,WAAY,MAAM,UAAkC;GAC1D,IAAI,CAAC,UACH;GAGF,MAAM,gBAAgB,MAAM;GAC5B,IAAI,kBAAkB,SAAS,IAAI,GACjC,SAAS,UAAU,aAAa;EAEpC;CACF,CAAC;AACH;;;;;;;;;;;;AAaA,SAAgB,YAGd,OAA+C;CAC/C,MAAM,OAAO,WAAW,MAAM,YAAY;CAC1C,MAAM,YAAY,YAAY;EAC5B,MAAM,OAAO,OAAO,KAAK,IAAI;EAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;GAChB,AAAC,MAAM,UAAkB,IAAI,CAAC,IAAI,KAAK,IAAI;EAC9C;CACF,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,mBAId,OACA,YACA;CACA,MAAM,EAAE,UAAU,OAAO,iBAAiB,MAAM;CAGhD,IAAI,CAAC,MAAM,QAAQ,cACjB,OAAO;EACL,GAAG,MAAM;EACT,GAAG;EACH;EACA;EACA;CACF;CAIF,MAAM,gBAAgB,MAAM,QAAQ,aAClC,MAAM,SACN,UACF;CACA,MAAM,cAAqC,EACzC,GAAG,OAAO,0BAA0B,aAAa,EACnD;CAEA,OAAO,OAAO,iBACZ,OAAO,OAAO,OAAO,eAAe,aAAa,CAAC,GAClD;EACE,GAAG;EACH,UAAU;GACR,OAAO;GACP,YAAY;GACZ,cAAc;GACd,UAAU;EACZ;EACA,OAAO;GACL,OAAO;GACP,YAAY;GACZ,cAAc;GACd,UAAU;EACZ;EACA,cAAc;GACZ,OAAO;GACP,YAAY;GACZ,cAAc;GACd,UAAU;EACZ;CACF,CACF;AACF;;;;;;;;;;;;AAaA,SAAgB,iBAId,OACA,SACM;CAKN,MAAM,gBAAgB,mBAAmB,OAJtB,iBACjB,SACA,MAAM,OAEiD,CAAC;CAE1D,IAAI,MAAM,cACR,MAAM,aAAa,UAAU,aAAa;MAE1C,MAAM,UAAU;CAElB,mCAAmC,KAAK;AAC1C"}
|
package/dist/fns/filterFns.cjs
CHANGED
|
@@ -97,13 +97,13 @@ const filterFn_lessThanOrEqualTo = Object.assign((row, columnId, filterValue) =>
|
|
|
97
97
|
*
|
|
98
98
|
* Blank range endpoints are treated as open-ended.
|
|
99
99
|
*/
|
|
100
|
-
const filterFn_between = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThan(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThan(row, columnId, filterValues[1])), { autoRemove: (val) =>
|
|
100
|
+
const filterFn_between = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThan(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThan(row, columnId, filterValues[1])), { autoRemove: (val) => testFalsy(val) || testFalsy(val[0]) && testFalsy(val[1]) });
|
|
101
101
|
/**
|
|
102
102
|
* Keeps rows whose value falls between an inclusive min/max pair.
|
|
103
103
|
*
|
|
104
104
|
* Blank range endpoints are treated as open-ended.
|
|
105
105
|
*/
|
|
106
|
-
const filterFn_betweenInclusive = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])), { autoRemove: (val) =>
|
|
106
|
+
const filterFn_betweenInclusive = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])), { autoRemove: (val) => testFalsy(val) || testFalsy(val[0]) && testFalsy(val[1]) });
|
|
107
107
|
/**
|
|
108
108
|
* Keeps rows whose numeric value is inside an inclusive `[min, max]` range.
|
|
109
109
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterFns.cjs","names":[],"sources":["../../src/fns/filterFns.ts"],"sourcesContent":["import type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n// Basic filters\n\n/**\n * Keeps rows whose column value is strictly equal to the filter value.\n *\n * Uses JavaScript `===` comparison and auto-removes empty filter values.\n */\nexport const filterFn_equals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) === filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose column value is loosely equal to the filter value.\n *\n * Uses JavaScript `==` comparison and auto-removes empty filter values. This is\n * useful for matching string input against numeric row values.\n */\nexport const filterFn_weakEquals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) == filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// String filters\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_includesStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row.getValue(columnId)?.toString().includes(String(filterValue)),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_includesString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row\n .getValue(columnId)\n ?.toString()\n .toLowerCase()\n .includes(String(filterValue).toLowerCase()),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value equals the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_equalsString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n row.getValue(columnId)?.toString().toLowerCase() ===\n String(filterValue).toLowerCase()\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value exactly equals the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_equalsStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId)?.toString() === String(filterValue)\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// Number filters\n\n/**\n * Keeps rows whose value is greater than the filter value.\n *\n * Numeric values are compared numerically when both sides can be coerced to\n * numbers; otherwise normalized strings are compared.\n */\nexport const filterFn_greaterThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n const rowValue = row.getValue(columnId)\n const numericRowValue =\n rowValue === null || rowValue === undefined ? 0 : +rowValue\n const numericFilterValue = Number(filterValue)\n\n if (!isNaN(numericFilterValue) && !isNaN(numericRowValue)) {\n return numericRowValue > numericFilterValue\n }\n\n const stringValue = (rowValue ?? '').toString().toLowerCase().trim()\n const stringFilterValue = String(filterValue).toLowerCase().trim()\n return stringValue > stringFilterValue\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is greater than or equal to the filter value.\n *\n * Delegates to the built-in greater-than and equality comparisons.\n */\nexport const filterFn_greaterThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n filterFn_greaterThan(row, columnId, filterValue) ||\n filterFn_equals(row, columnId, filterValue)\n )\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than the filter value.\n *\n * This is implemented as the inverse of greater-than-or-equal comparison.\n */\nexport const filterFn_lessThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThanOrEqualTo(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than or equal to the filter value.\n *\n * This is implemented as the inverse of greater-than comparison.\n */\nexport const filterFn_lessThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThan(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n// Range filters\n\n/**\n * Keeps rows whose value falls between an exclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_between = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThan(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThan(row, columnId, filterValues[1])),\n { autoRemove: (val: any) => !val },\n)\n\n/**\n * Keeps rows whose value falls between an inclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_betweenInclusive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])),\n { autoRemove: (val: any) => !val },\n)\n\n/**\n * Keeps rows whose numeric value is inside an inclusive `[min, max]` range.\n *\n * Filter values are normalized so blank endpoints become open-ended and\n * reversed endpoints are swapped.\n */\nexport const filterFn_inNumberRange = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: [number, number],\n ) => {\n const [min, max] = filterValue\n\n const rowValue: number = row.getValue(columnId)\n return rowValue >= min && rowValue <= max\n },\n {\n resolveFilterValue: (val: [any, any]) => {\n const [unsafeMin, unsafeMax] = val\n\n const parsedMin =\n typeof unsafeMin !== 'number' ? parseFloat(unsafeMin) : unsafeMin\n const parsedMax =\n typeof unsafeMax !== 'number' ? parseFloat(unsafeMax) : unsafeMax\n\n let min =\n unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin\n let max =\n unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax\n\n if (min > max) {\n const temp = min\n min = max\n max = temp\n }\n\n return [min, max] as const\n },\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n// Array filters\n\n/**\n * Keeps rows whose scalar column value equals at least one filter value.\n */\nexport const filterFn_arrHas = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n) => {\n return filterValue.some((val) => row.getValue<unknown>(columnId) === val)\n}\n\n/**\n * Keeps rows whose array or string column value includes at least one filter value.\n */\nexport const filterFn_arrIncludes = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n return filterValue.some((val) =>\n (row.getValue<unknown>(columnId) as Array<unknown> | string).includes(\n val as any,\n ),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes every filter value.\n */\nexport const filterFn_arrIncludesAll = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return !filterValue.some((val) => !value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes at least one filter value.\n */\nexport const filterFn_arrIncludesSome = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return filterValue.some((val) => value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n// Export\n\n/**\n * The built-in filter function registry.\n *\n * Pass this object to filtered row model creation or extend it with custom filter functions.\n */\nexport const filterFns = {\n arrIncludes: filterFn_arrIncludes,\n arrIncludesAll: filterFn_arrIncludesAll,\n arrHas: filterFn_arrHas,\n arrIncludesSome: filterFn_arrIncludesSome,\n between: filterFn_between,\n betweenInclusive: filterFn_betweenInclusive,\n equals: filterFn_equals,\n equalsString: filterFn_equalsString,\n inNumberRange: filterFn_inNumberRange,\n includesString: filterFn_includesString,\n includesStringSensitive: filterFn_includesStringSensitive,\n weakEquals: filterFn_weakEquals,\n}\n\nexport type BuiltInFilterFn = keyof typeof filterFns\n\n// Utils\n\nfunction testFalsy(val: any) {\n return val === undefined || val === null || val === ''\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filterFns.cjs","names":[],"sources":["../../src/fns/filterFns.ts"],"sourcesContent":["import type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n// Basic filters\n\n/**\n * Keeps rows whose column value is strictly equal to the filter value.\n *\n * Uses JavaScript `===` comparison and auto-removes empty filter values.\n */\nexport const filterFn_equals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) === filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose column value is loosely equal to the filter value.\n *\n * Uses JavaScript `==` comparison and auto-removes empty filter values. This is\n * useful for matching string input against numeric row values.\n */\nexport const filterFn_weakEquals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) == filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// String filters\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_includesStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row.getValue(columnId)?.toString().includes(String(filterValue)),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_includesString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row\n .getValue(columnId)\n ?.toString()\n .toLowerCase()\n .includes(String(filterValue).toLowerCase()),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value equals the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_equalsString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n row.getValue(columnId)?.toString().toLowerCase() ===\n String(filterValue).toLowerCase()\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value exactly equals the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_equalsStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId)?.toString() === String(filterValue)\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// Number filters\n\n/**\n * Keeps rows whose value is greater than the filter value.\n *\n * Numeric values are compared numerically when both sides can be coerced to\n * numbers; otherwise normalized strings are compared.\n */\nexport const filterFn_greaterThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n const rowValue = row.getValue(columnId)\n const numericRowValue =\n rowValue === null || rowValue === undefined ? 0 : +rowValue\n const numericFilterValue = Number(filterValue)\n\n if (!isNaN(numericFilterValue) && !isNaN(numericRowValue)) {\n return numericRowValue > numericFilterValue\n }\n\n const stringValue = (rowValue ?? '').toString().toLowerCase().trim()\n const stringFilterValue = String(filterValue).toLowerCase().trim()\n return stringValue > stringFilterValue\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is greater than or equal to the filter value.\n *\n * Delegates to the built-in greater-than and equality comparisons.\n */\nexport const filterFn_greaterThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n filterFn_greaterThan(row, columnId, filterValue) ||\n filterFn_equals(row, columnId, filterValue)\n )\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than the filter value.\n *\n * This is implemented as the inverse of greater-than-or-equal comparison.\n */\nexport const filterFn_lessThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThanOrEqualTo(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than or equal to the filter value.\n *\n * This is implemented as the inverse of greater-than comparison.\n */\nexport const filterFn_lessThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThan(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n// Range filters\n\n/**\n * Keeps rows whose value falls between an exclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_between = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThan(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThan(row, columnId, filterValues[1])),\n {\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n/**\n * Keeps rows whose value falls between an inclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_betweenInclusive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])),\n {\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n/**\n * Keeps rows whose numeric value is inside an inclusive `[min, max]` range.\n *\n * Filter values are normalized so blank endpoints become open-ended and\n * reversed endpoints are swapped.\n */\nexport const filterFn_inNumberRange = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: [number, number],\n ) => {\n const [min, max] = filterValue\n\n const rowValue: number = row.getValue(columnId)\n return rowValue >= min && rowValue <= max\n },\n {\n resolveFilterValue: (val: [any, any]) => {\n const [unsafeMin, unsafeMax] = val\n\n const parsedMin =\n typeof unsafeMin !== 'number' ? parseFloat(unsafeMin) : unsafeMin\n const parsedMax =\n typeof unsafeMax !== 'number' ? parseFloat(unsafeMax) : unsafeMax\n\n let min =\n unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin\n let max =\n unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax\n\n if (min > max) {\n const temp = min\n min = max\n max = temp\n }\n\n return [min, max] as const\n },\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n// Array filters\n\n/**\n * Keeps rows whose scalar column value equals at least one filter value.\n */\nexport const filterFn_arrHas = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n) => {\n return filterValue.some((val) => row.getValue<unknown>(columnId) === val)\n}\n\n/**\n * Keeps rows whose array or string column value includes at least one filter value.\n */\nexport const filterFn_arrIncludes = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n return filterValue.some((val) =>\n (row.getValue<unknown>(columnId) as Array<unknown> | string).includes(\n val as any,\n ),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes every filter value.\n */\nexport const filterFn_arrIncludesAll = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return !filterValue.some((val) => !value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes at least one filter value.\n */\nexport const filterFn_arrIncludesSome = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return filterValue.some((val) => value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n// Export\n\n/**\n * The built-in filter function registry.\n *\n * Pass this object to filtered row model creation or extend it with custom filter functions.\n */\nexport const filterFns = {\n arrIncludes: filterFn_arrIncludes,\n arrIncludesAll: filterFn_arrIncludesAll,\n arrHas: filterFn_arrHas,\n arrIncludesSome: filterFn_arrIncludesSome,\n between: filterFn_between,\n betweenInclusive: filterFn_betweenInclusive,\n equals: filterFn_equals,\n equalsString: filterFn_equalsString,\n inNumberRange: filterFn_inNumberRange,\n includesString: filterFn_includesString,\n includesStringSensitive: filterFn_includesStringSensitive,\n weakEquals: filterFn_weakEquals,\n}\n\nexport type BuiltInFilterFn = keyof typeof filterFns\n\n// Utils\n\nfunction testFalsy(val: any) {\n return val === undefined || val === null || val === ''\n}\n"],"mappings":"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"}
|
package/dist/fns/filterFns.js
CHANGED
|
@@ -96,13 +96,13 @@ const filterFn_lessThanOrEqualTo = Object.assign((row, columnId, filterValue) =>
|
|
|
96
96
|
*
|
|
97
97
|
* Blank range endpoints are treated as open-ended.
|
|
98
98
|
*/
|
|
99
|
-
const filterFn_between = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThan(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThan(row, columnId, filterValues[1])), { autoRemove: (val) =>
|
|
99
|
+
const filterFn_between = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThan(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThan(row, columnId, filterValues[1])), { autoRemove: (val) => testFalsy(val) || testFalsy(val[0]) && testFalsy(val[1]) });
|
|
100
100
|
/**
|
|
101
101
|
* Keeps rows whose value falls between an inclusive min/max pair.
|
|
102
102
|
*
|
|
103
103
|
* Blank range endpoints are treated as open-ended.
|
|
104
104
|
*/
|
|
105
|
-
const filterFn_betweenInclusive = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])), { autoRemove: (val) =>
|
|
105
|
+
const filterFn_betweenInclusive = Object.assign((row, columnId, filterValues) => (["", void 0].includes(filterValues[0]) || filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) && (!isNaN(Number(filterValues[0])) && !isNaN(Number(filterValues[1])) && Number(filterValues[0]) > Number(filterValues[1]) || ["", void 0].includes(filterValues[1]) || filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])), { autoRemove: (val) => testFalsy(val) || testFalsy(val[0]) && testFalsy(val[1]) });
|
|
106
106
|
/**
|
|
107
107
|
* Keeps rows whose numeric value is inside an inclusive `[min, max]` range.
|
|
108
108
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterFns.js","names":[],"sources":["../../src/fns/filterFns.ts"],"sourcesContent":["import type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n// Basic filters\n\n/**\n * Keeps rows whose column value is strictly equal to the filter value.\n *\n * Uses JavaScript `===` comparison and auto-removes empty filter values.\n */\nexport const filterFn_equals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) === filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose column value is loosely equal to the filter value.\n *\n * Uses JavaScript `==` comparison and auto-removes empty filter values. This is\n * useful for matching string input against numeric row values.\n */\nexport const filterFn_weakEquals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) == filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// String filters\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_includesStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row.getValue(columnId)?.toString().includes(String(filterValue)),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_includesString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row\n .getValue(columnId)\n ?.toString()\n .toLowerCase()\n .includes(String(filterValue).toLowerCase()),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value equals the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_equalsString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n row.getValue(columnId)?.toString().toLowerCase() ===\n String(filterValue).toLowerCase()\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value exactly equals the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_equalsStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId)?.toString() === String(filterValue)\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// Number filters\n\n/**\n * Keeps rows whose value is greater than the filter value.\n *\n * Numeric values are compared numerically when both sides can be coerced to\n * numbers; otherwise normalized strings are compared.\n */\nexport const filterFn_greaterThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n const rowValue = row.getValue(columnId)\n const numericRowValue =\n rowValue === null || rowValue === undefined ? 0 : +rowValue\n const numericFilterValue = Number(filterValue)\n\n if (!isNaN(numericFilterValue) && !isNaN(numericRowValue)) {\n return numericRowValue > numericFilterValue\n }\n\n const stringValue = (rowValue ?? '').toString().toLowerCase().trim()\n const stringFilterValue = String(filterValue).toLowerCase().trim()\n return stringValue > stringFilterValue\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is greater than or equal to the filter value.\n *\n * Delegates to the built-in greater-than and equality comparisons.\n */\nexport const filterFn_greaterThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n filterFn_greaterThan(row, columnId, filterValue) ||\n filterFn_equals(row, columnId, filterValue)\n )\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than the filter value.\n *\n * This is implemented as the inverse of greater-than-or-equal comparison.\n */\nexport const filterFn_lessThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThanOrEqualTo(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than or equal to the filter value.\n *\n * This is implemented as the inverse of greater-than comparison.\n */\nexport const filterFn_lessThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThan(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n// Range filters\n\n/**\n * Keeps rows whose value falls between an exclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_between = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThan(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThan(row, columnId, filterValues[1])),\n { autoRemove: (val: any) => !val },\n)\n\n/**\n * Keeps rows whose value falls between an inclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_betweenInclusive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])),\n { autoRemove: (val: any) => !val },\n)\n\n/**\n * Keeps rows whose numeric value is inside an inclusive `[min, max]` range.\n *\n * Filter values are normalized so blank endpoints become open-ended and\n * reversed endpoints are swapped.\n */\nexport const filterFn_inNumberRange = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: [number, number],\n ) => {\n const [min, max] = filterValue\n\n const rowValue: number = row.getValue(columnId)\n return rowValue >= min && rowValue <= max\n },\n {\n resolveFilterValue: (val: [any, any]) => {\n const [unsafeMin, unsafeMax] = val\n\n const parsedMin =\n typeof unsafeMin !== 'number' ? parseFloat(unsafeMin) : unsafeMin\n const parsedMax =\n typeof unsafeMax !== 'number' ? parseFloat(unsafeMax) : unsafeMax\n\n let min =\n unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin\n let max =\n unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax\n\n if (min > max) {\n const temp = min\n min = max\n max = temp\n }\n\n return [min, max] as const\n },\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n// Array filters\n\n/**\n * Keeps rows whose scalar column value equals at least one filter value.\n */\nexport const filterFn_arrHas = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n) => {\n return filterValue.some((val) => row.getValue<unknown>(columnId) === val)\n}\n\n/**\n * Keeps rows whose array or string column value includes at least one filter value.\n */\nexport const filterFn_arrIncludes = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n return filterValue.some((val) =>\n (row.getValue<unknown>(columnId) as Array<unknown> | string).includes(\n val as any,\n ),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes every filter value.\n */\nexport const filterFn_arrIncludesAll = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return !filterValue.some((val) => !value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes at least one filter value.\n */\nexport const filterFn_arrIncludesSome = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return filterValue.some((val) => value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n// Export\n\n/**\n * The built-in filter function registry.\n *\n * Pass this object to filtered row model creation or extend it with custom filter functions.\n */\nexport const filterFns = {\n arrIncludes: filterFn_arrIncludes,\n arrIncludesAll: filterFn_arrIncludesAll,\n arrHas: filterFn_arrHas,\n arrIncludesSome: filterFn_arrIncludesSome,\n between: filterFn_between,\n betweenInclusive: filterFn_betweenInclusive,\n equals: filterFn_equals,\n equalsString: filterFn_equalsString,\n inNumberRange: filterFn_inNumberRange,\n includesString: filterFn_includesString,\n includesStringSensitive: filterFn_includesStringSensitive,\n weakEquals: filterFn_weakEquals,\n}\n\nexport type BuiltInFilterFn = keyof typeof filterFns\n\n// Utils\n\nfunction testFalsy(val: any) {\n return val === undefined || val === null || val === ''\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filterFns.js","names":[],"sources":["../../src/fns/filterFns.ts"],"sourcesContent":["import type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n// Basic filters\n\n/**\n * Keeps rows whose column value is strictly equal to the filter value.\n *\n * Uses JavaScript `===` comparison and auto-removes empty filter values.\n */\nexport const filterFn_equals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) === filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose column value is loosely equal to the filter value.\n *\n * Uses JavaScript `==` comparison and auto-removes empty filter values. This is\n * useful for matching string input against numeric row values.\n */\nexport const filterFn_weakEquals = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId) == filterValue\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// String filters\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_includesStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row.getValue(columnId)?.toString().includes(String(filterValue)),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value includes the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_includesString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return Boolean(\n row\n .getValue(columnId)\n ?.toString()\n .toLowerCase()\n .includes(String(filterValue).toLowerCase()),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value equals the filter text.\n *\n * Both values are lowercased before comparison, and empty filter values are\n * auto-removed.\n */\nexport const filterFn_equalsString = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n row.getValue(columnId)?.toString().toLowerCase() ===\n String(filterValue).toLowerCase()\n )\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose stringified column value exactly equals the filter text.\n *\n * Matching is case-sensitive and empty filter values are auto-removed.\n */\nexport const filterFn_equalsStringSensitive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return row.getValue(columnId)?.toString() === String(filterValue)\n },\n { autoRemove: (val: any) => testFalsy(val) },\n)\n\n// Number filters\n\n/**\n * Keeps rows whose value is greater than the filter value.\n *\n * Numeric values are compared numerically when both sides can be coerced to\n * numbers; otherwise normalized strings are compared.\n */\nexport const filterFn_greaterThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n const rowValue = row.getValue(columnId)\n const numericRowValue =\n rowValue === null || rowValue === undefined ? 0 : +rowValue\n const numericFilterValue = Number(filterValue)\n\n if (!isNaN(numericFilterValue) && !isNaN(numericRowValue)) {\n return numericRowValue > numericFilterValue\n }\n\n const stringValue = (rowValue ?? '').toString().toLowerCase().trim()\n const stringFilterValue = String(filterValue).toLowerCase().trim()\n return stringValue > stringFilterValue\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is greater than or equal to the filter value.\n *\n * Delegates to the built-in greater-than and equality comparisons.\n */\nexport const filterFn_greaterThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return (\n filterFn_greaterThan(row, columnId, filterValue) ||\n filterFn_equals(row, columnId, filterValue)\n )\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than the filter value.\n *\n * This is implemented as the inverse of greater-than-or-equal comparison.\n */\nexport const filterFn_lessThan = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThanOrEqualTo(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n/**\n * Keeps rows whose value is less than or equal to the filter value.\n *\n * This is implemented as the inverse of greater-than comparison.\n */\nexport const filterFn_lessThanOrEqualTo = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n ) => {\n return !filterFn_greaterThan(row, columnId, filterValue)\n },\n { resolveFilterValue: (val: any) => testFalsy(val) },\n)\n\n// Range filters\n\n/**\n * Keeps rows whose value falls between an exclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_between = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThan(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThan(row, columnId, filterValues[1])),\n {\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n/**\n * Keeps rows whose value falls between an inclusive min/max pair.\n *\n * Blank range endpoints are treated as open-ended.\n */\nconst filterFn_betweenInclusive = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValues: [unknown, unknown],\n ): boolean =>\n ((['', undefined] as Array<any>).includes(filterValues[0]) ||\n filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) &&\n ((!isNaN(Number(filterValues[0])) &&\n !isNaN(Number(filterValues[1])) &&\n Number(filterValues[0]) > Number(filterValues[1])) ||\n (['', undefined] as Array<any>).includes(filterValues[1]) ||\n filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])),\n {\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n/**\n * Keeps rows whose numeric value is inside an inclusive `[min, max]` range.\n *\n * Filter values are normalized so blank endpoints become open-ended and\n * reversed endpoints are swapped.\n */\nexport const filterFn_inNumberRange = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: [number, number],\n ) => {\n const [min, max] = filterValue\n\n const rowValue: number = row.getValue(columnId)\n return rowValue >= min && rowValue <= max\n },\n {\n resolveFilterValue: (val: [any, any]) => {\n const [unsafeMin, unsafeMax] = val\n\n const parsedMin =\n typeof unsafeMin !== 'number' ? parseFloat(unsafeMin) : unsafeMin\n const parsedMax =\n typeof unsafeMax !== 'number' ? parseFloat(unsafeMax) : unsafeMax\n\n let min =\n unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin\n let max =\n unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax\n\n if (min > max) {\n const temp = min\n min = max\n max = temp\n }\n\n return [min, max] as const\n },\n autoRemove: (val: any) =>\n testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),\n },\n)\n\n// Array filters\n\n/**\n * Keeps rows whose scalar column value equals at least one filter value.\n */\nexport const filterFn_arrHas = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n) => {\n return filterValue.some((val) => row.getValue<unknown>(columnId) === val)\n}\n\n/**\n * Keeps rows whose array or string column value includes at least one filter value.\n */\nexport const filterFn_arrIncludes = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n return filterValue.some((val) =>\n (row.getValue<unknown>(columnId) as Array<unknown> | string).includes(\n val as any,\n ),\n )\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes every filter value.\n */\nexport const filterFn_arrIncludesAll = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return !filterValue.some((val) => !value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n/**\n * Keeps rows whose array column value includes at least one filter value.\n */\nexport const filterFn_arrIncludesSome = Object.assign(\n <TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: Array<unknown>,\n ) => {\n const value = row.getValue<Array<unknown>>(columnId)\n if (!Array.isArray(value)) return false\n return filterValue.some((val) => value.includes(val))\n },\n { autoRemove: (val: any) => testFalsy(val) || !val?.length },\n)\n\n// Export\n\n/**\n * The built-in filter function registry.\n *\n * Pass this object to filtered row model creation or extend it with custom filter functions.\n */\nexport const filterFns = {\n arrIncludes: filterFn_arrIncludes,\n arrIncludesAll: filterFn_arrIncludesAll,\n arrHas: filterFn_arrHas,\n arrIncludesSome: filterFn_arrIncludesSome,\n between: filterFn_between,\n betweenInclusive: filterFn_betweenInclusive,\n equals: filterFn_equals,\n equalsString: filterFn_equalsString,\n inNumberRange: filterFn_inNumberRange,\n includesString: filterFn_includesString,\n includesStringSensitive: filterFn_includesStringSensitive,\n weakEquals: filterFn_weakEquals,\n}\n\nexport type BuiltInFilterFn = keyof typeof filterFns\n\n// Utils\n\nfunction testFalsy(val: any) {\n return val === undefined || val === null || val === ''\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -68,7 +68,9 @@ export function table_reset<
|
|
|
68
68
|
* Merges new table options with the current resolved options.
|
|
69
69
|
*
|
|
70
70
|
* If `options.mergeOptions` is provided, it owns the merge behavior; otherwise
|
|
71
|
-
* options are shallow-merged.
|
|
71
|
+
* options are shallow-merged. Static options that should never change after
|
|
72
|
+
* initialization are restored on a fresh object so framework merge helpers may
|
|
73
|
+
* return readonly getter/proxy objects.
|
|
72
74
|
*
|
|
73
75
|
* @example
|
|
74
76
|
* ```ts
|
|
@@ -82,17 +84,52 @@ export function table_mergeOptions<
|
|
|
82
84
|
table: Table_Internal<TFeatures, TData>,
|
|
83
85
|
newOptions: TableOptions<TFeatures, TData>,
|
|
84
86
|
) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
const { features, atoms, initialState } = table.options
|
|
88
|
+
|
|
89
|
+
// simple merge if no mergeOptions is provided - performant
|
|
90
|
+
if (!table.options.mergeOptions) {
|
|
91
|
+
return {
|
|
92
|
+
...table.options,
|
|
93
|
+
...newOptions,
|
|
94
|
+
features,
|
|
95
|
+
atoms,
|
|
96
|
+
initialState,
|
|
97
|
+
}
|
|
90
98
|
}
|
|
91
99
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
// else use the mergeOptions function and preserve getters/setters
|
|
101
|
+
const mergedOptions = table.options.mergeOptions(
|
|
102
|
+
table.options as TableOptions<TFeatures, TData>,
|
|
103
|
+
newOptions,
|
|
104
|
+
)
|
|
105
|
+
const descriptors: PropertyDescriptorMap = {
|
|
106
|
+
...Object.getOwnPropertyDescriptors(mergedOptions),
|
|
95
107
|
}
|
|
108
|
+
|
|
109
|
+
return Object.defineProperties(
|
|
110
|
+
Object.create(Object.getPrototypeOf(mergedOptions)),
|
|
111
|
+
{
|
|
112
|
+
...descriptors,
|
|
113
|
+
features: {
|
|
114
|
+
value: features,
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
},
|
|
119
|
+
atoms: {
|
|
120
|
+
value: atoms,
|
|
121
|
+
enumerable: true,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: true,
|
|
124
|
+
},
|
|
125
|
+
initialState: {
|
|
126
|
+
value: initialState,
|
|
127
|
+
enumerable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
writable: true,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
) as TableOptions<TFeatures, TData>
|
|
96
133
|
}
|
|
97
134
|
|
|
98
135
|
/**
|
|
@@ -117,15 +154,7 @@ export function table_setOptions<
|
|
|
117
154
|
updater,
|
|
118
155
|
table.options as TableOptions<TFeatures, TData>,
|
|
119
156
|
)
|
|
120
|
-
|
|
121
|
-
const { features, atoms, initialState } = table.options
|
|
122
|
-
const mergedOptions = Object.assign(table_mergeOptions(table, newOptions), {
|
|
123
|
-
// Once the table instance is created those properties should never change after initialization,
|
|
124
|
-
// so we assign them back preserving the `table_mergeOptions` object reference
|
|
125
|
-
features,
|
|
126
|
-
atoms,
|
|
127
|
-
initialState,
|
|
128
|
-
})
|
|
157
|
+
const mergedOptions = table_mergeOptions(table, newOptions)
|
|
129
158
|
|
|
130
159
|
if (table.optionsStore) {
|
|
131
160
|
table.optionsStore.set(() => mergedOptions)
|
package/src/fns/filterFns.ts
CHANGED
|
@@ -217,7 +217,10 @@ const filterFn_between = Object.assign(
|
|
|
217
217
|
Number(filterValues[0]) > Number(filterValues[1])) ||
|
|
218
218
|
(['', undefined] as Array<any>).includes(filterValues[1]) ||
|
|
219
219
|
filterFn_lessThan(row, columnId, filterValues[1])),
|
|
220
|
-
{
|
|
220
|
+
{
|
|
221
|
+
autoRemove: (val: any) =>
|
|
222
|
+
testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),
|
|
223
|
+
},
|
|
221
224
|
)
|
|
222
225
|
|
|
223
226
|
/**
|
|
@@ -238,7 +241,10 @@ const filterFn_betweenInclusive = Object.assign(
|
|
|
238
241
|
Number(filterValues[0]) > Number(filterValues[1])) ||
|
|
239
242
|
(['', undefined] as Array<any>).includes(filterValues[1]) ||
|
|
240
243
|
filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])),
|
|
241
|
-
{
|
|
244
|
+
{
|
|
245
|
+
autoRemove: (val: any) =>
|
|
246
|
+
testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])),
|
|
247
|
+
},
|
|
242
248
|
)
|
|
243
249
|
|
|
244
250
|
/**
|