From 0679e3e094266153fc46ab865ac3222ca26e8b5a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 18 Oct 2019 00:21:44 +0200 Subject: [PATCH] feat: precached webui works in offline mode (#782) This adds precache logic for Web UI which is executed when IPFS API client (or full node) starts. The main purpose is to make Web UI load instantly in Brave and work in offline environments How does it work? During the build .tar archives are placed in `add-on/dist/precache`. This makes them available to fetch over `*-extension://{extension-id}/dist/precache/*` URLs. Right now we have only one archive: a 22MB file with release version of Web UI. When IPFS client starts, preache logic is executed: 1. read Web UI CID from Companion's config 2. check if local repo contains mentioned CID. - if it is present, finish - if missing, continue to the next step 3. precache asynchronously: - fetch TAR archive from `*-extension://{extension-id}/dist/precache/*.tar` - pass entire directory tree as unpacked streams to ipfs.add - confirm produced CID is matching the one from step (1) --- .travis.yml | 11 +- .../embedded-chromesockets/config.js | 1 - add-on/src/lib/ipfs-client/index.js | 13 +- add-on/src/lib/precache.js | 107 +++++++++++ package.json | 16 +- yarn.lock | 172 ++++++++++++++---- 6 files changed, 260 insertions(+), 60 deletions(-) create mode 100644 add-on/src/lib/precache.js diff --git a/.travis.yml b/.travis.yml index 080252a2e..65860b768 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,9 +19,12 @@ addons: install: - npm run ci:install script: - - npm run ci:build - - npm run ci:test - - npm run ci:lint + - npm run build + - npm run test + - npm run lint after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov notifications: - email: false + email: + if: branch = master + on_success: never + on_failure: always diff --git a/add-on/src/lib/ipfs-client/embedded-chromesockets/config.js b/add-on/src/lib/ipfs-client/embedded-chromesockets/config.js index b8d23e338..dacb06f52 100644 --- a/add-on/src/lib/ipfs-client/embedded-chromesockets/config.js +++ b/add-on/src/lib/ipfs-client/embedded-chromesockets/config.js @@ -25,7 +25,6 @@ const chromeDefaultOpts = { Swarm: [ // optional ws-star signaling provides a backup for non-LAN peer discovery // (this will be removed when autorelay and DHT are stable in js-ipfs) - '/dns4/ws-star1.par.dwebops.pub.com/tcp/443/wss/p2p-websocket-star', '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star' ], // Delegated Content and Peer Routing: https://github.com/ipfs/js-ipfs/pull/2195 diff --git a/add-on/src/lib/ipfs-client/index.js b/add-on/src/lib/ipfs-client/index.js index c7b69ecae..ce10d0075 100644 --- a/add-on/src/lib/ipfs-client/index.js +++ b/add-on/src/lib/ipfs-client/index.js @@ -10,7 +10,7 @@ const browser = require('webextension-polyfill') const external = require('./external') const embedded = require('./embedded') const embeddedWithChromeSockets = require('./embedded-chromesockets') -const { webuiCid } = require('../state') +const precache = require('../precache') let client @@ -70,15 +70,8 @@ async function _reloadIpfsClientDependents (instance, opts) { } // online only if (client && instance) { - if (webuiCid && instance.refs) { - // Optimization: preload the root CID to speed up the first time - // Web UI is opened. If embedded js-ipfs is used it will trigger - // remote (always recursive) preload of entire DAG to one of preload nodes. - // This way when embedded node wants to load resource related to webui - // it will get it fast from preload nodes. - log(`preloading webui root at ${webuiCid}`) - instance.refs(webuiCid, { recursive: false }) - } + // add important data to local ipfs repo for instant load + precache(instance) } } diff --git a/add-on/src/lib/precache.js b/add-on/src/lib/precache.js new file mode 100644 index 000000000..b300ffcbf --- /dev/null +++ b/add-on/src/lib/precache.js @@ -0,0 +1,107 @@ +'use strict' +/* eslint-env browser, webextensions */ +const pull = require('pull-stream/pull') +const drain = require('pull-stream/sinks/drain') +const toStream = require('it-to-stream') +const tar = require('tar-stream') +const CID = require('cids') +const { webuiCid } = require('./state') + +const debug = require('debug') +const log = debug('ipfs-companion:precache') +log.error = debug('ipfs-companion:precache:error') + +const PRECACHE_ARCHIVES = [ + { tarPath: '/dist/precache/webui.tar', cid: webuiCid } +] + +/** + * Adds important assets such as Web UI to the local js-ipfs-repo. + * This ensures they load instantly, even in offline environments. + */ +module.exports = async (ipfs) => { + for (const { cid, tarPath } of PRECACHE_ARCHIVES) { + if (!await inRepo(ipfs, cid)) { + await importTar(ipfs, tarPath, cid) + } else { + log(`${cid} already in local repo, skipping import`) + } + } +} + +async function inRepo (ipfs, cid) { + return new Promise((resolve, reject) => { + let local = false + pull( + ipfs.refs.localPullStream(), + drain(block => { + if (block.ref === cid) { + local = true + return false // abort stream + } + }, () => resolve(local)) + ) + }) +} + +async function importTar (ipfs, tarPath, expectedCid) { + const stream = toStream.readable(streamTar(tarPath)) + // TODO: HTTP 404 means precache is disabled in the current runtime + // (eg. in Firefox, due to https://github.com/ipfs-shipyard/ipfs-webui/issues/959) + const untarAndAdd = tar.extract() + + const files = [] + + untarAndAdd.on('entry', (header, stream, next) => { + // header is the tar header + // stream is the content body (might be an empty stream) + // call next when you are done with this entry + + if (header.type !== 'file') { + // skip non-files + stream.on('end', next) + stream.resume() // drain stream + return + } + + files.push(new Promise((resolve, reject) => { + let chunks = [] + stream.on('data', data => chunks.push(data)) + stream.on('end', () => { + resolve({ path: header.name, content: Buffer.concat(chunks) }) + chunks = null + next() + }) + })) + }) + + untarAndAdd.on('finish', async () => { + const { version } = new CID(expectedCid) + const opts = { cidVersion: version, pin: false, preload: false } + const results = await ipfs.add(await Promise.all(files), opts) + const root = results.find(e => e.hash === expectedCid) + if (root) { + log(`${tarPath} successfully precached`, root) + } else { + log.error('imported CID does not match expected one (requires new release with updated package.json)') + } + }) + + log(`importing ${tarPath} to js-ipfs-repo`) + stream.pipe(untarAndAdd) +} + +async function * streamTar (repoPath) { + const response = await fetch(repoPath) + const reader = response.body.getReader() + try { + while (true) { + const { done, value } = await reader.read() + if (done) return + yield value + } + } finally { + // Firefox only? https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultReader/releaseLock + if (typeof reader.releaseLock === 'function') reader.releaseLock() + } +} diff --git a/package.json b/package.json index 1ea681a58..3b51c0fe8 100644 --- a/package.json +++ b/package.json @@ -28,20 +28,23 @@ "build:minimize-dist": "shx rm -rf add-on/dist/lib add-on/dist/contentScripts/ add-on/dist/bundles/ipfsProxyContentScriptPayload.bundle.js", "build:bundle-all": "cross-env RELEASE_CHANNEL=${RELEASE_CHANNEL:=dev} run-s bundle:chromium bundle:brave:$RELEASE_CHANNEL bundle:firefox:$RELEASE_CHANNEL", "build:rename-artifacts": "./scripts/rename-artifacts.js", + "precache:clean": "shx rm -rf add-on/dist/precache", + "precache:webui:cid": "shx grep 'const webuiCid' add-on/src/lib/state.js | shx sed \"s/^const webuiCid = '//\" | shx sed \"s/'.*$//\"", + "precache:webui": "shx mkdir -p add-on/dist/precache && ipfs-or-gateway -c $(npm run -s precache:webui:cid) -p add-on/dist/precache/webui.tar --archive", "bundle": "run-s bundle:*", - "bundle:chromium": "shx cat add-on/manifest.common.json add-on/manifest.chromium.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/chromium && run-s build:rename-artifacts", - "bundle:firefox": "shx cat add-on/manifest.common.json add-on/manifest.firefox.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/firefox/ && run-s build:rename-artifacts", + "bundle:chromium": "run-s precache:webui && shx cat add-on/manifest.common.json add-on/manifest.chromium.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/chromium && run-s build:rename-artifacts", + "bundle:firefox": "run-s precache:clean && shx cat add-on/manifest.common.json add-on/manifest.firefox.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/firefox/ && run-s build:rename-artifacts", "bundle:firefox:dev": "npm run bundle:firefox", "bundle:firefox:stable": "npm run bundle:firefox", - "bundle:firefox:beta": "shx cat add-on/manifest.common.json add-on/manifest.firefox.json add-on/manifest.firefox-beta.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/firefox/ && run-s build:rename-artifacts", + "bundle:firefox:beta": "run-s precache:clean && shx cat add-on/manifest.common.json add-on/manifest.firefox.json add-on/manifest.firefox-beta.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/firefox/ && run-s build:rename-artifacts", "bundle:fennec": "npm run bundle:firefox", "bundle:fennec:dev": "npm run bundle:firefox:dev", "bundle:fennec:stable": "npm run bundle:firefox:stable", "bundle:fennec:beta": "npm run bundle:firefox:beta", - "bundle:brave": "shx cat add-on/manifest.common.json add-on/manifest.chromium.json add-on/manifest.brave.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/brave/ && run-s build:rename-artifacts", + "bundle:brave": "run-s precache:webui && shx cat add-on/manifest.common.json add-on/manifest.chromium.json add-on/manifest.brave.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/brave/ && run-s build:rename-artifacts", "bundle:brave:dev": "npm run bundle:brave", "bundle:brave:stable": "npm run bundle:brave", - "bundle:brave:beta": "shx cat add-on/manifest.common.json add-on/manifest.chromium.json add-on/manifest.brave.json add-on/manifest.brave-beta.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/brave/ && run-s build:rename-artifacts", + "bundle:brave:beta": "run-s precache:webui && shx cat add-on/manifest.common.json add-on/manifest.chromium.json add-on/manifest.brave.json add-on/manifest.brave-beta.json | json --deep-merge > add-on/manifest.json && web-ext build -a build/brave/ && run-s build:rename-artifacts", "watch": "npm-run-all build:copy --parallel watch:*", "watch:js": "run-p watch:js:*", "watch:js:webpack": "webpack --watch --progress -d --devtool inline-source-map --config ./webpack.config.js", @@ -93,6 +96,7 @@ "get-firefox": "2.2.1", "husky": "3.0.8", "ignore-styles": "5.0.1", + "ipfs-or-gateway": "2.1.0", "json": "9.0.6", "mem-storage-area": "1.0.3", "mocha": "6.2.1", @@ -138,6 +142,7 @@ "is-fqdn": "1.0.1", "is-ipfs": "0.6.1", "is-svg": "4.2.0", + "it-to-stream": "0.1.1", "lru-cache": "5.1.1", "merge-options": "1.0.1", "mime-types": "2.1.24", @@ -151,6 +156,7 @@ "pull-file-reader": "1.0.2", "readable-stream": "3.4.0", "tachyons": "4.11.1", + "tar-stream": "2.1.0", "timers-browserify-full": "0.0.1", "uri-to-multiaddr": "3.0.1", "webextension-polyfill": "0.5.0", diff --git a/yarn.lock b/yarn.lock index e829d2d40..c5121eb1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1472,7 +1472,7 @@ abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: dependencies: xtend "~4.0.0" -abstract-leveldown@^6.2.1, abstract-leveldown@~6.2.1: +abstract-leveldown@^6.1.1: version "6.2.1" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.1.tgz#37b655151e13c3d9b20fa3a04ce63ccaa345fce4" integrity sha512-zUgomHedGBCThDkUtc1bfilu2jEhRZ7Dk3RePhtMma/akw7UK2Upm2R5Dd8ynRBEt3uscwbWO0VQNx22/7RtWg== @@ -1503,6 +1503,14 @@ abstract-leveldown@~6.0.1, abstract-leveldown@~6.0.3: level-concat-iterator "~2.0.0" xtend "~4.0.0" +abstract-leveldown@~6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.1.1.tgz#f44bad5862d71c7b418110d7698ac25bedf24396" + integrity sha512-7fK/KySVqzKIomdhkSWzX4YBQhzkzEMbWSiaB6mSN9e+ZdV3KEeKxia/8xQzCkATA5xnnukdP88cFR0D2FsFXw== + dependencies: + level-concat-iterator "~2.0.0" + xtend "~4.0.0" + abstract-logging@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-1.0.0.tgz#8b7deafd310559bc28f77724dd1bb30177278c1b" @@ -2789,7 +2797,7 @@ byteman@^1.3.5: resolved "https://registry.yarnpkg.com/byteman/-/byteman-1.3.5.tgz#d6061f7536c7e7c4bcb756037ef9c4c266ec51fd" integrity sha512-FzWDstifFRxtHX234b93AGa1b77dA6NUFpEXe+AoG1NydGN//XDZLMXxRNUoMf7SYYhVxfpwUEUgQOziearJvA== -bytes@3.1.0: +bytes@3.1.0, bytes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== @@ -3258,6 +3266,11 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" +cli-spinners@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" + integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== + cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" @@ -3804,7 +3817,7 @@ datastore-pubsub@^0.2.1: interface-datastore "~0.7.0" multibase "~0.6.0" -date-fns@^1.27.2: +date-fns@^1.27.2, date-fns@^1.30.1: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== @@ -4008,12 +4021,12 @@ deferred-leveldown@~4.0.0: abstract-leveldown "~5.0.0" inherits "^2.0.3" -deferred-leveldown@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" - integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== +deferred-leveldown@~5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.2.1.tgz#8da87909cd3269c2d6aff67b1e607f93e4d96c15" + integrity sha512-PwXZRn5EmW+IKYVAYVc7G9FsRkShr0myPubPuq+mtLhDq9xSUqfvTlNZKoeQGeXACHXkeCFurKrz5oo6TZ3qwg== dependencies: - abstract-leveldown "~6.2.1" + abstract-leveldown "~6.1.0" inherits "^2.0.3" define-properties@^1.1.2, define-properties@^1.1.3: @@ -4389,12 +4402,12 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding-down@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" - integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== +encoding-down@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.2.0.tgz#7ca52446dac6e0fd09ad3584a7359809ea1a4844" + integrity sha512-XlIoQMBMbU4aE01uSKpAix0sXBJWK8YPhuOdvKa1CroThZyUpj0zWzt+bbe7g1KWsdhNFFzHkQHSdDymVtpJ1w== dependencies: - abstract-leveldown "^6.2.1" + abstract-leveldown "^6.1.1" inherits "^2.0.3" level-codec "^9.0.0" level-errors "^2.0.0" @@ -7115,6 +7128,20 @@ ipfs-multipart@^0.2.0, ipfs-multipart@~0.2.0: "@hapi/content" "^4.1.0" it-multipart "~0.0.2" +ipfs-or-gateway@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipfs-or-gateway/-/ipfs-or-gateway-2.1.0.tgz#9f39d7da5916409f80b7301f9b4908fcc667c51e" + integrity sha512-bWSCVm2tah2ktciX1WOJtipiXcsCRR06VRSdZTT970RFVjw1pHV5DKdPZx9mMgjZuun/ss5J7pnYvyeLehnH3w== + dependencies: + abort-controller "^3.0.0" + fs-extra "^8.1.0" + node-fetch "^2.6.0" + node-fetch-progress "^1.0.2" + ora "^4.0.2" + pretty-bytes "^5.3.0" + tar "^4.4.8" + yargs "^13.2.1" + ipfs-postmsg-proxy@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/ipfs-postmsg-proxy/-/ipfs-postmsg-proxy-3.1.1.tgz#7f14fcaecddcd1ca41d2ee077757efe234c92ac0" @@ -7751,6 +7778,11 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + is-ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-2.0.0.tgz#68eea07e8a0a0a94c2d080dd674c731ab2a461ab" @@ -8112,7 +8144,7 @@ it-pipe@^1.0.1: resolved "https://registry.yarnpkg.com/it-pipe/-/it-pipe-1.0.1.tgz#6443f12e2a24dd71728c172eb58a159bb957095e" integrity sha512-clx7NMIf4eXe3rp4dKLmT5vMYv/hvZv4lNi1/xx4ZJ8CFmpGod9rTKisyBNBTurbCEa3a7503COankdBj/uUCA== -it-to-stream@^0.1.1: +it-to-stream@0.1.1, it-to-stream@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/it-to-stream/-/it-to-stream-0.1.1.tgz#3fb4a9c4df868cd8f4aaf2071eba5ada5a3fad2a" integrity sha512-QQx/58JBvT189imr6fD234F8aVf8EdyQHJR0MxXAOShEWK1NWyahPYIQt/tQG7PId0ZG/6/3tUiVCfw2cq+e1w== @@ -8627,12 +8659,12 @@ level-mem@^3.0.1: memdown "~3.0.0" level-packager@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.0.tgz#9c01c6c8e2380d3196d61e56bd79c2eff4a9d5c3" - integrity sha512-3pbJmDgGvp/lUQNULPoYQZtUbhMI8KoViYDw7Sa0kWl1mPeHWWJF7T/9upWI/NTMuEikkEE/cd6wBvmrW1+ZnQ== + version "5.0.3" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.0.3.tgz#e22bc9887663d0808ab092453d691bc319b7e5a2" + integrity sha512-Ut62o3nvUNCxYldM5+13+0sYow6ifKj2C26/0ToB7zKgdypF5wRKcVkcztQVwsQi+ZnrmDzhimp7FKP5Ynv6Rg== dependencies: - encoding-down "^6.3.0" - levelup "^4.3.2" + encoding-down "^6.2.0" + levelup "^4.2.0" level-packager@~4.0.0: version "4.0.1" @@ -8643,9 +8675,9 @@ level-packager@~4.0.0: levelup "^3.0.0" level-supports@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" - integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== + version "1.0.0" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.0.tgz#376f3f2339c23be0ba2fe62b0fa0e3ac7d6d9988" + integrity sha512-01PKZumFhgysuHUbRz4c9DyA1egmcHJBAsZbm0Vf5agojC3uWOvAnhOD4swNUgHlfJBymXLi/xkBaEckeNRSvA== dependencies: xtend "^4.0.2" @@ -8708,12 +8740,12 @@ levelup@^3.0.0: level-iterator-stream "~3.0.0" xtend "~4.0.0" -levelup@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.3.2.tgz#31c5b1b29f146d1d35d692e01a6da4d28fa55ebd" - integrity sha512-cRTjU4ktWo59wf13PHEiOayHC3n0dOh4i5+FHr4tv4MX9+l7mqETicNq3Aj07HKlLdk0z5muVoDL2RD+ovgiyA== +levelup@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.3.1.tgz#ac740019789de1a2987e109b00fcbdad9ddc6ac9" + integrity sha512-vXRqqNDSZxbY4atrfz+yXS2fdfq027chwvc6ihX/pQYplYdFoppkfHFaF0V3PDe2mCnhtyieaizRBzTpmL5wAg== dependencies: - deferred-leveldown "~5.3.0" + deferred-leveldown "~5.2.1" level-errors "~2.0.0" level-iterator-stream "~4.0.0" level-supports "~1.0.0" @@ -9425,6 +9457,13 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + log-update@2.3.x, log-update@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" @@ -9914,6 +9953,14 @@ minipass@^2.2.1, minipass@^2.3.5: safe-buffer "^5.1.2" yallist "^3.0.0" +minipass@^2.8.6: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + minipass@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.0.0.tgz#adb830268348df8b32217ceda3fc48684faff232" @@ -10534,6 +10581,15 @@ node-environment-flags@1.0.5: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" +node-fetch-progress@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-progress/-/node-fetch-progress-1.0.2.tgz#2e1f072d1bbe60bfe7676e151eefc58ae5feff7b" + integrity sha512-SHU7Ye0zcN/GHnjp2FMOLbJeJQ4ji68nicY6yF13VAmEZZKcbkjl3btkYmmtbVaL3gKoQxxba7WfTM6zOMUMyg== + dependencies: + bytes "^3.0.0" + date-fns "^1.30.1" + throttle-debounce "^2.1.0" + node-fetch@^2.2.0, node-fetch@^2.3.0, node-fetch@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" @@ -11003,6 +11059,19 @@ options@>=0.0.5: resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= +ora@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.2.tgz#0e1e68fd45b135d28648b27cf08081fa6e8a297d" + integrity sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig== + dependencies: + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-spinners "^2.2.0" + is-interactive "^1.0.0" + log-symbols "^3.0.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -11733,6 +11802,11 @@ prepost@^1.1.0: resolved "https://registry.yarnpkg.com/prepost/-/prepost-1.1.0.tgz#6131567ab6fe3007b50762679f4b500e93e8ccbf" integrity sha512-HhwOYePY0JXrbqAHm0fGWdSBFqGAMCJvdTaKGxO7uO6S0cbdxXeTnMWDkgAJDS+6kXATaV3n0C0EGI6tR+nqQA== +pretty-bytes@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" + integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== + pretty-hrtime@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -13964,6 +14038,17 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tar-stream@2.1.0, tar-stream@^2.0.0, tar-stream@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3" + integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw== + dependencies: + bl "^3.0.0" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar-stream@^1.5.0, tar-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" @@ -13977,17 +14062,6 @@ tar-stream@^1.5.0, tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" -tar-stream@^2.0.0, tar-stream@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3" - integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw== - dependencies: - bl "^3.0.0" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - tar@5.0.5: version "5.0.5" resolved "https://registry.yarnpkg.com/tar/-/tar-5.0.5.tgz#03fcdb7105bc8ea3ce6c86642b9c942495b04f93" @@ -14013,6 +14087,19 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.3" +tar@^4.4.8: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + taskcluster-client@^11.0.4: version "11.0.4" resolved "https://registry.yarnpkg.com/taskcluster-client/-/taskcluster-client-11.0.4.tgz#ea8df77d78ac72de5fb087bb6b884a25f33c90ee" @@ -14129,6 +14216,11 @@ thenify-all@^1.0.0, thenify-all@^1.6.0: dependencies: any-promise "^1.0.0" +throttle-debounce@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.1.0.tgz#257e648f0a56bd9e54fe0f132c4ab8611df4e1d5" + integrity sha512-AOvyNahXQuU7NN+VVvOOX+uW6FPaWdAOdRP5HfwYxAfCzXTFKRMoIMk+n+po318+ktcChx+F1Dd91G3YHeMKyg== + throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" @@ -14803,7 +14895,7 @@ wayfarer@^7.0.0: resolved "https://registry.yarnpkg.com/wayfarer/-/wayfarer-7.0.0.tgz#ae65e759628e5042bdaa380aa47bb736ca07380c" integrity sha512-mKF6pIaNHTdmwWjzrjbIWDnlgFFPC7MuQ+gbUVjBLpXp40mYmiP3Eb7qtO0rgAcsj3kuzGu3sN2Ya6GqOYiTwQ== -wcwidth@^1.0.0: +wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= @@ -15224,7 +15316,7 @@ yargs@13.2.4, yargs@^13.2.2: y18n "^4.0.0" yargs-parser "^13.1.0" -yargs@13.3.0, yargs@^13.3.0: +yargs@13.3.0, yargs@^13.2.1, yargs@^13.3.0: version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==