From 4b858a4948db43c96c0b19cbac39cead8a42a2aa Mon Sep 17 00:00:00 2001 From: Moritz Langenstein <ml5717@ic.ac.uk> Date: Wed, 18 Dec 2019 18:00:30 +0000 Subject: [PATCH] (ml5717) GC, heap usage, gnuplot output and vertical slice of refactoring benchmarks --- .gitignore | 36 +- .gitlab-ci.yml | 5 + __tests__/benchmark.test.js | 726 ++++++++++++++++++++++++++++++++++-- package-lock.json | 312 +++++++++------- package.json | 6 +- plot-scripts/demo.p | 14 + plots/.gitkeep | 0 7 files changed, 908 insertions(+), 191 deletions(-) create mode 100644 plot-scripts/demo.p create mode 100644 plots/.gitkeep diff --git a/.gitignore b/.gitignore index c8f936e..cd44005 100644 --- a/.gitignore +++ b/.gitignore @@ -11,22 +11,26 @@ src/signalbuddy src/yjs src/tiny-worker -# Temporary test dump files -dot-seq-add.json -dot-seq-erase.json -dot-seq-sync.json - -dot-par-add.json -dot-par-erase.json -dot-par-sync.json - -path-seq-add.json -path-seq-erase.json -path-seq-sync.json - -path-par-add.json -path-par-erase.json -path-par-sync.json +# Temporary benchmark dump files +.dot-seq-add.json +.dot-seq-erase.json +.dot-seq-sync.json + +.dot-par-add.json +.dot-par-erase.json +.dot-par-sync.json + +.path-seq-add.json +.path-seq-erase.json +.path-seq-sync.json + +.path-par-add.json +.path-par-erase.json +.path-par-sync.json + +# Benchmark output files +plots/*.tsv +plots/*.pdf ### macOS ### # General diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f2c95d0..ac98c25 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -111,4 +111,9 @@ benchmark: dependencies: - npm_install script: + - apt install gnuplot - npm run test-benchmark + - npm run plot + artifacts: + paths: + - plots/ diff --git a/__tests__/benchmark.test.js b/__tests__/benchmark.test.js index e1fb945..129368f 100644 --- a/__tests__/benchmark.test.js +++ b/__tests__/benchmark.test.js @@ -1,5 +1,6 @@ import fs from "fs" import chalk from "chalk" +import gc from "expose-gc/function" import { connect } from "../src/room.js" @@ -21,11 +22,11 @@ import { createMessageReceivedEvent, handshake, syncStep1, - syncDone, + //syncDone, dotDraw, dotErase, - pathDraw, - pathErase, + //pathDraw, + //pathErase, } from "./benchmark.data.js" // Adapted from https://github.com/jprichardson/buffer-json (MIT license) @@ -64,27 +65,562 @@ function printBenchmark(title, iterations, results) { process.stdout.write(`\n ${title} (${iterations} iterations):\n`) for (const title in results) { - const { timeLoc, packets, size, timeRem, events } = results[title] + const { + timeLoc, + encodeRAM, + packets, + size, + timeRem, + decodeRAM, + events, + } = results[title] const synchronisation = title == "synchronisation" process.stdout.write( chalk` {yellow ⧗} {dim ${title}:} {yellow.inverse ${( timeLoc / (1e6 * (synchronisation ? 1 : iterations)) - ).toFixed(3)}ms ${ - synchronisation ? "total" : "/ it" - }} => {dim ${packets} packet(s)} => {magenta.inverse ${size}B} => {yellow.inverse ${( + ).toFixed(3)}ms ${synchronisation ? "total" : "/ it"}} + {red.inverse ${( + encodeRAM / + (1024 * 1024) + ).toFixed( + 3, + )}MB} => {dim ${packets} packet(s)} => {magenta.inverse ${size}B} => {yellow.inverse ${( timeRem / (1e6 * (synchronisation ? 1 : iterations)) - ).toFixed(3)}ms ${ - synchronisation ? "total" : "/ it" - }} => {dim ${events} event(s)}\n`, + ).toFixed(3)}ms ${synchronisation ? "total" : "/ it"}} + {red.inverse ${( + decodeRAM / + (1024 * 1024) + ).toFixed(3)}MB} => {dim ${events} event(s)}\n`, ) } process.stdout.write(`\n`) } +function writeBenchmarkHeader(filename, title, results) { + const columns = ["iterations"] + + for (const title of results) { + columns.push(`${title}_timeLoc`) + columns.push(`${title}_encodeRAM`) + columns.push(`${title}_packets`) + columns.push(`${title}_size`) + columns.push(`${title}_timeRem`) + columns.push(`${title}_decodeRAM`) + columns.push(`${title}_events`) + } + + return fs.writeFileSync( + filename, + `# Benchmark: ${title}\n# ${columns.join("\t")}\n`, + ) +} + +function appendBenchmark(filename, iterations, results) { + const columns = [iterations] + + for (const title in results) { + const { + timeLoc, + encodeRAM, + packets, + size, + timeRem, + decodeRAM, + events, + } = results[title] + + columns.push(timeLoc) + columns.push(encodeRAM) + columns.push(packets) + columns.push(size) + columns.push(timeRem) + columns.push(decodeRAM) + columns.push(events) + } + + return fs.appendFileSync(filename, `${columns.join("\t")}\n`) +} + +function captureHeapUsage() { + for (let i = 0; i < 10; i++) { + gc() + } + + return process.memoryUsage().heapUsed +} + +function runBidirectionalBenchmark( + BENCHMARK, + FILENAME, + ITERATIONSLIST, + + addData, + eraseData, + + addOnInitFrontend, + addBroadcastGroupTimeout, + addOnBroadcastGroup, + addPacketsFilename, + + eraseOnInitFrontend, + eraseBroadcastGroupTimeout, + eraseOnBroadcastGroup, + erasePacketsFilename, + + syncSendGroupTimeout, + syncOnSendGroup, + syncPacketsFilename, + + addOnInitBackend, + addEventGroupTimeout, + addOnEventGroup, + + eraseOnInitBackend, + eraseEventGroupTimeout, + eraseOnEventGroup, + + syncEventGroupTimeout, + syncOnEventGroup, +) { + if (BENCHMARK && FILENAME) { + writeBenchmarkHeader(FILENAME, BENCHMARK, [ + "addPath", + "extendErasureIntervals", + "synchronisation", + ]) + } + + return ITERATIONSLIST.reduce( + (promise, ITERATIONS) => + promise.then(() => { + const pathIDs = [] + let prevTime + let currTime + + let connectRAM // eslint-disable-line no-unused-vars + let addLocTime = 0 + let addPackets = [] + let addSize = 0 + let addRAM + let eraseLocTime = 0 + let erasePackets = [] + let eraseSize = 0 + let eraseRAM + let syncLocTime + let syncPackets = [] + let syncSize = 0 + let syncRAM + let disconnectRAM // eslint-disable-line no-unused-vars + + let connectUpdRAM // eslint-disable-line no-unused-vars + let addRemTime = 0 + let addEvents = 0 + let addRemRAM + let eraseRemTime = 0 + let eraseEvents = 0 + let eraseRemRAM + let disconnectUpdRAM // eslint-disable-line no-unused-vars + + let connectSyncRAM // eslint-disable-line no-unused-vars + let syncRemTime = 0 + let syncEvents = 0 + let syncRemRAM + let disconnectSyncRAM // eslint-disable-line no-unused-vars + + let timeout + + let room = null + let updateRoom = null + let syncRoom = null + + return ( + // eslint-disable-next-line no-async-promise-executor + new Promise(async (resolve) => { + room = await connect("room", MockConnection) + getEventListener( + "room", + "messageReceived", + )(createMessageReceivedEvent(handshake, "tw-ml")) + + connectRAM = captureHeapUsage() + + return resolve() + }) + .then( + () => + new Promise((resolve) => { + let broadcasts = 0 + + broadcastListener.callback = (channel, message) => { + currTime = process.hrtime() + + addPackets[addPackets.length - 1].push(message) + addSize += message.message.length + + clearTimeout(timeout) + timeout = setTimeout(() => { + broadcasts += 1 + + addLocTime += + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + + prevTime = process.hrtime() + + addOnBroadcastGroup( + room, + addPackets, + pathIDs, + addData, + ITERATIONS, + broadcasts, + resolve, + ) + }, addBroadcastGroupTimeout) + } + + prevTime = process.hrtime() + + addOnInitFrontend(room, addPackets, pathIDs, addData) + }), + ) + .then(() => { + broadcastListener.callback = null + + dumpBSON(addPacketsFilename, addPackets) + addPackets = null + + addRAM = captureHeapUsage() + }) + .then( + () => + new Promise((resolve) => { + let broadcasts = 0 + + broadcastListener.callback = (channel, message) => { + currTime = process.hrtime() + + erasePackets[erasePackets.length - 1].push(message) + eraseSize += message.message.length + + clearTimeout(timeout) + timeout = setTimeout(() => { + broadcasts += 1 + + eraseLocTime += + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + + prevTime = process.hrtime() + + eraseOnBroadcastGroup( + room, + erasePackets, + pathIDs, + eraseData, + ITERATIONS, + broadcasts, + resolve, + ) + }, eraseBroadcastGroupTimeout) + } + + prevTime = process.hrtime() + + eraseOnInitFrontend(room, erasePackets, pathIDs, eraseData) + }), + ) + .then(() => { + broadcastListener.callback = null + + dumpBSON(erasePacketsFilename, erasePackets) + erasePackets = null + + eraseRAM = captureHeapUsage() + }) + .then( + () => + new Promise((resolve) => { + sendListener.callback = (uid, channel, message) => { + const currTime = process.hrtime() + syncLocTime = + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + + syncPackets.push(message) + syncSize += message.message.length + + clearTimeout(timeout) + timeout = setTimeout( + () => syncOnSendGroup(syncPackets, resolve), + syncSendGroupTimeout, + ) + } + + prevTime = process.hrtime() + + getEventListener( + "room", + "messageReceived", + )(createMessageReceivedEvent(syncStep1)) + }), + ) + .then(() => { + sendListener.callback = null + + dumpBSON(syncPacketsFilename, syncPackets) + syncPackets = null + + syncRAM = captureHeapUsage() + + room.disconnect() + room = null + + disconnectRAM = captureHeapUsage() + }) + .then( + () => + // eslint-disable-next-line no-async-promise-executor + new Promise(async (resolve) => { + updateRoom = await connect("update", MockConnection) + getEventListener( + "update", + "messageReceived", + )(createMessageReceivedEvent(handshake, "tw-ml")) + + connectUpdRAM = captureHeapUsage() + + addPackets = loadBSON(addPacketsFilename) + + return resolve() + }), + ) + .then( + () => + new Promise((resolve) => { + let broadcasts = 0 + + let currTime + + const timeoutCallback = () => { + broadcasts += 1 + + addRemTime += + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + + prevTime = process.hrtime() + + addOnEventGroup(addPackets, ITERATIONS, broadcasts, resolve) + } + + updateRoom.addEventListener("addOrUpdatePath", () => { + currTime = process.hrtime() + + addEvents += 1 + + clearTimeout(timeout) + timeout = setTimeout(timeoutCallback, addEventGroupTimeout) + }) + + updateRoom.addEventListener("removedIntervalsChange", () => { + currTime = process.hrtime() + + addEvents += 1 + + clearTimeout(timeout) + timeout = setTimeout(timeoutCallback, addEventGroupTimeout) + }) + + prevTime = process.hrtime() + + addOnInitBackend(addPackets) + }), + ) + .then(() => { + addPackets = null + + addRemRAM = captureHeapUsage() + + erasePackets = loadBSON(erasePacketsFilename) + }) + .then( + () => + new Promise((resolve) => { + let broadcasts = 0 + + let currTime + + const timeoutCallback = () => { + broadcasts += 1 + + eraseRemTime += + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + + prevTime = process.hrtime() + + eraseOnEventGroup( + erasePackets, + ITERATIONS, + broadcasts, + resolve, + ) + } + + updateRoom.addEventListener("removedIntervalsChange", () => { + currTime = process.hrtime() + + eraseEvents += 1 + + clearTimeout(timeout) + timeout = setTimeout( + timeoutCallback, + eraseEventGroupTimeout, + ) + }) + + prevTime = process.hrtime() + + eraseOnInitBackend(erasePackets) + }), + ) + .then(() => { + erasePackets = null + + eraseRemRAM = captureHeapUsage() + + updateRoom.disconnect() + updateRoom = null + + disconnectUpdRAM = captureHeapUsage() + }) + .then( + () => + // eslint-disable-next-line no-async-promise-executor + new Promise(async (resolve) => { + syncRoom = await connect("sync", MockConnection) + getEventListener( + "sync", + "messageReceived", + )(createMessageReceivedEvent(handshake, "tw-ml")) + + connectSyncRAM = captureHeapUsage() + + syncPackets = loadBSON(syncPacketsFilename) + + return resolve() + }), + ) + .then( + () => + new Promise((resolve) => { + syncRoom.addEventListener("addOrUpdatePath", () => { + const currTime = process.hrtime() + + syncRemTime = + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + syncEvents += 1 + + clearTimeout(timeout) + timeout = setTimeout( + () => syncOnEventGroup(resolve), + syncEventGroupTimeout, + ) + }) + + syncRoom.addEventListener("removedIntervalsChange", () => { + const currTime = process.hrtime() + + syncRemTime = + (currTime[0] - prevTime[0]) * 1e9 + + (currTime[1] - prevTime[1]) + syncEvents += 1 + + clearTimeout(timeout) + timeout = setTimeout( + () => syncOnEventGroup(resolve), + syncEventGroupTimeout, + ) + }) + + prevTime = process.hrtime() + + for (const syncPacket of syncPackets) { + getEventListener( + "sync", + "messageReceived", + )(createMessageReceivedEvent(syncPacket)) + } + }), + ) + .then(() => { + syncPackets = null + + syncRemRAM = captureHeapUsage() + + syncRoom.disconnect() + syncRoom = null + + disconnectSyncRAM = captureHeapUsage() + }) + .then(() => { + if (!BENCHMARK) { + return + } + + addPackets = loadBSON(addPacketsFilename).reduce( + (sum, packets) => sum + packets.length, + 0, + ) + erasePackets = loadBSON(erasePacketsFilename).reduce( + (sum, packets) => sum + packets.length, + 0, + ) + syncPackets = loadBSON(syncPacketsFilename).length + + const results = { + addPath: { + timeLoc: addLocTime, + encodeRAM: addRAM, + packets: addPackets, + size: addSize, + timeRem: addRemTime, + decodeRAM: addRemRAM, + events: addEvents, + }, + extendErasureIntervals: { + timeLoc: eraseLocTime, + encodeRAM: eraseRAM, + packets: erasePackets, + size: eraseSize, + timeRem: eraseRemTime, + decodeRAM: eraseRemRAM, + events: eraseEvents, + }, + synchronisation: { + timeLoc: syncLocTime, + encodeRAM: syncRAM, + packets: syncPackets, + size: syncSize, + timeRem: syncRemTime, + decodeRAM: syncRemRAM, + events: syncEvents, + }, + } + + printBenchmark(BENCHMARK, ITERATIONS, results) + appendBenchmark(FILENAME, ITERATIONS, results) + }) + ) + }), + Promise.resolve(), + ) +} + describe("drawing app mesh", () => { beforeEach(() => { getUserID.mockClear() @@ -96,13 +632,156 @@ describe("drawing app mesh", () => { destructor.mockClear() addEventListener.mockClear() MockConnection.mockClear() - }) - it("benchmarks a single draw and erase update sequentially", () => { - const ITERATIONS = 1000 + captureHeapUsage() + }) - jest.setTimeout(ITERATIONS * 400) + const ITERATIONSLIST = [10, 25, 50, 75, 100, 250, 500] + const BLOCKSIZE = 10 // eslint-disable-line no-unused-vars + + jest.setTimeout(1000 * 60 * 60) + + it("benchmarks a dot draw and erase update sequentially", () => { + return runBidirectionalBenchmark( + "dot draw and erase [sequential]" /* BENCHMARK */, + "plots/dot-seq-benchmark.tsv", + ITERATIONSLIST /* ITERATIONSLIST */, + dotDraw /* addData */, + dotErase /* eraseData */, + function addOnInitFrontend(room, addPackets, pathIDs, addData) { + addPackets.push([]) + + const drawPathID = room.addPath(addData[0]) + + pathIDs.push(drawPathID) + for (let i = 1; i < addData.length; i++) { + room.extendPath(drawPathID, addData[i]) + } + } /* addOnInitFrontend */, + 100 /* addBroadcastGroupTimeout */, + function addOnBroadcastGroup( + room, + addPackets, + pathIDs, + addData, + ITERATIONS, + broadcasts, + resolve, + ) { + if (broadcasts < ITERATIONS) { + addPackets.push([]) + + const drawPathID = room.addPath(addData[0]) + pathIDs.push(drawPathID) + + for (let i = 1; i < addData.length; i++) { + room.extendPath(drawPathID, addData[i]) + } + } else { + resolve() + } + } /* addOnBroadcastGroup */, + ".dot-seq-add.json" /* addPacketsFilename */, + function eraseOnInitFrontend(room, erasePackets, pathIDs, eraseData) { + erasePackets.push([]) + + const erasePathID = pathIDs[0] + + for (let i = 0; i < eraseData.length; i++) { + room.extendErasureIntervals( + erasePathID, + eraseData[i][0], + eraseData[i][1], + ) + } + } /* eraseOnInitFrontend */, + 100 /* eraseBroadcastGroupTimeout */, + function eraseOnBroadcastGroup( + room, + erasePackets, + pathIDs, + eraseData, + ITERATIONS, + broadcasts, + resolve, + ) { + if (broadcasts < ITERATIONS) { + erasePackets.push([]) + + const erasePathID = pathIDs[broadcasts] + + for (let i = 0; i < eraseData.length; i++) { + room.extendErasureIntervals( + erasePathID, + eraseData[i][0], + eraseData[i][1], + ) + } + } else { + resolve() + } + } /* eraseOnBroadcastGroup */, + ".dot-seq-erase.json" /* erasePacketsFilename */, + 1000 /* syncSendGroupTimeout */, + function syncOnSendGroup(syncPackets, resolve) { + resolve() + } /* syncOnSendGroup */, + ".dot-seq-sync.json" /* syncPacketsFilename */, + function addOnInitBackend(addPackets) { + for (const packet of addPackets[0]) { + getEventListener( + "update", + "messageReceived", + )(createMessageReceivedEvent(packet)) + } + } /* addOnInitBackend */, + 100 /* addEventGroupTimeout */, + function addOnEventGroup(addPackets, ITERATIONS, broadcasts, resolve) { + if (broadcasts >= ITERATIONS) { + return resolve() + } + + for (const packet of addPackets[broadcasts]) { + getEventListener( + "update", + "messageReceived", + )(createMessageReceivedEvent(packet)) + } + } /* addOnEventGroupTimeout */, + function eraseOnInitBackend(erasePackets) { + for (const packet of erasePackets[0]) { + getEventListener( + "update", + "messageReceived", + )(createMessageReceivedEvent(packet)) + } + } /* eraseOnInitBackend */, + 100 /* eraseEventGroupTimeout */, + function eraseOnEventGroup( + erasePackets, + ITERATIONS, + broadcasts, + resolve, + ) { + if (broadcasts >= ITERATIONS) { + return resolve() + } + + for (const packet of erasePackets[broadcasts]) { + getEventListener( + "update", + "messageReceived", + )(createMessageReceivedEvent(packet)) + } + } /* eraseOnEventGroupTimeout */, + 1000 /* syncEventGroupTimeout */, + function snycOnEventGroup(resolve) { + resolve() + } /* syncOnEventGroup */, + ) + }) + /*it("benchmarks a single draw and erase update sequentially", () => { const dotIDs = [] let prevTime @@ -403,10 +1082,6 @@ describe("drawing app mesh", () => { }) it("benchmarks a single draw and erase update in parallel", () => { - const ITERATIONS = 1000 - - jest.setTimeout(ITERATIONS * 30) - const dotIDs = [] let prevTime @@ -714,8 +1389,6 @@ describe("drawing app mesh", () => { }) it("communicates a single draw and erase update", () => { - jest.setTimeout(20000) - let dotID let addPackets = [] @@ -1005,10 +1678,6 @@ describe("drawing app mesh", () => { }) it("benchmarks a path draw and erase update sequentially", () => { - const ITERATIONS = 1000 - - jest.setTimeout(ITERATIONS * 1500) - const pathIDs = [] let prevTime let currTime @@ -1344,11 +2013,6 @@ describe("drawing app mesh", () => { }) it("benchmarks a path draw and erase update in parallel", () => { - const ITERATIONS = 1000 - const BLOCKSIZE = 10 - - jest.setTimeout(ITERATIONS * 800) - const pathIDs = [] let prevTime @@ -1686,8 +2350,6 @@ describe("drawing app mesh", () => { }) it("communicates a path draw and erase update", () => { - jest.setTimeout(15000) - let pathID let addPackets = [] @@ -1988,5 +2650,5 @@ describe("drawing app mesh", () => { syncRoom.disconnect() syncRoom = null }) - }) + })*/ }) diff --git a/package-lock.json b/package-lock.json index b01e3a0..2e16192 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,15 +14,15 @@ } }, "@babel/core": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", - "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", + "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", "@babel/generator": "^7.7.4", "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.4", + "@babel/parser": "^7.7.5", "@babel/template": "^7.7.4", "@babel/traverse": "^7.7.4", "@babel/types": "^7.7.4", @@ -114,9 +114,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz", - "integrity": "sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz", + "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.7.4", @@ -188,9 +188,9 @@ } }, "@babel/parser": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", - "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", + "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", "dev": true }, "@babel/plugin-syntax-object-rest-spread": { @@ -203,12 +203,12 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz", - "integrity": "sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz", + "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.7.4", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-simple-access": "^7.7.4", "babel-plugin-dynamic-import-node": "^2.3.0" @@ -578,9 +578,9 @@ } }, "@types/babel__generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", - "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -678,9 +678,9 @@ "dev": true }, "@types/node": { - "version": "12.12.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", - "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==" + "version": "12.12.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.20.tgz", + "integrity": "sha512-VAe+DiwpnC/g448uN+/3gRl4th0BTdrR9gSLIOHA+SUQskaYZQDOHG7xmjiE7JUhjbXnbXytf6Ih+/pA6CtMFQ==" }, "@types/stack-utils": { "version": "1.0.1", @@ -1125,9 +1125,9 @@ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" }, "asar": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/asar/-/asar-2.0.1.tgz", - "integrity": "sha512-Vo9yTuUtyFahkVMFaI6uMuX6N7k5DWa6a/8+7ov0/f8Lq9TVR0tUjzSzxQSxT1Y+RJIZgnP7BVb6Uhi+9cjxqA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/asar/-/asar-2.0.3.tgz", + "integrity": "sha512-QdHKO+HOYVtE4B/M3up3i4LSJeJgsa2CTVBrjBf9GgLUPGGUFZowcdJ5yE4gOJuRAHNdqB9JFeRfFfaOu5x8Rw==", "dev": true, "requires": { "chromium-pickle-js": "^0.2.0", @@ -2357,6 +2357,16 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", @@ -2700,9 +2710,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001012", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001012.tgz", - "integrity": "sha512-7RR4Uh04t9K1uYRWzOJmzplgEOAXbfK72oVNokCdMzA67trrhPzy93ahKk1AWHiA0c58tD2P+NHqxrA8FZ+Trg==", + "version": "1.0.30001016", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001016.tgz", + "integrity": "sha512-yYQ2QfotceRiH4U+h1Us86WJXtVHDmy3nEKIdYPsZCYnOV5/tMgGbmoIlrMzmh2VXlproqYtVaKeGDBkMZifFA==", "dev": true }, "canvas-renderer": { @@ -3171,9 +3181,9 @@ "dev": true }, "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", "dev": true }, "core-util-is": { @@ -3629,9 +3639,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.320", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.320.tgz", - "integrity": "sha512-GVyRfGaKs/Vsf915WDaK5NG9vfud8nJFyapyQcrVS+sp8IeMpfml/YMvhthXsSOLlc0rzwdtnkNJE/+q4EPbTA==", + "version": "1.3.322", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", + "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==", "dev": true }, "elegant-spinner": { @@ -3746,12 +3756,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "ws": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz", - "integrity": "sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==", - "requires": { - "async-limiter": "^1.0.0" - } + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" } } }, @@ -3851,9 +3858,9 @@ } }, "es-abstract": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.2.tgz", - "integrity": "sha512-jYo/J8XU2emLXl3OLwfwtuFfuF2w6DYPs+xy9ZfVyPkDcrauu6LYrw/q2TyCtrbc/KUdCiC5e9UajRhgNkVopA==", + "version": "1.17.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", + "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", @@ -3864,6 +3871,7 @@ "is-regex": "^1.0.4", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", + "object.assign": "^4.1.0", "string.prototype.trimleft": "^2.1.0", "string.prototype.trimright": "^2.1.0" } @@ -4192,6 +4200,12 @@ "jest-regex-util": "^24.9.0" } }, + "expose-gc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/expose-gc/-/expose-gc-1.0.0.tgz", + "integrity": "sha512-ecOHrdm+zyOCGIwX18/1RHkUWgxDqGGRiGhaNC+42jReTtudbm2ID/DMa/wpaHwqy5YQHPZvsDqRM2F2iZ0uVA==", + "dev": true + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -4382,9 +4396,9 @@ } }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { @@ -4403,12 +4417,12 @@ } }, "fb-watchman": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, "requires": { - "bser": "^2.0.0" + "bser": "2.1.1" } }, "figgy-pudding": { @@ -4435,6 +4449,13 @@ "flat-cache": "^2.0.1" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "filesize": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", @@ -4618,14 +4639,15 @@ "dev": true }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "node-pre-gyp": "*" }, "dependencies": { "abbrev": { @@ -4673,7 +4695,7 @@ } }, "chownr": { - "version": "1.1.1", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true @@ -4703,7 +4725,7 @@ "optional": true }, "debug": { - "version": "4.1.1", + "version": "3.2.6", "bundled": true, "dev": true, "optional": true, @@ -4730,12 +4752,12 @@ "optional": true }, "fs-minipass": { - "version": "1.2.5", + "version": "1.2.7", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "^2.6.0" } }, "fs.realpath": { @@ -4761,7 +4783,7 @@ } }, "glob": { - "version": "7.1.3", + "version": "7.1.6", "bundled": true, "dev": true, "optional": true, @@ -4790,7 +4812,7 @@ } }, "ignore-walk": { - "version": "3.0.1", + "version": "3.0.3", "bundled": true, "dev": true, "optional": true, @@ -4809,7 +4831,7 @@ } }, "inherits": { - "version": "2.0.3", + "version": "2.0.4", "bundled": true, "dev": true, "optional": true @@ -4851,7 +4873,7 @@ "optional": true }, "minipass": { - "version": "2.3.5", + "version": "2.9.0", "bundled": true, "dev": true, "optional": true, @@ -4861,12 +4883,12 @@ } }, "minizlib": { - "version": "1.2.1", + "version": "1.3.3", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "^2.9.0" } }, "mkdirp": { @@ -4879,24 +4901,24 @@ } }, "ms": { - "version": "2.1.1", + "version": "2.1.2", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.3.0", + "version": "2.4.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^4.1.0", + "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.12.0", + "version": "0.14.0", "bundled": true, "dev": true, "optional": true, @@ -4910,7 +4932,7 @@ "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", - "tar": "^4" + "tar": "^4.4.2" } }, "nopt": { @@ -4924,13 +4946,22 @@ } }, "npm-bundled": { - "version": "1.0.6", + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.4.1", + "version": "1.4.7", "bundled": true, "dev": true, "optional": true, @@ -5001,7 +5032,7 @@ "optional": true }, "process-nextick-args": { - "version": "2.0.0", + "version": "2.0.1", "bundled": true, "dev": true, "optional": true @@ -5042,7 +5073,7 @@ } }, "rimraf": { - "version": "2.6.3", + "version": "2.7.1", "bundled": true, "dev": true, "optional": true, @@ -5069,7 +5100,7 @@ "optional": true }, "semver": { - "version": "5.7.0", + "version": "5.7.1", "bundled": true, "dev": true, "optional": true @@ -5122,18 +5153,18 @@ "optional": true }, "tar": { - "version": "4.4.8", + "version": "4.4.13", "bundled": true, "dev": true, "optional": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "yallist": "^3.0.3" } }, "util-deprecate": { @@ -5158,7 +5189,7 @@ "optional": true }, "yallist": { - "version": "3.0.3", + "version": "3.1.1", "bundled": true, "dev": true, "optional": true @@ -5323,12 +5354,12 @@ "dev": true }, "graphlib": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.7.tgz", - "integrity": "sha512-TyI9jIy2J4j0qgPmOOrHTCtpPqJGN/aurBwc6ZT+bRii+di1I+Wv3obRhVrmBEXet+qkMaEX67dXrwsd3QQM6w==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", "dev": true, "requires": { - "lodash": "^4.17.5" + "lodash": "^4.17.15" } }, "growly": { @@ -5751,9 +5782,9 @@ "dev": true }, "inquirer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", - "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", + "integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -5765,7 +5796,7 @@ "lodash": "^4.17.15", "mute-stream": "0.0.8", "run-async": "^2.2.0", - "rxjs": "^6.4.0", + "rxjs": "^6.5.3", "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" @@ -6037,12 +6068,12 @@ "dev": true }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", "dev": true, "requires": { - "has": "^1.0.1" + "has": "^1.0.3" } }, "is-stream": { @@ -7806,13 +7837,13 @@ } }, "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "object.pick": { @@ -8318,9 +8349,9 @@ "dev": true }, "psl": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.5.0.tgz", - "integrity": "sha512-4vqUjKi2huMu1OJiLhi3jN6jeeKvMZdI1tYgi/njW5zV52jNLgSAZSdN16m9bJFe61/cT8ulmw4qFitV9QRsEA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", + "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", "dev": true }, "public-encrypt": { @@ -8703,9 +8734,9 @@ "dev": true }, "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-uviWSi5N67j3t3UKFxej1loCH0VZn5XuqdNxoLShPcYPw6cUZn74K1VRj+9myynRX03bxIBEkwlkob/ujLsJVw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -8946,9 +8977,9 @@ } }, "sdp": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.10.0.tgz", - "integrity": "sha512-H+VjfyQpRz9GezhshJmkXTtCAT9/2g9az3GFDPYfGOz0eAOQU1fCrL3S9Dq/eUT9FtOyLi/czdR9PzK3fKUYOQ==" + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.11.0.tgz", + "integrity": "sha512-3goRWORJWhZyNQWsAH3X0Z4pb4MhZFBRT/665m+LzYmmp2E9w2ifTbPl1J2EejOSrTJ10Kr3obY0yHZEN11Iaw==" }, "semver": { "version": "6.3.0", @@ -8984,9 +9015,9 @@ } }, "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", "dev": true }, "serve-static": { @@ -9525,9 +9556,9 @@ } }, "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, "string-length": { @@ -9580,14 +9611,13 @@ } }, "string.prototype.padend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", - "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz", + "integrity": "sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.4.3", - "function-bind": "^1.0.2" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "string.prototype.trimleft": { @@ -9719,9 +9749,9 @@ "dev": true }, "terser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.1.tgz", - "integrity": "sha512-e05giplw+8sIYh50qXYHZmr0b76O5dOSm9JwSDebGFLri4ItYzxsnumiAK+yuI56R+H7uIjT9KbVEKNkrprzHw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.3.tgz", + "integrity": "sha512-0ikKraVtRDKGzHrzkCv5rUNDzqlhmhowOBqC0XqUHFpW+vJ45+20/IFBcebwKfiS2Z9fJin6Eo+F1zLZsxi8RA==", "dev": true, "requires": { "commander": "^2.20.0", @@ -9730,16 +9760,16 @@ } }, "terser-webpack-plugin": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", - "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", + "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", @@ -9840,9 +9870,9 @@ }, "dependencies": { "@types/node": { - "version": "10.17.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.6.tgz", - "integrity": "sha512-0a2X6cgN3RdPBL2MIlR6Lt0KlM7fOFsutuXcdglcOq6WvLnYXgPQSh0Mx6tO1KCAE8MxbHSOSTWDoUxRq+l3DA==", + "version": "10.17.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.11.tgz", + "integrity": "sha512-dNd2pp8qTzzNLAs3O8nH3iU9DG9866KHq9L3ISPB7DOGERZN81nW/5/g/KzMJpCU8jrbCiMRBzV9/sCEdRosig==", "dev": true }, "chalk": { @@ -10152,9 +10182,9 @@ } }, "nanoid": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.7.tgz", - "integrity": "sha512-fmS3qwDldm4bE01HCIRqNk+f255CNjnAoeV3Zzzv0KemObHKqYgirVaZA9DtKcjogicWjYcHkJs4D5A8CjnuVQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.8.tgz", + "integrity": "sha512-g1z+n5s26w0TGKh7gjn7HCqurNKMZWzH08elXzh/gM/csQHd/UqDV6uxMghQYg9IvqRPm1QpeMk50YMofHvEjQ==", "dev": true }, "npm-run-path": { @@ -10619,9 +10649,9 @@ } }, "tree-kill": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", - "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, "trim-right": { @@ -10709,15 +10739,15 @@ "dev": true }, "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==", "dev": true }, "uglify-js": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz", - "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", + "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", "dev": true, "optional": true, "requires": { @@ -10978,9 +11008,9 @@ "dev": true }, "webpack": { - "version": "4.41.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", - "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", + "version": "4.41.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.3.tgz", + "integrity": "sha512-EcNzP9jGoxpQAXq1VOoTet0ik7/VVU1MovIfcUSAjLowc7GhcQku/sOXALvq5nPpSei2HF6VRhibeJSC3i/Law==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", @@ -11003,7 +11033,7 @@ "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.1", + "terser-webpack-plugin": "^1.4.3", "watchpack": "^1.6.0", "webpack-sources": "^1.4.1" }, diff --git a/package.json b/package.json index 049c501..ec0cef4 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "test": "jest --testPathIgnorePatterns .*.data.js .*benchmark.test.js src/liowebrtc src/rtcpeerconnection src/signalbuddy src/yjs src/tiny-worker", "test-changed": "jest --only-changed --testPathIgnorePatterns __tests__/*.data.js src/liowebrtc src/rtcpeerconnection src/signalbuddy src/yjs src/tiny-worker", "test-coverage": "jest --coverage --testPathIgnorePatterns __tests__/*.data.js src/liowebrtc src/rtcpeerconnection src/signalbuddy src/yjs src/tiny-worker", - "test-benchmark": "jest --testPathPattern .*benchmark.test.js --testPathIgnorePatterns .*.data.js src/liowebrtc src/rtcpeerconnection src/signalbuddy src/yjs src/tiny-worker", + "test-benchmark": "jest --testPathPattern .*benchmark.test.js --testPathIgnorePatterns .*.data.js src/liowebrtc src/rtcpeerconnection src/signalbuddy src/yjs src/tiny-worker --runInBand", "test-e2e:peer1": "testcafe chrome:headless __e2e_tests__/peer1.e2e.js", "test-e2e:peer2": "testcafe chrome:headless __e2e_tests__/peer2.e2e.js", "test-e2e": "run-p test-e2e:*", @@ -27,7 +27,8 @@ "format": "prettier --ignore-path .gitignore --check --write '**/*.{html,js,json,md}'", "format-check": "prettier --ignore-path .gitignore --check '**/*.{html,js,json,md}'", "lint": "eslint --ignore-path .gitignore '**/*.js'", - "validate": "npm ls" + "validate": "npm ls", + "plot": "find plot-scripts/ -maxdepth 1 -type f -name '*.p' -exec gnuplot {} \\;" }, "dependencies": { "@ungap/event-target": "^0.1.0", @@ -55,6 +56,7 @@ "eslint": "^6.5.1", "eslint-config-prettier": "^6.5.0", "eslint-plugin-testcafe": "^0.2.1", + "expose-gc": "^1.0.0", "jest": "^24.9.0", "npm-run-all": "^4.1.5", "prettier": "^1.18.2", diff --git a/plot-scripts/demo.p b/plot-scripts/demo.p new file mode 100644 index 0000000..e0fcdf5 --- /dev/null +++ b/plot-scripts/demo.p @@ -0,0 +1,14 @@ +set xlabel "Iterations" +set ylabel "Time [ms]" +set title "addPath() performance scalability" +set key inside bottom right + +set terminal dumb size 120, 30 +set autoscale + +plot "plots/dot-seq-benchmark.tsv" using 1:($2/(1e6*$1)) with lines title "dot [sequential]" + +set terminal pdf +set output "plots/dot-seq-benchmark.pdf" + +plot "plots/dot-seq-benchmark.tsv" using 1:($2/(1e6*$1)) with lines title "dot [sequential]" diff --git a/plots/.gitkeep b/plots/.gitkeep new file mode 100644 index 0000000..e69de29 -- GitLab