From 67b9242196b3ff7948025d7d0583fe73d839d883 Mon Sep 17 00:00:00 2001 From: Mohammed Sohail Date: Thu, 31 Mar 2022 13:02:53 +0300 Subject: [PATCH] update: worker pool for concurrency and new spec --- .taprc | 4 - package.json | 1 + scenarios/reset_pin/reset_pin.test.js | 113 --------------------- scenarios/reset_pin/tap-parallel-not-ok | 0 scenarios/stateless/display_sarafu.test.js | 41 -------- scenarios/stateless/initial_menu.test.js | 41 -------- scenarios/stateless/tap-parallel-not-ok | 0 src/config.js | 7 +- src/jobAllocator.js | 30 ++++++ src/parser.js | 25 ----- src/sample | 15 ++- src/scenarioBuilder.js | 46 +++++++++ src/specParser.js | 42 ++++++++ src/worker.js | 26 +++++ yarn.lock | 108 +++++++++++++++----- 15 files changed, 244 insertions(+), 255 deletions(-) delete mode 100644 .taprc delete mode 100644 scenarios/reset_pin/reset_pin.test.js delete mode 100644 scenarios/reset_pin/tap-parallel-not-ok delete mode 100644 scenarios/stateless/display_sarafu.test.js delete mode 100644 scenarios/stateless/initial_menu.test.js delete mode 100644 scenarios/stateless/tap-parallel-not-ok create mode 100644 src/jobAllocator.js delete mode 100644 src/parser.js create mode 100644 src/scenarioBuilder.js create mode 100644 src/specParser.js create mode 100644 src/worker.js diff --git a/.taprc b/.taprc deleted file mode 100644 index 5824d13..0000000 --- a/.taprc +++ /dev/null @@ -1,4 +0,0 @@ -reporter: spec -comments: false -coverage: false -check-coverage: false diff --git a/package.json b/package.json index 882acae..37be2d1 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "phin": "^3.6.1", + "piscina": "^3.2.0", "rangi": "^1.0.2" } } diff --git a/scenarios/reset_pin/reset_pin.test.js b/scenarios/reset_pin/reset_pin.test.js deleted file mode 100644 index 4cb4d34..0000000 --- a/scenarios/reset_pin/reset_pin.test.js +++ /dev/null @@ -1,113 +0,0 @@ -const test = require("tap").test; -const rangi = require("rangi"); - -const lib = require("../../lib"); -const conf = require("../../config"); - -test("Reset Pin", async (t) => { - t.before((t) => { - if (!process.env.CURRENT_PIN || !process.env.NEW_PIN) { - t.bailout("ENV not set"); - } - }); - - const sessionId = lib.newSession(); - const currentPin = process.env.CURRENT_PIN; - const newPin = process.env.NEW_PIN; - - t.test("Display menu and Sarafu balance", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /Balance/g); - t.end(); - }); - - t.test("Go to My Accont menu", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "3"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /PIN options/g); - t.end(); - }); - - t.test("Go to Pin options", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "3*5"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /Change my PIN/g); - t.end(); - }); - - t.test("Start Pin Change", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "3*5*1"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /Enter current PIN/g); - t.end(); - }); - - t.test("Enter current Pin", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient( - conf.user.ussdPhone, - sessionId, - `3*5*1*${currentPin}` - ); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /new four number PIN/g); - t.end(); - }); - - t.test("Enter new Pin", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient( - conf.user.ussdPhone, - sessionId, - `3*5*1*${currentPin}*${newPin}` - ); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /new four number PIN again/g); - t.end(); - }); - - t.test("Enter new Pin agin", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient( - conf.user.ussdPhone, - sessionId, - `3*5*1*${currentPin}*${newPin}*${newPin}` - ); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /Your request has been sent/g); - t.end(); - }); - - t.test("Exit", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient( - conf.user.ussdPhone, - sessionId, - `3*5*1*${currentPin}*${newPin}*${newPin}*99` - ); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "END"); - t.match(r.text, /Thank/g); - t.end(); - }); -}); diff --git a/scenarios/reset_pin/tap-parallel-not-ok b/scenarios/reset_pin/tap-parallel-not-ok deleted file mode 100644 index e69de29..0000000 diff --git a/scenarios/stateless/display_sarafu.test.js b/scenarios/stateless/display_sarafu.test.js deleted file mode 100644 index de24320..0000000 --- a/scenarios/stateless/display_sarafu.test.js +++ /dev/null @@ -1,41 +0,0 @@ -const test = require("tap").test; -const rangi = require("rangi"); - -const lib = require("../../lib"); -const conf = require("../../config"); - -test("Display Sarafu", async (t) => { - const sessionId = lib.newSession(); - - t.plan(3); - - t.test("Display menu and Sarafu balance", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /Balance/g); - t.end(); - }); - - t.test("Go to My Sarafu menu", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "2"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /SRF/g); - t.end(); - }); - - t.test("Exit", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "2*00"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "END"); - t.match(r.text, /Thank/g); - t.end(); - }); -}); diff --git a/scenarios/stateless/initial_menu.test.js b/scenarios/stateless/initial_menu.test.js deleted file mode 100644 index 1071e2d..0000000 --- a/scenarios/stateless/initial_menu.test.js +++ /dev/null @@ -1,41 +0,0 @@ -const test = require("tap").test; -const rangi = require("rangi"); - -const lib = require("../../lib"); -const conf = require("../../config"); - -test("Initial Menu", async (t) => { - const sessionId = lib.newSession(); - - t.plan(3); - - t.test("Display menu and Sarafu balance", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /Balance/g); - t.end(); - }); - - t.test("Go to help menu", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "4"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "CON"); - t.match(r.text, /assistance/g); - t.end(); - }); - - t.test("Exit", async (t) => { - await lib.wait(conf.test.waitNextMenu); - const r = await lib.ussdClient(conf.user.ussdPhone, sessionId, "4*99"); - console.log(rangi.cyan(r.text)); - - t.equal(r.code, "END"); - t.match(r.text, /Thank/g); - t.end(); - }); -}); diff --git a/scenarios/stateless/tap-parallel-not-ok b/scenarios/stateless/tap-parallel-not-ok deleted file mode 100644 index e69de29..0000000 diff --git a/src/config.js b/src/config.js index 0cf92a7..a29efd3 100644 --- a/src/config.js +++ b/src/config.js @@ -4,10 +4,5 @@ module.exports = { endpoint: "https://ussd.grassecon.net", timeout: 3000, }, - test: { - waitNextMenu: 3000, - }, - user: { - ussdPhone: "254711777734", - }, + defaultWaitNextMenu: 3000, }; diff --git a/src/jobAllocator.js b/src/jobAllocator.js new file mode 100644 index 0000000..7baa2c1 --- /dev/null +++ b/src/jobAllocator.js @@ -0,0 +1,30 @@ +const path = require("path"); +const rangi = require("rangi"); +const Piscina = require("piscina"); + +const parser = require("./specParser").parser; + +const piscina = new Piscina({ + filename: path.resolve(__dirname, "worker.js"), +}); + +(async function () { + const workload = parser(); + + console.log( + rangi.red(`number of piscina workers to be allocated: ${workload.length}`) + ); + + const parallelExecutor = []; + + for (let i = 0; i < workload.length; i++) { + parallelExecutor.push( + piscina.run({ + jobId: i, + tasks: workload[i], + }) + ); + } + + await Promise.all(parallelExecutor); +})(); diff --git a/src/parser.js b/src/parser.js deleted file mode 100644 index 53c6f2e..0000000 --- a/src/parser.js +++ /dev/null @@ -1,25 +0,0 @@ -const setTimeout = require("timers/promises").setTimeout; -const readFile = require("fs").readFile; - -const parseScenario = require("./builder").parseScenario; -const request = require("./request").request; - -readFile(process.argv[2], "utf8", (err, data) => { - if (err) { - return console.log(err); - } - execute(data); -}); - -async function execute(input) { - const parsedScenarioFile = input.split("\n"); - - for (const work of parsedScenarioFile) { - const parsedWork = parseScenario(work); - - for (const requestJob of parsedWork) { - await request(requestJob); - await setTimeout(requestJob.test.waitNextMenu); - } - } -} diff --git a/src/sample b/src/sample index 2c8d97e..5c8ebe4 100644 --- a/src/sample +++ b/src/sample @@ -1,4 +1,15 @@ +# 254711777734 +wait 5 reset_pin current_pin=2222,new_pin=3333 reset_pin current_pin=3333,new_pin=2222 -send_tx to=0727806655,amount=1,pin=2222 -send_tx to=0706533739,amount=1,pin=2222 \ No newline at end of file +send_tx to=0706533739,amount=1,pin=2222 +send_tx to=0706533739,amount=0.55,pin=2222 +# 254722741115 +wait 2 +reset_pin current_pin=2222,new_pin=3333 +reset_pin current_pin=3333,new_pin=4444 +# 254750123123 +wait 15 +send_tx to=0706533739,amount=1,pin=2222 +wait 1 +# END \ No newline at end of file diff --git a/src/scenarioBuilder.js b/src/scenarioBuilder.js new file mode 100644 index 0000000..6ede823 --- /dev/null +++ b/src/scenarioBuilder.js @@ -0,0 +1,46 @@ +const crypto = require("crypto"); + +const scenario = require("./scenario"); +const config = require("./config"); + +function builder(scenarioName, scenarioConfig, scenarioPhone) { + const scenes = []; + + const builtScenario = scenario[scenarioName](scenarioConfig); + const sessionId = crypto.randomBytes(16).toString("hex"); + + for (const scene of builtScenario) { + scene.sessionId = sessionId; + scene.ussdPhone = scenarioPhone; + + Object.assign(scene, config); + + scenes.push(scene); + } + + return scenes; +} + +function parseScenario(scenarioPhone, scenarioString) { + const [scenarioName, scenarioConfig] = scenarioString.split(" "); + + return builder( + scenarioName, + parseScenarioConfig(scenarioConfig), + scenarioPhone + ); +} + +function parseScenarioConfig(scenarioConfigString) { + const configs = scenarioConfigString.split(","); + const configObject = {}; + + for (const conf of configs) { + [key, value] = conf.split("="); + configObject[key] = value; + } + + return configObject; +} + +module.exports = { parseScenario }; diff --git a/src/specParser.js b/src/specParser.js new file mode 100644 index 0000000..5f3c47d --- /dev/null +++ b/src/specParser.js @@ -0,0 +1,42 @@ +const readFile = require("fs").readFileSync; +const parseScenario = require("./scenarioBuilder").parseScenario; + +const CASE_DELIM = "#"; +const SPECIAL_TIMEOUT = "wait"; + +function parser() { + const rawData = readFile("sample", "utf8"); + const lines = rawData.split("\n"); + const allScenarios = []; + + let scenario = []; + + for (var line = 0; line < lines.length; line++) { + const lineData = lines[line].split(" "); + + var scenarioPhone; + + if (lineData[0] === CASE_DELIM) { + scenarioPhone = lineData[1]; + + if (line > 0) { + allScenarios.push(scenario); + scenario = []; + } + } else if (lineData[0] === SPECIAL_TIMEOUT) { + scenario.push([ + { + input: false, + timeout: true, + duration: lineData[1] * 1000, + }, + ]); + } else { + scenario.push(parseScenario(scenarioPhone, lines[line])); + } + } + + return allScenarios; +} + +module.exports = { parser }; diff --git a/src/worker.js b/src/worker.js new file mode 100644 index 0000000..476ee8d --- /dev/null +++ b/src/worker.js @@ -0,0 +1,26 @@ +const setTimeout = require("timers/promises").setTimeout; +const rangi = require("rangi"); + +module.exports = async ({ jobId, tasks }) => { + for (const task of tasks) { + for (action of task) { + if (!action.input && action.timeout) { + console.log( + rangi.green( + `jobid ${jobId}: waiting ${action.duration}ms before carrying out next action` + ) + ); + await setTimeout(action.duration); + } else { + console.log( + rangi.cyan( + `jobid ${jobId}: session: ${action.sessionId}, input: ${action.input}` + ) + ); + await setTimeout(action.defaultWaitNextMenu); + } + } + } + + return; +}; diff --git a/yarn.lock b/yarn.lock index 10db74f..6051f45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,11 @@ dependencies: "@jridgewell/trace-mapping" "^0.3.0" +"@assemblyscript/loader@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.10.1.tgz#70e45678f06c72fa2e350e8553ec4a4d72b92e06" + integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== + "@babel/code-frame@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -254,7 +259,7 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@isaacs/import-jsx@^4.0.1": +"@isaacs/import-jsx@*", "@isaacs/import-jsx@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@isaacs/import-jsx/-/import-jsx-4.0.1.tgz#493cab5fc543a0703dba7c3f5947d6499028a169" integrity sha512-l34FEsEqpdYdGcQjRCxWy+7rHY6euUbOBz9FI+Mq6oQeVhNegHcXFSJxVxrJvOpO31NbnDjS74quKXDlPDearA== @@ -308,10 +313,10 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== -"@types/react@^17": - version "17.0.42" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.42.tgz#8242b9219bf8a911c47f248e327206fea3f4ee5a" - integrity sha512-nuab3x3CpJ7VFeNA+3HTUuEkvClYHXqWtWd7Ud6AZYW7Z3NH9WKtgU+tFB0ZLcHq+niB/HnzLcaZPqMJ95+k5Q== +"@types/react@*": + version "17.0.43" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55" + integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -418,6 +423,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.2.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -448,7 +458,7 @@ browserslist@^4.17.5: resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== dependencies: - caniuse-lite "^1.0.config.test.waitNextMenu1317" + caniuse-lite "^1.0.30001317" electron-to-chromium "^1.4.84" escalade "^3.1.1" node-releases "^2.0.2" @@ -493,10 +503,10 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.config.test.waitNextMenu1317: - version "1.0.config.test.waitNextMenu1320" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.config.test.waitNextMenu1320.tgz#8397391bec389b8ccce328636499b7284ee13285" - integrity sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA== +caniuse-lite@^1.0.30001317: + version "1.0.30001323" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz#a451ff80dec7033016843f532efda18f02eec011" + integrity sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA== cardinal@^2.1.1: version "2.1.1" @@ -696,9 +706,9 @@ diff@^4.0.1, diff@^4.0.2: integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== electron-to-chromium@^1.4.84: - version "1.4.92" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.92.tgz#88996e9aceb3a500710fd439abfa89b6cc1ac56c" - integrity sha512-YAVbvQIcDE/IJ/vzDMjD484/hsRbFPW2qXJPaYTfOhtligmfYEYOep+5QojpaEU9kq6bMvNeC2aG7arYvTHYsA== + version "1.4.103" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz#abfe376a4d70fa1e1b4b353b95df5d6dfd05da3a" + integrity sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg== emoji-regex@^8.0.0: version "8.0.0" @@ -730,6 +740,11 @@ esprima@^4.0.0, esprima@~4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +eventemitter-asyncresource@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz#734ff2e44bf448e627f7748f905d6bdd57bdb65b" + integrity sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ== + events-to-array@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/events-to-array/-/events-to-array-1.1.2.tgz#2d41f563e1fe400ed4962fe1a4d5c6a7539df7f6" @@ -859,6 +874,20 @@ hasha@^5.0.0: is-stream "^2.0.0" type-fest "^0.8.0" +hdr-histogram-js@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz#0b860534655722b6e3f3e7dca7b78867cf43dcb5" + integrity sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g== + dependencies: + "@assemblyscript/loader" "^0.10.1" + base64-js "^1.2.0" + pako "^1.0.3" + +hdr-histogram-percentiles-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz#9409f4de0c2dda78e61de2d9d78b1e9f3cba283c" + integrity sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -887,7 +916,7 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ink@^3.2.0: +ink@*, ink@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ink/-/ink-3.2.0.tgz#434793630dc57d611c8fe8fffa1db6b56f1a16bb" integrity sha512-firNp1q3xxTzoItj/eOOSZQnYSlyrWks5llCTVX37nJ59K3eXbQ8PtzCguqo8YI19EELo5QxaKnJd4VxzhU8tg== @@ -1147,6 +1176,24 @@ ms@^2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +nice-napi@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nice-napi/-/nice-napi-1.0.2.tgz#dc0ab5a1eac20ce548802fc5686eaa6bc654927b" + integrity sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA== + dependencies: + node-addon-api "^3.0.0" + node-gyp-build "^4.2.2" + +node-addon-api@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + +node-gyp-build@^4.2.2: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + node-preload@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" @@ -1269,6 +1316,11 @@ package-hash@^4.0.0: lodash.flattendeep "^4.4.0" release-zalgo "^1.0.0" +pako@^1.0.3: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + patch-console@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/patch-console/-/patch-console-1.0.0.tgz#19b9f028713feb8a3c023702a8cc8cb9f7466f9d" @@ -1306,6 +1358,17 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +piscina@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/piscina/-/piscina-3.2.0.tgz#f5a1dde0c05567775690cccefe59d9223924d154" + integrity sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA== + dependencies: + eventemitter-asyncresource "^1.0.0" + hdr-histogram-js "^2.0.1" + hdr-histogram-percentiles-obj "^3.0.0" + optionalDependencies: + nice-napi "^1.0.2" + pkg-dir@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" @@ -1331,9 +1394,9 @@ rangi@^1.0.2: integrity sha1-gJ9lLg1kboT25UbeFcL0ZpI+b6k= react-devtools-core@^4.19.1: - version "4.24.2" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.24.2.tgz#ce10e3ea502559ce4299c13837d2374cf0d435a7" - integrity sha512-UC3rvQCG/dnC95NPNWBFrUEtdAEiFZ9xZe1tTHFOELVR5qfNLroZ3w9tC51NQvvK5E10G2ko3lQ5Vrh3p0bHrA== + version "4.24.3" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.24.3.tgz#371fef3f5c639db0dc59eeef334dd5e10ac61661" + integrity sha512-+htKZxLxDN14jhRG3+IXRiJqNSGHUiPYrMtv9e7qlZxcbKeJjVs+C/hd8kZF5rydp3faBwFN6ZpTaZnLA3/ZGA== dependencies: shell-quote "^1.6.1" ws "^7" @@ -1347,13 +1410,12 @@ react-reconciler@^0.26.2: object-assign "^4.1.1" scheduler "^0.20.2" -react@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== +react@*: + version "18.0.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.0.0.tgz#b468736d1f4a5891f38585ba8e8fb29f91c3cb96" + integrity sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" readdirp@~3.6.0: version "3.6.0" @@ -1639,7 +1701,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -treport@^3.0.3: +treport@*: version "3.0.3" resolved "https://registry.yarnpkg.com/treport/-/treport-3.0.3.tgz#0666bb1b00b6ed6e2ba82ae76b79d77fb03c505a" integrity sha512-pCg4Bc0Uv0ntAkYjYJAncA6h6Srv1eEFa5vcak8paahgU1TrJ2rZm0RPZ8E8uycz+P55quzsDnACw01jpWfk7Q==