@rokkit/data 1.0.0-next.94

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/src/parser.js ADDED
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Constructs a regular expression pattern for matching search filter strings.
3
+ * The pattern captures "column", "operator", and "value" groups for filter expressions.
4
+ * Supported operators include common comparison and wildcard operators.
5
+ *
6
+ * Examples of valid expressions this regex can match:
7
+ * - "username:john_doe"
8
+ * - "age>30"
9
+ * - "status!=active"
10
+ * - "title~\"Product Manager\""
11
+ * - "completed!~*yes"
12
+ *
13
+ * The "column" group matches one or more word characters.
14
+ * The "operator" group matches one among the specified comparison or wildcard operators:
15
+ * :, >, <, >=, <=, =<, =>, =, !=, ~, ~*, !~, !~*.
16
+ * The "value" group matches either a double-quoted string or a single unquoted word
17
+ * that doesn't include whitespace or any of the operator characters.
18
+ *
19
+ * @returns {RegExp} - The regular expression pattern to identify search filter elements.
20
+ */
21
+ export function getRegex() {
22
+ const column = '[\\w]+'
23
+ const operator = ':|>|<|>=|<=|=<|=>|=|!=|~|~\\*|!~|!~\\*'
24
+ const value = '("[^"]+"|[^\\s=:<>!~*]+)'
25
+
26
+ const pattern = `(?<group>((?<column>${column})\\s?(?<operator>${operator})\\s?)(?<value>${value}))`
27
+
28
+ return new RegExp(pattern, 'gm')
29
+ }
30
+
31
+ /**
32
+ * Parses a search string and extracts filters based on a predefined regular expression pattern.
33
+ * Each filter captures column, operator, and value components. Any remaining text that
34
+ * does not fit the pattern is considered a general search term.
35
+ *
36
+ * @param {string} string - The search string to parse for filters.
37
+ * @returns {Object[]} - An array of filter objects each containing the column, operator, and value,
38
+ * plus an additional object for general search if there is remaining text.
39
+ */
40
+ export function parseFilters(string) {
41
+ const results = []
42
+ const regex = getRegex()
43
+
44
+ // Split the string into an array of tokens
45
+ const tokens = string.matchAll(regex)
46
+ let search = string
47
+
48
+ // Iterate over the tokens
49
+ for (const token of tokens) {
50
+ // Extract the named groups from the token
51
+ let { group, column, operator, value } = token.groups
52
+ search = search.replace(group, '').trim()
53
+
54
+ operator = replaceOperators(operator)
55
+ value = processValue(value, operator)
56
+
57
+ if (column && value) results.push({ column, operator, value })
58
+ }
59
+
60
+ if (search.length > 0) {
61
+ results.push({
62
+ operator: '~*',
63
+ value: new RegExp(removeQuotes(search), 'i')
64
+ })
65
+ }
66
+
67
+ return results
68
+ }
69
+
70
+ /**
71
+ * Replaces various shorthand operators with their standardized equivalent for filtering.
72
+ *
73
+ * @param {string} operator - The operator to be replaced.
74
+ * @returns {string} - The replaced operator string.
75
+ */
76
+ function replaceOperators(operator) {
77
+ return operator.replace(':', '~*').replace('=>', '>=').replace('=<', '<=')
78
+ }
79
+
80
+ /**
81
+ * Processes the filter value provided, converting it into a format suitable for filtering.
82
+ * If the operator includes a tilde (~), the value is converted to a RegExp.
83
+ *
84
+ * @param {string|number} value - The value to be processed. It could be a string needing quote removal or a number that needs parsing.
85
+ * @param {string} operator - The operator that determines the type of processing to be applied to the value.
86
+ * @returns {string|number|RegExp} - The processed value, which may be a RegExp if the operator involves pattern matching.
87
+ */
88
+ function processValue(value, operator) {
89
+ // If the value can be parsed as an integer, do so. Otherwise, strip quotes if present.
90
+
91
+ value = !isNaN(parseInt(value)) ? parseInt(value) : removeQuotes(value)
92
+ // If the operator includes a tilde (~), treat the value as a regular expression,
93
+ // case-insensitive if '*' is present, sensitive otherwise.
94
+ if (operator.includes('~')) {
95
+ value = operator.includes('*') ? new RegExp(value, 'i') : new RegExp(value)
96
+ }
97
+
98
+ return value
99
+ }
100
+
101
+ /**
102
+ * Removes double quotes from the start and end of a string.
103
+ *
104
+ * @param {string} str - The input string from which the surrounding quotes should be removed.
105
+ * @returns {string} - The unquoted string.
106
+ */
107
+ function removeQuotes(str) {
108
+ const quoteMatch = str.match(/^"([^"]+)"$/)
109
+ return quoteMatch ? quoteMatch[1] : str
110
+ }
package/src/renamer.js ADDED
@@ -0,0 +1,98 @@
1
+ import { omit, identity } from 'ramda'
2
+
3
+ /**
4
+ *
5
+ *
6
+ * @typedef {Object} OptionsToRenameKeys
7
+ * @property {string} [prefix] - The prefix to add to the key.
8
+ * @property {string} [suffix] - The suffix to add to the key.
9
+ * @property {string} [separator='_'] - The separator to use between the key and the prefix or suffix.
10
+ * @property {Array} [keys] - The keys to rename.
11
+ */
12
+
13
+ /**
14
+ * A generator function that produces a function to rename keys.
15
+ *
16
+ * @param {OptionsToRenameKeys} options - Options to rename keys
17
+ * @returns {Object} - A renamer object.
18
+ *
19
+ * Example:
20
+ *
21
+ * renamer({ prefix: 'a', keys: ['a', 'b'] }).get()
22
+ * renamer({ prefix: 'a', separator: '-' }).get()
23
+ * renamer().setPrefix('a')
24
+ * .setSeparator('-')
25
+ * .setKeys(['a', 'b'])
26
+ * .get()
27
+ * renamer().setPrefix('a').get()
28
+ * renamer().setSuffix('b').get()
29
+ * renamer().setKeys(['a', 'b']).get()
30
+ */
31
+ export function renamer(options = {}) {
32
+ const { prefix, suffix, separator = '_', keys = [] } = options
33
+ const rename = getRenamer(prefix, suffix, separator)
34
+ const renameObject = getObjectRenamer(rename, keys)
35
+
36
+ return {
37
+ get: () => ({ rename, renameObject }),
38
+ setPrefix: (value) => renamer({ ...omit(['suffix'], options), prefix: value }),
39
+ setSuffix: (value) => renamer({ ...omit(['prefix'], options), suffix: value }),
40
+ setKeys: (value) => renamer({ ...options, keys: value }),
41
+ setSeparator: (value) => renamer({ ...options, separator: value })
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Generates a renamer function which adds a prefix or suffix to a string.
47
+ *
48
+ * @param {string} prefix - The prefix to add to the key.
49
+ * @param {string} suffix - The suffix to add to the key.
50
+ * @param {string} separator - The separator to use between the key and the prefix or suffix.
51
+ * @returns {Function} - A function that takes a string and adds a prefix or suffix.
52
+ */
53
+ function getRenamer(prefix, suffix, separator) {
54
+ let rename = identity
55
+
56
+ if (prefix) {
57
+ rename = (x) => [prefix, x].join(separator)
58
+ } else if (suffix) {
59
+ rename = (x) => [x, suffix].join(separator)
60
+ }
61
+ return rename
62
+ }
63
+
64
+ /**
65
+ * Returns a function that renames the keys of an object.
66
+ *
67
+ * @param {Function} rename - The function to rename the keys.
68
+ * @param {Array} keys - The keys to rename.
69
+ * @returns {Function} - A function that takes an object and renames the keys.
70
+ */
71
+ function getObjectRenamer(rename, keys) {
72
+ if (rename === identity) return identity
73
+ if (keys.length > 0) {
74
+ const lookup = keys.reduce((acc, key) => ({ ...acc, [key]: rename(key) }), {})
75
+ return usingLookup(lookup)
76
+ }
77
+ return forObject(rename)
78
+ }
79
+
80
+ /**
81
+ * Renames the keys of an object using a lookup table.
82
+ *
83
+ * @param {Object} lookup - The lookup table.
84
+ * @returns {Function} - A function that takes an object and renames the keys using the lookup table.
85
+ */
86
+ function usingLookup(lookup) {
87
+ return (row) => Object.keys(row).reduce((acc, key) => ({ ...acc, [lookup[key]]: row[key] }), {})
88
+ }
89
+
90
+ /**
91
+ * Renames the keys of an object using a function.
92
+ *
93
+ * @param {Function} rename - The function to rename the keys.
94
+ * @returns {Function} - A function that takes an object and renames the keys using the function.
95
+ */
96
+ function forObject(rename) {
97
+ return (row) => Object.keys(row).reduce((acc, key) => ({ ...acc, [rename(key)]: row[key] }), {})
98
+ }
package/src/rollup.js ADDED
@@ -0,0 +1,138 @@
1
+ import { omit, pick, mergeLeft, map, difference, uniq, pipe } from 'ramda'
2
+
3
+ /**
4
+ * Groups data by specified keys.
5
+ *
6
+ * @param {Array} data - An array of data points.
7
+ * @param {Array} groupByKeys - Keys to group the data by.
8
+ * @param {Array} summaries - An array of summary objects to define aggregation operations.
9
+ * @returns {Object} Grouped data object with aggregation placeholders.
10
+ */
11
+ export function groupDataByKeys(data, groupByKeys, summaries) {
12
+ const keysExtractor = pick(groupByKeys)
13
+ const groupedData = data.reduce((grouped, row) => {
14
+ const key = JSON.stringify(keysExtractor(row))
15
+ if (!grouped[key]) {
16
+ grouped[key] = { ...keysExtractor(row), ...initialValues(summaries) }
17
+ }
18
+ addToSummaries(grouped[key], row, summaries)
19
+ return grouped
20
+ }, {})
21
+
22
+ return Object.values(groupedData)
23
+ }
24
+
25
+ /**
26
+ * Sets initial values for summaries.
27
+ *
28
+ * @param {Array} summaries - An array of summary objects.
29
+ * @returns {Object} An object with keys for each summary initialized to empty arrays.
30
+ */
31
+ export function initialValues(summaries) {
32
+ const fields = summaries.map(({ reducers }) => reducers.map((r) => r.field)).flat()
33
+ return fields.reduce((acc, name) => ({ ...acc, [name]: [] }), {})
34
+ }
35
+
36
+ /**
37
+ * Adds data to summary aggregation arrays.
38
+ *
39
+ * @param {Object} group - The group object to add data to.
40
+ * @param {Object} row - The data row being processed.
41
+ * @param {Array} summaries - An array of summary objects.
42
+ */
43
+ export function addToSummaries(group, row, summaries) {
44
+ summaries.forEach(({ mapper, reducers }) => {
45
+ const value = mapper(row)
46
+ reducers.forEach((r) => {
47
+ group[r.field].push(value)
48
+ })
49
+ })
50
+ }
51
+
52
+ /**
53
+ * Fills grouped data with aligned data if specified in configuration.
54
+ *
55
+ * @param {Object} groupedData - The grouped data object.
56
+ * @param {Object} config - Configuration object containing alignment settings.
57
+ * @returns {Array} Aligned data array.
58
+ */
59
+ export function fillAlignedData(groupedData, config, fillRowsFunc) {
60
+ // const fillRowsFunc = getAlignGenerator(df.data, config)
61
+ const { actual_flag, children } = config
62
+ return Object.values(groupedData).map((row) => ({
63
+ ...row,
64
+ [children]: [
65
+ ...row[children].map((value) => ({ ...value, [actual_flag]: 1 })),
66
+ ...fillRowsFunc(row[children])
67
+ ]
68
+ }))
69
+ }
70
+
71
+ /**
72
+ * Performs aggregation operations on grouped data.
73
+ *
74
+ * @param {Array} dataArray - An array of grouped data with aggregation arrays.
75
+ * @param {Array} summaries - An array of summary objects with reducer functions.
76
+ * @returns {Array} Aggregated data array with computed summary values.
77
+ */
78
+ export function aggregateData(dataArray, summaries) {
79
+ const fields = summaries.map(({ name, reducers }) => reducers.map((r) => ({ name, ...r }))).flat()
80
+ return dataArray.map((row) => ({
81
+ ...row,
82
+ ...fields.reduce(
83
+ (acc, { field, formula }) => ({
84
+ ...acc,
85
+ [field]: formula(row[field])
86
+ }),
87
+ {}
88
+ )
89
+ }))
90
+ }
91
+
92
+ /**
93
+ * Creates a generator that produces missing rows in a dataset based on specified columns.
94
+ * The function determines all unique combinations of the specified columns in config.align_by
95
+ * and returns a generator function to create the missing combinations, potentially with default
96
+ * values for other columns.
97
+ * @param {Array<Object>} data - The array of objects representing the dataset.
98
+ * @param {Object} config - The configuration object.
99
+ *
100
+ * @returns {Function} A generator function that when called, produces the missing rows.
101
+ */
102
+ export function getAlignGenerator(data, config) {
103
+ const { align_by, group_by, actual_flag } = config
104
+ const template = { ...omit([...align_by, ...group_by], config.template), [actual_flag]: 0 }
105
+ const subset = pipe(map(pick(align_by)), uniq)(data)
106
+
107
+ return pipe(map(pick(align_by)), uniq, difference(subset), map(mergeLeft(template)))
108
+ }
109
+
110
+ /**
111
+ * Returns an aggregator object with a mapper and reducer function.
112
+ *
113
+ * @param {Array<string>} from - The key or keys to aggregate.
114
+ * @param {Function} using - The aggregation function.
115
+ * @returns {import('./types').SummaryConfig} - An object with a mapper and reducer function.
116
+ */
117
+ // export function getAggregator(from, into, using = identity) {
118
+ // // const mapper = pick(Array.isArray ? from : [from])
119
+ // return {
120
+ // mapper: pick(from),
121
+ // reducers: [{ field: into, formula: using }]
122
+ // }
123
+ // }
124
+
125
+ /**
126
+ * Returns the default aggregator which rolls up the columns other than the group_by columns into a single object.
127
+ *
128
+ * @param {import('./types').Metadata} metadata - The metadata for the columns to be aggregated.
129
+ * @param {Object} config - The configuration used to build the aggregator.
130
+ *
131
+ * @returns {Object} An object containing the default aggregator for the specified metadata and configuration.
132
+ */
133
+ // export function defaultAggregator(metadata, config) {
134
+ // const child = metadata.filter((col) => !config.group_by.includes(col.name))
135
+ // const keys = child.map((col) => col.name)
136
+
137
+ // return { ...getAggregator(keys, config.children), metadata: child }
138
+ // }
package/src/types.js ADDED
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Options for the sort order of the column.
3
+ *
4
+ * @typedef {'ascending'|'descending'|'none'} SortOptions
5
+ */
6
+
7
+ /**
8
+ * Options for aligning text in a column.
9
+ * @typedef {'left'|'center'|'right'|'justify'} HorizontalAlignOptions
10
+ */
11
+
12
+ /**
13
+ * Options for the action type of the column.
14
+ * @typedef {'edit'|'delete'|'select'} ActionTypes
15
+ */
16
+
17
+ /**
18
+ * @typedef {'checked'|'unchecked'|'indeterminate'} SelectionState
19
+ */
20
+
21
+ /**
22
+ * @typedef {string|[string,boolean]|ColumnSorter} SortableColumn
23
+ */
24
+
25
+ /**
26
+ * @typedef {Object} ColumnSorter
27
+ * @property {string} name
28
+ * @property {function} sorter
29
+ */
30
+
31
+ /**
32
+ * @typedef {Object} ColumnAggregator
33
+ * @property {string} name
34
+ * @property {function} aggregator
35
+ * @property {string} suffix
36
+ */
37
+
38
+ /**
39
+ * Options for joining two data sets
40
+ *
41
+ * @typedef OptionsToRenameKeys
42
+ * @property {string} [prefix] - Prefix to be added to each attribute
43
+ * @property {string} [suffix] - Suffix to be added to each attribute
44
+ * @property {string} [separator='_'] - Separator to be used when adding prefix or suffix. defaults to _
45
+ */
46
+
47
+ /**
48
+ * Structure to map custom fields for rendering. This is used to identofy the attributes for various purposes.
49
+ *
50
+ * @typedef FieldMapping
51
+ * @property {string} [id='id'] Unique id for the item
52
+ * @property {string} [text='text'] the text to render
53
+ * @property {string} [value='value'] the value associated with the item
54
+ * @property {string} [url='url'] a URL
55
+ * @property {string} [icon='icon'] icon to render
56
+ * @property {string} [image='image'] the image to render
57
+ * @property {string} [children='children'] children of the item
58
+ * @property {string} [summary='summary'] summary of the item
59
+ * @property {string} [notes='notes'] notes for the item
60
+ * @property {string} [props='props'] additional properties
61
+ * @property {string} [isOpen='_open'] item is open or closed
62
+ * @property {string} [level='level'] level of item
63
+ * @property {string} [parent='parent'] item is a parent
64
+ * @property {string} [currency='currency] column specifying currency to be used for the current value
65
+ * @property {string} [isDeleted='_deleted'] item is deleted
66
+ * @property {FieldMapping} [fields] Field mapping to be used on children in the next level
67
+ */
68
+
69
+ /**
70
+ * Column metadata for the table.
71
+ *
72
+ * @typedef {Object} ColumnMetadata
73
+ *
74
+ * @property {string} name - The name of the column.
75
+ * @property {string} type - The data type of the column (e.g., "string", "number", "date").
76
+ * @property {FieldMapping} [field] - The field mapping for the column.
77
+ * @property {number} [digits=0] - The number of digits for numeric values (defaults to 0).
78
+ * @property {Function} formatter - A function to format the column value.
79
+ * @property {boolean} [sortable] - Indicates if the column is sortable (true/false).
80
+ * @property {SortOptions} [sortOrder] - The sort order of the column.
81
+ * @property {HorizontalAlignOptions} [align] - The alignment of the column content.
82
+ * @property {ActionTypes} [action] - Action attribute for action columns.
83
+ */
84
+
85
+ /**
86
+ * @typedef {Array<ColumnMetadata>} Metadata
87
+ */
88
+
89
+ /**
90
+ * @typedef {Object<string,number} ColumnIndexMap
91
+ */
92
+
93
+ /**
94
+ * Track the state of a row in the table.
95
+ *
96
+ * @typedef {Object} TreeTableNode
97
+ * @property {number} row - Reference to actual row in the data.
98
+ * @property {number} depth - The depth of the node in the hierarchy.
99
+ * @property {string} [value] - The value of the hierarchy node.
100
+ * @property {boolean} [isHidden] - Indicates whether the node is visible (true/false).
101
+ * @property {boolean} [isParent] - Indicates if this node is a parent (true/false).
102
+ * @property {boolean} [isExpanded] - Indicates whether the node is expanded (true/false).
103
+ * @property {number} [parent] - Reference to the parent node in the flat list.
104
+ * @property {SelectionState} [selected] - Indicates whether the node is selected (true/false/indeterminate).
105
+ * @property {Array<any>} children - Reference to the children nodes in the flat list.
106
+ */
107
+
108
+ /**
109
+ * Track the state of all rows in the table.
110
+ *
111
+ * @typedef {Object} TreeTable
112
+ * @property {TreeTableNode[]} rows - Flat list of hierarchy nodes.
113
+ */
114
+
115
+ /**
116
+ * @typedef {Object} OverrideConfig
117
+ * @property {string} actual_flag - the field used for identifying filler rows in the data
118
+ * @property {string} children - the field used for collecting children of a node in rollup
119
+ */
120
+
121
+ /**
122
+ * @typedef {Object} ReducerConfig
123
+ * @property {string} field - The target field to hold the reduced value
124
+ * @property {Function} using - The function to use for reducing the data
125
+ */
126
+
127
+ /**
128
+ * @typedef {Object} SummaryConfig
129
+ * @property {Function} mapper - A function used to collect the data for the summary
130
+ * @property {Array<ReducerConfig} reducers - Array of reducer configurations
131
+ * @property {Metadata} [metadata] - Array of column metadata for the summary
132
+ */
133
+
134
+ /**
135
+ * @typedef {Object} DataFrameConfig
136
+ * @property {Array<string>} group_by=[] - The columns to group by.
137
+ * @property {Array<string>} align_by=[] - The columns to be aligned during rollup.
138
+ * @property {Array<SummaryConfig>} summaries=[] - Array of summary configurations.
139
+ * @property {any} template={} - Template row to be used for filling in missing rows.
140
+ * @extends OverrideConfig
141
+ */
142
+
143
+ /**
144
+ * @typedef {Function} SortBy
145
+ * @description Sort the DataFrame by the specified columns.
146
+ * @param {SortableColumn} columns - The columns to sort by.
147
+ * @returns {DataFrame} - The sorted DataFrame.
148
+ */
149
+
150
+ /**
151
+ * DataFrame-like object with data manipulation methods.
152
+ *
153
+ * @typedef {Object} DataFrame
154
+ * @property {Array<Object>} data - Array of objects representing the rows of data.
155
+ * @property {Metadata} metadata - Array of column metadata for the data.
156
+ * @property {DataFrameConfig} config - Configuration options for the DataFrame.
157
+ * @property {ColumnIndexMap} columns - A map of column names to their index in the metadata.
158
+ * @property {function(OverrideConfig):DataFrame} override - Method to override the configuration of the DataFrame.
159
+ * @property {function(...string):DataFrame} groupBy - Method to group the DataFrame by specified columns.
160
+ * @property {function(function(any)):DataFrame} where - Sets the filter function for the DataFrame
161
+ * @property {function():DataFrame} align - Method to align the DataFrame.
162
+ * @property {function():DataFrame} using - set the template to be used for filling in missing rows.
163
+ * @property {function():DataFrame} summarize - add a summarizer to be used during rollup
164
+ * @property {function(...SortableColumn):DataFrame} sortBy - Method to sort the DataFrame by specified columns.
165
+ * @property {function():DataFrame} join - perform join with another DataFrame returning a new DataFrmae. Defaults to innerJoin, other join types can be specified.
166
+ * @property {function():DataFrame} innerJoin - perform an ineer join with another DataFrame and return a new DataFrame.
167
+ * @property {function():DataFrame} leftJoin - perform a left join with another DataFrame and return a new DataFrame.
168
+ * @property {function():DataFrame} rightJoin - perform a right join with another DataFrame returning a new DataFrame.
169
+ * @property {function():DataFrame} fullJoin - perform a full join with another DataFrame returning a new DataFrame.
170
+ * @property {function():DataFrame} nestedJoin - perform a nested join with another DataFrame returning a new DataFrame.
171
+ * @property {function():DataFrame} rename - Method to rename the columns of the DataFrame.
172
+ * @property {function():DataFrame} drop - Method to drop the columns of the DataFrame.
173
+ * @property {function():DataFrame} delete - Method to delete the rows of the DataFrame.
174
+ * @property {function():DataFrame} update - Method to update the rows of the DataFrame.
175
+ * @property {function():DataFrame} union - Method to combine the rows of the DataFrame with another DataFrame.
176
+ * @property {function():DataFrame} minus - Method to remove the rows of the DataFrame which are present in another DataFrame.
177
+ * @property {function():DataFrame} intersect - Method to keep the rows of the DataFrame which are present in another DataFrame.
178
+ * @property {function():DataFrame} rollup - Method to rollup the DataFrame.
179
+ * @property {function():Arrat<Object>} select - Method to select the columns of the DataFrame.
180
+
181
+ */
182
+
183
+ /**
184
+ * @typedef {inner|outer|full|nested} JoinType
185
+ */
186
+ /**
187
+ * Options for joining two data sets
188
+ *
189
+ * @typedef JoinOptions
190
+ * @property {boolean} [inner] - Flag indicating inner join
191
+ * @property {JoinType} [type='inner] - The join type to use (inner, outer, full, nested).
192
+ * @property {string} [prefix] - prefix to be used for renaming keys in the second data set.
193
+ * @property {string} [suffix] - suffix to be used for renaming keys in the second data set.
194
+ * @property {string} [separator='_'] - separator to be used for renaming keys in the second data set.
195
+ */
196
+
197
+ /**
198
+ * DataView
199
+ * @typedef {Object} DataView
200
+ * @property {TreeTable} hierarchy - The state of the rows in the table.
201
+ * @property {Metadata} columns - The metadata for the columns in the table.
202
+ * @property {Function} sortBy - Sort the DataView by the specified columns.
203
+ * @property {Function} clearSort - Clear the sorting of the DataView.
204
+ * @property {Function} filter - Filter the DataView by the specified columns.
205
+ * @property {Function} toggle - toggle expand or collapse the DataView by the specified columns.
206
+ * @property {Function} select - select the DataView by the specified columns.
207
+ */
208
+ export {}
package/src/utils.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Check if a value is a date string
3
+ * @param {string} value
4
+ * @returns {boolean}
5
+ */
6
+ function isDateString(value) {
7
+ return !isNaN(Date.parse(value))
8
+ }
9
+
10
+ /**
11
+ * Infer the type of a value as array, date or the default type
12
+ * @param {any} value
13
+ * @returns {string}
14
+ */
15
+ function inferArrayAndDateTypes(value) {
16
+ if (Array.isArray(value)) return 'array'
17
+ if (value instanceof Date) return 'date'
18
+
19
+ return typeof value
20
+ }
21
+ /**
22
+ * Derive the type of a value
23
+ * @param {any} value
24
+ * @returns {string}
25
+ */
26
+ export function getType(value) {
27
+ const type = inferArrayAndDateTypes(value)
28
+ if (type === 'string' && isDateString(value)) return 'date'
29
+ if (type === 'number' && Number.isInteger(value)) return 'integer'
30
+ return type
31
+ }