diff --git a/docs/package.json b/docs/package.json index 147b549720..3f9eb1779e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,6 +7,7 @@ "examples": "docusaurus-examples", "start": "npm run build:arrow && npm run theme && docusaurus-start", "build": "echo 'No build'", + "clean": "rimraf dist", "build:arrow": "cpx ../node_modules/superstore-arrow/superstore.arrow static/arrow/", "build:webpack": "webpack --config webpack.config.js --color", "docs": "npm run build:webpack && npm run theme && docusaurus-build", diff --git a/packages/perspective-bench/bench/perspective.benchmark.js b/packages/perspective-bench/bench/perspective.benchmark.js index e407341498..1bfcdc6edc 100644 --- a/packages/perspective-bench/bench/perspective.benchmark.js +++ b/packages/perspective-bench/bench/perspective.benchmark.js @@ -21,26 +21,7 @@ const COLUMN_PIVOT_OPTIONS = [[], ["Sub-Category"]]; const ROW_PIVOT_OPTIONS = [[], ["State"], ["State", "City"]]; const COLUMN_TYPES = {Sales: "number", "Order Date": "datetime", State: "string"}; -const COMPUTED_FUNCS = { - "+": (x, y) => x + y, - "-": (x, y) => x - y, - "*": (x, y) => x * y, - "/": (x, y) => x / y, - pow2: x => Math.pow(x, 2), - sqrt: x => Math.sqrt(x), - uppercase: x => x.toUpperCase(), - concat_comma: (x, y) => x + y, - week_bucket: x => { - let date = new Date(x); - let day = date.getDay(); - let diff = date.getDate() - day + (day == 0 ? -6 : 1); - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - date.setDate(diff); - return date; - } -}; +const COMPUTED_FUNCS = ["+", "-", "*", "/", "pow2", "sqrt", "uppercase", "concat_comma", "week_bucket"]; const COMPUTED_CONFIG = {computed_function_name: "+", column: "computed", inputs: ["Sales", "Profit"]}; @@ -64,10 +45,10 @@ const COMPLEX_COMPUTED_CONFIGS = { datetime: [ {computed_function_name: "day_bucket", column: "computed", inputs: ["Order Date"]}, {computed_function_name: "second_bucket", column: "computed2", inputs: ["Order Date"]}, - {computed_function_name: "day_of_week", column: "computed3", inputs: ["computed2"]}, + {computed_function_name: "day_of_week", column: "computed3", inputs: ["Order Date"]}, {computed_function_name: "month_of_year", column: "computed4", inputs: ["Ship Date"]}, - {computed_function_name: "year_bucket", column: "computed5", inputs: ["computed2"]}, - {computed_function_name: "minute_bucket", column: "computed6", inputs: ["computed2"]} + {computed_function_name: "year_bucket", column: "computed5", inputs: ["Ship Date"]}, + {computed_function_name: "minute_bucket", column: "computed6", inputs: ["Ship Date"]} ] }; @@ -83,14 +64,7 @@ const COMPLEX_EXPRESSIONS = { `concat(lower("Customer ID"), ', ', lower("Order ID"))`, `concat("State", ' ', "City")` ], - datetime: [ - `bucket("Order Date", 'D')`, - `// computed2\n bucket("Order Date", 'S')`, - `day_of_week("computed2")`, - `month_of_year("Ship Date")`, - `bucket("computed2", 'Y')`, - `bucket("computed2", 'm')` - ] + datetime: [`bucket("Order Date", 'D')`, `bucket("Order Date", 's')`, `day_of_week("Order Date")`, `month_of_year("Ship Date")`, `bucket("Ship Date", 'Y')`, `bucket("Ship Date", 'm')`] }; /****************************************************************************** @@ -182,8 +156,8 @@ describe("Update", async () => { }); describe("ctx0 sorted", async () => { - table = worker.table(data.arrow.slice()); - view = table.view({ + table = await worker.table(data.arrow.slice()); + view = await table.view({ sort: [["Customer Name", "desc"]] }); @@ -198,9 +172,9 @@ describe("Update", async () => { }); describe("ctx0 sorted deep", async () => { - table = worker.table(data.arrow.slice()); + table = await worker.table(data.arrow.slice()); //table_indexed = worker.table(data.arrow.slice(), {index: "Row ID"}); - view = table.view({ + view = await table.view({ sort: [ ["Customer Name", "desc"], ["Order Date", "asc"] @@ -292,110 +266,110 @@ describe("Update", async () => { } }); -describe("Deltas", async () => { - // Generate update data from Perspective - const static_table = await worker.table(data.arrow.slice()); - const static_view = await static_table.view(); - - let table, view; - - afterEach(async () => { - await view.delete(); - await table.delete(); - }); - - describe("mixed", async () => { - describe("ctx0", async () => { - table = await worker.table(data.arrow.slice()); - view = await table.view(); - view.on_update(() => {}, {mode: "row"}); - const test_data = await static_view.to_arrow({end_row: 500}); - benchmark("row delta", async () => { - for (let i = 0; i < 3; i++) { - table.update(test_data.slice ? test_data.slice() : test_data); - await table.size(); - } - }); - }); - - describe("ctx1", async () => { - table = await worker.table(data.arrow.slice()); - view = await table.view({ - row_pivots: ["State"] - }); - view.on_update(() => {}, {mode: "row"}); - const test_data = await static_view.to_arrow({end_row: 500}); - benchmark("row delta", async () => { - for (let i = 0; i < 3; i++) { - table.update(test_data.slice()); - await table.size(); - } - }); - }); - - describe("ctx1 deep", async () => { - table = await worker.table(data.arrow.slice()); - view = await table.view({ - row_pivots: ["State", "City"] - }); - view.on_update(() => {}, {mode: "row"}); - const test_data = await static_view.to_arrow({end_row: 500}); - benchmark("row delta", async () => { - for (let i = 0; i < 3; i++) { - table.update(test_data.slice()); - await table.size(); - } - }); - }); - - describe("ctx2", async () => { - table = await worker.table(data.arrow.slice()); - view = await table.view({ - row_pivots: ["State"], - column_pivots: ["Sub-Category"] - }); - view.on_update(() => {}, {mode: "row"}); - const test_data = await static_view.to_arrow({end_row: 500}); - benchmark("row delta", async () => { - for (let i = 0; i < 3; i++) { - table.update(test_data.slice()); - await table.size(); - } - }); - }); - - describe("ctx2 deep", async () => { - table = await worker.table(data.arrow.slice()); - view = await table.view({ - row_pivots: ["State", "City"], - column_pivots: ["Sub-Category"] - }); - view.on_update(() => {}, {mode: "row"}); - const test_data = await static_view.to_arrow({end_row: 500}); - benchmark("row delta", async () => { - for (let i = 0; i < 3; i++) { - table.update(test_data.slice()); - await table.size(); - } - }); - }); - - describe("ctx1.5", async () => { - table = await worker.table(data.arrow.slice()); - view = await table.view({ - column_pivots: ["Sub-Category"] - }); - view.on_update(() => {}, {mode: "row"}); - const test_data = await static_view.to_arrow({end_row: 500}); - benchmark("row delta", async () => { - for (let i = 0; i < 3; i++) { - table.update(test_data.slice()); - await table.size(); - } - }); - }); - }); -}); +// describe("Deltas", async () => { +// // Generate update data from Perspective +// const static_table = await worker.table(data.arrow.slice()); +// const static_view = await static_table.view(); + +// let table, view; + +// afterEach(async () => { +// await view.delete(); +// await table.delete(); +// }); + +// describe("mixed", async () => { +// describe("ctx0", async () => { +// table = await worker.table(data.arrow.slice()); +// view = await table.view(); +// view.on_update(() => {}, {mode: "row"}); +// const test_data = await static_view.to_arrow({end_row: 500}); +// benchmark("row delta", async () => { +// for (let i = 0; i < 3; i++) { +// table.update(test_data.slice ? test_data.slice() : test_data); +// await table.size(); +// } +// }); +// }); + +// describe("ctx1", async () => { +// table = await worker.table(data.arrow.slice()); +// view = await table.view({ +// row_pivots: ["State"] +// }); +// view.on_update(() => {}, {mode: "row"}); +// const test_data = await static_view.to_arrow({end_row: 500}); +// benchmark("row delta", async () => { +// for (let i = 0; i < 3; i++) { +// table.update(test_data.slice()); +// await table.size(); +// } +// }); +// }); + +// describe("ctx1 deep", async () => { +// table = await worker.table(data.arrow.slice()); +// view = await table.view({ +// row_pivots: ["State", "City"] +// }); +// view.on_update(() => {}, {mode: "row"}); +// const test_data = await static_view.to_arrow({end_row: 500}); +// benchmark("row delta", async () => { +// for (let i = 0; i < 3; i++) { +// table.update(test_data.slice()); +// await table.size(); +// } +// }); +// }); + +// describe("ctx2", async () => { +// table = await worker.table(data.arrow.slice()); +// view = await table.view({ +// row_pivots: ["State"], +// column_pivots: ["Sub-Category"] +// }); +// view.on_update(() => {}, {mode: "row"}); +// const test_data = await static_view.to_arrow({end_row: 500}); +// benchmark("row delta", async () => { +// for (let i = 0; i < 3; i++) { +// table.update(test_data.slice()); +// await table.size(); +// } +// }); +// }); + +// describe("ctx2 deep", async () => { +// table = await worker.table(data.arrow.slice()); +// view = await table.view({ +// row_pivots: ["State", "City"], +// column_pivots: ["Sub-Category"] +// }); +// view.on_update(() => {}, {mode: "row"}); +// const test_data = await static_view.to_arrow({end_row: 500}); +// benchmark("row delta", async () => { +// for (let i = 0; i < 3; i++) { +// table.update(test_data.slice()); +// await table.size(); +// } +// }); +// }); + +// describe("ctx1.5", async () => { +// table = await worker.table(data.arrow.slice()); +// view = await table.view({ +// column_pivots: ["Sub-Category"] +// }); +// view.on_update(() => {}, {mode: "row"}); +// const test_data = await static_view.to_arrow({end_row: 500}); +// benchmark("row delta", async () => { +// for (let i = 0; i < 3; i++) { +// table.update(test_data.slice()); +// await table.size(); +// } +// }); +// }); +// }); +// }); describe("View", async () => { let table; @@ -437,7 +411,7 @@ describe("View", async () => { }); benchmark(`sorted float asc`, async () => { - view = table.view({ + view = await table.view({ aggregate, row_pivot, column_pivot, @@ -447,7 +421,7 @@ describe("View", async () => { }); benchmark(`sorted float desc`, async () => { - view = table.view({ + view = await table.view({ aggregate, row_pivot, column_pivot, @@ -457,7 +431,7 @@ describe("View", async () => { }); benchmark(`sorted str asc`, async () => { - view = table.view({ + view = await table.view({ aggregate, row_pivot, column_pivot, @@ -467,7 +441,7 @@ describe("View", async () => { }); benchmark(`sorted str desc`, async () => { - view = table.view({ + view = await table.view({ aggregate, row_pivot, column_pivot, @@ -502,7 +476,7 @@ describe("View", async () => { }); describe("Expression/Computed Column", async () => { - for (const name of Object.keys(COMPUTED_FUNCS)) { + for (const computed_func of COMPUTED_FUNCS) { describe("mixed", async () => { // Use a single source table for computed let table; @@ -511,9 +485,9 @@ describe("Expression/Computed Column", async () => { await table.delete(); }); - COMPUTED_CONFIG.computed_function_name = name; + COMPUTED_CONFIG.computed_function_name = computed_func; - switch (name) { + switch (computed_func) { case "pow2": case "sqrt": { @@ -550,54 +524,38 @@ describe("Expression/Computed Column", async () => { }); table = await worker.table(data.arrow.slice()); - let add_computed_method; - - if (table.add_computed) { - add_computed_method = table.add_computed; - } - benchmark(`computed: \`${name}\``, async () => { - if (add_computed_method) { - COMPUTED_CONFIG.func = COMPUTED_FUNCS[name]; - COMPUTED_CONFIG.type = "float"; - - table = table.add_computed([COMPUTED_CONFIG]); + benchmark(`computed: \`${computed_func}\``, async () => { + let config = {}; + if (table.validate_expressions) { + // New expressions API + config.expressions = SIMPLE_EXPRESSION; } else { - let config = {}; - if (view.expression_schema) { - // New expressions API - config.expressions = SIMPLE_EXPRESSION; - } else { - // Old computed_columns API - config.computed_columns = [COMPUTED_CONFIG]; - } - - view = await table.view(config); + // Old computed_columns API + config.computed_columns = [COMPUTED_CONFIG]; } - // must process update + view = await table.view(config); await table.size(); }); - if (!add_computed_method) { - benchmark(`sort computed: \`${name}\``, async () => { - let config = { - sort: [["computed", "desc"]] - }; + benchmark(`sort computed: \`${computed_func}\``, async () => { + let config = { + sort: [["computed", "desc"]] + }; - if (view.expression_schema) { - // New expressions API - config.expressions = SIMPLE_EXPRESSION; - } else { - // Old computed_columns API - config.computed_columns = [COMPUTED_CONFIG]; - } + if (table.validate_expressions) { + // New expressions API + config.expressions = SIMPLE_EXPRESSION; + } else { + // Old computed_columns API + config.computed_columns = [COMPUTED_CONFIG]; + } - view = await table.view(config); + view = await table.view(config); - await table.size(); - }); - } + await table.size(); + }); }); describe("ctx1", async () => { @@ -611,17 +569,12 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Not running pivoted computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`row pivot computed: \`${name}\``, async () => { + benchmark(`row pivot computed: \`${computed_func}\``, async () => { let config = { row_pivots: ["computed"] }; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API config.expressions = SIMPLE_EXPRESSION; } else { @@ -646,18 +599,13 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Not running pivoted computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`row and column pivot computed: \`${name}\``, async () => { + benchmark(`row and column pivot computed: \`${computed_func}\``, async () => { let config = { row_pivots: ["computed"], column_pivots: ["computed"] }; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API config.expressions = SIMPLE_EXPRESSION; } else { @@ -682,17 +630,12 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Not running pivoted computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`column pivot computed: \`${name}\``, async () => { + benchmark(`column pivot computed: \`${computed_func}\``, async () => { let config = { column_pivots: ["computed"] }; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API config.expressions = SIMPLE_EXPRESSION; } else { @@ -709,7 +652,7 @@ describe("Expression/Computed Column", async () => { } // multi-dependency computed columns - for (const name in COMPLEX_COMPUTED_CONFIGS) { + for (const data_type in COMPLEX_COMPUTED_CONFIGS) { describe("mixed", async () => { // Use a single source table for computed let table; @@ -729,20 +672,15 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Cannot run complex computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`computed complex: \`${name}\``, async () => { + benchmark(`computed complex: \`${data_type}\``, async () => { let config = {}; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API - config.expressions = COMPLEX_EXPRESSIONS[name]; + config.expressions = COMPLEX_EXPRESSIONS[data_type]; } else { // Old computed_columns API - config.computed_columns = COMPLEX_COMPUTED_CONFIGS[name]; + config.computed_columns = COMPLEX_COMPUTED_CONFIGS[data_type]; } view = await table.view(config); @@ -750,16 +688,16 @@ describe("Expression/Computed Column", async () => { await table.size(); }); - benchmark(`sort computed complex: \`${name}\``, async () => { + benchmark(`sort computed complex: \`${data_type}\``, async () => { let config = {}; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API - config.expressions = COMPLEX_EXPRESSIONS[name]; - config.sort = [[COMPLEX_EXPRESSIONS[name][0], "desc"]]; + config.expressions = COMPLEX_EXPRESSIONS[data_type]; + config.sort = [[COMPLEX_EXPRESSIONS[data_type][0], "desc"]]; } else { // Old computed_columns API - config.computed_columns = COMPLEX_COMPUTED_CONFIGS[name]; + config.computed_columns = COMPLEX_COMPUTED_CONFIGS[data_type]; config.sort = [["computed", "desc"]]; } @@ -780,21 +718,16 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Cannot run complex computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`row pivot computed complex: \`${name}\``, async () => { + benchmark(`row pivot computed complex: \`${data_type}\``, async () => { let config = {}; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API - config.expressions = COMPLEX_EXPRESSIONS[name]; - config.row_pivots = [COMPLEX_EXPRESSIONS[name][0]]; + config.expressions = COMPLEX_EXPRESSIONS[data_type]; + config.row_pivots = [COMPLEX_EXPRESSIONS[data_type][0]]; } else { // Old computed_columns API - config.computed_columns = COMPLEX_COMPUTED_CONFIGS[name]; + config.computed_columns = COMPLEX_COMPUTED_CONFIGS[data_type]; config.row_pivots = ["computed"]; } @@ -814,22 +747,17 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Cannot run complex computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`row and column pivot computed complex: \`${name}\``, async () => { + benchmark(`row and column pivot computed complex: \`${data_type}\``, async () => { let config = {}; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API - config.expressions = COMPLEX_EXPRESSIONS[name]; - config.row_pivots = [COMPLEX_EXPRESSIONS[name][0]]; - config.column_pivots = [COMPLEX_EXPRESSIONS[name][1]]; + config.expressions = COMPLEX_EXPRESSIONS[data_type]; + config.row_pivots = [COMPLEX_EXPRESSIONS[data_type][0]]; + config.column_pivots = [COMPLEX_EXPRESSIONS[data_type][1]]; } else { // Old computed_columns API - config.computed_columns = COMPLEX_COMPUTED_CONFIGS[name]; + config.computed_columns = COMPLEX_COMPUTED_CONFIGS[data_type]; config.row_pivots = ["computed"]; config.column_pivots = ["computed2"]; } @@ -850,21 +778,16 @@ describe("Expression/Computed Column", async () => { table = await worker.table(data.arrow.slice()); - if (table.add_computed) { - console.error("Cannot run complex computed column benchmarks on versions before 0.5.0."); - return; - } - - benchmark(`column pivot computed complex: \`${name}\``, async () => { + benchmark(`column pivot computed complex: \`${data_type}\``, async () => { let config = {}; - if (view.expression_schema) { + if (table.validate_expressions) { // New expressions API - config.expressions = COMPLEX_EXPRESSIONS[name]; - config.column_pivots = [COMPLEX_EXPRESSIONS[name][0]]; + config.expressions = COMPLEX_EXPRESSIONS[data_type]; + config.column_pivots = [COMPLEX_EXPRESSIONS[data_type][0]]; } else { // Old computed_columns API - config.computed_columns = COMPLEX_COMPUTED_CONFIGS[name]; + config.computed_columns = COMPLEX_COMPUTED_CONFIGS[data_type]; config.column_pivots = ["computed"]; } diff --git a/packages/perspective-bench/bench/versions.js b/packages/perspective-bench/bench/versions.js index 238c7bca9c..bb786a869f 100644 --- a/packages/perspective-bench/bench/versions.js +++ b/packages/perspective-bench/bench/versions.js @@ -9,53 +9,7 @@ const PerspectiveBench = require("@finos/perspective-bench"); -const JPMC_VERSIONS = [ - //"0.2.23", /* memory leak */ - "0.2.22", - "0.2.21", - "0.2.20", - "0.2.18", - "0.2.16", - "0.2.15", - "0.2.12", - "0.2.11", - "0.2.10", - "0.2.9", - "0.2.8", - "0.2.7", - "0.2.6", - "0.2.5", - "0.2.4", - "0.2.3", - "0.2.2", - "0.2.1", - "0.2.0" -]; - -const FINOS_VERSIONS = ["0.3.1", "0.3.0", "0.3.0-rc.3", "0.3.0-rc.2", "0.3.0-rc.1"]; - -const UMD_VERSIONS = [ - "0.6.0", - "0.5.6", - "0.5.5", - "0.5.4", - "0.5.3", - "0.5.2", - "0.5.1", - "0.5.0", - "0.4.8", - "0.4.7", - "0.4.6", - "0.4.5", - "0.4.4", - "0.4.2", - "0.4.1", - "0.4.0", - "0.3.9", - "0.3.8", - "0.3.7", - "0.3.6" -]; +const VERSIONS = ["0.8.3", "0.8.2", "0.8.1", "0.8.0", "0.7.0", "0.6.0", "0.5.6", "0.5.5", "0.5.4", "0.5.3", "0.5.2", "0.5.1", "0.5.0"]; async function run() { await PerspectiveBench.run("master", "bench/perspective.benchmark.js", `http://${process.env.PSP_DOCKER_PUPPETEER ? `localhost` : `host.docker.internal`}:8080/perspective.js`, { @@ -63,7 +17,7 @@ async function run() { puppeteer: true }); - for (const version of UMD_VERSIONS) { + for (const version of VERSIONS) { const url = `https://unpkg.com/@finos/perspective@${version}/dist/umd/perspective.js`; await PerspectiveBench.run(version, "bench/perspective.benchmark.js", url, { output: "dist/benchmark", @@ -71,24 +25,6 @@ async function run() { puppeteer: true }); } - - for (const version of FINOS_VERSIONS) { - const url = `https://unpkg.com/@finos/perspective@${version}/build/perspective.js`; - await PerspectiveBench.run(version, "bench/perspective.benchmark.js", url, { - output: "dist/benchmark", - read: true, - puppeteer: true - }); - } - - for (const version of JPMC_VERSIONS) { - const url = `https://unpkg.com/@jpmorganchase/perspective@${version}/build/perspective.js`; - await PerspectiveBench.run(version, "bench/perspective.benchmark.js", url, { - output: "dist/benchmark", - read: true, - puppeteer: true - }); - } } run(); diff --git a/packages/perspective-bench/src/js/bench.js b/packages/perspective-bench/src/js/bench.js index add1734ad3..91a47ff694 100644 --- a/packages/perspective-bench/src/js/bench.js +++ b/packages/perspective-bench/src/js/bench.js @@ -83,7 +83,20 @@ exports.run = async function run(version, benchmark, ...cmdArgs) { const puppeteer = require("puppeteer"); let browser = await puppeteer.launch({ headless: true, - args: ["--no-sandbox"] + args: [ + "--no-sandbox", + "--allow-file-access-from-files", + `--window-size=1280,1024`, + "--disable-accelerated-2d-canvas", + "--disable-gpu", + "--no-sandbox", + "--disable-setuid-sandbox", + "--disable-dev-shm-usage", + '--proxy-server="direct://"', + "--proxy-bypass-list=*", + "--disable-web-security", + "--allow-file-access" + ] }); execSync(`renice -n -20 ${browser.process().pid}`, {stdio: "inherit"}); diff --git a/packages/perspective-bench/src/js/browser_runtime.js b/packages/perspective-bench/src/js/browser_runtime.js index a765a8d935..e7c57895a6 100644 --- a/packages/perspective-bench/src/js/browser_runtime.js +++ b/packages/perspective-bench/src/js/browser_runtime.js @@ -309,7 +309,7 @@ class Suite { return results.map(x => { // TODO perspective bug :( for (const col of columns) { - x[col] = x[col] || "-"; + x[col] = x[col] === undefined ? "-" : x[col]; } return x; }); diff --git a/packages/perspective/src/js/perspective.js b/packages/perspective/src/js/perspective.js index 07819ce748..8cebccb9ee 100644 --- a/packages/perspective/src/js/perspective.js +++ b/packages/perspective/src/js/perspective.js @@ -25,6 +25,8 @@ if (typeof self !== "undefined" && self.performance === undefined) { self.performance = {now: Date.now}; } +const WARNED_KEYS = new Set(); + /** * The main API module for `@finos/perspective`. * @@ -1494,13 +1496,19 @@ export default function(Module) { for (const key of Object.keys(_config)) { if (defaults.CONFIG_ALIASES[key]) { if (!config[defaults.CONFIG_ALIASES[key]]) { - console.warn(`Deprecated: "${key}" config parameter, please use "${defaults.CONFIG_ALIASES[key]}" instead`); + if (!WARNED_KEYS.has(key)) { + console.warn(`Deprecated: "${key}" config parameter, please use "${defaults.CONFIG_ALIASES[key]}" instead`); + WARNED_KEYS.add(key); + } config[defaults.CONFIG_ALIASES[key]] = _config[key]; } else { throw new Error(`Duplicate configuration parameter "${key}"`); } } else if (key === "aggregate") { - console.warn(`Deprecated: "aggregate" config parameter has been replaced by "aggregates" and "columns"`); + if (!WARNED_KEYS.has("aggregate")) { + console.warn(`Deprecated: "aggregate" config parameter has been replaced by "aggregates" and "columns"`); + WARNED_KEYS.add("aggregate"); + } // backwards compatibility: deconstruct `aggregate` into // `aggregates` and `columns` config["aggregates"] = {};