From 4d3307285b8ba7b61d12709228a1b8f1d21605a5 Mon Sep 17 00:00:00 2001 From: Natan Muntean Date: Thu, 14 Mar 2024 14:52:27 +0200 Subject: [PATCH 1/3] type changes for column table --- package-lock.json | 4 +-- src/op/window-functions.js | 8 ++--- src/query/query.js | 1 + src/query/verb.js | 7 ++-- src/table/bit-set.js | 2 +- src/table/column-table.js | 6 ++-- src/table/table.js | 7 ++-- src/table/transformable.js | 68 +++++++++++++++++++------------------- 8 files changed, 53 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b219a06..7275e9eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "arquero", - "version": "5.3.0", + "version": "5.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "arquero", - "version": "5.3.0", + "version": "5.4.0", "license": "BSD-3-Clause", "dependencies": { "acorn": "^8.11.2", diff --git a/src/op/window-functions.js b/src/op/window-functions.js index 833a9b47..2a89dd71 100644 --- a/src/op/window-functions.js +++ b/src/op/window-functions.js @@ -12,15 +12,15 @@ import NULL from '../util/null'; /** * Retrieve an output value from a window operator. * @callback WindowValue - * @param {WindowState} state The window state object. + * @param {import('../engine/window/window-state').WindowState} state The window state object. * @return {*} The output value. */ /** * An operator instance for a window function. * @typedef {object} WindowOperator - * @property {AggregateInit} init Initialize the operator. - * @property {AggregateValue} value Retrieve an output value. + * @property {import('./aggregate-functions').AggregateInit} init Initialize the operator. + * @property {import('./aggregate-functions').AggregateValue} value Retrieve an output value. */ /** @@ -33,7 +33,7 @@ import NULL from '../util/null'; /** * An operator definition for a window function. * @typedef {object} WindowDef - * @property {AggregateCreate} create Create a new operator instance. + * @property {import('./aggregate-functions').AggregateCreate} create Create a new operator instance. * @property {number[]} param Two-element array containing the * counts of input fields and additional parameters. */ diff --git a/src/query/query.js b/src/query/query.js index 9222afb5..2188429c 100644 --- a/src/query/query.js +++ b/src/query/query.js @@ -1,3 +1,4 @@ +import Table from '../table/table'; import Transformable from '../table/transformable'; import { Query as QueryType } from './constants'; import { Verb, Verbs } from './verb'; diff --git a/src/query/verb.js b/src/query/verb.js index 3fd167bd..68574b90 100644 --- a/src/query/verb.js +++ b/src/query/verb.js @@ -24,6 +24,7 @@ import { } from './constants'; import toAST from './to-ast'; +import Table from '../table/table'; /** * Model an Arquero verb as a serializable object. @@ -177,9 +178,9 @@ export const Verbs = { select: createVerb('select', [ { name: 'columns', type: SelectionList } ]), - ungroup: createVerb('ungroup'), - unorder: createVerb('unorder'), - reify: createVerb('reify'), + ungroup: createVerb('ungroup', []), + unorder: createVerb('unorder', []), + reify: createVerb('reify', []), dedupe: createVerb('dedupe', [ { name: 'keys', type: ExprList, default: [] } ]), diff --git a/src/table/bit-set.js b/src/table/bit-set.js index 71d6823e..c377262c 100644 --- a/src/table/bit-set.js +++ b/src/table/bit-set.js @@ -107,7 +107,7 @@ export default class BitSet { /** * Negate all bits in this bitset. * Modifies this BitSet in place. - * @return {this} + * @return {BitSet} */ not() { const bits = this._bits; diff --git a/src/table/column-table.js b/src/table/column-table.js index d78eaf81..fc63c3d0 100644 --- a/src/table/column-table.js +++ b/src/table/column-table.js @@ -78,7 +78,7 @@ export default class ColumnTable extends Table { * The new table may have different data, filter, grouping, or ordering * based on the values of the optional configuration argument. If a * setting is not specified, it is inherited from the current table. - * @param {CreateOptions} [options] Creation options for the new table. + * @param {import('./table').CreateOptions} [options] Creation options for the new table. * @return {ColumnTable} A newly created table. */ create({ data, names, filter, groups, order }) { @@ -148,7 +148,7 @@ export default class ColumnTable extends Table { * @param {string} name The column name. * @param {ArrayConstructor|import('./table').TypedArrayConstructor} [constructor=Array] * The array constructor for instantiating the output array. - * @return {import('./table').DataValue[]|import('./table).TypedArray} The array of column values. + * @return {import('./table').DataValue[]|import('./table').TypedArray} The array of column values. */ array(name, constructor = Array) { const column = this.column(name); @@ -197,7 +197,7 @@ export default class ColumnTable extends Table { /** * Returns an array of objects representing table rows. - * @param {ObjectsOptions} [options] The options for row object generation. + * @param {import('./table').ObjectsOptions} [options] The options for row object generation. * @return {object[]} An array of row objects. */ objects(options = {}) { diff --git a/src/table/table.js b/src/table/table.js index 88ef5ac8..8554d48f 100644 --- a/src/table/table.js +++ b/src/table/table.js @@ -2,6 +2,7 @@ import Transformable from './transformable'; import error from '../util/error'; import isNumber from '../util/is-number'; import repeat from '../util/repeat'; +import Reducer from '../engine/reduce/reducer'; /** * Abstract class representing a data table. @@ -35,7 +36,7 @@ export default class Table extends Transformable { * based on the values of the optional configuration argument. If a * setting is not specified, it is inherited from the current table. * @param {CreateOptions} [options] Creation options for the new table. - * @return {this} A newly created table. + * @return {Table} A newly created table. */ create(options) { // eslint-disable-line no-unused-vars error('Not implemented'); @@ -274,7 +275,7 @@ export default class Table extends Transformable { * @param {PrintOptions|number} options The options for row object * generation, determining which rows and columns are printed. If * number-valued, specifies the row limit. - * @return {this} The table instance. + * @return {Table} The table instance. */ print(options = {}) { if (isNumber(options)) { @@ -461,7 +462,7 @@ export default class Table extends Transformable { * @param {number} [end] Zero-based index before which to end extraction. * A negative index indicates an offset from the end of the group. * If end is omitted, slice extracts through the end of the group. - * @return {this} A new table with sliced rows. + * @return {Table} A new table with sliced rows. * @example table.slice(1, -1) */ slice(start = 0, end = Infinity) { diff --git a/src/table/transformable.js b/src/table/transformable.js index 488cbf70..23624011 100644 --- a/src/table/transformable.js +++ b/src/table/transformable.js @@ -21,7 +21,7 @@ export default class Transformable { * table's parameter set and returns the table. Any prior parameters * with names matching the input parameters are overridden. * @param {Params} [values] The parameter values. - * @return {this|Params} The current parameters values (if called with + * @return {Transformable|Params} The current parameters values (if called with * no arguments) or this table. */ params(values) { @@ -41,7 +41,7 @@ export default class Transformable { * Instead, the backing data itself is filtered and ordered as needed. * @param {number[]} [indices] Ordered row indices to materialize. * If unspecified, all rows passing the table filter are used. - * @return {this} A reified table. + * @return {Transformable} A reified table. */ reify(indices) { return this.__reify(this, indices); @@ -53,7 +53,7 @@ export default class Transformable { * Count the number of values in a group. This method is a shorthand * for {@link Transformable#rollup} with a count aggregate function. * @param {CountOptions} [options] Options for the count. - * @return {this} A new table with groupby and count columns. + * @return {Transformable} A new table with groupby and count columns. * @example table.groupby('colA').count() * @example table.groupby('colA').count({ as: 'num' }) */ @@ -73,7 +73,7 @@ export default class Transformable { * where to place derived columns. Specifying both before and after is an * error. Unlike the relocate verb, this option affects only new columns; * updated columns with existing names are excluded from relocation. - * @return {this} A new table with derived columns added. + * @return {Transformable} A new table with derived columns added. * @example table.derive({ sumXY: d => d.x + d.y }) * @example table.derive({ z: d => d.x * d.y }, { before: 'x' }) */ @@ -89,7 +89,7 @@ export default class Transformable { * @param {TableExpr} criteria Filter criteria as a table expression. * Both aggregate and window functions are permitted, taking into account * {@link Transformable#groupby} or {@link Transformable#orderby} settings. - * @return {this} A new table with filtered rows. + * @return {Transformable} A new table with filtered rows. * @example table.filter(d => abs(d.value) < 5) */ filter(criteria) { @@ -105,7 +105,7 @@ export default class Transformable { * @param {number} [end] Zero-based index before which to end extraction. * A negative index indicates an offset from the end of the group. * If end is omitted, slice extracts through the end of the group. - * @return {this} A new table with sliced rows. + * @return {Transformable} A new table with sliced rows. * @example table.slice(1, -1) */ slice(start, end) { @@ -121,7 +121,7 @@ export default class Transformable { * The keys may be specified using column name strings, column index * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. - * @return {this} A new table with grouped rows. + * @return {Transformable} A new table with grouped rows. * @example table.groupby('colA', 'colB') * @example table.groupby({ key: d => d.colA + d.colB }) */ @@ -148,7 +148,7 @@ export default class Transformable { * with output column names for keys and table expressions * for values (the output names will be ignored). * If an array, array values must be valid key parameters. - * @return {this} A new ordered table. + * @return {Transformable} A new ordered table. * @example table.orderby('a', desc('b')) * @example table.orderby({ a: 'a', b: desc('b') )}) * @example table.orderby(desc(d => d.a)) @@ -169,7 +169,7 @@ export default class Transformable { * @param {RelocateOptions} options Options for relocating. Must include * either the before or after property to indicate where to place the * relocated columns. Specifying both before and after is an error. - * @return {this} A new table with relocated columns. + * @return {Transformable} A new table with relocated columns. * @example table.relocate(['colY', 'colZ'], { after: 'colX' }) * @example table.relocate(not('colB', 'colC'), { before: 'colA' }) * @example table.relocate({ colA: 'newA', colB: 'newB' }, { after: 'colC' }) @@ -182,7 +182,7 @@ export default class Transformable { * Rename one or more columns, preserving column order. * @param {...Select} columns One or more rename objects with current * column names as keys and new column names as values. - * @return {this} A new table with renamed columns. + * @return {Transformable} A new table with renamed columns. * @example table.rename({ oldName: 'newName' }) * @example table.rename({ a: 'a2', b: 'b2' }) */ @@ -199,7 +199,7 @@ export default class Transformable { * keys and table expressions for values. The expressions must be valid * aggregate expressions: window functions are not allowed and column * references must be arguments to aggregate functions. - * @return {this} A new table of aggregate summary values. + * @return {Transformable} A new table of aggregate summary values. * @example table.groupby('colA').rollup({ mean: d => mean(d.colB) }) * @example table.groupby('colA').rollup({ mean: op.median('colB') }) */ @@ -216,7 +216,7 @@ export default class Transformable { * If function-valued, the input should be an aggregate table * expression compatible with {@link Transformable#rollup}. * @param {SampleOptions} [options] Options for sampling. - * @return {this} A new table with sampled rows. + * @return {Transformable} A new table with sampled rows. * @example table.sample(50) * @example table.sample(100, { replace: true }) * @example table.groupby('colA').sample(() => op.floor(0.5 * op.count())) @@ -233,7 +233,7 @@ export default class Transformable { * as values, or functions that take a table as input and returns a valid * selection parameter (typically the output of selection helper functions * such as {@link all}, {@link not}, or {@link range}). - * @return {this} A new table of selected columns. + * @return {Transformable} A new table of selected columns. * @example table.select('colA', 'colB') * @example table.select(not('colB', 'colC')) * @example table.select({ colA: 'newA', colB: 'newB' }) @@ -245,7 +245,7 @@ export default class Transformable { /** * Ungroup a table, removing any grouping criteria. * Undoes the effects of {@link Transformable#groupby}. - * @return {this} A new ungrouped table, or this table if not grouped. + * @return {Transformable} A new ungrouped table, or this table if not grouped. * @example table.ungroup() */ ungroup() { @@ -255,7 +255,7 @@ export default class Transformable { /** * Unorder a table, removing any sorting criteria. * Undoes the effects of {@link Transformable#orderby}. - * @return {this} A new unordered table, or this table if not ordered. + * @return {Transformable} A new unordered table, or this table if not ordered. * @example table.unorder() */ unorder() { @@ -272,7 +272,7 @@ export default class Transformable { * The keys may be specified using column name strings, column index * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. - * @return {this} A new de-duplicated table. + * @return {Transformable} A new de-duplicated table. * @example table.dedupe() * @example table.dedupe('a', 'b') * @example table.dedupe({ abs: d => op.abs(d.a) }) @@ -303,7 +303,7 @@ export default class Transformable { * missing rows. All combinations of expanded values are considered, and * new rows are added for each combination that does not appear in the * input table. - * @return {this} A new table with imputed values and/or rows. + * @return {Transformable} A new table with imputed values and/or rows. * @example table.impute({ v: () => 0 }) * @example table.impute({ v: d => op.mean(d.v) }) * @example table.impute({ v: () => 0 }, { expand: ['x', 'y'] }) @@ -326,7 +326,7 @@ export default class Transformable { * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. * @param {FoldOptions} [options] Options for folding. - * @return {this} A new folded table. + * @return {Transformable} A new folded table. * @example table.fold('colA') * @example table.fold(['colA', 'colB']) * @example table.fold(range(5, 8)) @@ -354,7 +354,7 @@ export default class Transformable { * If object-valued, the input object should have output value * names for keys and aggregate table expressions for values. * @param {PivotOptions} [options] Options for pivoting. - * @return {this} A new pivoted table. + * @return {Transformable} A new pivoted table. * @example table.pivot('key', 'value') * @example table.pivot(['keyA', 'keyB'], ['valueA', 'valueB']) * @example table.pivot({ key: d => d.key }, { value: d => sum(d.value) }) @@ -371,7 +371,7 @@ export default class Transformable { * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. * @param {SpreadOptions} [options] Options for spreading. - * @return {this} A new table with the spread columns added. + * @return {Transformable} A new table with the spread columns added. * @example table.spread({ a: split(d.text, '') }) * @example table.spread('arrayCol', { limit: 100 }) */ @@ -389,7 +389,7 @@ export default class Transformable { * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. * @param {UnrollOptions} [options] Options for unrolling. - * @return {this} A new unrolled table. + * @return {Transformable} A new unrolled table. * @example table.unroll('colA', { limit: 1000 }) */ unroll(values, options) { @@ -411,7 +411,7 @@ export default class Transformable { * @param {...ExprList} values The column values to add from the * secondary table. Can be column name strings or objects with column * names as keys and table expressions as values. - * @return {this} A new table with lookup values added. + * @return {Transformable} A new table with lookup values added. * @example table.lookup(other, ['key1', 'key2'], 'value1', 'value2') */ lookup(other, on, ...values) { @@ -451,7 +451,7 @@ export default class Transformable { * If object-valued, specifies the key-value pairs for each output, * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. - * @return {this} A new joined table. + * @return {Transformable} A new joined table. * @example table.join(other, ['keyL', 'keyR']) * @example table.join(other, (a, b) => equal(a.keyL, b.keyR)) */ @@ -488,7 +488,7 @@ export default class Transformable { * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. With this method, * any options will be overridden with {left: true, right: false}. - * @return {this} A new joined table. + * @return {Transformable} A new joined table. * @example table.join_left(other, ['keyL', 'keyR']) * @example table.join_left(other, (a, b) => equal(a.keyL, b.keyR)) */ @@ -526,7 +526,7 @@ export default class Transformable { * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. With this method, * any options will be overridden with {left: false, right: true}. - * @return {this} A new joined table. + * @return {Transformable} A new joined table. * @example table.join_right(other, ['keyL', 'keyR']) * @example table.join_right(other, (a, b) => equal(a.keyL, b.keyR)) */ @@ -564,7 +564,7 @@ export default class Transformable { * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. With this method, * any options will be overridden with {left: true, right: true}. - * @return {this} A new joined table. + * @return {Transformable} A new joined table. * @example table.join_full(other, ['keyL', 'keyR']) * @example table.join_full(other, (a, b) => equal(a.keyL, b.keyR)) */ @@ -591,7 +591,7 @@ export default class Transformable { * If object-valued, specifies the key-value pairs for each output, * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. - * @return {this} A new joined table. + * @return {Transformable} A new joined table. * @example table.cross(other) * @example table.cross(other, [['leftKey', 'leftVal'], ['rightVal']]) */ @@ -615,7 +615,7 @@ export default class Transformable { * join key values can be arrays or objects, and that normal join * semantics do not consider null or undefined values to be equal (that is, * null !== null). Use the op.equal function to handle these cases. - * @return {this} A new filtered table. + * @return {Transformable} A new filtered table. * @example table.semijoin(other) * @example table.semijoin(other, ['keyL', 'keyR']) * @example table.semijoin(other, (a, b) => equal(a.keyL, b.keyR)) @@ -640,7 +640,7 @@ export default class Transformable { * join key values can be arrays or objects, and that normal join * semantics do not consider null or undefined values to be equal (that is, * null !== null). Use the op.equal function to handle these cases. - * @return {this} A new filtered table. + * @return {Transformable} A new filtered table. * @example table.antijoin(other) * @example table.antijoin(other, ['keyL', 'keyR']) * @example table.antijoin(other, (a, b) => equal(a.keyL, b.keyR)) @@ -657,7 +657,7 @@ export default class Transformable { * Only named columns in this table are included in the output. * @see Transformable#union * @param {...TableRef} tables A list of tables to concatenate. - * @return {this} A new concatenated table. + * @return {Transformable} A new concatenated table. * @example table.concat(other) * @example table.concat(other1, other2) * @example table.concat([other1, other2]) @@ -674,7 +674,7 @@ export default class Transformable { * Only named columns in this table are included in the output. * @see Transformable#concat * @param {...TableRef} tables A list of tables to union. - * @return {this} A new unioned table. + * @return {Transformable} A new unioned table. * @example table.union(other) * @example table.union(other1, other2) * @example table.union([other1, other2]) @@ -690,7 +690,7 @@ export default class Transformable { * calls, but additionally suppresses duplicate rows. * @see Transformable#semijoin * @param {...TableRef} tables A list of tables to intersect. - * @return {this} A new filtered table. + * @return {Transformable} A new filtered table. * @example table.intersect(other) * @example table.intersect(other1, other2) * @example table.intersect([other1, other2]) @@ -706,7 +706,7 @@ export default class Transformable { * calls, but additionally suppresses duplicate rows. * @see Transformable#antijoin * @param {...TableRef} tables A list of tables to difference. - * @return {this} A new filtered table. + * @return {Transformable} A new filtered table. * @example table.except(other) * @example table.except(other1, other2) * @example table.except([other1, other2]) @@ -756,7 +756,7 @@ export default class Transformable { /** * A function defined over rows from two tables. - * @typedef {(a?: Struct, b?: Struct, $?: Params) => any} TableFunc2 + * @typedef {(a?: Struct, b?: Struct, $?: Params) => any} TableExprFunc2 */ /** From b60a8376e16880308084c8af9052794da2f07552 Mon Sep 17 00:00:00 2001 From: Natan Muntean Date: Fri, 15 Mar 2024 10:47:49 +0200 Subject: [PATCH 2/3] fixed most ts issues --- src/arrow/arrow-column.js | 2 +- src/arrow/encode/index.js | 3 +- src/arrow/encode/profiler.js | 14 ++--- src/engine/reduce/field-reducer.js | 7 ++- src/engine/window/window.js | 2 + src/expression/parse-expression.js | 9 ++- src/expression/parse.js | 2 +- src/expression/rewrite.js | 2 +- src/format/from-arrow.js | 2 +- src/format/from-fixed.js | 2 +- src/format/from-json.js | 2 +- src/format/parse/parse-delimited.js | 2 +- src/format/parse/parse-lines.js | 2 +- src/format/util.js | 2 +- src/format/value.js | 4 ++ src/helpers/selection.js | 7 ++- src/index.js | 2 +- src/op/functions/date.js | 12 ++-- src/op/index.js | 4 +- src/op/op-api.js | 1 + src/op/window-functions.js | 28 +++++++++ src/query/query.js | 5 +- src/query/util.js | 2 + src/query/verb.js | 1 + src/register.js | 9 +-- src/table/column-table.js | 19 +++--- src/table/regroup.js | 12 ++-- src/table/table.js | 26 ++++++-- src/table/transformable.js | 97 +++++++++++++++++++---------- src/util/concat.js | 2 +- src/util/parse-dsv.js | 2 +- src/util/parse-iso-date.js | 3 +- src/verbs/derive.js | 2 +- src/verbs/relocate.js | 2 +- src/verbs/util/parse.js | 6 +- tsconfig.json | 6 +- 36 files changed, 207 insertions(+), 98 deletions(-) diff --git a/src/arrow/arrow-column.js b/src/arrow/arrow-column.js index 2bb6e484..ac773bdd 100644 --- a/src/arrow/arrow-column.js +++ b/src/arrow/arrow-column.js @@ -9,7 +9,7 @@ const isListType = type => isList(type) || isFixedSizeList(type); /** * Create an Arquero column that proxies access to an Arrow column. - * @param {object} arrow An Apache Arrow column. + * @param {object} vector An Apache Arrow column. * @return {import('../table/column').ColumnType} An Arquero-compatible column. */ export default function arrowColumn(vector, nested) { diff --git a/src/arrow/encode/index.js b/src/arrow/encode/index.js index 8bdd2255..c786c996 100644 --- a/src/arrow/encode/index.js +++ b/src/arrow/encode/index.js @@ -14,7 +14,7 @@ import isFunction from '../../util/is-function'; * @property {number} [limit=Infinity] The maximum number of rows to include. * @property {number} [offset=0] The row offset indicating how many initial * rows to skip. - * @property {string[]|(data: object) => string[]} [columns] Ordered list of + * @property {string[]|((data: object) => string[])} [columns] Ordered list of * column names to include. If function-valued, the function should accept * a dataset as input and return an array of column name strings. * @property {object} [types] The Arrow data types to use. If specified, @@ -45,6 +45,7 @@ export default function(data, options = {}) { cols[name] = col; }); const T = table(); + // @ts-ignore return new T(cols); } diff --git a/src/arrow/encode/profiler.js b/src/arrow/encode/profiler.js index 29c3883f..9a045568 100644 --- a/src/arrow/encode/profiler.js +++ b/src/arrow/encode/profiler.js @@ -99,14 +99,14 @@ function infer(p) { else if (p.nums === valid) { return Type.Float64; } - else if (p.bigints === valid) { - const v = -p.min > p.max ? -p.min - 1n : p.max; +else if (p.bigints === valid) { + const v = -p.min > p.max ? BigInt(-p.min) - 1n : p.max; return p.min < 0 - ? v < 2 ** 63 ? Type.Int64 - : error(`BigInt exceeds 64 bits: ${v}`) - : p.max < 2 ** 64 ? Type.Uint64 - : error(`BigInt exceeds 64 bits: ${p.max}`); - } + ? v < 2n ** 63n ? Type.Int64 + : error(`BigInt exceeds 64 bits: ${v}`) + : p.max < 2n ** 64n ? Type.Uint64 + : error(`BigInt exceeds 64 bits: ${p.max}`); +} else if (p.bools === valid) { return Type.Bool; } diff --git a/src/engine/reduce/field-reducer.js b/src/engine/reduce/field-reducer.js index 56841dad..beb7a2d4 100644 --- a/src/engine/reduce/field-reducer.js +++ b/src/engine/reduce/field-reducer.js @@ -16,10 +16,13 @@ export default function(oplist, stream) { const { ops, output } = expand(oplist, stream); const fields = oplist[0].fields; const n = fields.length; + + if (n > 2 ) { + error('Unsupported field count: ' + n); + } const cls = n === 0 ? FieldReducer : n === 1 ? Field1Reducer - : n === 2 ? Field2Reducer - : error('Unsupported field count: ' + n); + : Field2Reducer; return new cls(fields, ops, output, stream); } diff --git a/src/engine/window/window.js b/src/engine/window/window.js index 184f734b..efeb332e 100644 --- a/src/engine/window/window.js +++ b/src/engine/window/window.js @@ -12,7 +12,9 @@ const peersValue = op => !!op.peers; function windowOp(spec) { const { id, name, fields = [], params = [] } = spec; const op = getWindow(name).create(...params); + // @ts-ignore if (fields.length) op.get = fields[0]; + // @ts-ignore op.id = id; return op; } diff --git a/src/expression/parse-expression.js b/src/expression/parse-expression.js index d9366766..5ae50313 100644 --- a/src/expression/parse-expression.js +++ b/src/expression/parse-expression.js @@ -27,7 +27,12 @@ import isArray from '../util/is-array'; import isNumber from '../util/is-number'; import toString from '../util/to-string'; -const PARSER_OPT = { ecmaVersion: 11 }; +const PARSER_OPT = { + /** + * @type {import('acorn').ecmaVersion} + */ + ecmaVersion: 11 +}; const DEFAULT_PARAM_ID = '$'; const DEFAULT_TUPLE_ID = 'd'; const DEFAULT_TUPLE_ID1 = 'd1'; @@ -93,8 +98,10 @@ function parseAST(expr) { const code = expr.field ? fieldRef(expr) : isArray(expr) ? toString(expr) : expr; + // @ts-ignore return parse(`expr=(${code})`, PARSER_OPT).body[0].expression.right; } catch (err) { + // @ts-ignore error(`Expression parse error: ${expr+''}`, err); } } diff --git a/src/expression/parse.js b/src/expression/parse.js index fecf5afa..6531a35b 100644 --- a/src/expression/parse.js +++ b/src/expression/parse.js @@ -79,7 +79,7 @@ export default function(input, opt = {}) { // return expression asts if requested if (opt.ast) { - return { names, exprs }; + return { names, exprs, ops: [] }; } // compile input field accessors diff --git a/src/expression/rewrite.js b/src/expression/rewrite.js index f9046cbb..90fdabf8 100644 --- a/src/expression/rewrite.js +++ b/src/expression/rewrite.js @@ -17,7 +17,7 @@ const dictOps = { * @param {object} col The actual table column instance. * @param {object} op Parent AST node operating on the column reference. */ -export default function(ref, name, index = 0, col, op) { +export default function(ref, name, index = 0, col = 0, op = 0) { ref.type = Column; ref.name = name; ref.table = index; diff --git a/src/format/from-arrow.js b/src/format/from-arrow.js index 0a35d53b..07da6e4c 100644 --- a/src/format/from-arrow.js +++ b/src/format/from-arrow.js @@ -20,7 +20,7 @@ import ColumnTable from '../table/column-table'; * @param {ArrowOptions} options Options for Arrow import. * @return {ColumnTable} A new table containing the imported values. */ -export default function(arrow, options = {}) { +export default function(arrow, options = {columns: undefined}) { if (arrow && !arrow.batches) { arrow = fromIPC()(arrow); } diff --git a/src/format/from-fixed.js b/src/format/from-fixed.js index 958c8029..bb36c956 100644 --- a/src/format/from-fixed.js +++ b/src/format/from-fixed.js @@ -51,7 +51,7 @@ export default function(text, options = {}) { ); } -function positions({ positions, widths }) { +function positions({ positions = undefined, widths = undefined }) { if (!positions && !widths) { error('Fixed width files require a "positions" or "widths" option'); } diff --git a/src/format/from-json.js b/src/format/from-json.js index a3441ba3..ac5fbb41 100644 --- a/src/format/from-json.js +++ b/src/format/from-json.js @@ -27,7 +27,7 @@ import isString from '../util/is-string'; * The data payload can also be provided as the "data" property of an * enclosing object, with an optional "schema" property containing table * metadata such as a "fields" array of ordered column information. - * @param {string|object} data A string in JSON format, or pre-parsed object. + * @param {string|object} json A string in JSON format, or pre-parsed object. * @param {JSONParseOptions} options The formatting options. * @return {ColumnTable} A new table containing the parsed values. */ diff --git a/src/format/parse/parse-delimited.js b/src/format/parse/parse-delimited.js index 340b59e2..0ad7dbdf 100644 --- a/src/format/parse/parse-delimited.js +++ b/src/format/parse/parse-delimited.js @@ -26,7 +26,7 @@ import error from '../../util/error'; // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -export default function(text, { delimiter = ',', skip, comment }) { +export default function(text, { delimiter = ',', skip = undefined, comment = undefined }) { if (delimiter.length !== 1) { error(`Text "delimiter" should be a single character, found "${delimiter}"`); } diff --git a/src/format/parse/parse-lines.js b/src/format/parse/parse-lines.js index 7764c608..cd3c5964 100644 --- a/src/format/parse/parse-lines.js +++ b/src/format/parse/parse-lines.js @@ -1,7 +1,7 @@ import { NEWLINE, RETURN } from './constants'; import filter from './text-filter'; -export default function(text, { skip, comment }) { +export default function(text, { skip = undefined, comment = undefined }) { let N = text.length; let I = 0; // current character index diff --git a/src/format/util.js b/src/format/util.js index 1d855c37..8f313bad 100644 --- a/src/format/util.js +++ b/src/format/util.js @@ -17,7 +17,7 @@ import isFunction from '../util/is-function'; * Column format options. The object keys should be column names. * The object values should be formatting functions or objects. * If specified, these override any automatically inferred options. - * @typedef {Object.} ColumnFormatOptions */ /** diff --git a/src/format/value.js b/src/format/value.js index 10adea64..52c795ed 100644 --- a/src/format/value.js +++ b/src/format/value.js @@ -32,6 +32,7 @@ import isTypedArray from '../util/is-typed-array'; */ export default function(v, options = {}) { if (isFunction(options)) { + // @ts-ignore return options(v) + ''; } @@ -39,18 +40,21 @@ export default function(v, options = {}) { if (type === 'object') { if (isDate(v)) { + // @ts-ignore return options.utc ? formatUTCDate(v) : formatDate(v); } else { const s = JSON.stringify( v, (k, v) => isTypedArray(v) ? Array.from(v) : v ); + // @ts-ignore const maxlen = options.maxlen || 30; return s.length > maxlen ? s.slice(0, 28) + '\u2026' + (s[0] === '[' ? ']' : '}') : s; } } else if (type === 'number') { + // @ts-ignore const digits = options.digits || 0; let a; return v !== 0 && ((a = Math.abs(v)) >= 1e18 || a < Math.pow(10, -digits)) diff --git a/src/helpers/selection.js b/src/helpers/selection.js index 9732af5a..d5097289 100644 --- a/src/helpers/selection.js +++ b/src/helpers/selection.js @@ -96,10 +96,11 @@ export function range(start, end) { * @return {SelectHelper} Selection function compatible with select(). */ export function matches(pattern) { - if (isString(pattern)) pattern = RegExp(escapeRegExp(pattern)); + let _pattern; + if (isString(pattern)) _pattern = RegExp(escapeRegExp(pattern)); return decorate( - table => table.columnNames(name => pattern.test(name)), - () => ({ matches: [pattern.source, pattern.flags] }) + table => table.columnNames(name => _pattern.test(name)), + () => ({ matches: [_pattern.source, _pattern.flags] }) ); } diff --git a/src/index.js b/src/index.js index f89313b3..0ce9e2ab 100644 --- a/src/index.js +++ b/src/index.js @@ -23,7 +23,7 @@ export const internal = { }; // export public API -import pkg from '../package.json'; +import * as pkg from '../package.json'; export const version = pkg.version; export { seed } from './util/random'; export { default as fromArrow } from './format/from-arrow'; diff --git a/src/op/functions/date.js b/src/op/functions/date.js index 51ac4d7b..987bc2cc 100644 --- a/src/op/functions/date.js +++ b/src/op/functions/date.js @@ -22,7 +22,7 @@ const t = d => ( * @param {number} [minutes=0] The minute within the hour. * @param {number} [seconds=0] The second within the minute. * @param {number} [milliseconds=0] The milliseconds within the second. - * @return {date} The resuting Date value. + * @return {Date} The resuting Date value. */ function datetime(year, month, date, hours, minutes, seconds, milliseconds) { return !arguments.length @@ -48,7 +48,7 @@ function datetime(year, month, date, hours, minutes, seconds, milliseconds) { * @param {number} [minutes=0] The minute within the hour. * @param {number} [seconds=0] The second within the minute. * @param {number} [milliseconds=0] The milliseconds within the second. - * @return {date} The resuting Date value. + * @return {Date} The resuting Date value. */ function utcdatetime(year, month, date, hours, minutes, seconds, milliseconds) { return !arguments.length @@ -71,14 +71,14 @@ function dayofyear(date) { t0.setMonth(0); t0.setDate(1); const tz = (t1.getTimezoneOffset() - t0.getTimezoneOffset()) * msMinute; - return Math.floor(1 + ((t1 - t0) - tz) / msDay); + return Math.floor(1 + ((t1.valueOf() - t0.valueOf()) - tz) / msDay); } function utcdayofyear(date) { t1.setTime(+date); t1.setUTCHours(0, 0, 0, 0); const t0 = Date.UTC(t1.getUTCFullYear(), 0, 1); - return Math.floor(1 + (t1 - t0) / msDay); + return Math.floor(1 + (t1.valueOf() - t0) / msDay); } function week(date, firstday) { @@ -92,7 +92,7 @@ function week(date, firstday) { t0.setDate(1 - (t0.getDay() + 7 - i) % 7); t0.setHours(0, 0, 0, 0); const tz = (t1.getTimezoneOffset() - t0.getTimezoneOffset()) * msMinute; - return Math.floor((1 + (t1 - t0) - tz) / msWeek); + return Math.floor((1 + (t1.valueOf() - t0.valueOf()) - tz) / msWeek); } function utcweek(date, firstday) { @@ -105,7 +105,7 @@ function utcweek(date, firstday) { t0.setUTCDate(1); t0.setUTCDate(1 - (t0.getUTCDay() + 7 - i) % 7); t0.setUTCHours(0, 0, 0, 0); - return Math.floor((1 + (t1 - t0)) / msWeek); + return Math.floor((1 + (t1.valueOf() - t0.valueOf())) / msWeek); } export default { diff --git a/src/op/index.js b/src/op/index.js index a5a0f83e..5f5876f9 100644 --- a/src/op/index.js +++ b/src/op/index.js @@ -39,7 +39,7 @@ export function hasWindow(name) { /** * Get an aggregate function definition. * @param {string} name The name of the aggregate function. - * @return {AggregateDef} The aggregate function definition, + * @return {import('./aggregate-functions').AggregateDef} The aggregate function definition, * or undefined if not found. */ export function getAggregate(name) { @@ -49,7 +49,7 @@ export function getAggregate(name) { /** * Get a window function definition. * @param {string} name The name of the window function. - * @return {WindowDef} The window function definition, + * @return {import('./window-functions').WindowDef} The window function definition, * or undefined if not found. */ export function getWindow(name) { diff --git a/src/op/op-api.js b/src/op/op-api.js index e5c7ca6b..95c4fb61 100644 --- a/src/op/op-api.js +++ b/src/op/op-api.js @@ -1,3 +1,4 @@ +// @ts-nocheck import functions from './functions'; import op from './op'; diff --git a/src/op/window-functions.js b/src/op/window-functions.js index 2a89dd71..679ed623 100644 --- a/src/op/window-functions.js +++ b/src/op/window-functions.js @@ -43,6 +43,8 @@ const rank = { let rank; return { init: () => rank = 1, + add: noop, + rem: noop, value: w => { const i = w.index; return (i && !w.peer(i)) ? (rank = i + 1) : rank; @@ -57,6 +59,8 @@ const cume_dist = { let cume; return { init: () => cume = 0, + add: noop, + rem: noop, value: w => { const { index, peer, size } = w; let i = index; @@ -80,6 +84,8 @@ export default { create() { return { init: noop, + add: noop, + rem: noop, value: w => w.index + 1 }; }, @@ -95,6 +101,8 @@ export default { let j, rank; return { init: () => (j = -1, rank = 1), + add: noop, + rem: noop, value: w => { const i = w.index; if (i >= j) { @@ -114,6 +122,8 @@ export default { let drank; return { init: () => drank = 1, + add: noop, + rem: noop, value: w => { const i = w.index; return (i && !w.peer(i)) ? ++drank : drank; @@ -129,6 +139,8 @@ export default { const { init, value } = rank.create(); return { init, + add: noop, + rem: noop, value: w => (value(w) - 1) / (w.size - 1) }; }, @@ -146,6 +158,8 @@ export default { const { init, value } = cume_dist.create(); return { init, + add: noop, + rem: noop, value: w => Math.ceil(num * value(w)) }; }, @@ -158,6 +172,8 @@ export default { offset = +offset || 1; return { init: noop, + add: noop, + rem: noop, value: (w, f) => { const i = w.index - offset; return i >= 0 ? w.value(i, f) : defaultValue; @@ -173,6 +189,8 @@ export default { offset = +offset || 1; return { init: noop, + add: noop, + rem: noop, value: (w, f) => { const i = w.index + offset; return i < w.size ? w.value(i, f) : defaultValue; @@ -187,6 +205,8 @@ export default { create() { return { init: noop, + add: noop, + rem: noop, value: (w, f) => w.value(w.i0, f) }; }, @@ -198,6 +218,8 @@ export default { create() { return { init: noop, + add: noop, + rem: noop, value: (w, f) => w.value(w.i1 - 1, f) }; }, @@ -211,6 +233,8 @@ export default { if (!(nth > 0)) error('nth_value nth must be greater than zero.'); return { init: noop, + add: noop, + rem: noop, value: (w, f) => { const i = w.i0 + (nth - 1); return i < w.i1 ? w.value(i, f) : NULL; @@ -226,6 +250,8 @@ export default { let value; return { init: () => value = defaultValue, + add: noop, + rem: noop, value: (w, f) => { const v = w.value(w.index, f); return isValid(v) ? (value = v) : value; @@ -241,6 +267,8 @@ export default { let value, idx; return { init: () => (value = defaultValue, idx = -1), + add: noop, + rem: noop, value: (w, f) => w.index <= idx ? value : (idx = find(w, f, w.index)) >= 0 ? (value = w.value(idx, f)) : (idx = w.size, value = defaultValue) diff --git a/src/query/query.js b/src/query/query.js index 2188429c..257671cc 100644 --- a/src/query/query.js +++ b/src/query/query.js @@ -108,7 +108,10 @@ export default class Query extends Transformable { evaluate(table, catalog) { table = table || catalog(this._table); for (const verb of this._verbs) { - table = verb.evaluate(table.params(this._params), catalog); + const tableParams = table.params(this._params); + if (tableParams instanceof Table) { + table = verb.evaluate(tableParams, catalog); + } } return table; } diff --git a/src/query/util.js b/src/query/util.js index 878c4967..7f85f12e 100644 --- a/src/query/util.js +++ b/src/query/util.js @@ -47,7 +47,9 @@ export function fromObject(value) { : !isObject(value) ? value : isArray(value.verbs) ? Query.from(value) : isArray(value.all) ? all() + // @ts-ignore : isArray(value.range) ? range(...value.range) + // @ts-ignore : isArray(value.match) ? matches(RegExp(...value.match)) : isArray(value.not) ? not(value.not.map(toObject)) : fromExprObject(value); diff --git a/src/query/verb.js b/src/query/verb.js index 68574b90..b9a04c05 100644 --- a/src/query/verb.js +++ b/src/query/verb.js @@ -122,6 +122,7 @@ export class Verb { * @property {string} name The name of the parameter. * @property {ParamType} type The type of the parameter. * @property {{ [key: string]: ParamType }} [props] Types for non-literal properties. + * @property {any} [default] Default value for the parameter. */ /** diff --git a/src/register.js b/src/register.js index 1c6f725c..7b992ef9 100644 --- a/src/register.js +++ b/src/register.js @@ -86,6 +86,7 @@ export function addWindowFunction(name, def, options) { */ export function addFunction(name, fn, options = {}) { if (arguments.length === 1) { + // @ts-ignore fn = name; name = fn.name; if (name === '' || name === 'anonymous') { @@ -130,6 +131,7 @@ function verifyTableMethod(name, fn, options) { // perform name checks if (RESERVED[name]) onReserve(name, type); if ((name + '')[0] === '_') onIllegal(name, type); + // @ts-ignore check(name, options, proto, type); } @@ -217,11 +219,6 @@ export function addPackage(bundle, options = {}) { * @typedef {import('./op/window-functions').WindowDef} WindowDef */ -/** - * Verb parameter definition. - * @typedef {import('./query/verb').ParamDef} ParamDef - */ - /** * Verb definition. * @typedef {object} VerbDef @@ -233,7 +230,7 @@ export function addPackage(bundle, options = {}) { * Verb parameter definition. * @typedef {object} ParamDef * @property {string} name The verb parameter name. - * @property {ParamType} type The verb parameter type. + * @property {import('./query/verb').ParamType} type The verb parameter type. */ /** diff --git a/src/table/column-table.js b/src/table/column-table.js index fc63c3d0..e67f5eae 100644 --- a/src/table/column-table.js +++ b/src/table/column-table.js @@ -79,14 +79,15 @@ export default class ColumnTable extends Table { * based on the values of the optional configuration argument. If a * setting is not specified, it is inherited from the current table. * @param {import('./table').CreateOptions} [options] Creation options for the new table. - * @return {ColumnTable} A newly created table. + * @return {this} A newly created table. */ - create({ data, names, filter, groups, order }) { + create({ data, names, filter, groups, order } = { data: undefined, names: undefined, filter: undefined, groups: undefined, order: undefined}) { const f = filter !== undefined ? filter : this.mask(); + // @ts-ignore return new ColumnTable( data || this._data, - names || (!data ? this._names : null), + names || (!data ? Object.assign([], this._names) : null), f, groups !== undefined ? groups : regroup(this._group, filter && f), order !== undefined ? order : this._order, @@ -100,7 +101,7 @@ export default class ColumnTable extends Table { * prior to assignment. In the case of repeated column names, input table * columns overwrite existing columns. * @param {...ColumnTable} tables The tables to merge with this table. - * @return {ColumnTable} A new table with merged columns. + * @return {this} A new table with merged columns. * @example table.assign(table1, table2) */ assign(...tables) { @@ -181,9 +182,11 @@ export default class ColumnTable extends Table { getter(name) { const column = this.column(name); const indices = this.isFiltered() || this.isOrdered() ? this.indices() : null; + if (!column) { + error(`Unrecognized column: ${name}`); + } return indices ? row => column.get(indices[row]) - : column ? row => column.get(row) - : error(`Unrecognized column: ${name}`); + : row => column.get(row); } /** @@ -240,11 +243,11 @@ export default class ColumnTable extends Table { * Instead, the backing data itself is filtered and ordered as needed. * @param {number[]} [indices] Ordered row indices to materialize. * If unspecified, all rows passing the table filter are used. - * @return {ColumnTable} A reified table. + * @return {this} A reified table. */ reify(indices) { const nrows = indices ? indices.length : this.numRows(); - const names = this._names; + const names = Object.assign([], this._names); let data, groups; if (!indices && !this.isOrdered()) { diff --git a/src/table/regroup.js b/src/table/regroup.js index 063ce985..9e56cf16 100644 --- a/src/table/regroup.js +++ b/src/table/regroup.js @@ -1,10 +1,11 @@ import { array_agg, entries_agg, map_agg, object_agg } from '../op/op-api'; import error from '../util/error'; import uniqueName from '../util/unique-name'; +import BitSet from './bit-set'; /** * Regroup table rows in response to a BitSet filter. - * @param {GroupBySpec} groups The current groupby specification. + * @param {import('./column-table').GroupBySpec} groups The current groupby specification. * @param {BitSet} filter The filter to apply. */ export function regroup(groups, filter) { @@ -36,7 +37,7 @@ export function regroup(groups, filter) { /** * Regroup table rows in response to a re-indexing. * This operation may or may not involve filtering of rows. - * @param {GroupBySpec} groups The current groupby specification. + * @param {import('./column-table').GroupBySpec} groups The current groupby specification. * @param {Function} scan Function to scan new row indices. * @param {boolean} filter Flag indicating if filtering may occur. * @param {number} nrows The number of rows in the new table. @@ -76,10 +77,13 @@ export function reindex(groups, scan, filter, nrows) { } export function nest(table, idx, obj, type) { + if (type !== 'map' && type !== 'entries' && type !== 'object') { + error('groups option must be "map", "entries", or "object".'); + } + const agg = type === 'map' || type === true ? map_agg : type === 'entries' ? entries_agg - : type === 'object' ? object_agg - : error('groups option must be "map", "entries", or "object".'); + : object_agg; const { names } = table.groups(); const col = uniqueName(table.columnNames(), '_'); diff --git a/src/table/table.js b/src/table/table.js index 8554d48f..de6413e9 100644 --- a/src/table/table.js +++ b/src/table/table.js @@ -1,3 +1,4 @@ + import Transformable from './transformable'; import error from '../util/error'; import isNumber from '../util/is-number'; @@ -36,10 +37,12 @@ export default class Table extends Transformable { * based on the values of the optional configuration argument. If a * setting is not specified, it is inherited from the current table. * @param {CreateOptions} [options] Creation options for the new table. - * @return {Table} A newly created table. + * @return {this} A newly created table. */ create(options) { // eslint-disable-line no-unused-vars error('Not implemented'); + // @ts-ignore + return {}; } /** @@ -209,6 +212,7 @@ export default class Table extends Transformable { */ array(name, constructor) { // eslint-disable-line no-unused-vars error('Not implemented'); + return []; } /** @@ -242,6 +246,8 @@ export default class Table extends Transformable { */ getter(name) { // eslint-disable-line no-unused-vars error('Not implemented'); + // @ts-ignore + return {}; } /** @@ -251,6 +257,7 @@ export default class Table extends Transformable { */ objects(options) { // eslint-disable-line no-unused-vars error('Not implemented'); + return []; } /** @@ -260,6 +267,7 @@ export default class Table extends Transformable { */ object(row) { // eslint-disable-line no-unused-vars error('Not implemented'); + return {}; } /** @@ -268,6 +276,7 @@ export default class Table extends Transformable { */ [Symbol.iterator]() { error('Not implemented'); + return Array.prototype[Symbol.iterator].call([]); } /** @@ -275,15 +284,19 @@ export default class Table extends Transformable { * @param {PrintOptions|number} options The options for row object * generation, determining which rows and columns are printed. If * number-valued, specifies the row limit. - * @return {Table} The table instance. + * @return {this} The table instance. */ print(options = {}) { if (isNumber(options)) { + // @ts-ignore options = { limit: options }; + // @ts-ignore } else if (options.limit == null) { + // @ts-ignore options.limit = 10; } + // @ts-ignore const obj = this.objects({ ...options, grouped: false }); const msg = `${this[Symbol.toStringTag]}. Showing ${obj.length} rows.`; @@ -353,7 +366,7 @@ export default class Table extends Transformable { // if not grouped, return a single partition if (!this.isGrouped()) { - return [ this.indices(order) ]; + return [ Array.from(this.indices(order)) ]; } // generate partitions @@ -462,7 +475,7 @@ export default class Table extends Transformable { * @param {number} [end] Zero-based index before which to end extraction. * A negative index indicates an offset from the end of the group. * If end is omitted, slice extracts through the end of the group. - * @return {Table} A new table with sliced rows. + * @return {this} A new table with sliced rows. * @example table.slice(1, -1) */ slice(start = 0, end = Infinity) { @@ -483,9 +496,10 @@ export default class Table extends Transformable { * This method allows the use of custom reducer implementations, * for example to produce multiple rows for an aggregate. * @param {Reducer} reducer The reducer to apply. - * @return {Table} A new table of reducer outputs. + * @return {this} A new table of reducer outputs. */ reduce(reducer) { + // @ts-ignore return this.__reduce(this, reducer); } } @@ -532,7 +546,7 @@ export default class Table extends Transformable { * @property {string[]} names Column names for each group. * @property {RowExpression[]} get Value accessor functions for each group. * @property {number[]} rows Indices of an example table row for each group. - * @property {number[]} keys Per-row group indices, length is total rows of table. + * @property {Uint32Array} keys Per-row group indices, length is total rows of table. */ /** diff --git a/src/table/transformable.js b/src/table/transformable.js index 23624011..a43f9eba 100644 --- a/src/table/transformable.js +++ b/src/table/transformable.js @@ -21,7 +21,7 @@ export default class Transformable { * table's parameter set and returns the table. Any prior parameters * with names matching the input parameters are overridden. * @param {Params} [values] The parameter values. - * @return {Transformable|Params} The current parameters values (if called with + * @return {this|Params} The current parameters values (if called with * no arguments) or this table. */ params(values) { @@ -41,9 +41,10 @@ export default class Transformable { * Instead, the backing data itself is filtered and ordered as needed. * @param {number[]} [indices] Ordered row indices to materialize. * If unspecified, all rows passing the table filter are used. - * @return {Transformable} A reified table. + * @return {this} A reified table. */ reify(indices) { + // @ts-ignore return this.__reify(this, indices); } @@ -53,11 +54,12 @@ export default class Transformable { * Count the number of values in a group. This method is a shorthand * for {@link Transformable#rollup} with a count aggregate function. * @param {CountOptions} [options] Options for the count. - * @return {Transformable} A new table with groupby and count columns. + * @return {this} A new table with groupby and count columns. * @example table.groupby('colA').count() * @example table.groupby('colA').count({ as: 'num' }) */ count(options) { + // @ts-ignore return this.__count(this, options); } @@ -73,11 +75,12 @@ export default class Transformable { * where to place derived columns. Specifying both before and after is an * error. Unlike the relocate verb, this option affects only new columns; * updated columns with existing names are excluded from relocation. - * @return {Transformable} A new table with derived columns added. + * @return {this} A new table with derived columns added. * @example table.derive({ sumXY: d => d.x + d.y }) * @example table.derive({ z: d => d.x * d.y }, { before: 'x' }) */ derive(values, options) { + // @ts-ignore return this.__derive(this, values, options); } @@ -89,10 +92,11 @@ export default class Transformable { * @param {TableExpr} criteria Filter criteria as a table expression. * Both aggregate and window functions are permitted, taking into account * {@link Transformable#groupby} or {@link Transformable#orderby} settings. - * @return {Transformable} A new table with filtered rows. + * @return {this} A new table with filtered rows. * @example table.filter(d => abs(d.value) < 5) */ filter(criteria) { + // @ts-ignore return this.__filter(this, criteria); } @@ -105,7 +109,7 @@ export default class Transformable { * @param {number} [end] Zero-based index before which to end extraction. * A negative index indicates an offset from the end of the group. * If end is omitted, slice extracts through the end of the group. - * @return {Transformable} A new table with sliced rows. + * @return {this} A new table with sliced rows. * @example table.slice(1, -1) */ slice(start, end) { @@ -121,11 +125,12 @@ export default class Transformable { * The keys may be specified using column name strings, column index * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. - * @return {Transformable} A new table with grouped rows. + * @return {this} A new table with grouped rows. * @example table.groupby('colA', 'colB') * @example table.groupby({ key: d => d.colA + d.colB }) */ groupby(...keys) { + // @ts-ignore return this.__groupby(this, keys.flat()); } @@ -148,12 +153,13 @@ export default class Transformable { * with output column names for keys and table expressions * for values (the output names will be ignored). * If an array, array values must be valid key parameters. - * @return {Transformable} A new ordered table. + * @return {this} A new ordered table. * @example table.orderby('a', desc('b')) * @example table.orderby({ a: 'a', b: desc('b') )}) * @example table.orderby(desc(d => d.a)) */ orderby(...keys) { + // @ts-ignore return this.__orderby(this, keys.flat()); } @@ -169,12 +175,13 @@ export default class Transformable { * @param {RelocateOptions} options Options for relocating. Must include * either the before or after property to indicate where to place the * relocated columns. Specifying both before and after is an error. - * @return {Transformable} A new table with relocated columns. + * @return {this} A new table with relocated columns. * @example table.relocate(['colY', 'colZ'], { after: 'colX' }) * @example table.relocate(not('colB', 'colC'), { before: 'colA' }) * @example table.relocate({ colA: 'newA', colB: 'newB' }, { after: 'colC' }) */ relocate(columns, options) { + // @ts-ignore return this.__relocate(this, toArray(columns), options); } @@ -182,11 +189,12 @@ export default class Transformable { * Rename one or more columns, preserving column order. * @param {...Select} columns One or more rename objects with current * column names as keys and new column names as values. - * @return {Transformable} A new table with renamed columns. + * @return {this} A new table with renamed columns. * @example table.rename({ oldName: 'newName' }) * @example table.rename({ a: 'a2', b: 'b2' }) */ rename(...columns) { + // @ts-ignore return this.__rename(this, columns.flat()); } @@ -199,11 +207,12 @@ export default class Transformable { * keys and table expressions for values. The expressions must be valid * aggregate expressions: window functions are not allowed and column * references must be arguments to aggregate functions. - * @return {Transformable} A new table of aggregate summary values. + * @return {this} A new table of aggregate summary values. * @example table.groupby('colA').rollup({ mean: d => mean(d.colB) }) * @example table.groupby('colA').rollup({ mean: op.median('colB') }) */ rollup(values) { + // @ts-ignore return this.__rollup(this, values); } @@ -216,12 +225,13 @@ export default class Transformable { * If function-valued, the input should be an aggregate table * expression compatible with {@link Transformable#rollup}. * @param {SampleOptions} [options] Options for sampling. - * @return {Transformable} A new table with sampled rows. + * @return {this} A new table with sampled rows. * @example table.sample(50) * @example table.sample(100, { replace: true }) * @example table.groupby('colA').sample(() => op.floor(0.5 * op.count())) */ sample(size, options) { + // @ts-ignore return this.__sample(this, size, options); } @@ -233,32 +243,35 @@ export default class Transformable { * as values, or functions that take a table as input and returns a valid * selection parameter (typically the output of selection helper functions * such as {@link all}, {@link not}, or {@link range}). - * @return {Transformable} A new table of selected columns. + * @return {this} A new table of selected columns. * @example table.select('colA', 'colB') * @example table.select(not('colB', 'colC')) * @example table.select({ colA: 'newA', colB: 'newB' }) */ select(...columns) { + // @ts-ignore return this.__select(this, columns.flat()); } /** * Ungroup a table, removing any grouping criteria. * Undoes the effects of {@link Transformable#groupby}. - * @return {Transformable} A new ungrouped table, or this table if not grouped. + * @return {this} A new ungrouped table, or this table if not grouped. * @example table.ungroup() */ ungroup() { + // @ts-ignore return this.__ungroup(this); } /** * Unorder a table, removing any sorting criteria. * Undoes the effects of {@link Transformable#orderby}. - * @return {Transformable} A new unordered table, or this table if not ordered. + * @return {this} A new unordered table, or this table if not ordered. * @example table.unorder() */ unorder() { + // @ts-ignore return this.__unorder(this); } @@ -272,12 +285,13 @@ export default class Transformable { * The keys may be specified using column name strings, column index * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. - * @return {Transformable} A new de-duplicated table. + * @return {this} A new de-duplicated table. * @example table.dedupe() * @example table.dedupe('a', 'b') * @example table.dedupe({ abs: d => op.abs(d.a) }) */ dedupe(...keys) { + // @ts-ignore return this.__dedupe(this, keys.flat()); } @@ -303,12 +317,13 @@ export default class Transformable { * missing rows. All combinations of expanded values are considered, and * new rows are added for each combination that does not appear in the * input table. - * @return {Transformable} A new table with imputed values and/or rows. + * @return {this} A new table with imputed values and/or rows. * @example table.impute({ v: () => 0 }) * @example table.impute({ v: d => op.mean(d.v) }) * @example table.impute({ v: () => 0 }, { expand: ['x', 'y'] }) */ impute(values, options) { + // @ts-ignore return this.__impute(this, values, options); } @@ -326,12 +341,13 @@ export default class Transformable { * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. * @param {FoldOptions} [options] Options for folding. - * @return {Transformable} A new folded table. + * @return {this} A new folded table. * @example table.fold('colA') * @example table.fold(['colA', 'colB']) * @example table.fold(range(5, 8)) */ fold(values, options) { + // @ts-ignore return this.__fold(this, values, options); } @@ -354,12 +370,13 @@ export default class Transformable { * If object-valued, the input object should have output value * names for keys and aggregate table expressions for values. * @param {PivotOptions} [options] Options for pivoting. - * @return {Transformable} A new pivoted table. + * @return {this} A new pivoted table. * @example table.pivot('key', 'value') * @example table.pivot(['keyA', 'keyB'], ['valueA', 'valueB']) * @example table.pivot({ key: d => d.key }, { value: d => sum(d.value) }) */ pivot(keys, values, options) { + // @ts-ignore return this.__pivot(this, keys, values, options); } @@ -371,11 +388,12 @@ export default class Transformable { * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. * @param {SpreadOptions} [options] Options for spreading. - * @return {Transformable} A new table with the spread columns added. + * @return {this} A new table with the spread columns added. * @example table.spread({ a: split(d.text, '') }) * @example table.spread('arrayCol', { limit: 100 }) */ spread(values, options) { + // @ts-ignore return this.__spread(this, values, options); } @@ -389,10 +407,11 @@ export default class Transformable { * numbers, value objects with output column names for keys and table * expressions for values, or selection helper functions. * @param {UnrollOptions} [options] Options for unrolling. - * @return {Transformable} A new unrolled table. + * @return {this} A new unrolled table. * @example table.unroll('colA', { limit: 1000 }) */ unroll(values, options) { + // @ts-ignore return this.__unroll(this, values, options); } @@ -411,10 +430,11 @@ export default class Transformable { * @param {...ExprList} values The column values to add from the * secondary table. Can be column name strings or objects with column * names as keys and table expressions as values. - * @return {Transformable} A new table with lookup values added. + * @return {this} A new table with lookup values added. * @example table.lookup(other, ['key1', 'key2'], 'value1', 'value2') */ lookup(other, on, ...values) { + // @ts-ignore return this.__lookup(this, other, on, values.flat()); } @@ -451,11 +471,12 @@ export default class Transformable { * If object-valued, specifies the key-value pairs for each output, * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. - * @return {Transformable} A new joined table. + * @return {this} A new joined table. * @example table.join(other, ['keyL', 'keyR']) * @example table.join(other, (a, b) => equal(a.keyL, b.keyR)) */ join(other, on, values, options) { + // @ts-ignore return this.__join(this, other, on, values, options); } @@ -488,12 +509,13 @@ export default class Transformable { * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. With this method, * any options will be overridden with {left: true, right: false}. - * @return {Transformable} A new joined table. + * @return {this} A new joined table. * @example table.join_left(other, ['keyL', 'keyR']) * @example table.join_left(other, (a, b) => equal(a.keyL, b.keyR)) */ join_left(other, on, values, options) { const opt = { ...options, left: true, right: false }; + // @ts-ignore return this.__join(this, other, on, values, opt); } @@ -526,12 +548,13 @@ export default class Transformable { * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. With this method, * any options will be overridden with {left: false, right: true}. - * @return {Transformable} A new joined table. + * @return {this} A new joined table. * @example table.join_right(other, ['keyL', 'keyR']) * @example table.join_right(other, (a, b) => equal(a.keyL, b.keyR)) */ join_right(other, on, values, options) { const opt = { ...options, left: false, right: true }; + // @ts-ignore return this.__join(this, other, on, values, opt); } @@ -564,12 +587,13 @@ export default class Transformable { * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. With this method, * any options will be overridden with {left: true, right: true}. - * @return {Transformable} A new joined table. + * @return {this} A new joined table. * @example table.join_full(other, ['keyL', 'keyR']) * @example table.join_full(other, (a, b) => equal(a.keyL, b.keyR)) */ join_full(other, on, values, options) { const opt = { ...options, left: true, right: true }; + // @ts-ignore return this.__join(this, other, on, values, opt); } @@ -591,11 +615,12 @@ export default class Transformable { * If object-valued, specifies the key-value pairs for each output, * defined using two-table table expressions. * @param {JoinOptions} [options] Options for the join. - * @return {Transformable} A new joined table. + * @return {this} A new joined table. * @example table.cross(other) * @example table.cross(other, [['leftKey', 'leftVal'], ['rightVal']]) */ cross(other, values, options) { + // @ts-ignore return this.__cross(this, other, values, options); } @@ -615,12 +640,13 @@ export default class Transformable { * join key values can be arrays or objects, and that normal join * semantics do not consider null or undefined values to be equal (that is, * null !== null). Use the op.equal function to handle these cases. - * @return {Transformable} A new filtered table. + * @return {this} A new filtered table. * @example table.semijoin(other) * @example table.semijoin(other, ['keyL', 'keyR']) * @example table.semijoin(other, (a, b) => equal(a.keyL, b.keyR)) */ semijoin(other, on) { + // @ts-ignore return this.__semijoin(this, other, on); } @@ -640,12 +666,13 @@ export default class Transformable { * join key values can be arrays or objects, and that normal join * semantics do not consider null or undefined values to be equal (that is, * null !== null). Use the op.equal function to handle these cases. - * @return {Transformable} A new filtered table. + * @return {this} A new filtered table. * @example table.antijoin(other) * @example table.antijoin(other, ['keyL', 'keyR']) * @example table.antijoin(other, (a, b) => equal(a.keyL, b.keyR)) */ antijoin(other, on) { + // @ts-ignore return this.__antijoin(this, other, on); } @@ -657,12 +684,13 @@ export default class Transformable { * Only named columns in this table are included in the output. * @see Transformable#union * @param {...TableRef} tables A list of tables to concatenate. - * @return {Transformable} A new concatenated table. + * @return {this} A new concatenated table. * @example table.concat(other) * @example table.concat(other1, other2) * @example table.concat([other1, other2]) */ concat(...tables) { + // @ts-ignore return this.__concat(this, tables.flat()); } @@ -674,12 +702,13 @@ export default class Transformable { * Only named columns in this table are included in the output. * @see Transformable#concat * @param {...TableRef} tables A list of tables to union. - * @return {Transformable} A new unioned table. + * @return {this} A new unioned table. * @example table.union(other) * @example table.union(other1, other2) * @example table.union([other1, other2]) */ union(...tables) { + // @ts-ignore return this.__union(this, tables.flat()); } @@ -690,12 +719,13 @@ export default class Transformable { * calls, but additionally suppresses duplicate rows. * @see Transformable#semijoin * @param {...TableRef} tables A list of tables to intersect. - * @return {Transformable} A new filtered table. + * @return {this} A new filtered table. * @example table.intersect(other) * @example table.intersect(other1, other2) * @example table.intersect([other1, other2]) */ intersect(...tables) { + // @ts-ignore return this.__intersect(this, tables.flat()); } @@ -706,12 +736,13 @@ export default class Transformable { * calls, but additionally suppresses duplicate rows. * @see Transformable#antijoin * @param {...TableRef} tables A list of tables to difference. - * @return {Transformable} A new filtered table. + * @return {this} A new filtered table. * @example table.except(other) * @example table.except(other1, other2) * @example table.except([other1, other2]) */ except(...tables) { + // @ts-ignore return this.__except(this, tables.flat()); } } diff --git a/src/util/concat.js b/src/util/concat.js index 4c776840..7a78c143 100644 --- a/src/util/concat.js +++ b/src/util/concat.js @@ -1,4 +1,4 @@ -export default function(list, fn = (x => x), delim = '') { +export default function(list, fn = ((_, x) => x), delim = '') { const n = list.length; if (!n) return ''; diff --git a/src/util/parse-dsv.js b/src/util/parse-dsv.js index 185cdfbe..fbd670bf 100644 --- a/src/util/parse-dsv.js +++ b/src/util/parse-dsv.js @@ -31,7 +31,7 @@ const RETURN = 13; // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. export default function( text, - { delimiter = ',', comment, skip } = {} + { delimiter = ',', comment = undefined, skip = undefined } = {} ) { if (delimiter.length !== 1) { error(`Text delimiter should be a single character: "${delimiter}"`); diff --git a/src/util/parse-iso-date.js b/src/util/parse-iso-date.js index c3f9e9fc..f1ebc671 100644 --- a/src/util/parse-iso-date.js +++ b/src/util/parse-iso-date.js @@ -1,5 +1,6 @@ import isISODateString from './is-iso-date-string'; -export default function(value, parse = Date.parse) { +export default function(value, parse) { + parse = parse ?? Date.parse; return isISODateString(value) ? parse(value) : value; } \ No newline at end of file diff --git a/src/verbs/derive.js b/src/verbs/derive.js index 29d066f1..6876203a 100644 --- a/src/verbs/derive.js +++ b/src/verbs/derive.js @@ -2,7 +2,7 @@ import relocate from './relocate'; import _derive from '../engine/derive'; import parse from '../expression/parse'; -export default function(table, values, options = {}) { +export default function(table, values, options = { before: null, after: null }) { const dt = _derive(table, parse(values, { table }), options); return options.drop || (options.before == null && options.after == null) diff --git a/src/verbs/relocate.js b/src/verbs/relocate.js index 731e28f0..e61680d4 100644 --- a/src/verbs/relocate.js +++ b/src/verbs/relocate.js @@ -2,7 +2,7 @@ import _select from '../engine/select'; import resolve from '../helpers/selection'; import error from '../util/error'; -export default function(table, columns, { before, after } = {}) { +export default function(table, columns, { before, after } = { before: null, after: null }) { const bef = before != null; const aft = after != null; diff --git a/src/verbs/util/parse.js b/src/verbs/util/parse.js index 0d78b0f6..9783e54e 100644 --- a/src/verbs/util/parse.js +++ b/src/verbs/util/parse.js @@ -9,7 +9,7 @@ import isString from '../../util/is-string'; import isFunction from '../../util/is-function'; import toArray from '../../util/to-array'; -export default function(name, table, params, options = { window: false }) { +export default function(name, table, params, options) { const exprs = new Map(); const marshal = param => { @@ -25,6 +25,8 @@ export default function(name, table, params, options = { window: false }) { if (options.preparse) { options.preparse(exprs); } - + if (options === undefined) { + options = { window: false }; + } return parse(exprs, { table, ...options }); } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index ee068bf1..7a72532a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,9 +2,13 @@ "include": ["src/**/*"], "compilerOptions": { "allowJs": true, + "checkJs": true, "declaration": true, "emitDeclarationOnly": true, "outDir": "dist/types", - "skipLibCheck": true + "target": "ES2020", + "moduleResolution": "node", + "skipLibCheck": false, + "resolveJsonModule": true } } From 214c95b020ecb3695b96993d118736e69346e4b5 Mon Sep 17 00:00:00 2001 From: Natan Muntean Date: Fri, 15 Mar 2024 11:59:55 +0200 Subject: [PATCH 3/3] lint and test fixes --- package.json | 2 ++ src/arrow/encode/profiler.js | 13 +++++++------ src/expression/parse-expression.js | 8 ++++---- src/helpers/selection.js | 9 +++++---- src/query/verb.js | 1 + src/table/bit-set.js | 2 +- src/table/regroup.js | 9 ++++----- src/table/table.js | 1 + src/util/parse-iso-date.js | 4 +++- src/verbs/util/parse.js | 7 +++---- 10 files changed, 31 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 1431d60e..026eb9e2 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,10 @@ "postbuild": "tsc", "preperf": "npm run build", "perf": "TZ=America/Los_Angeles tape 'perf/**/*-perf.js'", + "perf-windows": "SET TZ=America/Los_Angeles && tape perf/**/*-perf.js", "lint": "eslint src test --ext .js", "test": "TZ=America/Los_Angeles tape 'test/**/*-test.js' --require esm", + "test-windows": "SET TZ=America/Los_Angeles && tape test/**/*-test.js --require esm", "prepublishOnly": "npm test && npm run lint && npm run build" }, "dependencies": { diff --git a/src/arrow/encode/profiler.js b/src/arrow/encode/profiler.js index 9a045568..e138d1f5 100644 --- a/src/arrow/encode/profiler.js +++ b/src/arrow/encode/profiler.js @@ -99,14 +99,15 @@ function infer(p) { else if (p.nums === valid) { return Type.Float64; } -else if (p.bigints === valid) { + else if (p.bigints === valid) { + // eslint-disable-next-line no-undef const v = -p.min > p.max ? BigInt(-p.min) - 1n : p.max; return p.min < 0 - ? v < 2n ** 63n ? Type.Int64 - : error(`BigInt exceeds 64 bits: ${v}`) - : p.max < 2n ** 64n ? Type.Uint64 - : error(`BigInt exceeds 64 bits: ${p.max}`); -} + ? v < 2n ** 63n ? Type.Int64 + : error(`BigInt exceeds 64 bits: ${v}`) + : p.max < 2n ** 64n ? Type.Uint64 + : error(`BigInt exceeds 64 bits: ${p.max}`); + } else if (p.bools === valid) { return Type.Bool; } diff --git a/src/expression/parse-expression.js b/src/expression/parse-expression.js index 5ae50313..5bfa5898 100644 --- a/src/expression/parse-expression.js +++ b/src/expression/parse-expression.js @@ -28,10 +28,10 @@ import isNumber from '../util/is-number'; import toString from '../util/to-string'; const PARSER_OPT = { - /** - * @type {import('acorn').ecmaVersion} - */ - ecmaVersion: 11 + /** + * @type {import('acorn').ecmaVersion} + */ + ecmaVersion: 11 }; const DEFAULT_PARAM_ID = '$'; const DEFAULT_TUPLE_ID = 'd'; diff --git a/src/helpers/selection.js b/src/helpers/selection.js index d5097289..2b156197 100644 --- a/src/helpers/selection.js +++ b/src/helpers/selection.js @@ -96,11 +96,12 @@ export function range(start, end) { * @return {SelectHelper} Selection function compatible with select(). */ export function matches(pattern) { - let _pattern; - if (isString(pattern)) _pattern = RegExp(escapeRegExp(pattern)); + if (isString(pattern)) pattern = RegExp(escapeRegExp(pattern)); return decorate( - table => table.columnNames(name => _pattern.test(name)), - () => ({ matches: [_pattern.source, _pattern.flags] }) + // @ts-ignore + table => table.columnNames(name => pattern.test(name)), + // @ts-ignore + () => ({ matches: [pattern.source, pattern.flags] }) ); } diff --git a/src/query/verb.js b/src/query/verb.js index b9a04c05..9b6142bb 100644 --- a/src/query/verb.js +++ b/src/query/verb.js @@ -24,6 +24,7 @@ import { } from './constants'; import toAST from './to-ast'; +// eslint-disable-next-line no-unused-vars import Table from '../table/table'; /** diff --git a/src/table/bit-set.js b/src/table/bit-set.js index c377262c..71d6823e 100644 --- a/src/table/bit-set.js +++ b/src/table/bit-set.js @@ -107,7 +107,7 @@ export default class BitSet { /** * Negate all bits in this bitset. * Modifies this BitSet in place. - * @return {BitSet} + * @return {this} */ not() { const bits = this._bits; diff --git a/src/table/regroup.js b/src/table/regroup.js index 9e56cf16..14bbdf30 100644 --- a/src/table/regroup.js +++ b/src/table/regroup.js @@ -1,12 +1,11 @@ import { array_agg, entries_agg, map_agg, object_agg } from '../op/op-api'; import error from '../util/error'; import uniqueName from '../util/unique-name'; -import BitSet from './bit-set'; /** * Regroup table rows in response to a BitSet filter. * @param {import('./column-table').GroupBySpec} groups The current groupby specification. - * @param {BitSet} filter The filter to apply. + * @param {import('./column-table').BitSet} filter The filter to apply. */ export function regroup(groups, filter) { if (!groups || !filter) return groups; @@ -77,9 +76,9 @@ export function reindex(groups, scan, filter, nrows) { } export function nest(table, idx, obj, type) { - if (type !== 'map' && type !== 'entries' && type !== 'object') { - error('groups option must be "map", "entries", or "object".'); - } + if (type !== 'map' && type !== true && type !== 'entries' && type !== 'object') { + error('groups option must be "map", "entries", or "object".'); + } const agg = type === 'map' || type === true ? map_agg : type === 'entries' ? entries_agg diff --git a/src/table/table.js b/src/table/table.js index de6413e9..9894fd27 100644 --- a/src/table/table.js +++ b/src/table/table.js @@ -3,6 +3,7 @@ import Transformable from './transformable'; import error from '../util/error'; import isNumber from '../util/is-number'; import repeat from '../util/repeat'; +// eslint-disable-next-line no-unused-vars import Reducer from '../engine/reduce/reducer'; /** diff --git a/src/util/parse-iso-date.js b/src/util/parse-iso-date.js index f1ebc671..6bd50df1 100644 --- a/src/util/parse-iso-date.js +++ b/src/util/parse-iso-date.js @@ -1,6 +1,8 @@ import isISODateString from './is-iso-date-string'; export default function(value, parse) { - parse = parse ?? Date.parse; + if (parse === undefined) { + parse = Date.parse; + } return isISODateString(value) ? parse(value) : value; } \ No newline at end of file diff --git a/src/verbs/util/parse.js b/src/verbs/util/parse.js index 9783e54e..ed1f8c7b 100644 --- a/src/verbs/util/parse.js +++ b/src/verbs/util/parse.js @@ -21,12 +21,11 @@ export default function(name, table, params, options) { }; toArray(params).forEach(marshal); - - if (options.preparse) { - options.preparse(exprs); - } if (options === undefined) { options = { window: false }; } + if (options.preparse) { + options.preparse(exprs); + } return parse(exprs, { table, ...options }); } \ No newline at end of file