From da18a5a55134f26daa971a842e2419efaa944779 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 30 Oct 2024 20:50:42 +1100 Subject: [PATCH 01/38] pear stage does not require "main" in package.json (#398) --- subsystems/sidecar/ops/stage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsystems/sidecar/ops/stage.js b/subsystems/sidecar/ops/stage.js index 8a8bd5671..cf69e736c 100644 --- a/subsystems/sidecar/ops/stage.js +++ b/subsystems/sidecar/ops/stage.js @@ -111,13 +111,12 @@ module.exports = class Stage extends Opstream { if (dryRun) this.push({ tag: 'dry' }) const root = state.dir - const main = unixPathResolve('/', state.main) const src = new LocalDrive(root, { followLinks: bare === false, metadata: new Map() }) const dst = bundle.drive const opts = { ignore, dryRun, batch: true } const builtins = terminalBare ? sidecar.gunk.bareBuiltins : sidecar.gunk.builtins const linker = new ScriptLinker(src, { builtins }) - const entrypoints = [main, ...(state.manifest.pear?.stage?.entrypoints || [])].map((entry) => unixPathResolve('/', entry)) + const entrypoints = [...(state.manifest.main ? [state.main] : []), ...(state.manifest.pear?.stage?.entrypoints || [])].map((entry) => unixPathResolve('/', entry)) const mods = await linker.warmup(entrypoints) for await (const [filename, mod] of mods) src.metadata.put(filename, mod.cache()) const mirror = new Mirror(src, dst, opts) From a8c16ed8a9e7dce1c599be7b1bab3e72e80b9a00 Mon Sep 17 00:00:00 2001 From: David Mark Clements Date: Wed, 30 Oct 2024 11:37:20 +0100 Subject: [PATCH 02/38] app worker teardown iteration (#397) * app worker teardown * .. * endend * end end * fixed * fixed --- gui/gui.js | 25 +++++++++++-------------- lib/worker.js | 7 +++++-- test/fixtures/worker/index.js | 5 +++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/gui/gui.js b/gui/gui.js index a54889185..088c0c52b 100644 --- a/gui/gui.js +++ b/gui/gui.js @@ -10,7 +10,6 @@ const IPC = require('pear-ipc') const ReadyResource = require('ready-resource') const Worker = require('../lib/worker') const constants = require('../constants') - const kMap = Symbol('pear.gui.map') const kCtrl = Symbol('pear.gui.ctrl') @@ -380,7 +379,9 @@ class App { appReady = false static root = unixPathResolve(resolve(__dirname, '..')) - constructor (state, ipc) { + constructor (gui) { + const { state, ipc } = gui + this.gui = gui this.state = state this.ipc = ipc this.contextMenu = null @@ -647,8 +648,9 @@ class App { resolve(false) } }) - - const unloaders = PearGUI.ctrls().map((ctrl) => { + const pipes = [...this.gui.pipes] + const closingPipes = pipes.map((pipe) => new Promise((resolve) => { pipe.once('close', resolve) })) + const unloaders = [closingPipes, ...PearGUI.ctrls().map((ctrl) => { const closed = () => ctrl.closed if (!ctrl.unload) { if (ctrl.unloader) return ctrl.unloader.then(closed, closed) @@ -656,7 +658,8 @@ class App { } ctrl.unload({ type: 'close' }) return ctrl.unloader.then(closed, closed) - }) + })] + for (const pipe of pipes) pipe.end() const unloading = Promise.all(unloaders) unloading.then(clear, clear) const result = await Promise.race([timeout, unloading]) @@ -1498,8 +1501,8 @@ class PearGUI extends ReadyResource { electron.ipcMain.handle('versions', (evt, ...args) => this.versions(...args)) electron.ipcMain.handle('restart', (evt, ...args) => this.restart(...args)) - electron.ipcMain.on('workerRun', (evt, link) => { - const pipe = this.worker.run(link) + electron.ipcMain.on('workerRun', (evt, link, args) => { + const pipe = this.worker.run(link, args) const id = this.pipes.alloc(pipe) pipe.on('close', () => { this.pipes.free(id) @@ -1529,16 +1532,10 @@ class PearGUI extends ReadyResource { } pipe.write(data) }) - - electron.app.once('will-quit', () => { - for (const pipe of this.pipes) { - pipe.sp.kill('SIGTERM') - } - }) } async app () { - const app = new App(this.state, this.ipc) + const app = new App(this) this.once('close', async () => { app.quit() }) await app.start() return app diff --git a/lib/worker.js b/lib/worker.js index b7e3cdf07..c1e5cbaa3 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -39,7 +39,7 @@ class Worker { } run (link, args = []) { - if (isElectronRenderer) return this.#ipc.workerRun(link) + if (isElectronRenderer) return this.#ipc.workerRun(link, args) args = [...this.#args(link), ...args] const sp = spawn(constants.RUNTIME, args, { stdio: ['inherit', 'inherit', 'inherit', 'overlapped'], @@ -51,7 +51,9 @@ class Worker { this.#unref() }) const pipe = sp.stdio[3] - pipe.sp = sp + pipe.on('end', () => { + if (pipe.ended === false) pipe.end() + }) return pipe } @@ -65,6 +67,7 @@ class Worker { return null } const pipe = new Pipe(fd) + pipe.on('end', () => pipe.end()) this.#pipe = pipe pipe.once('close', () => { // allow close event to propagate between processes before exiting: diff --git a/test/fixtures/worker/index.js b/test/fixtures/worker/index.js index 495737978..24a536980 100644 --- a/test/fixtures/worker/index.js +++ b/test/fixtures/worker/index.js @@ -1,13 +1,14 @@ const pipe = Pear.worker.pipe() let i = 0 - +let interval = null pipe.on('data', (data) => { const str = data.toString() if (str === 'ping') { - setInterval(() => pipe.write((i++).toString()), 2000) + interval = setInterval(() => pipe.write((i++).toString()), 2000) } if (str === 'exit') { + clearInterval(interval) Pear.exit() } }) From 0d49b1457c302bd271ef0e7d2c2b9b714f61e3fb Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:16:20 +0100 Subject: [PATCH 03/38] updated changelog (#402) * updated changelog * Update CHANGELOG.md --------- Co-authored-by: David Mark Clements --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf1d7a61a..c69c90851 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Pear Runtime Changelog +## v1.6.0 + +### Features + +* Internal - Added sidecar logs +* Performance - Added DHT persistent cache + +### Fixes + +* Desktop - Forced teardown fix for Pear Desktop apps that take longer than 15 seconds to close +* Dependencies - udx-native updated to 1.13.3 +* Internal - Block of spindown while platform is updating +* Desktop - Fix teardown of worker on app exit + +### Improvements + +* API - Removed deprecated preferences methods from Pear API +* CLI - Added --force flag to `dump` +* Internal - Added RocksDB native support + ## v1.5.0 ### Features From c369ac3110d0894919ff6f09cea6424726b069a5 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 31 Oct 2024 02:38:42 +1100 Subject: [PATCH 04/38] dump-dry-run (#400) --- cmd/dump.js | 6 +++--- cmd/index.js | 1 + subsystems/sidecar/ops/dump.js | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cmd/dump.js b/cmd/dump.js index fb3eef39a..0b6d13d7f 100644 --- a/cmd/dump.js +++ b/cmd/dump.js @@ -6,7 +6,7 @@ const { outputter, permit, isTTY } = require('./iface') const output = outputter('stage', { dumping: ({ link, dir, list }) => list > -1 ? '' : `\nšŸ Dumping ${link} into ${dir}`, file: ({ key, value }) => `${key}${value ? '\n' + value : ''}`, - complete: '\nDumping complete!\n', + complete: ({ dryRun }) => { return dryRun ? '\nDumping dry run complete!\n' : '\nDumping complete!\n' }, error: (err, info, ipc) => { if (err.info && err.info.encrypted && info.ask && isTTY) { return permit(ipc, err.info, 'dump') @@ -19,11 +19,11 @@ const output = outputter('stage', { }) module.exports = (ipc) => async function dump (cmd) { - const { checkout, json, encryptionKey, ask, force } = cmd.flags + const { dryRun, checkout, json, encryptionKey, ask, force } = cmd.flags const { link } = cmd.args let { dir } = cmd.args if (!link) throw ERR_INVALID_INPUT(' must be specified.') if (!dir) throw ERR_INVALID_INPUT(' must be specified.') dir = dir === '-' ? '-' : (isAbsolute(dir) ? dir : resolve('.', dir)) - await output(json, ipc.dump({ id: Bare.pid, link, dir, checkout, encryptionKey, force }), { ask }, ipc) + await output(json, ipc.dump({ id: Bare.pid, link, dir, dryRun, checkout, encryptionKey, force }), { ask }, ipc) } diff --git a/cmd/index.js b/cmd/index.js index f99a22513..9634320b1 100644 --- a/cmd/index.js +++ b/cmd/index.js @@ -123,6 +123,7 @@ module.exports = async (ipc, argv = Bare.argv.slice(1)) => { summary('Synchronize files from key to dir'), arg('', 'Pear link to dump from, supports pathname'), arg('', 'Directory path to dump to, may be - for stdout'), + flag('--dry-run|-d', 'Execute a dump without writing'), flag('--checkout ', 'Dump from specified checkout, n is version length'), flag('--json', 'Newline delimited JSON output'), flag('--force|-f', 'Force overwrite existing files'), diff --git a/subsystems/sidecar/ops/dump.js b/subsystems/sidecar/ops/dump.js index 32dd9eaca..b5f736499 100644 --- a/subsystems/sidecar/ops/dump.js +++ b/subsystems/sidecar/ops/dump.js @@ -13,7 +13,7 @@ const hypercoreid = require('hypercore-id-encoding') module.exports = class Dump extends Opstream { constructor (...args) { super((...args) => this.#op(...args), ...args) } - async #op ({ link, dir, checkout, encryptionKey, force }) { + async #op ({ link, dir, dryRun, checkout, encryptionKey, force }) { const { session, sidecar } = this await sidecar.ready() @@ -65,6 +65,8 @@ module.exports = class Dump extends Opstream { this.push({ tag: 'dumping', data: { link, dir } }) + if (dryRun) this.push({ tag: 'dry' }) + if (!isFileLink) { try { await bundle.calibrate() @@ -98,7 +100,7 @@ module.exports = class Dump extends Opstream { const dst = new LocalDrive(dir) - const mirror = src.mirror(dst, { prefix }) + const mirror = src.mirror(dst, { dryRun, prefix }) for await (const diff of mirror) { if (diff.op === 'add') { this.push({ tag: 'byte-diff', data: { type: 1, sizes: [diff.bytesAdded], message: diff.key } }) From 44e63be4918ac44b9b176f5f47db5fd8359c70df Mon Sep 17 00:00:00 2001 From: dmc Date: Wed, 30 Oct 2024 17:17:12 +0100 Subject: [PATCH 05/38] decal disk run bug fix --- decal.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/decal.html b/decal.html index f8e477446..281d9aa0a 100644 --- a/decal.html +++ b/decal.html @@ -492,12 +492,14 @@

From af39125ea035d5d57fe5f81fab92b7bce2e5785a Mon Sep 17 00:00:00 2001 From: dmc Date: Wed, 30 Oct 2024 17:28:27 +0100 Subject: [PATCH 06/38] decal bar fix --- decal.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decal.html b/decal.html index 281d9aa0a..ddbece24f 100644 --- a/decal.html +++ b/decal.html @@ -814,11 +814,11 @@

} show () { this.shadowRoot.querySelector('#loader').style.display = 'block' - document.getElementById('bar').style.display = 'none' + document.getElementById('bar').style.display = 'block' } hide () { this.shadowRoot.querySelector('#loader').style.display = 'none' - document.getElementById('bar').style.display = 'block' + document.getElementById('bar').style.display = 'none' } async restart () { let countdown = 3000 From 9f9283fb291e45b1b7b2c1dee1e276832e3ade84 Mon Sep 17 00:00:00 2001 From: dmc Date: Wed, 30 Oct 2024 17:34:08 +0100 Subject: [PATCH 07/38] v1.6.0 changelog update --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c69c90851..e66717ea8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Internal - Added sidecar logs * Performance - Added DHT persistent cache +* CLI - `pear dump --dry-run` flag ### Fixes @@ -13,11 +14,12 @@ * Dependencies - udx-native updated to 1.13.3 * Internal - Block of spindown while platform is updating * Desktop - Fix teardown of worker on app exit +* Desktop - Decal run from disk bug fix +* Desktop - Decal bar bug fix ### Improvements * API - Removed deprecated preferences methods from Pear API -* CLI - Added --force flag to `dump` * Internal - Added RocksDB native support ## v1.5.0 From f4ef12afc2269330e7fb2e612ec9b83dafdec047 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 06:26:00 -0700 Subject: [PATCH 08/38] Bump deps (#410) Co-authored-by: GitHub Actions Bot --- package-lock.json | 69 +++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index c9939db40..f9e80753d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,24 +84,27 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -313,9 +316,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -571,9 +574,9 @@ } }, "node_modules/bare-bundle": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.7.2.tgz", - "integrity": "sha512-JBOB0+HpFtLec1QlIZOsqhjPif4yLvnlhSspxesnmm10CA40oQHFWuacVmNXY7Nc82H8GhEeGavaEXuvar8I8g==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.8.0.tgz", + "integrity": "sha512-D3UfsjylCRgI6EFY8YgSdL8/IfKqsfoLb72zAQzpr21zlLVSUuR36KvAp+KDqAm3NQWiUjVPdGjJAvEIjT3baw==" }, "node_modules/bare-cov": { "version": "1.0.1", @@ -780,9 +783,9 @@ } }, "node_modules/bare-url": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.5.tgz", - "integrity": "sha512-l+8YzaTQXR8JHPvgR156QCmuCQnXuyqutnYJiYTci7ec6AjdsQVFT7300wS+cyR1ujPaJqgccXrARhOs4WCpaw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.6.tgz", + "integrity": "sha512-Q5UfRDH9RE+EJjd4Jibg8h9QjnLStVzElNMCYaSB/azwCZ0A8GmGqeEb5osYyVeCKkvSGLP5WQI9vbVhn8mXyQ==", "dependencies": { "bare-path": "^3.0.0" } @@ -3046,15 +3049,6 @@ "resolved": "https://registry.npmjs.org/listen-async/-/listen-async-1.0.0.tgz", "integrity": "sha512-i8x+jPmM3YaeU+5zL+NWMwzPT0/WV0q23rviQuu9EkdPuAYjnnsa5LDL406hJ/QNNkziKpnJ1T+3VxJQELskqw==" }, - "node_modules/load-addon": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-addon/-/load-addon-1.0.0.tgz", - "integrity": "sha512-6XaA7xfpHW1CeQRrLFE9+9y8nDZMX3ZaoCMSo+Gp2i58dfY549SQqqb2ukAgQtAACEDJmaroHJvnL03cJ+KLvA==", - "deprecated": "Use require-addon instead", - "dependencies": { - "bare-addon-resolve": "^1.3.0" - } - }, "node_modules/load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", @@ -3935,6 +3929,17 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-addon": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.0.2.tgz", + "integrity": "sha512-KvQKkAf1bRtPBJ5mYSmiqF8h/84WEhI02RMseQ78GRSCz5tj1aziIMLtUEQbZ5wDtMGSZcgqT5PdwZ2OMMX/ZQ==", + "dependencies": { + "bare-addon-resolve": "^1.3.0" + }, + "engines": { + "bare": ">=1.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -3988,14 +3993,14 @@ } }, "node_modules/rocksdb-native": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-2.6.2.tgz", - "integrity": "sha512-3IZ/hpz+kvd9H5uLAj5HmWlldj1V0aLov3wMzx5CzET+Ucd+4y6YB0nDCvCM5Hny3NgBCABwhOCo7I5w3H7I/A==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-2.6.3.tgz", + "integrity": "sha512-836w8wT5E4tbLEWPtV44Hbu4ewRTzIDJjNqqlzj8YSgYtoh8KGAEt6dnF1w1M3qVi8/AFSO/r5IZo1k89f7aKQ==", "dependencies": { "b4a": "^1.6.6", "compact-encoding": "^2.15.0", - "load-addon": "^1.0.0", "ready-resource": "^1.0.0", + "require-addon": "^1.0.2", "streamx": "^2.16.1" } }, @@ -4234,9 +4239,9 @@ "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/sodium-native": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.2.2.tgz", - "integrity": "sha512-/gYaDtIK76FRcW0oBhIKJvLCDp706rJugd8wxJUBdbutgWrDlviG4tp8k+HfIRdy0Z+MbQE32ZGr4RPu1vXSsw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.2.1.tgz", + "integrity": "sha512-48X3PfRLW+f0fgb3J7f7mkZ9eBKcGR/bD5mdXXLAx4RWwKUe3095yPQgiUUQTfh8Q29JzwhSQATitQDBIozN/w==", "dependencies": { "node-gyp-build": "^4.8.0" } From 93b23f33d84eb405399c91a8a7be369ed135f905 Mon Sep 17 00:00:00 2001 From: Jan Keith Darunday Date: Mon, 4 Nov 2024 23:28:50 +0800 Subject: [PATCH 09/38] Remove terminal reload and restart (#411) * Disable terminal platform reload * Remove pear/reload message listener * Disable both restart and reload * Update error messages * Remove sending of pear/reload message * Remove unused import --- lib/api.js | 13 ++++++------- run.js | 22 +--------------------- subsystems/sidecar/index.js | 9 --------- 3 files changed, 7 insertions(+), 37 deletions(-) diff --git a/lib/api.js b/lib/api.js index 0e93d7f32..8e8f42402 100644 --- a/lib/api.js +++ b/lib/api.js @@ -1,6 +1,5 @@ 'use strict' const Worker = require('./worker') -const { BARE_RESTART_EXIT_CODE } = require('../constants') const noop = () => {} const teardown = global.Bare ? require('./teardown') : noop const program = global.Bare || global.process @@ -110,16 +109,16 @@ class API { versions = () => this.#reftrack(this.#ipc.versions()) restart = async (opts = {}) => { - const restart = this.#reftrack(this.#ipc.restart({ ...opts, hard: true })) - return restart + if (this.#state.type === 'terminal') throw new Error('Pear.restart is not supported for terminal apps') + + return this.#reftrack(this.#ipc.restart({ ...opts, hard: true })) } reload = async (opts = {}) => { - if (!opts.platform) { - // TODO: use Pear.shutdown when it lands instead - if (this.#state.type === 'terminal') Bare.exit(BARE_RESTART_EXIT_CODE) - else global.location.reload() + if (this.#state.type === 'terminal') throw new Error('Pear.reload is not supported for terminal apps') + if (!opts.platform) { + global.location.reload() return } diff --git a/run.js b/run.js index f54c5ffa6..db00c377c 100644 --- a/run.js +++ b/run.js @@ -19,8 +19,6 @@ const { } = require('./errors') const parseLink = require('./lib/parse-link') const teardown = require('./lib/teardown') -const { PLATFORM_LOCK } = require('./constants') -const fsext = require('fs-native-extensions') module.exports = async function run ({ ipc, args, cmdArgs, link, storage, detached, flags, appArgs, indices }) { const { drive, pathname } = parseLink(link) @@ -113,26 +111,8 @@ module.exports = async function run ({ ipc, args, cmdArgs, link, storage, detach const ipcConfig = await ipc.config() state.update({ config: ipcConfig }) - const pear = new API(ipc, state) + global.Pear = new API(ipc, state) - global.Pear = pear - - const reloadSubscriber = ipc.messages({ type: 'pear/reload' }) - reloadSubscriber.on('data', async () => { - ipc.stream.destroy() - - const fd = await new Promise((resolve, reject) => fs.open(PLATFORM_LOCK, 'r+', (err, fd) => err ? reject(err) : resolve(fd))) - await fsext.waitForLock(fd) - await new Promise((resolve, reject) => fs.close(fd, (err) => err ? reject(err) : resolve(fd))) - - await global.Pear.restart() - }).on('error', () => {}) - - global.Pear.teardown(async () => { - if (reloadSubscriber.destroyed) return - reloadSubscriber.end() - return new Promise((resolve) => reloadSubscriber.on('close', resolve)) - }) const protocol = new Module.Protocol({ exists (url) { return Object.hasOwn(bundle.sources, url.href) || Object.hasOwn(bundle.assets, url.href) diff --git a/subsystems/sidecar/index.js b/subsystems/sidecar/index.js index 776e77dd7..69d9766d4 100644 --- a/subsystems/sidecar/index.js +++ b/subsystems/sidecar/index.js @@ -557,15 +557,6 @@ class Sidecar extends ReadyResource { return } - if (!hard && this.hasClients) { - const seen = new Set() - for (const { userData: app } of this.clients) { - if (!app.state || seen.has(app.state.id)) continue - seen.add(app.state.id) - app.message({ type: 'pear/reload' }) - } - } - const sidecarClosed = new Promise((resolve) => this.corestore.once('close', resolve)) let restarts = await this.#shutdown(client) // ample time for any OS cleanup operations: From 9fe004a15309522f31620986f44f8642883cf829 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 5 Nov 2024 23:23:29 +1100 Subject: [PATCH 10/38] Improve worker runtime + teardown (#414) * worker-runtime-teardown * worker-runtime-teardown --- lib/worker.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/worker.js b/lib/worker.js index c1e5cbaa3..c146a298f 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -1,6 +1,7 @@ 'use strict' const { isElectronRenderer, isWindows, isBare } = require('which-runtime') const fs = isBare ? require('bare-fs') : require('fs') +const teardown = isBare ? require('./teardown') : (fn) => fn() const { spawn } = isBare ? require('bare-subprocess') : require('child_process') const { command } = require('paparam') const Pipe = isBare @@ -16,6 +17,7 @@ class Worker { #ref = null #unref = null #ipc = null + static RUNTIME = constants.RUNTIME constructor ({ ref = noop, unref = noop, ipc = null } = {}) { this.#ref = ref this.#unref = unref @@ -41,7 +43,7 @@ class Worker { run (link, args = []) { if (isElectronRenderer) return this.#ipc.workerRun(link, args) args = [...this.#args(link), ...args] - const sp = spawn(constants.RUNTIME, args, { + const sp = spawn(this.constructor.RUNTIME, args, { stdio: ['inherit', 'inherit', 'inherit', 'overlapped'], windowsHide: true }) @@ -67,11 +69,12 @@ class Worker { return null } const pipe = new Pipe(fd) - pipe.on('end', () => pipe.end()) + pipe.on('end', () => { + teardown(() => pipe.end(), Number.MAX_SAFE_INTEGER) + }) this.#pipe = pipe pipe.once('close', () => { - // allow close event to propagate between processes before exiting: - setImmediate(() => program.exit()) + teardown(() => program.exit(), Number.MAX_SAFE_INTEGER) }) return pipe } From 82a0f0db0d4f80e6801700e1c7acb360b8a27dba Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 5 Nov 2024 23:26:25 +1100 Subject: [PATCH 11/38] encrypted test (#415) * encrypted-test-2 * fix * encrypted --- test/04-encrypted.test.js | 27 ++++++++------ test/fixtures/encrypted/.npmrc | 2 - test/fixtures/encrypted/index.js | 21 ++++------- test/fixtures/encrypted/package.json | 9 ----- test/helper.js | 55 +++++++++++++++++++++++++++- 5 files changed, 77 insertions(+), 37 deletions(-) delete mode 100644 test/fixtures/encrypted/.npmrc diff --git a/test/04-encrypted.test.js b/test/04-encrypted.test.js index 38739408f..310d1b47c 100644 --- a/test/04-encrypted.test.js +++ b/test/04-encrypted.test.js @@ -12,12 +12,13 @@ test.hook('encrypted setup', rig.setup) test('stage, seed and run encrypted app', async function ({ ok, is, plan, comment, timeout, teardown }) { timeout(180000) - plan(7) + plan(8) + + const dir = encrypted const helper = new Helper(rig) teardown(() => helper.close(), { order: Infinity }) await helper.ready() - const dir = encrypted const id = Math.floor(Math.random() * 10000) @@ -31,11 +32,13 @@ test('stage, seed and run encrypted app', async function ({ ok, is, plan, commen comment('staging throws without encryption key') const stagingA = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(stagingA)) const error = await Helper.pick(stagingA, { tag: 'error' }) is(error.code, 'ERR_PERMISSION_REQUIRED') comment('staging with encryption key') const stagingB = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, encryptionKey: name, bare: true }) + teardown(() => Helper.teardownStream(stagingB)) const final = await Helper.pick(stagingB, { tag: 'final' }) ok(final.success, 'stage succeeded') @@ -43,27 +46,27 @@ test('stage, seed and run encrypted app', async function ({ ok, is, plan, commen const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, encryptionKey: name, cmdArgs: [] }) teardown(() => Helper.teardownStream(seeding)) const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) - const appKey = await until.key const announced = await until.announced ok(announced, 'seeding is announced') - comment('run encrypted pear application') - const link = 'pear://' + appKey - const running = await Helper.open(link, { tags: ['exit'] }, { platformDir: rig.platformDir, encryptionKey: name }) - const { value } = await running.inspector.evaluate('Pear.versions()', { awaitPromise: true }) + const key = await until.key + ok(hypercoreid.isValid(key), 'app key is valid') - is(value?.app?.key, appKey, 'app version matches staged key') + const link = `pear://${key}` + const { pipe } = await Helper.run({ link, encryptionKey: name, platformDir: rig.platformDir }) - await running.inspector.evaluate('disableInspector()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + const result = await Helper.untilResult(pipe) + const versions = JSON.parse(result) + is(versions.app.key, key, 'app version matches staged key') comment('pear info encrypted app') const infoCmd = helper.info({ link, encryptionKey: name, cmdArgs: [] }) const untilInfo = await Helper.pick(infoCmd, [{ tag: 'info' }]) const info = await untilInfo.info ok(info, 'retrieves info from encrypted app') + + await Helper.untilClose(pipe) + ok(true, 'ended') }) test.hook('encrypted cleanup', rig.cleanup) diff --git a/test/fixtures/encrypted/.npmrc b/test/fixtures/encrypted/.npmrc deleted file mode 100644 index b15cbc2c0..000000000 --- a/test/fixtures/encrypted/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -package-lock=false - diff --git a/test/fixtures/encrypted/index.js b/test/fixtures/encrypted/index.js index 6ef4509c5..904c6250d 100644 --- a/test/fixtures/encrypted/index.js +++ b/test/fixtures/encrypted/index.js @@ -1,13 +1,8 @@ -import bareInspector from 'bare-inspector' -import { Inspector } from 'pear-inspect' - -const inspector = new Inspector({ inspector: bareInspector }) -const key = await inspector.enable() -const inspectorKey = key.toString('hex') -console.log(`{ "tag": "inspector", "data": { "key": "${inspectorKey}" }}`) - -function disableInspector () { - inspector.disable() -} - -global.disableInspector = disableInspector +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + Pear.versions().then((versions) => { + pipe.write(JSON.stringify(versions)) + }).catch((err) => { + pipe.write(`${err}`) + }) +}) diff --git a/test/fixtures/encrypted/package.json b/test/fixtures/encrypted/package.json index dc30072de..cf1b91ce5 100644 --- a/test/fixtures/encrypted/package.json +++ b/test/fixtures/encrypted/package.json @@ -1,18 +1,9 @@ { "name": "encrypted", - "version": "1.0.0", - "description": "", "main": "index.js", - "type": "module", "pear": { "name": "encrypted", "type": "terminal", "encrypted": true - }, - "keywords": [], - "author": "Holepunch", - "dependencies": { - "bare-inspector": "^3.0.1", - "pear-inspect": "^1.2.2" } } diff --git a/test/helper.js b/test/helper.js index 0e7f64cb9..7d9038114 100644 --- a/test/helper.js +++ b/test/helper.js @@ -16,12 +16,14 @@ const updaterBootstrap = require('pear-updater-bootstrap') const b4a = require('b4a') const HOST = platform + '-' + arch const BY_ARCH = path.join('by-arch', HOST, 'bin', `pear-runtime${isWindows ? '.exe' : ''}`) -const { PLATFORM_DIR } = require('../constants') +const constants = require('../constants') +const { PLATFORM_DIR, RUNTIME } = constants const { pathname } = new URL(global.Pear.config.applink) const NO_GC = global.Pear.config.args.includes('--no-tmp-gc') const MAX_OP_STEP_WAIT = env.CI ? 360000 : 120000 const tmp = fs.realpathSync(os.tmpdir()) Error.stackTraceLimit = Infinity +const program = global.Bare || global.process const rigPear = path.join(tmp, 'rig-pear') @@ -143,6 +145,57 @@ class Helper extends IPC { // ONLY ADD STATICS, NEVER ADD PUBLIC METHODS OR PROPERTIES (see pear-ipc) static localDir = isWindows ? path.normalize(pathname.slice(1)) : pathname + static async run ({ link, encryptionKey, platformDir }) { + if (encryptionKey) program.argv.splice(2, 0, '--encryption-key', encryptionKey) + if (platformDir) Pear.worker.constructor.RUNTIME = path.join(platformDir, 'current', BY_ARCH) + + const pipe = Pear.worker.run(link) + + if (platformDir) Pear.worker.constructor.RUNTIME = RUNTIME + if (encryptionKey) program.argv.splice(2, 2) + + return { pipe } + } + + static async untilResult (pipe, timeout = 5000) { + const res = new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => reject(new Error('timed out')), timeout) + pipe.on('data', (data) => { + clearTimeout(timeoutId) + resolve(data.toString()) + }) + pipe.on('close', () => { + clearTimeout(timeoutId) + reject(new Error('unexpected closed')) + }) + pipe.on('end', () => { + clearTimeout(timeoutId) + reject(new Error('unexpected ended')) + }) + }) + pipe.write('start') + return res + } + + static async untilClose (pipe, timeout = 5000) { + // TODO: fix the "Error: RPC destroyed" when calling pipe.end() too fast, then remove this hack delay + await new Promise((resolve) => setTimeout(resolve, 1000)) + + const res = new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => reject(new Error('timed out')), timeout) + pipe.on('close', () => { + clearTimeout(timeoutId) + resolve('closed') + }) + pipe.on('end', () => { + clearTimeout(timeoutId) + resolve('ended') + }) + }) + pipe.end() + return res + } + static async open (link, { tags = [] } = {}, opts = {}) { if (!link) throw new Error('Key is missing') From c4e212889a9702a9511dea1357a861f50583a2c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:01:01 +0100 Subject: [PATCH 12/38] Bump deps (#413) Co-authored-by: GitHub Actions Bot --- package-lock.json | 59 +++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9e80753d..9c74e796b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -558,11 +558,11 @@ "dev": true }, "node_modules/bare-addon-resolve": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.5.1.tgz", - "integrity": "sha512-GGNEyxmA8msVlYYK9N0YRwGnT1tK9wrcP9Im8ij8pCBXxDvk5324eIXGpiEiTURQzYvZtaa5Vnv4N9vqLulLyA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.6.0.tgz", + "integrity": "sha512-knN/FxR5o7LVdyEnYCC7V1m1T2vOKw+T+zAl165hiXeva1/nqbfug131QRvrfiEjIu8PEXtUy9KcM4F+rCcGkg==", "dependencies": { - "bare-module-resolve": "^1.5.0" + "bare-module-resolve": "^1.8.0" } }, "node_modules/bare-ansi-escapes": { @@ -672,21 +672,29 @@ } }, "node_modules/bare-module": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.5.2.tgz", - "integrity": "sha512-ezBENLzjH7ilcazHpp7A5Ovi/K5k8YRID0cqQHZvY+XeL1dlD1xaqMb03ggk8L0xHvsG4OIAHswuV0NNOy/rFg==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.0.tgz", + "integrity": "sha512-HQf1acyCl1ga1ihfvYxLQoM2VwgCSmqBMe2DxEzmiBlE1vJPHHlXh/9tX0xLYSoVrLiEHGRfdTGjUccUWQaxnA==", "dependencies": { "bare-bundle": "^1.3.0", - "bare-module-resolve": "^1.6.0", + "bare-module-lexer": "^1.0.0", + "bare-module-resolve": "^1.8.0", "bare-path": "^3.0.0", - "bare-url": "^2.0.1", - "cjs-module-lexer": "^1.2.3" + "bare-url": "^2.0.1" + } + }, + "node_modules/bare-module-lexer": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.0.6.tgz", + "integrity": "sha512-kP8wY9LtqaI5Iqqn+NRDuT53XMdeOmZrsKrrvA9VchgOMTWkU+4sTGMLOgIxty/uglcJxeMguH0F94L46sqQSQ==", + "dependencies": { + "require-addon": "^1.0.2" } }, "node_modules/bare-module-resolve": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.7.2.tgz", - "integrity": "sha512-OXOaRhMPrBnhEXwSWgoM3CFLfZeRL7YY9hiBTi3wHxjeHs8pP2Si66OU2LCI/EVTJ20+kyICHtSY4IefUHLY/A==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.8.0.tgz", + "integrity": "sha512-3UHBfM3manIQYgh0ximl5dMvX+DW09r69KTrZ9Ibfr85OFVyN4oGMrg67X7MXrdoQeXFkzb++BgGaNKcVmPObw==", "dependencies": { "semifies": "^1.0.0" } @@ -783,9 +791,9 @@ } }, "node_modules/bare-url": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.6.tgz", - "integrity": "sha512-Q5UfRDH9RE+EJjd4Jibg8h9QjnLStVzElNMCYaSB/azwCZ0A8GmGqeEb5osYyVeCKkvSGLP5WQI9vbVhn8mXyQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.7.tgz", + "integrity": "sha512-SY52Xkmk3Fc6Ome0Ta7LZzrkiRKVA57LQWvsAnenQ0HwwXQvK/JPu6FBcLuuIdHKRZzKsNQXON5DONCxmBURNA==", "dependencies": { "bare-path": "^3.0.0" } @@ -1326,9 +1334,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", - "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz", + "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -1339,6 +1347,7 @@ "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.4", + "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", @@ -1979,9 +1988,9 @@ } }, "node_modules/flat-tree": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/flat-tree/-/flat-tree-1.12.0.tgz", - "integrity": "sha512-hcDXNuIIugsOYPYogrDAvTwrvXw8q1AybTGyPNy+QdA8JWdgcnVceLfWpJIkAmH1itJiDeqjpjvLmnTFF6fi4Q==" + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/flat-tree/-/flat-tree-1.12.1.tgz", + "integrity": "sha512-GchQ+onbnw5QaqsGbpcV6c8etAd396X/EVdDxutQMkGapB0lRvV9heIXS6ZffQVCse0hm2hBpK7GJz2Zp7qiMg==" }, "node_modules/flatted": { "version": "3.3.1", @@ -4687,9 +4696,9 @@ } }, "node_modules/udx-native": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.0.tgz", - "integrity": "sha512-w4/bZsvzg5lZwBPRx56mGsQMD1HtnL81s5ig96xzX6GPGMCdOMfxa4ktAM2qh7vOj1nu6kL2FjKBO+Fe7lUBrw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.1.tgz", + "integrity": "sha512-8NWeYnXWpixAyEE1U6/pIT5ErOjZA+js2tjZWOjLZPbFkpM/aTn7N7jgWXztvHlOODjbSh7oWCnaqs1/hqkVLg==", "dependencies": { "b4a": "^1.5.0", "bare-events": "^2.2.0", From 5b0f947d7e1aac70e3d1c059c4e347ad9457dc84 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:41:41 +0100 Subject: [PATCH 13/38] rollback bare-module (#418) --- package-lock.json | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c74e796b..84fbbdaa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -672,23 +672,15 @@ } }, "node_modules/bare-module": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.0.tgz", - "integrity": "sha512-HQf1acyCl1ga1ihfvYxLQoM2VwgCSmqBMe2DxEzmiBlE1vJPHHlXh/9tX0xLYSoVrLiEHGRfdTGjUccUWQaxnA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.5.2.tgz", + "integrity": "sha512-ezBENLzjH7ilcazHpp7A5Ovi/K5k8YRID0cqQHZvY+XeL1dlD1xaqMb03ggk8L0xHvsG4OIAHswuV0NNOy/rFg==", "dependencies": { "bare-bundle": "^1.3.0", - "bare-module-lexer": "^1.0.0", - "bare-module-resolve": "^1.8.0", + "bare-module-resolve": "^1.6.0", "bare-path": "^3.0.0", - "bare-url": "^2.0.1" - } - }, - "node_modules/bare-module-lexer": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.0.6.tgz", - "integrity": "sha512-kP8wY9LtqaI5Iqqn+NRDuT53XMdeOmZrsKrrvA9VchgOMTWkU+4sTGMLOgIxty/uglcJxeMguH0F94L46sqQSQ==", - "dependencies": { - "require-addon": "^1.0.2" + "bare-url": "^2.0.1", + "cjs-module-lexer": "^1.2.3" } }, "node_modules/bare-module-resolve": { From b9c04db63a4d9e328dd7843a847ece486b086c9b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 00:50:51 +0100 Subject: [PATCH 14/38] Bump deps (#421) Co-authored-by: GitHub Actions Bot --- package-lock.json | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 84fbbdaa7..f56bb79a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -672,15 +672,23 @@ } }, "node_modules/bare-module": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.5.2.tgz", - "integrity": "sha512-ezBENLzjH7ilcazHpp7A5Ovi/K5k8YRID0cqQHZvY+XeL1dlD1xaqMb03ggk8L0xHvsG4OIAHswuV0NNOy/rFg==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.0.tgz", + "integrity": "sha512-HQf1acyCl1ga1ihfvYxLQoM2VwgCSmqBMe2DxEzmiBlE1vJPHHlXh/9tX0xLYSoVrLiEHGRfdTGjUccUWQaxnA==", "dependencies": { "bare-bundle": "^1.3.0", - "bare-module-resolve": "^1.6.0", + "bare-module-lexer": "^1.0.0", + "bare-module-resolve": "^1.8.0", "bare-path": "^3.0.0", - "bare-url": "^2.0.1", - "cjs-module-lexer": "^1.2.3" + "bare-url": "^2.0.1" + } + }, + "node_modules/bare-module-lexer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.0.7.tgz", + "integrity": "sha512-udUm4rxx65rmpSpU+zw0NHLKhLNwCUaTj3GdTbTX0kGktpwaGpt+94CKGOJ+IplNt5MES3Ok7NdQDBU5fV2HCw==", + "dependencies": { + "require-addon": "^1.0.2" } }, "node_modules/bare-module-resolve": { @@ -2413,9 +2421,9 @@ } }, "node_modules/hyperdrive": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.13.0.tgz", - "integrity": "sha512-G+1iwjGb6FcpVbfNrWCnD8LHuch0cV/qagdHY25N6sKUt9+8QoO1OGkdSnX9yjvZ5U40mHAmZeSzAq0jnynJAQ==", + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.13.1.tgz", + "integrity": "sha512-V7JJ0bVhjRrhfo0WrAOPMQ2RVBZQqG1qbd2V96tnvKJ1/eqq4gWEOKl/tHMX0j1+N5jABgKmSgb60NNEfTTscQ==", "dependencies": { "hyperbee": "^2.11.1", "hyperblobs": "^2.3.0", @@ -3582,13 +3590,13 @@ } }, "node_modules/pear-updater-bootstrap": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pear-updater-bootstrap/-/pear-updater-bootstrap-1.2.1.tgz", - "integrity": "sha512-WYCaP47Sj0Mn0vZ/0kRuawthkPg3UlzTIZ9DU8r019RMNg5if/n13I5cLkEx01Sx+t40VhmiVbuDy5usY/39kA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pear-updater-bootstrap/-/pear-updater-bootstrap-1.2.2.tgz", + "integrity": "sha512-/rfkQ3/A6fr/0c1cg81c42PgFVErj0cersBhud8MC3M26GseMLpD0fWh+XrWYa5OBtLjJrn4N+z51iaw2Xxf/w==", "dependencies": { "corestore": "^6.16.2", "hypercore-id-encoding": "^1.2.0", - "hyperdrive": "^11.6.3", + "hyperdrive": "^11.13.1", "hyperswarm": "^4.7.14", "pear-updater": "^3.0.1" }, From b53715cb230c9b6b9002430fbf907ce9f5916f49 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Wed, 6 Nov 2024 01:18:23 +0100 Subject: [PATCH 15/38] Revert "Bump deps (#421)" (#422) This reverts commit b9c04db63a4d9e328dd7843a847ece486b086c9b. --- package-lock.json | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index f56bb79a7..84fbbdaa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -672,23 +672,15 @@ } }, "node_modules/bare-module": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.0.tgz", - "integrity": "sha512-HQf1acyCl1ga1ihfvYxLQoM2VwgCSmqBMe2DxEzmiBlE1vJPHHlXh/9tX0xLYSoVrLiEHGRfdTGjUccUWQaxnA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.5.2.tgz", + "integrity": "sha512-ezBENLzjH7ilcazHpp7A5Ovi/K5k8YRID0cqQHZvY+XeL1dlD1xaqMb03ggk8L0xHvsG4OIAHswuV0NNOy/rFg==", "dependencies": { "bare-bundle": "^1.3.0", - "bare-module-lexer": "^1.0.0", - "bare-module-resolve": "^1.8.0", + "bare-module-resolve": "^1.6.0", "bare-path": "^3.0.0", - "bare-url": "^2.0.1" - } - }, - "node_modules/bare-module-lexer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.0.7.tgz", - "integrity": "sha512-udUm4rxx65rmpSpU+zw0NHLKhLNwCUaTj3GdTbTX0kGktpwaGpt+94CKGOJ+IplNt5MES3Ok7NdQDBU5fV2HCw==", - "dependencies": { - "require-addon": "^1.0.2" + "bare-url": "^2.0.1", + "cjs-module-lexer": "^1.2.3" } }, "node_modules/bare-module-resolve": { @@ -2421,9 +2413,9 @@ } }, "node_modules/hyperdrive": { - "version": "11.13.1", - "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.13.1.tgz", - "integrity": "sha512-V7JJ0bVhjRrhfo0WrAOPMQ2RVBZQqG1qbd2V96tnvKJ1/eqq4gWEOKl/tHMX0j1+N5jABgKmSgb60NNEfTTscQ==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.13.0.tgz", + "integrity": "sha512-G+1iwjGb6FcpVbfNrWCnD8LHuch0cV/qagdHY25N6sKUt9+8QoO1OGkdSnX9yjvZ5U40mHAmZeSzAq0jnynJAQ==", "dependencies": { "hyperbee": "^2.11.1", "hyperblobs": "^2.3.0", @@ -3590,13 +3582,13 @@ } }, "node_modules/pear-updater-bootstrap": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/pear-updater-bootstrap/-/pear-updater-bootstrap-1.2.2.tgz", - "integrity": "sha512-/rfkQ3/A6fr/0c1cg81c42PgFVErj0cersBhud8MC3M26GseMLpD0fWh+XrWYa5OBtLjJrn4N+z51iaw2Xxf/w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pear-updater-bootstrap/-/pear-updater-bootstrap-1.2.1.tgz", + "integrity": "sha512-WYCaP47Sj0Mn0vZ/0kRuawthkPg3UlzTIZ9DU8r019RMNg5if/n13I5cLkEx01Sx+t40VhmiVbuDy5usY/39kA==", "dependencies": { "corestore": "^6.16.2", "hypercore-id-encoding": "^1.2.0", - "hyperdrive": "^11.13.1", + "hyperdrive": "^11.6.3", "hyperswarm": "^4.7.14", "pear-updater": "^3.0.1" }, From 04e32658764176b1dbb4ba0713285dcf5394e1a6 Mon Sep 17 00:00:00 2001 From: Jan Keith Darunday Date: Wed, 6 Nov 2024 08:32:20 +0800 Subject: [PATCH 16/38] Disable platform reload in desktop applications (#419) * Disable desktop platform reload * Remove unused hard restart IPC option --- lib/api.js | 10 +++------- subsystems/sidecar/index.js | 6 ++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/api.js b/lib/api.js index 8e8f42402..6e413a8a1 100644 --- a/lib/api.js +++ b/lib/api.js @@ -111,18 +111,14 @@ class API { restart = async (opts = {}) => { if (this.#state.type === 'terminal') throw new Error('Pear.restart is not supported for terminal apps') - return this.#reftrack(this.#ipc.restart({ ...opts, hard: true })) + return this.#reftrack(this.#ipc.restart(opts)) } reload = async (opts = {}) => { if (this.#state.type === 'terminal') throw new Error('Pear.reload is not supported for terminal apps') + if (opts.platform) throw new Error('Platform Pear.reload is not supported for desktop apps') - if (!opts.platform) { - global.location.reload() - return - } - - return this.#reftrack(this.#ipc.restart({ ...opts, hard: false })) + global.location.reload() } updates = (listener) => this.messages({ type: 'pear/updates' }, listener) diff --git a/subsystems/sidecar/index.js b/subsystems/sidecar/index.js index 69d9766d4..61ca93893 100644 --- a/subsystems/sidecar/index.js +++ b/subsystems/sidecar/index.js @@ -517,8 +517,8 @@ class Sidecar extends ReadyResource { return metadata } - async restart ({ platform = false, hard = true } = {}, client) { - LOG.info('sidecar', `${hard ? 'Hard' : 'Soft'} restarting ${platform ? 'platform' : 'client'}`) + async restart ({ platform = false } = {}, client) { + LOG.info('sidecar', `Restarting ${platform ? 'platform' : 'client'}`) if (platform === false) { const { dir, cwd, cmdArgs, env } = client.userData.state const appling = client.userData.state.appling @@ -564,8 +564,6 @@ class Sidecar extends ReadyResource { // shutdown successful, reset death clock this.deathClock() - if (!hard) return - restarts = restarts.filter(({ run }) => run) if (restarts.length === 0) return LOG.info('sidecar', 'Restarting', restarts.length, 'apps') From c68a6a475cacf43f55ee57d26cde74598f595d02 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 6 Nov 2024 11:58:15 +1100 Subject: [PATCH 17/38] smoke test with worker (#405) --- scripts/test.mjs | 3 +- test/.gitignore | 3 +- test/01-smoke.test.js | 178 ++++++++++++------ test/fixtures/app-with-assets/index.js | 28 --- test/fixtures/app-with-assets/lib/utils.js | 6 - test/fixtures/app-with-assets/package.json | 15 -- test/fixtures/dht-bootstrap/index.js | 9 + test/fixtures/dht-bootstrap/package.json | 8 + test/fixtures/require-assets/index.js | 11 ++ test/fixtures/require-assets/package.json | 11 ++ .../text-file.txt | 0 test/fixtures/sub-dep-require-assets/index.js | 11 ++ .../sub-dep-require-assets/lib/utils.js | 3 + .../sub-dep-require-assets/package.json | 11 ++ .../sub-dep-require-assets/text-file.txt | 1 + test/fixtures/versions/index.js | 9 + test/fixtures/versions/package.json | 8 + 17 files changed, 210 insertions(+), 105 deletions(-) delete mode 100644 test/fixtures/app-with-assets/index.js delete mode 100644 test/fixtures/app-with-assets/lib/utils.js delete mode 100644 test/fixtures/app-with-assets/package.json create mode 100644 test/fixtures/dht-bootstrap/index.js create mode 100644 test/fixtures/dht-bootstrap/package.json create mode 100644 test/fixtures/require-assets/index.js create mode 100644 test/fixtures/require-assets/package.json rename test/fixtures/{app-with-assets => require-assets}/text-file.txt (100%) create mode 100644 test/fixtures/sub-dep-require-assets/index.js create mode 100644 test/fixtures/sub-dep-require-assets/lib/utils.js create mode 100644 test/fixtures/sub-dep-require-assets/package.json create mode 100644 test/fixtures/sub-dep-require-assets/text-file.txt create mode 100644 test/fixtures/versions/index.js create mode 100644 test/fixtures/versions/package.json diff --git a/scripts/test.mjs b/scripts/test.mjs index 5bc368ec0..8a1634091 100644 --- a/scripts/test.mjs +++ b/scripts/test.mjs @@ -16,7 +16,8 @@ const force = Bare.argv.includes('--force-install') const dirs = [ path.join(root, 'test', 'fixtures', 'harness', 'node_modules'), path.join(root, 'test', 'fixtures', 'encrypted', 'node_modules'), - path.join(root, 'test', 'fixtures', 'app-with-assets', 'node_modules') + path.join(root, 'test', 'fixtures', 'require-assets', 'node_modules'), + path.join(root, 'test', 'fixtures', 'sub-dep-require-assets', 'node_modules') ] for (const dir of dirs) { if (force === false && fs.existsSync(dir)) continue diff --git a/test/.gitignore b/test/.gitignore index b334f9221..35975d3c1 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,3 +1,4 @@ corestores node_modules -.DS_Store \ No newline at end of file +.DS_Store +package-lock.json diff --git a/test/01-smoke.test.js b/test/01-smoke.test.js index b7e01f0b1..a5f1d17e7 100644 --- a/test/01-smoke.test.js +++ b/test/01-smoke.test.js @@ -3,92 +3,162 @@ const test = require('brittle') const path = require('bare-path') const hypercoreid = require('hypercore-id-encoding') const Helper = require('./helper') -const harness = path.join(Helper.localDir, 'test', 'fixtures', 'harness') -const assets = path.join(Helper.localDir, 'test', 'fixtures', 'app-with-assets') +const versionsDir = path.join(Helper.localDir, 'test', 'fixtures', 'versions') +const dhtBootstrapDir = path.join(Helper.localDir, 'test', 'fixtures', 'dht-bootstrap') +const requireAssets = path.join(Helper.localDir, 'test', 'fixtures', 'require-assets') +const subDepRequireAssets = path.join(Helper.localDir, 'test', 'fixtures', 'sub-dep-require-assets') -test('smoke', async function ({ ok, is, plan, comment, teardown, timeout, end }) { +test('smoke', async function ({ ok, is, alike, plan, comment, teardown, timeout }) { timeout(180000) - plan(6) - const stager = new Helper() - teardown(() => stager.close(), { order: Infinity }) - await stager.ready() - const dir = harness + plan(10) + + const testVersions = async () => { + const dir = versionsDir + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const id = Math.floor(Math.random() * 10000) + + comment('staging') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') + + comment('seeding') + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + teardown(() => Helper.teardownStream(seeding)) + const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) + const announced = await until.announced + ok(announced, 'seeding is announced') + + const key = await until.key + ok(hypercoreid.isValid(key), 'app key is valid') + + const link = `pear://${key}` + const run = await Helper.run({ link }) + + const result = await Helper.untilResult(run.pipe) + const versions = JSON.parse(result) + is(versions.app.key, key, 'app version matches staged key') + + await Helper.untilClose(run.pipe) + ok(true, 'ended') + } + + const testDhtBootstrap = async () => { + const dir = dhtBootstrapDir + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const id = Math.floor(Math.random() * 10000) + + comment('staging') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') + + comment('seeding') + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + teardown(() => Helper.teardownStream(seeding)) + const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) + const announced = await until.announced + ok(announced, 'seeding is announced') + + const key = await until.key + ok(hypercoreid.isValid(key), 'app key is valid') + + const link = `pear://${key}` + const run = await Helper.run({ link }) + + const result = await Helper.untilResult(run.pipe) + const dhtBootstrap = JSON.parse(result) + alike(dhtBootstrap, Pear.config.dht.bootstrap, 'dht bootstrap matches Pear.config.dht.bootstrap') + + await Helper.untilClose(run.pipe) + ok(true, 'ended') + } + + await Promise.all([testVersions(), testDhtBootstrap()]) +}) + +test('app with assets', async function ({ ok, is, plan, comment, teardown, timeout }) { + timeout(180000) + plan(5) + + const dir = requireAssets + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() const id = Math.floor(Math.random() * 10000) comment('staging') - const staging = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) teardown(() => Helper.teardownStream(staging)) - const final = await Helper.pick(staging, { tag: 'final' }) - ok(final.success, 'stage succeeded') + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') comment('seeding') - const seeder = new Helper() - teardown(() => seeder.close(), { order: Infinity }) - await seeder.ready() - const seeding = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) teardown(() => Helper.teardownStream(seeding)) const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) - - const key = await until.key const announced = await until.announced - - ok(hypercoreid.isValid(key), 'app key is valid') ok(announced, 'seeding is announced') - comment('running') - const link = 'pear://' + key - const running = await Helper.open(link, { tags: ['exit'] }) + const key = await until.key + ok(hypercoreid.isValid(key), 'app key is valid') - const { value } = await running.inspector.evaluate('Pear.versions()', { awaitPromise: true }) - is(value?.app?.key, key, 'app version matches staged key') + const link = `pear://${key}` + const run = await Helper.run({ link }) - const dhtBootstrap = await running.inspector.evaluate('Pear.config.dht.bootstrap') - is(JSON.stringify(dhtBootstrap.value), JSON.stringify(Pear.config.dht.bootstrap), 'dht bootstrap matches Pear.config.dth.bootstrap') + const result = await Helper.untilResult(run.pipe) + is(result.trim(), 'This is the content of the asset', 'Read asset from entrypoint') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(run.pipe) + ok(true, 'ended') }) -test('app with assets', async function ({ is, plan, comment, teardown, timeout }) { +test('app with assets in sub dep', async function ({ ok, is, plan, comment, teardown, timeout }) { timeout(180000) - plan(3) - const stager = new Helper() - teardown(() => stager.close(), { order: Infinity }) - await stager.ready() - const dir = assets + plan(5) + + const dir = subDepRequireAssets + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() const id = Math.floor(Math.random() * 10000) comment('staging') - const staging = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) teardown(() => Helper.teardownStream(staging)) - await Helper.pick(staging, { tag: 'final' }) + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') comment('seeding') - const seeder = new Helper() - teardown(() => seeder.close(), { order: Infinity }) - await seeder.ready() - const seeding = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) teardown(() => Helper.teardownStream(seeding)) const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) + const announced = await until.announced + ok(announced, 'seeding is announced') const key = await until.key - await until.announced - - comment('running') - const link = 'pear://' + key - const running = await Helper.open(link, { tags: ['exit'] }) + ok(hypercoreid.isValid(key), 'app key is valid') - const { value: fromIndex } = await running.inspector.evaluate('global.readAsset()', { awaitPromise: true }) - is(fromIndex.trim(), 'This is the content of the asset', 'Read asset from entrypoint') + const link = `pear://${key}` + const run = await Helper.run({ link }) - const { value: fromUtils } = await running.inspector.evaluate('global.readAssetFromUtils()', { awaitPromise: true }) - is(fromUtils.trim(), 'This is the content of the asset', 'Read asset from lib') + const result = await Helper.untilResult(run.pipe) + is(result.trim(), 'This is the content of the asset', 'Read asset from entrypoint') - await running.inspector.evaluate('disableInspector()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(run.pipe) + ok(true, 'ended') }) diff --git a/test/fixtures/app-with-assets/index.js b/test/fixtures/app-with-assets/index.js deleted file mode 100644 index c36a32984..000000000 --- a/test/fixtures/app-with-assets/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const bareInspector = require('bare-inspector') -const { Inspector } = require('pear-inspect') -const fsp = require('bare-fs/promises') -const readAssetFromUtils = require('./lib/utils.js') - -const inspector = new Inspector({ inspector: bareInspector }) - -async function readAsset () { - const text = await fsp.readFile(require.asset('./text-file.txt')) - return text.toString() -} - -async function run () { - const key = await inspector.enable() - const inspectorKey = key.toString('hex') - console.log(`{ "tag": "inspector", "data": { "key": "${inspectorKey}" }}`) -} - -run() - - -function disableInspector () { - inspector.disable() -} - -global.disableInspector = disableInspector -global.readAsset = readAsset -global.readAssetFromUtils = readAssetFromUtils diff --git a/test/fixtures/app-with-assets/lib/utils.js b/test/fixtures/app-with-assets/lib/utils.js deleted file mode 100644 index 5e27af61b..000000000 --- a/test/fixtures/app-with-assets/lib/utils.js +++ /dev/null @@ -1,6 +0,0 @@ -const fsp = require('bare-fs/promises') - -module.exports = async () => { - const text = await fsp.readFile(require.asset('../text-file.txt')) - return text.toString() -} diff --git a/test/fixtures/app-with-assets/package.json b/test/fixtures/app-with-assets/package.json deleted file mode 100644 index 606cc7d4b..000000000 --- a/test/fixtures/app-with-assets/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "app-with-assets", - "main": "index.js", - "pear": { - "name": "app-with-assets", - "type": "terminal" - }, - "devDependencies": { - "bare-inspector": "^3.0.1", - "pear-inspect": "^1.2.2" - }, - "dependencies": { - "bare-fs": "^3.1.1" - } -} diff --git a/test/fixtures/dht-bootstrap/index.js b/test/fixtures/dht-bootstrap/index.js new file mode 100644 index 000000000..9a9477366 --- /dev/null +++ b/test/fixtures/dht-bootstrap/index.js @@ -0,0 +1,9 @@ +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + try { + pipe.write(JSON.stringify(Pear.config.dht.bootstrap)) + } catch (err) { + console.error(err) + Pear.exit() + } +}) diff --git a/test/fixtures/dht-bootstrap/package.json b/test/fixtures/dht-bootstrap/package.json new file mode 100644 index 000000000..a45982743 --- /dev/null +++ b/test/fixtures/dht-bootstrap/package.json @@ -0,0 +1,8 @@ +{ + "name": "dht-bootstrap", + "main": "index.js", + "pear": { + "name": "dht-bootstrap", + "type": "terminal" + } +} diff --git a/test/fixtures/require-assets/index.js b/test/fixtures/require-assets/index.js new file mode 100644 index 000000000..9699ee397 --- /dev/null +++ b/test/fixtures/require-assets/index.js @@ -0,0 +1,11 @@ +const fs = require('bare-fs') + +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + try { + pipe.write(fs.readFileSync(require.asset('./text-file.txt'))) + } catch (err) { + console.error(err) + Pear.exit() + } +}) diff --git a/test/fixtures/require-assets/package.json b/test/fixtures/require-assets/package.json new file mode 100644 index 000000000..c74ebe47d --- /dev/null +++ b/test/fixtures/require-assets/package.json @@ -0,0 +1,11 @@ +{ + "name": "require-assets", + "main": "index.js", + "pear": { + "name": "require-assets", + "type": "terminal" + }, + "dependencies": { + "bare-fs": "^3.1.1" + } +} diff --git a/test/fixtures/app-with-assets/text-file.txt b/test/fixtures/require-assets/text-file.txt similarity index 100% rename from test/fixtures/app-with-assets/text-file.txt rename to test/fixtures/require-assets/text-file.txt diff --git a/test/fixtures/sub-dep-require-assets/index.js b/test/fixtures/sub-dep-require-assets/index.js new file mode 100644 index 000000000..10cec31e2 --- /dev/null +++ b/test/fixtures/sub-dep-require-assets/index.js @@ -0,0 +1,11 @@ +const readAsset = require('./lib/utils.js') + +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + try { + pipe.write(readAsset()) + } catch (err) { + console.error(err) + Pear.exit() + } +}) diff --git a/test/fixtures/sub-dep-require-assets/lib/utils.js b/test/fixtures/sub-dep-require-assets/lib/utils.js new file mode 100644 index 000000000..e204d2fea --- /dev/null +++ b/test/fixtures/sub-dep-require-assets/lib/utils.js @@ -0,0 +1,3 @@ +const fs = require('bare-fs') + +module.exports = () => fs.readFileSync(require.asset('../text-file.txt')) diff --git a/test/fixtures/sub-dep-require-assets/package.json b/test/fixtures/sub-dep-require-assets/package.json new file mode 100644 index 000000000..6b371a5f9 --- /dev/null +++ b/test/fixtures/sub-dep-require-assets/package.json @@ -0,0 +1,11 @@ +{ + "name": "sub-dep-require-assets", + "main": "index.js", + "pear": { + "name": "sub-dep-require-assets", + "type": "terminal" + }, + "dependencies": { + "bare-fs": "^3.1.1" + } +} diff --git a/test/fixtures/sub-dep-require-assets/text-file.txt b/test/fixtures/sub-dep-require-assets/text-file.txt new file mode 100644 index 000000000..d0912597b --- /dev/null +++ b/test/fixtures/sub-dep-require-assets/text-file.txt @@ -0,0 +1 @@ +This is the content of the asset diff --git a/test/fixtures/versions/index.js b/test/fixtures/versions/index.js new file mode 100644 index 000000000..69ebc295e --- /dev/null +++ b/test/fixtures/versions/index.js @@ -0,0 +1,9 @@ +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + Pear.versions().then((versions) => { + pipe.write(JSON.stringify(versions)) + }).catch((err) => { + console.error(err) + Pear.exit() + }) +}) diff --git a/test/fixtures/versions/package.json b/test/fixtures/versions/package.json new file mode 100644 index 000000000..238ff9dce --- /dev/null +++ b/test/fixtures/versions/package.json @@ -0,0 +1,8 @@ +{ + "name": "versions", + "main": "index.js", + "pear": { + "name": "versions", + "type": "terminal" + } +} From cba2245d633dac7be5197439bff0aa27fd58cf99 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:00:09 +0100 Subject: [PATCH 18/38] corrected loader bar color (#423) --- decal.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decal.html b/decal.html index ddbece24f..b0bec8f0a 100644 --- a/decal.html +++ b/decal.html @@ -58,7 +58,7 @@ outline: none; } #bar { - background: #0D0F16; + background: #151517; height: 50px; padding-top: 12px; padding-right: 8px; From 0c1e341e1793f553db46c1faec0fd68b0d1e1a0f Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:13:31 +0100 Subject: [PATCH 19/38] updated readme stage build key (#428) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a0b1dcf2..ffee8d192 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ pear://pqbzjhqyonxprx8hghxexnmctw75mr91ewqw5dxe1zmntfyaddqy ### Stage Build ``` -pear://fbdbkwt5yojdfidmqeh39tomepj348hn78xzwk181ecqr61jkzzo +pear://17g37zzfo3dnmchf57ixw93gpxcncjmfyzybf4tjo99xi55ewf7o ``` Note: Always use the production build unless you are sure of what you are doing. The stage build may introduce untested breaking changes that could affect other Pear apps. From 2409eb8a494abf0a84db430138b29b5b3bc265f7 Mon Sep 17 00:00:00 2001 From: Jan Keith Darunday Date: Thu, 7 Nov 2024 23:28:35 +0800 Subject: [PATCH 20/38] Remove getMediaSourceId as it is no longer supported (#420) --- gui/gui.js | 10 ---------- gui/preload.js | 4 ---- 2 files changed, 14 deletions(-) diff --git a/gui/gui.js b/gui/gui.js index 088c0c52b..a1572f72a 100644 --- a/gui/gui.js +++ b/gui/gui.js @@ -895,11 +895,6 @@ class GuiCtrl { if (this.closed) return false } - async getMediaSourceId () { - if (this.closed) throw Error(`Cannot get media source id if the ${this[kCtrl]} is closed`) - return (this.win && this.win.getMediaSourceId()) - } - async dimensions (opts = null) { if (this.closed) return null const item = this[kCtrl] === 'view' ? this.view : this.win @@ -1477,7 +1472,6 @@ class PearGUI extends ReadyResource { electron.ipcMain.handle('restore', (evt, ...args) => this.restore(...args)) electron.ipcMain.handle('focus', (evt, ...args) => this.focus(...args)) electron.ipcMain.handle('blur', (evt, ...args) => this.blur(...args)) - electron.ipcMain.handle('getMediaSourceId', (evt, ...args) => this.getMediaSourceId(...args)) electron.ipcMain.handle('dimensions', (evt, ...args) => this.dimensions(...args)) electron.ipcMain.handle('isVisible', (evt, ...args) => this.isVisible(...args)) electron.ipcMain.handle('isClosed', (evt, ...args) => this.isClosed(...args)) @@ -1600,7 +1594,6 @@ class PearGUI extends ReadyResource { hide () { return false }, focus () { return false }, blur () { return false }, - getMediaSourceId () { return -1 }, dimensions () { return null }, maximize () { return false }, minimize () { return false }, @@ -1652,7 +1645,6 @@ class PearGUI extends ReadyResource { if (act === 'show') return instance.show() if (act === 'hide') return instance.hide() if (act === 'dimensions') return instance.dimensions(...args) - if (act === 'getMediaSourceId') return instance.getMediaSourceId() if (act === 'isClosed') return instance.isClosed() if (act === 'isVisible') return instance.isVisible() if (act === 'isMinimized') return instance.isMinimized() @@ -1685,8 +1677,6 @@ class PearGUI extends ReadyResource { blur ({ id }) { return this.get(id).blur() } - getMediaSourceId ({ id }) { return this.get(id).getMediaSourceId() } - dimensions ({ id, options }) { return this.get(id).dimensions(options) } isVisible ({ id }) { return this.get(id).isVisible() } diff --git a/gui/preload.js b/gui/preload.js index e6d3e2720..1f65a19df 100644 --- a/gui/preload.js +++ b/gui/preload.js @@ -67,7 +67,6 @@ module.exports = class PearGUI extends ReadyResource { fullscreen () { return ipc.parent({ act: 'fullscreen', id: this.#id }) } restore () { return ipc.parent({ act: 'restore', id: this.#id }) } dimensions (options = null) { return ipc.parent({ act: 'dimensions', id: this.#id, options }) } - getMediaSourceId () { return ipc.parent({ act: 'getMediaSourceId', id: this.#id }) } isVisible () { return ipc.parent({ act: 'isVisible', id: this.#id }) } isMinimized () { return ipc.parent({ act: 'isMinimized', id: this.#id }) } isMaximized () { return ipc.parent({ act: 'isMaximized', id: this.#id }) } @@ -86,7 +85,6 @@ module.exports = class PearGUI extends ReadyResource { fullscreen () { return ipc.fullscreen({ id: this.id }) } restore () { return ipc.restore({ id: this.id }) } close () { return ipc.close({ id: this.id }) } - getMediaSourceId () { return ipc.getMediaSourceId({ id: this.id }) } dimensions (options = null) { return ipc.dimensions({ id: this.id, options }) } isVisible () { return ipc.isVisible({ id: this.id }) } isMinimized () { return ipc.isMinimized({ id: this.id }) } @@ -162,7 +160,6 @@ module.exports = class PearGUI extends ReadyResource { focus (options = null) { return ipc.focus({ id: this.id, options }) } blur () { return ipc.blur({ id: this.id }) } - getMediaSourceId () { return ipc.getMediaSourceId({ id: this.id }) } dimensions (options = null) { return ipc.dimensions({ id: this.id, options }) } minimize () { if (this.constructor[kGuiCtrl] === 'view') throw new Error('A View cannot be minimized') @@ -241,7 +238,6 @@ class IPC { restore (...args) { return electron.ipcRenderer.invoke('restore', ...args) } focus (...args) { return electron.ipcRenderer.invoke('focus', ...args) } blur (...args) { return electron.ipcRenderer.invoke('blur', ...args) } - getMediaSourceId (...args) { return electron.ipcRenderer.invoke('getMediaSourceId', ...args) } dimensions (...args) { return electron.ipcRenderer.invoke('dimensions', ...args) } isVisible (...args) { return electron.ipcRenderer.invoke('isVisible', ...args) } isClosed (...args) { return electron.ipcRenderer.invoke('isClosed', ...args) } From 13758e44016e18ead0b918cf1a90194310284556 Mon Sep 17 00:00:00 2001 From: Jan Keith Darunday Date: Thu, 7 Nov 2024 23:29:23 +0800 Subject: [PATCH 21/38] Add tests for running workers in terminal apps (#427) * Add tests for running workers in terminal apps * Use a separate runner instead of harness and use new helper methods * Remove unnecessary package.json fields * Use simpler workers * Add test for passing passing args to worker * Update wrong name in package.json * Switch worker runner to use args * Cleanup unused message argument --- test/03-worker.test.js | 72 +++++++++++++++++++++++- test/fixtures/hello-world/index.js | 9 +++ test/fixtures/hello-world/package.json | 8 +++ test/fixtures/print-args/index.js | 9 +++ test/fixtures/print-args/package.json | 8 +++ test/fixtures/worker-runner/index.js | 10 ++++ test/fixtures/worker-runner/package.json | 8 +++ test/helper.js | 4 +- 8 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/hello-world/index.js create mode 100644 test/fixtures/hello-world/package.json create mode 100644 test/fixtures/print-args/index.js create mode 100644 test/fixtures/print-args/package.json create mode 100644 test/fixtures/worker-runner/index.js create mode 100644 test/fixtures/worker-runner/package.json diff --git a/test/03-worker.test.js b/test/03-worker.test.js index 737d9a282..7a0972dcd 100644 --- a/test/03-worker.test.js +++ b/test/03-worker.test.js @@ -4,8 +4,11 @@ const test = require('brittle') const path = require('bare-path') const Helper = require('./helper') const worker = path.join(Helper.localDir, 'test', 'fixtures', 'worker') +const helloWorld = path.join(Helper.localDir, 'test', 'fixtures', 'hello-world') +const printArgs = path.join(Helper.localDir, 'test', 'fixtures', 'print-args') +const workerRunner = path.join(Helper.localDir, 'test', 'fixtures', 'worker-runner') -test('worker pipe', async function ({ is, plan, comment, teardown }) { +test('worker pipe', async function ({ is, plan, teardown }) { plan(1) const helper = new Helper() teardown(() => helper.close()) @@ -29,3 +32,70 @@ test('worker pipe', async function ({ is, plan, comment, teardown }) { pipe.write('exit') }) + +test('worker should receive args from the parent', async function ({ is, plan }) { + plan(1) + + const args = ['hello', 'world'] + const { pipe } = await Helper.run({ link: printArgs, args }) + const result = await Helper.untilResult(pipe) + + is(result, JSON.stringify(args), 'worker should receive args from the parent') + + await Helper.untilClose(pipe) +}) + +test('worker should run directly in a terminal app', async function ({ is, plan, comment, teardown }) { + plan(1) + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const testId = Math.floor(Math.random() * 100000) + comment('Staging worker-runner...') + const staging = helper.stage({ channel: `test-${testId}`, name: `test-${testId}`, key: null, dir: workerRunner, cmdArgs: [], dryRun: false, bare: true, ignore: [] }) + teardown(() => Helper.teardownStream(staging)) + const until = await Helper.pick(staging, [{ tag: 'staging' }, { tag: 'final' }]) + const { link } = await until.staging + await until.final + + comment('Running worker using worker-runner...') + const { pipe } = await Helper.run({ link, args: [helloWorld] }) + const response = await Helper.untilResult(pipe) + + is(response, 'hello world', 'worker should send expected response') + + await Helper.untilClose(pipe) +}) + +test('worker should run as a link in a terminal app', async function ({ is, plan, comment, teardown }) { + plan(1) + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const testId = Math.floor(Math.random() * 100000) + comment('Staging worker-runner...') + const staging1 = helper.stage({ channel: `test-${testId}`, name: `test-${testId}`, key: null, dir: workerRunner, cmdArgs: [], dryRun: false, bare: true, ignore: [] }) + teardown(() => Helper.teardownStream(staging1)) + const until1 = await Helper.pick(staging1, [{ tag: 'staging' }, { tag: 'final' }]) + const { link: runnerLink } = await until1.staging + await until1.final + + comment('Staging worker...') + const staging2 = helper.stage({ channel: `test-worker-${testId}`, name: `test-worker-${testId}`, key: null, dir: helloWorld, cmdArgs: [], dryRun: false, bare: true, ignore: [] }) + teardown(() => Helper.teardownStream(staging2)) + const until2 = await Helper.pick(staging2, [{ tag: 'staging' }, { tag: 'final' }]) + const { link: workerLink } = await until2.staging + await until2.final + + comment('Running worker using worker-runner...') + const { pipe } = await Helper.run({ link: runnerLink, args: [workerLink] }) + const response = await Helper.untilResult(pipe) + + is(response, 'hello world', 'worker should send expected response') + + await Helper.untilClose(pipe) +}) diff --git a/test/fixtures/hello-world/index.js b/test/fixtures/hello-world/index.js new file mode 100644 index 000000000..b5f75016c --- /dev/null +++ b/test/fixtures/hello-world/index.js @@ -0,0 +1,9 @@ +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + try { + pipe.write('hello world') + } catch (err) { + console.error(err) + Pear.exit() + } +}) diff --git a/test/fixtures/hello-world/package.json b/test/fixtures/hello-world/package.json new file mode 100644 index 000000000..1e7ab9043 --- /dev/null +++ b/test/fixtures/hello-world/package.json @@ -0,0 +1,8 @@ +{ + "name": "hello-world", + "main": "index.js", + "pear": { + "name": "hello-world", + "type": "terminal" + } +} diff --git a/test/fixtures/print-args/index.js b/test/fixtures/print-args/index.js new file mode 100644 index 000000000..0280dbbb2 --- /dev/null +++ b/test/fixtures/print-args/index.js @@ -0,0 +1,9 @@ +const pipe = Pear.worker.pipe() +pipe.on('data', () => { + try { + pipe.write(JSON.stringify(Pear.config.args)) + } catch (err) { + console.error(err) + Pear.exit() + } +}) diff --git a/test/fixtures/print-args/package.json b/test/fixtures/print-args/package.json new file mode 100644 index 000000000..5e83bfb43 --- /dev/null +++ b/test/fixtures/print-args/package.json @@ -0,0 +1,8 @@ +{ + "name": "print-args", + "main": "index.js", + "pear": { + "name": "print-args", + "type": "terminal" + } +} diff --git a/test/fixtures/worker-runner/index.js b/test/fixtures/worker-runner/index.js new file mode 100644 index 000000000..a93a51567 --- /dev/null +++ b/test/fixtures/worker-runner/index.js @@ -0,0 +1,10 @@ +const pipe = Pear.worker.pipe() + +const [workerPath] = Pear.config.args +const workerPipe = Pear.worker.run(workerPath) +workerPipe.on('data', (data) => { + pipe.write(data) + workerPipe.end() +}) + +workerPipe.write('start') diff --git a/test/fixtures/worker-runner/package.json b/test/fixtures/worker-runner/package.json new file mode 100644 index 000000000..488e04b65 --- /dev/null +++ b/test/fixtures/worker-runner/package.json @@ -0,0 +1,8 @@ +{ + "name": "worker-runner", + "main": "index.js", + "pear": { + "name": "worker-runner", + "type": "terminal" + } +} diff --git a/test/helper.js b/test/helper.js index 7d9038114..ced0ed876 100644 --- a/test/helper.js +++ b/test/helper.js @@ -145,11 +145,11 @@ class Helper extends IPC { // ONLY ADD STATICS, NEVER ADD PUBLIC METHODS OR PROPERTIES (see pear-ipc) static localDir = isWindows ? path.normalize(pathname.slice(1)) : pathname - static async run ({ link, encryptionKey, platformDir }) { + static async run ({ link, encryptionKey, platformDir, args = [] }) { if (encryptionKey) program.argv.splice(2, 0, '--encryption-key', encryptionKey) if (platformDir) Pear.worker.constructor.RUNTIME = path.join(platformDir, 'current', BY_ARCH) - const pipe = Pear.worker.run(link) + const pipe = Pear.worker.run(link, args) if (platformDir) Pear.worker.constructor.RUNTIME = RUNTIME if (encryptionKey) program.argv.splice(2, 2) From 23e98b56ee419180d2c75cbea55fa23e6dad4b25 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 8 Nov 2024 03:46:33 +1100 Subject: [PATCH 22/38] improve-logger (#429) --- lib/logger.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/logger.js b/lib/logger.js index a63d1c98a..9a5652a7f 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -3,7 +3,7 @@ const { isBare, isWindows } = require('which-runtime') const hrtime = isBare ? require('bare-hrtime') : process.hrtime class Logger { - constructor ({ labels, fields = '', stacks = false, level = 1, pretty = false } = {}) { + constructor ({ labels, fields = '', stacks = false, level, pretty = false } = {}) { fields = this._parseFields(fields) this._labels = new Set(this._parseLabels(labels)) this._labels.add('internal') @@ -93,7 +93,7 @@ class Logger { } _parseLevel (level) { - if (typeof level !== 'string') return level + if (typeof level === 'number') return level level = level.toUpperCase() if (level === 'OFF' || level === '0') return 0 if (level === 'ERR' || level === 'ERROR' || level === '1') return 1 From 850d19c027e2192eee1b1b297cfcf64f8cc13cf8 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 8 Nov 2024 16:07:37 +1100 Subject: [PATCH 23/38] hotfix-logger (#430) --- lib/logger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger.js b/lib/logger.js index 9a5652a7f..7668a691c 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -94,7 +94,7 @@ class Logger { _parseLevel (level) { if (typeof level === 'number') return level - level = level.toUpperCase() + if (typeof level === 'string') level = level.toUpperCase() if (level === 'OFF' || level === '0') return 0 if (level === 'ERR' || level === 'ERROR' || level === '1') return 1 if (level === 'INF' || level === 'INFO' || level === '2') return 2 From 85ada9edbdedc90e1c443a3f536a77ffc7225f45 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 8 Nov 2024 19:32:35 +1100 Subject: [PATCH 24/38] teardown-test (#432) --- test/02-teardown.test.js | 172 ++++++++---------- .../worker-teardown-exit-code/index.js | 9 + .../worker-teardown-exit-code/package.json | 8 + .../fixtures/worker-teardown-os-kill/index.js | 8 + .../worker-teardown-os-kill/package.json | 8 + test/fixtures/worker-teardown/index.js | 7 + test/fixtures/worker-teardown/package.json | 8 + test/helper.js | 8 +- 8 files changed, 133 insertions(+), 95 deletions(-) create mode 100644 test/fixtures/worker-teardown-exit-code/index.js create mode 100644 test/fixtures/worker-teardown-exit-code/package.json create mode 100644 test/fixtures/worker-teardown-os-kill/index.js create mode 100644 test/fixtures/worker-teardown-os-kill/package.json create mode 100644 test/fixtures/worker-teardown/index.js create mode 100644 test/fixtures/worker-teardown/package.json diff --git a/test/02-teardown.test.js b/test/02-teardown.test.js index 13213d04f..591970098 100644 --- a/test/02-teardown.test.js +++ b/test/02-teardown.test.js @@ -1,149 +1,135 @@ 'use strict' +const { isWindows } = require('which-runtime') const test = require('brittle') const path = require('bare-path') +const os = require('bare-os') const hypercoreid = require('hypercore-id-encoding') const Helper = require('./helper') -const harness = path.join(Helper.localDir, 'test', 'fixtures', 'harness') +const workerTeardownDir = path.join(Helper.localDir, 'test', 'fixtures', 'worker-teardown') +const workerTeardownOsKillDir = path.join(Helper.localDir, 'test', 'fixtures', 'worker-teardown-os-kill') +const workerTeardownExitCodeDir = path.join(Helper.localDir, 'test', 'fixtures', 'worker-teardown-exit-code') -test('teardown', async function ({ is, ok, plan, comment, teardown, timeout }) { +test('teardown on pipe end', { skip: isWindows }, async function ({ ok, is, plan, comment, teardown, timeout }) { timeout(180000) + plan(4) - plan(5) - - const stager = new Helper() - teardown(() => stager.close(), { order: Infinity }) - await stager.ready() + const dir = workerTeardownDir - const dir = harness + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() const id = Math.floor(Math.random() * 10000) comment('staging') - const stage = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) - const final = await Helper.pick(stage, { tag: 'final' }) - ok(final.success, 'stage succeeded') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') comment('seeding') - const seeder = new Helper() - teardown(() => seeder.close(), { order: Infinity }) - await seeder.ready() - const seed = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir }) - teardown(() => Helper.teardownStream(seed)) - const until = await Helper.pick(seed, [{ tag: 'key' }, { tag: 'announced' }]) - const key = await until.key + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + teardown(() => Helper.teardownStream(seeding)) + const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) const announced = await until.announced - - ok(hypercoreid.isValid(key), 'app key is valid') ok(announced, 'seeding is announced') - comment('running') - const link = 'pear://' + key - const running = await Helper.open(link, { tags: ['teardown', 'exit'] }) - - await running.inspector.evaluate('Pear.teardown(() => console.log(\'teardown\'))') - await running.inspector.evaluate('Pear.shutdown()') - await running.inspector.close() + const key = await until.key + ok(hypercoreid.isValid(key), 'app key is valid') - const td = await running.until.teardown - is(td, 'teardown', 'teardown has been triggered') + const link = `pear://${key}` + const run = await Helper.run({ link }) + const { pipe } = run - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + const td = await Helper.untilResult(pipe, 5000, () => pipe.end()) + is(td, 'teardown', 'teardown executed') }) -test('teardown during teardown', async function ({ is, ok, plan, comment, teardown, timeout }) { +test('teardown on os kill', { skip: isWindows }, async function ({ ok, is, plan, comment, teardown, timeout }) { timeout(180000) plan(5) - const stager = new Helper() - teardown(() => stager.close(), { order: Infinity }) - await stager.ready() + const dir = workerTeardownOsKillDir - const dir = harness + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() const id = Math.floor(Math.random() * 10000) comment('staging') - const stage = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) - const final = await Helper.pick(stage, { tag: 'final' }) - ok(final.success, 'stage succeeded') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') comment('seeding') - const seeder = new Helper() - teardown(() => seeder.close(), { order: Infinity }) - await seeder.ready() - const seed = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir }) - teardown(() => Helper.teardownStream(seed)) - const until = await Helper.pick(seed, [{ tag: 'key' }, { tag: 'announced' }]) - const key = await until.key + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + teardown(() => Helper.teardownStream(seeding)) + const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) const announced = await until.announced - - ok(hypercoreid.isValid(key), 'app key is valid') ok(announced, 'seeding is announced') - comment('running') - const link = 'pear://' + key - const running = await Helper.open(link, { tags: ['teardown', 'exit'] }) - - await running.inspector.evaluate( - `(() => { - const { teardown } = Pear - const a = () => { b() } - const b = () => { teardown(() => console.log('teardown from b')) } - teardown( () => a() ) - })()`) + const key = await until.key + ok(hypercoreid.isValid(key), 'app key is valid') - await running.inspector.evaluate('Pear.shutdown()') - await running.inspector.close() + const link = `pear://${key}` + const run = await Helper.run({ link }) + const { pipe } = run - const td = await running.until.teardown - is(td, 'teardown from b', 'teardown from b has been triggered') + const pid = +(await Helper.untilResult(pipe)) + ok(pid > 0, 'worker pid is valid') - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + const td = await Helper.untilResult(pipe, 5000, () => os.kill(pid)) + ok(td, 'teardown executed') }) -// TODO: fixme -test.skip('exit with non-zero code in teardown', async function ({ is, ok, plan, comment, teardown }) { - plan(4) +test('teardown on os kill with exit code', { skip: isWindows }, async function ({ ok, is, plan, comment, teardown, timeout }) { + timeout(180000) + plan(6) - const stager = new Helper() - teardown(() => stager.close(), { order: Infinity }) - await stager.ready() + const dir = workerTeardownExitCodeDir - const dir = harness + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() const id = Math.floor(Math.random() * 10000) comment('staging') - const stage = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) - const final = await Helper.pick(stage, { tag: 'final' }) - ok(final.success, 'stage succeeded') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + const staged = await Helper.pick(staging, { tag: 'final' }) + ok(staged.success, 'stage succeeded') comment('seeding') - const seeder = new Helper() - teardown(() => seeder.close()) - teardown(() => seeder.close(), { order: Infinity }) - await seeder.ready() - const seed = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir }) - teardown(() => Helper.teardownStream(seed)) - const until = await Helper.pick(seed, [{ tag: 'key' }, { tag: 'announced' }]) - const key = await until.key + const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] }) + teardown(() => Helper.teardownStream(seeding)) + const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }]) const announced = await until.announced + ok(announced, 'seeding is announced') + const key = await until.key ok(hypercoreid.isValid(key), 'app key is valid') - ok(announced, 'seeding is announced') - comment('running') - const link = 'pear://' + key - const running = await Helper.open(link, { tags: ['teardown', 'exit'] }) + const link = `pear://${key}` + const run = await Helper.run({ link }) + const { pipe } = run + + const pid = +(await Helper.untilResult(pipe)) + ok(pid > 0, 'worker pid is valid') - await running.inspector.evaluate('Pear.teardown(() => Pear.exit(124))') + const exitCodePromise = new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => reject(new Error('timed out')), 5000) + pipe.on('crash', (data) => { + clearTimeout(timeoutId) + resolve(data.exitCode) + }) + }) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - // running.subprocess.kill('SIGINT') <-- this was forcing the exit code, which false-positives the test + const td = await Helper.untilResult(pipe, 5000, () => os.kill(pid)) + ok(td, 'teardown executed') - const { code } = await running.until.exit - is(code, 124, 'exit code is 124') + const exitCode = await exitCodePromise + is(exitCode, 124, 'exit code is 124') }) diff --git a/test/fixtures/worker-teardown-exit-code/index.js b/test/fixtures/worker-teardown-exit-code/index.js new file mode 100644 index 000000000..04a351c33 --- /dev/null +++ b/test/fixtures/worker-teardown-exit-code/index.js @@ -0,0 +1,9 @@ +const pipe = Pear.worker.pipe() +pipe.on('data', () => pipe.write(`${Bare.pid}`)) + +Pear.teardown(async () => { + await new Promise((resolve) => { + pipe.write('teardown', resolve) + }) + Pear.exit(124) +}) diff --git a/test/fixtures/worker-teardown-exit-code/package.json b/test/fixtures/worker-teardown-exit-code/package.json new file mode 100644 index 000000000..b0a017614 --- /dev/null +++ b/test/fixtures/worker-teardown-exit-code/package.json @@ -0,0 +1,8 @@ +{ + "name": "worker-teardown-exit-code", + "main": "index.js", + "pear": { + "name": "worker-teardown-exit-code", + "type": "terminal" + } +} diff --git a/test/fixtures/worker-teardown-os-kill/index.js b/test/fixtures/worker-teardown-os-kill/index.js new file mode 100644 index 000000000..3df111bec --- /dev/null +++ b/test/fixtures/worker-teardown-os-kill/index.js @@ -0,0 +1,8 @@ +const pipe = Pear.worker.pipe() +pipe.on('data', () => pipe.write(`${Bare.pid}`)) + +Pear.teardown(async () => { + await new Promise((resolve) => { + pipe.write('teardown', resolve) + }) +}) diff --git a/test/fixtures/worker-teardown-os-kill/package.json b/test/fixtures/worker-teardown-os-kill/package.json new file mode 100644 index 000000000..110c14a67 --- /dev/null +++ b/test/fixtures/worker-teardown-os-kill/package.json @@ -0,0 +1,8 @@ +{ + "name": "worker-teardown-os-kill", + "main": "index.js", + "pear": { + "name": "worker-teardown-os-kill", + "type": "terminal" + } +} diff --git a/test/fixtures/worker-teardown/index.js b/test/fixtures/worker-teardown/index.js new file mode 100644 index 000000000..ef1f86798 --- /dev/null +++ b/test/fixtures/worker-teardown/index.js @@ -0,0 +1,7 @@ +const pipe = Pear.worker.pipe() + +Pear.teardown(async () => { + await new Promise((resolve) => { + pipe.write('teardown', resolve) + }) +}) diff --git a/test/fixtures/worker-teardown/package.json b/test/fixtures/worker-teardown/package.json new file mode 100644 index 000000000..22b52079e --- /dev/null +++ b/test/fixtures/worker-teardown/package.json @@ -0,0 +1,8 @@ +{ + "name": "worker-teardown", + "main": "index.js", + "pear": { + "name": "worker-teardown", + "type": "terminal" + } +} diff --git a/test/helper.js b/test/helper.js index ced0ed876..aef6abfdd 100644 --- a/test/helper.js +++ b/test/helper.js @@ -157,7 +157,7 @@ class Helper extends IPC { return { pipe } } - static async untilResult (pipe, timeout = 5000) { + static async untilResult (pipe, timeout = 5000, runFn) { const res = new Promise((resolve, reject) => { const timeoutId = setTimeout(() => reject(new Error('timed out')), timeout) pipe.on('data', (data) => { @@ -173,7 +173,11 @@ class Helper extends IPC { reject(new Error('unexpected ended')) }) }) - pipe.write('start') + if (runFn) { + await runFn() + } else { + pipe.write('start') + } return res } From 9c2923dc30254665cb970d0b290345f85422f91e Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:14:38 +0100 Subject: [PATCH 25/38] fix double help on pear --help (#424) * fix double help on pear --help * bump paparam --- package-lock.json | 8 ++++---- package.json | 6 ++++-- shell.js | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 84fbbdaa7..8f7cc45e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "mime-db": "^1.53.0", "mirror-drive": "^1.4.0", "mutexify": "^1.4.0", - "paparam": "^1.4.0", + "paparam": "^1.6.0", "pear-changelog": "^1.0.1", "pear-interface": "^1.0.0", "pear-ipc": "^2.2.8", @@ -3439,9 +3439,9 @@ } }, "node_modules/paparam": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.5.0.tgz", - "integrity": "sha512-s8aFexFgeSRnVg71oE3f8Bylq7pOicnkI0VHE6Mmzg5734nIUVKrlxNHGbN878qazFE01dqFe9VxCjWoLcaRdA==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.6.0.tgz", + "integrity": "sha512-q1l/DIPX9kUIOzFRlqvNz+kukTbladRDeIMGRyEMfO6OZj21Q4v1bALTwxE+d43qQ1BPvKa29IfmsoiAF9953Q==" }, "node_modules/parent-module": { "version": "1.0.1", diff --git a/package.json b/package.json index cd3bca23f..00694dec6 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,9 @@ ], "standard": { "globals": [ - "Bare", "Pear", "LOG" + "Bare", + "Pear", + "LOG" ], "ignore": [ "__snapshots__", @@ -97,7 +99,7 @@ "mime-db": "^1.53.0", "mirror-drive": "^1.4.0", "mutexify": "^1.4.0", - "paparam": "^1.4.0", + "paparam": "^1.6.0", "pear-changelog": "^1.0.1", "pear-interface": "^1.0.0", "pear-ipc": "^2.2.8", diff --git a/shell.js b/shell.js index 2e2c99c5e..6996460a8 100644 --- a/shell.js +++ b/shell.js @@ -1,4 +1,4 @@ 'use strict' const { command, arg, rest } = require('paparam') const def = [...require('./def/pear')] -module.exports = (argv) => command('pear', ...def, arg(''), rest('rest')).parse(argv) +module.exports = (argv) => command('pear', ...def, arg(''), rest('rest')).parse(argv, { silent: true }) From 4beac340f3d486fc36734f41bf604c699cdf1e62 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:17:53 +0100 Subject: [PATCH 26/38] pear-ipc refactor (#417) * pear-ipc refactor * updated package-lock * updated pear-ipc exports --- cli.js | 2 +- gui/gui.js | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- subsystems/sidecar/index.js | 2 +- test/helper.js | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cli.js b/cli.js index 8b3e0e500..f30b9e02c 100644 --- a/cli.js +++ b/cli.js @@ -9,7 +9,7 @@ crasher('cli', SWAP) cli() async function cli () { - const ipc = new IPC({ + const ipc = new IPC.Client({ lock: PLATFORM_LOCK, socketPath: SOCKET_PATH, connectTimeout: CONNECT_TIMEOUT, diff --git a/gui/gui.js b/gui/gui.js index a1572f72a..4dee512b5 100644 --- a/gui/gui.js +++ b/gui/gui.js @@ -1396,7 +1396,7 @@ class PearGUI extends ReadyResource { constructor ({ socketPath, connectTimeout, tryboot, state }) { super() this.state = state - this.ipc = new IPC({ + this.ipc = new IPC.Client({ lock: constants.PLATFORM_LOCK, socketPath, connectTimeout, diff --git a/package-lock.json b/package-lock.json index 8f7cc45e7..75a324d0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "paparam": "^1.6.0", "pear-changelog": "^1.0.1", "pear-interface": "^1.0.0", - "pear-ipc": "^2.2.8", + "pear-ipc": "^3.0.0", "pear-link": "^2.0.1", "pear-updater": "^3.1.0", "pear-updater-bootstrap": "^1.2.0", @@ -3536,9 +3536,9 @@ } }, "node_modules/pear-ipc": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/pear-ipc/-/pear-ipc-2.4.0.tgz", - "integrity": "sha512-p6qECm68vz/peF0X+strSlLuac1XXmell8W1vP70E6Zp/cdCNFxHyRr2yOg6C9tk/EixQvONJ7N9/l9TPdXcag==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pear-ipc/-/pear-ipc-3.0.0.tgz", + "integrity": "sha512-NDmLJFRbXy6eXWMEh161nXDUOqRwAgWdVhuZfmeNs5G9Kr2OY4tu5x+Vsg/zjzuCuL5QxhwNwZmymt/imWpefQ==", "dependencies": { "bare-fs": "^3.0.2", "bare-os": "^3.2.0", diff --git a/package.json b/package.json index 00694dec6..9c70dc29a 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "paparam": "^1.6.0", "pear-changelog": "^1.0.1", "pear-interface": "^1.0.0", - "pear-ipc": "^2.2.8", + "pear-ipc": "^3.0.0", "pear-link": "^2.0.1", "pear-updater": "^3.1.0", "pear-updater-bootstrap": "^1.2.0", diff --git a/subsystems/sidecar/index.js b/subsystems/sidecar/index.js index 61ca93893..775f08d31 100644 --- a/subsystems/sidecar/index.js +++ b/subsystems/sidecar/index.js @@ -100,7 +100,7 @@ class Sidecar extends ReadyResource { this.corestore = corestore this.gunk = gunk - this.ipc = new IPC({ + this.ipc = new IPC.Server({ handlers: this, lock: PLATFORM_LOCK, socketPath: SOCKET_PATH diff --git a/test/helper.js b/test/helper.js index aef6abfdd..8e8a9f1b4 100644 --- a/test/helper.js +++ b/test/helper.js @@ -103,7 +103,7 @@ class OperationError extends Error { } } -class Helper extends IPC { +class Helper extends IPC.Client { static Rig = Rig static tmp = tmp static PLATFORM_DIR = PLATFORM_DIR From 773d68b63cba5f58ea6179dbb328a222dcf1dd2a Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:27:12 +0100 Subject: [PATCH 27/38] fix not found screen (#433) --- not-found.html | 1 + 1 file changed, 1 insertion(+) diff --git a/not-found.html b/not-found.html index b7229f25b..da0d4b52d 100644 --- a/not-found.html +++ b/not-found.html @@ -63,6 +63,7 @@ background-repeat: repeat; background-size: 150px 190px; margin-top: 50px; + background-color: #151517; } #panel { flex-direction: column; From 753611403da439b4a96b2d481b27a82d2d3fd8c3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 01:37:57 +0100 Subject: [PATCH 28/38] Bump deps (#426) Co-authored-by: GitHub Actions Bot --- package-lock.json | 82 ++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 75a324d0c..85d965e59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -183,9 +183,9 @@ "dev": true }, "node_modules/@hyperswarm/secret-stream": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.7.0.tgz", - "integrity": "sha512-4N0x/G0VAmZaDvUAZRWEpPyAs0PnHfY+lOgNV4KLFhKNfw+GkVVXMlwpSXTDcqRSlDvla8iRg3OICZRu7RTOJQ==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.7.1.tgz", + "integrity": "sha512-isb18Pt6lXBpOQMRmpqItw+kYynXilOFyOhto/RMP15WQtTWC0rR5jfZPYXU7ZYV6Kxd2lyQ4ZBevoIcvEJHEQ==", "dependencies": { "b4a": "^1.1.0", "hypercore-crypto": "^3.3.1", @@ -574,9 +574,9 @@ } }, "node_modules/bare-bundle": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.8.0.tgz", - "integrity": "sha512-D3UfsjylCRgI6EFY8YgSdL8/IfKqsfoLb72zAQzpr21zlLVSUuR36KvAp+KDqAm3NQWiUjVPdGjJAvEIjT3baw==" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.8.1.tgz", + "integrity": "sha512-5LUrTCVJtCiUPd6jbNYBNC9sMgDxsQbRvOuwr6qa2DlzNiHErLjDzcN9KOGIoSsv68O9jzS+syzfniRoaPo/rQ==" }, "node_modules/bare-cov": { "version": "1.0.1", @@ -672,15 +672,23 @@ } }, "node_modules/bare-module": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.5.2.tgz", - "integrity": "sha512-ezBENLzjH7ilcazHpp7A5Ovi/K5k8YRID0cqQHZvY+XeL1dlD1xaqMb03ggk8L0xHvsG4OIAHswuV0NNOy/rFg==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.1.tgz", + "integrity": "sha512-U5B2DGdiiVGYKzdPBzDOFUNybNwK+Qbg6gMY0J1M+wgLJvlCwLRQHjtrBLvkP00LJvn8RlPWyi71ZnHLY6PiRQ==", "dependencies": { "bare-bundle": "^1.3.0", - "bare-module-resolve": "^1.6.0", + "bare-module-lexer": "^1.0.0", + "bare-module-resolve": "^1.8.0", "bare-path": "^3.0.0", - "bare-url": "^2.0.1", - "cjs-module-lexer": "^1.2.3" + "bare-url": "^2.0.1" + } + }, + "node_modules/bare-module-lexer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.0.7.tgz", + "integrity": "sha512-udUm4rxx65rmpSpU+zw0NHLKhLNwCUaTj3GdTbTX0kGktpwaGpt+94CKGOJ+IplNt5MES3Ok7NdQDBU5fV2HCw==", + "dependencies": { + "require-addon": "^1.0.2" } }, "node_modules/bare-module-resolve": { @@ -783,9 +791,9 @@ } }, "node_modules/bare-url": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.7.tgz", - "integrity": "sha512-SY52Xkmk3Fc6Ome0Ta7LZzrkiRKVA57LQWvsAnenQ0HwwXQvK/JPu6FBcLuuIdHKRZzKsNQXON5DONCxmBURNA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.8.tgz", + "integrity": "sha512-fnfTsxuCImhvJ04nnekI1n+2/AN837Napp6Z6D0Wyt+Ds7t7u6StcMVSJXwGbq82QGCvSWE5ozIHFLwELOrzsg==", "dependencies": { "bare-path": "^3.0.0" } @@ -1031,9 +1039,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -2331,9 +2339,9 @@ } }, "node_modules/hypercore": { - "version": "10.37.25", - "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-10.37.25.tgz", - "integrity": "sha512-47kDQWiRSOTbpps+lAKrKYo+6at7pmTN1lvlmUhNPDDOz8GjEnUhH36iiUzk90tF12Y9/GEaL09TP3yljIRswA==", + "version": "10.37.26", + "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-10.37.26.tgz", + "integrity": "sha512-jjJ0m/O9bFlcS5kSqE09XLLca40wVBeKfMTwJKepJdpMBWmQWJopfTI6fr5pUIfwTYDZNXNt7CxAPYKo/j4EVA==", "dependencies": { "@hyperswarm/secret-stream": "^6.0.0", "b4a": "^1.1.0", @@ -2413,9 +2421,9 @@ } }, "node_modules/hyperdrive": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.13.0.tgz", - "integrity": "sha512-G+1iwjGb6FcpVbfNrWCnD8LHuch0cV/qagdHY25N6sKUt9+8QoO1OGkdSnX9yjvZ5U40mHAmZeSzAq0jnynJAQ==", + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.13.1.tgz", + "integrity": "sha512-V7JJ0bVhjRrhfo0WrAOPMQ2RVBZQqG1qbd2V96tnvKJ1/eqq4gWEOKl/tHMX0j1+N5jABgKmSgb60NNEfTTscQ==", "dependencies": { "hyperbee": "^2.11.1", "hyperblobs": "^2.3.0", @@ -3536,9 +3544,9 @@ } }, "node_modules/pear-ipc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pear-ipc/-/pear-ipc-3.0.0.tgz", - "integrity": "sha512-NDmLJFRbXy6eXWMEh161nXDUOqRwAgWdVhuZfmeNs5G9Kr2OY4tu5x+Vsg/zjzuCuL5QxhwNwZmymt/imWpefQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pear-ipc/-/pear-ipc-3.0.1.tgz", + "integrity": "sha512-CzcNLbjtsJTPiKj2nI54nnVJTsfiE9q09CZKqUTJqCKXUYdRfqG7io94hUWCvuZkaDIwXWVfnUKDhFTvRAtWCw==", "dependencies": { "bare-fs": "^3.0.2", "bare-os": "^3.2.0", @@ -3582,13 +3590,13 @@ } }, "node_modules/pear-updater-bootstrap": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pear-updater-bootstrap/-/pear-updater-bootstrap-1.2.1.tgz", - "integrity": "sha512-WYCaP47Sj0Mn0vZ/0kRuawthkPg3UlzTIZ9DU8r019RMNg5if/n13I5cLkEx01Sx+t40VhmiVbuDy5usY/39kA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pear-updater-bootstrap/-/pear-updater-bootstrap-1.2.2.tgz", + "integrity": "sha512-/rfkQ3/A6fr/0c1cg81c42PgFVErj0cersBhud8MC3M26GseMLpD0fWh+XrWYa5OBtLjJrn4N+z51iaw2Xxf/w==", "dependencies": { "corestore": "^6.16.2", "hypercore-id-encoding": "^1.2.0", - "hyperdrive": "^11.6.3", + "hyperdrive": "^11.13.1", "hyperswarm": "^4.7.14", "pear-updater": "^3.0.1" }, @@ -4240,9 +4248,9 @@ "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/sodium-native": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.2.1.tgz", - "integrity": "sha512-48X3PfRLW+f0fgb3J7f7mkZ9eBKcGR/bD5mdXXLAx4RWwKUe3095yPQgiUUQTfh8Q29JzwhSQATitQDBIozN/w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.0.tgz", + "integrity": "sha512-OcMgoS0NJx+4yVUlhvL9uZsVZfmyHZ2RpSXkiIoOHMglqvJDeGwn1rUigPrvcNTq3m9hPXtt6syxQbF3vvwmRQ==", "dependencies": { "node-gyp-build": "^4.8.0" } @@ -4688,9 +4696,9 @@ } }, "node_modules/udx-native": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.1.tgz", - "integrity": "sha512-8NWeYnXWpixAyEE1U6/pIT5ErOjZA+js2tjZWOjLZPbFkpM/aTn7N7jgWXztvHlOODjbSh7oWCnaqs1/hqkVLg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.2.tgz", + "integrity": "sha512-aPkxfSiSH6QMr7IoGbkf23RY+AHVMTHwA64pCaTLJSQU2qSYsJcNiFPKNP6VFHzXGiE3m+HzLx7/r0orzySobw==", "dependencies": { "b4a": "^1.5.0", "bare-events": "^2.2.0", From d6981f51024ef4d2279efd082391a4935f76b5b3 Mon Sep 17 00:00:00 2001 From: Jan Keith Darunday Date: Sat, 9 Nov 2024 09:24:16 +0800 Subject: [PATCH 29/38] Use worker instead of inspector on updates tests (#434) * Use worker instead of inspector on updates tests * Remove unused harness fixture * Remove high timeout for the updates listener * Reduce test timeouts * Specify result timeout for tests that stage platform * Remove unused helper methods and bare-inspector and pear-inspect dependencies * Switch to listening to the pipe end event to end the update listener Note: needed to ensure that untilResult does not send any data or else the end event won't emit on the worker side if it does not have any data handler * Use pipe.resume() instead of not sending anything * Remove encrypted from npm install dirs * clean up dev dependencies --------- Co-authored-by: rafapaezbas --- package-lock.json | 77 --------- package.json | 6 - scripts/test.mjs | 2 - test/05-updates.test.js | 256 ++++++++++++++--------------- test/fixtures/harness/.npmrc | 1 - test/fixtures/harness/index.js | 63 ------- test/fixtures/harness/package.json | 28 ---- test/fixtures/updates/index.js | 10 ++ test/fixtures/updates/package.json | 8 + test/helper.js | 95 ----------- 10 files changed, 143 insertions(+), 403 deletions(-) delete mode 100644 test/fixtures/harness/.npmrc delete mode 100644 test/fixtures/harness/index.js delete mode 100644 test/fixtures/harness/package.json create mode 100644 test/fixtures/updates/index.js create mode 100644 test/fixtures/updates/package.json diff --git a/package-lock.json b/package-lock.json index 85d965e59..094886e6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,13 +72,11 @@ }, "devDependencies": { "@hyperswarm/testnet": "^3.1.4", - "bare-inspector": "^3.0.1", "brittle": "^3.5.2", "graceful-goodbye": "^1.3.0", "hyperbee": "^2.0.1", "hypercore": "^10.36.4", "newline-decoder": "^1.0.2", - "pear-inspect": "^1.2.2", "port-get": "^1.0.4", "standard": "^17.0.0" } @@ -592,15 +590,6 @@ "v8-to-istanbul": "^9.3.0" } }, - "node_modules/bare-crypto": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.3.0.tgz", - "integrity": "sha512-cRDBxNDGqn8Dq6svSuYRktq2M23Mlv22F1j9WmarbuAUgdOrvA9Si9vCMDW91vTUgpZQ0fj9PbdC8E5nJmHkYA==", - "dev": true, - "dependencies": { - "bare-stream": "^2.0.0" - } - }, "node_modules/bare-dns": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bare-dns/-/bare-dns-1.0.5.tgz", @@ -644,33 +633,6 @@ "bare-tcp": "^1.8.0" } }, - "node_modules/bare-https": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bare-https/-/bare-https-1.3.0.tgz", - "integrity": "sha512-8TePE37QM7F5Tq1W0iv+rigOVuaKd/uYf7Dm+CfNSLCCuMILVhRcIAF/eXwt3fB5BDdOBPM233I16fpVC4ykSg==", - "dev": true, - "dependencies": { - "bare-http1": "^3.8.0", - "bare-tcp": "^1.1.2", - "bare-tls": "^1.0.2" - } - }, - "node_modules/bare-inspector": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/bare-inspector/-/bare-inspector-3.0.2.tgz", - "integrity": "sha512-6ZE4doPi4gVFVgbow79u/CinmLQFyXLhFumBPz4h5Dd6y1hMij6NVsynzinLTkWeNbsiszQgm9l9OfVaNp9HyQ==", - "dev": true, - "dependencies": { - "bare-events": "^2.1.0", - "bare-http1": "^3.5.2", - "bare-stream": "^2.0.0", - "bare-url": "^2.0.0", - "bare-ws": "^1.1.0" - }, - "engines": { - "bare": ">=1.2.0" - } - }, "node_modules/bare-module": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.1.tgz", @@ -771,15 +733,6 @@ "bare-stream": "^2.0.0" } }, - "node_modules/bare-tls": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bare-tls/-/bare-tls-1.2.0.tgz", - "integrity": "sha512-03gQ2x8C1hL9To5sBGDidH8NdmtUj8wKaklJ2omWZlLDPD1Ry8Z1y5vg65GXDXoVdJkMDBIR0Smuq0pdjDIWWQ==", - "dev": true, - "dependencies": { - "bare-stream": "^2.0.0" - } - }, "node_modules/bare-tty": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/bare-tty/-/bare-tty-4.0.2.tgz", @@ -798,19 +751,6 @@ "bare-path": "^3.0.0" } }, - "node_modules/bare-ws": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/bare-ws/-/bare-ws-1.3.1.tgz", - "integrity": "sha512-dEnPJhD1a6wJioR4cuLFgigcigYbDX/di/2aCfOcM6tGwTRccu0fspJ8zuDegsRwmXj6ZsiviMKs3K55w94mMg==", - "dev": true, - "dependencies": { - "bare-crypto": "^1.2.0", - "bare-events": "^2.3.1", - "bare-http1": "^3.8.0", - "bare-https": "^1.3.0", - "bare-stream": "^2.1.2" - } - }, "node_modules/big-sparse-array": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/big-sparse-array/-/big-sparse-array-1.0.3.tgz", @@ -3517,23 +3457,6 @@ "b4a": "^1.6.4" } }, - "node_modules/pear-inspect": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/pear-inspect/-/pear-inspect-1.2.3.tgz", - "integrity": "sha512-a5N0oAbPpHY81kU5de97QXBlU+ysr20v7gFn/13/Dxqt3hLH+e7+ztMjEBVGavM+nK52BPpgEVcxCappzHWDIw==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "bare-inspector": "^3.0.1", - "hyperdht": "^6.11.5", - "which-runtime": "^1.2.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0", - "bare-path": "^3.0.0", - "bare-subprocess": "^4.0.0" - } - }, "node_modules/pear-interface": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pear-interface/-/pear-interface-1.0.3.tgz", diff --git a/package.json b/package.json index 9c70dc29a..809680947 100644 --- a/package.json +++ b/package.json @@ -127,14 +127,8 @@ }, "devDependencies": { "@hyperswarm/testnet": "^3.1.4", - "bare-inspector": "^3.0.1", "brittle": "^3.5.2", "graceful-goodbye": "^1.3.0", - "hyperbee": "^2.0.1", - "hypercore": "^10.36.4", - "newline-decoder": "^1.0.2", - "pear-inspect": "^1.2.2", - "port-get": "^1.0.4", "standard": "^17.0.0" }, "repository": { diff --git a/scripts/test.mjs b/scripts/test.mjs index 8a1634091..4b45570e2 100644 --- a/scripts/test.mjs +++ b/scripts/test.mjs @@ -14,8 +14,6 @@ const root = path.dirname(dirname) const force = Bare.argv.includes('--force-install') const dirs = [ - path.join(root, 'test', 'fixtures', 'harness', 'node_modules'), - path.join(root, 'test', 'fixtures', 'encrypted', 'node_modules'), path.join(root, 'test', 'fixtures', 'require-assets', 'node_modules'), path.join(root, 'test', 'fixtures', 'sub-dep-require-assets', 'node_modules') ] diff --git a/test/05-updates.test.js b/test/05-updates.test.js index 6250242ce..facfed17e 100644 --- a/test/05-updates.test.js +++ b/test/05-updates.test.js @@ -4,18 +4,19 @@ const path = require('bare-path') const fs = require('bare-fs') const hypercoreid = require('hypercore-id-encoding') const Helper = require('./helper') -const harness = path.join(Helper.localDir, 'test', 'fixtures', 'harness') -const seedOpts = (id) => ({ channel: `test-${id}`, name: `test-${id}`, key: null, dir: harness, cmdArgs: [] }) +const updates = path.join(Helper.localDir, 'test', 'fixtures', 'updates') +const seedOpts = (id) => ({ channel: `test-${id}`, name: `test-${id}`, key: null, dir: updates, cmdArgs: [] }) const stageOpts = (id, dir) => ({ ...seedOpts(id, dir), dryRun: false, bare: true, ignore: [] }) const releaseOpts = (id, key) => ({ channel: `test-${id}`, name: `test-${id}`, key }) const ts = () => new Date().toISOString().replace(/[:.]/g, '-') const rig = new Helper.Rig() const { tmp } = rig +const PLATFORM_STAGE_TIMEOUT = 30_000 + test.hook('updates setup', rig.setup) test('Pear.updates(listener) should notify when restaging and releasing application (same pear instance)', async function ({ ok, is, plan, comment, teardown, timeout }) { - timeout(180000) plan(7) const testId = Math.floor(Math.random() * 100000) @@ -27,63 +28,64 @@ test('Pear.updates(listener) should notify when restaging and releasing applicat comment('\tstaging') const staging = stager1.stage(stageOpts(testId)) + teardown(() => Helper.teardownStream(staging)) const until = await Helper.pick(staging, [{ tag: 'staging' }, { tag: 'final' }]) const { key, link } = await until.staging await until.final comment('\trunning') - const running = await Helper.open(link, { tags: ['exit'] }, rig) - const update1Promise = await running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false }) - const update1ActualPromise = running.inspector.awaitPromise(update1Promise.objectId) - const update2LazyPromise = update1ActualPromise.then(() => running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false })) + const { pipe } = await Helper.run({ link }) + const versions = await Helper.untilResult(pipe).then((data) => JSON.parse(data)) + ok(versions?.app, 'updater is ready') + + const untilUpdate1 = Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const untilUpdate2 = untilUpdate1.then(() => Helper.untilResult(pipe)).then((data) => JSON.parse(data)) comment('2. Create new file, restage, and reseed') const file = `${ts()}.tmp` comment(`\tcreating test file (${file})`) - fs.writeFileSync(path.join(harness, file), 'test') - teardown(() => { try { fs.unlinkSync(path.join(harness, file)) } catch { /* ignore */ } }) + fs.writeFileSync(path.join(updates, file), 'test') + teardown(() => { try { fs.unlinkSync(path.join(updates, file)) } catch { /* ignore */ } }) + comment('\tstaging') const stager2 = new Helper(rig) teardown(() => stager2.close(), { order: Infinity }) await stager2.ready() - await Helper.pick(stager2.stage(stageOpts(testId)), { tag: 'final' }) + const staging2 = stager2.stage(stageOpts(testId)) + teardown(() => Helper.teardownStream(staging2)) + await Helper.pick(staging2, { tag: 'final' }) - fs.unlinkSync(path.join(harness, file)) + fs.unlinkSync(path.join(updates, file)) - const update1 = await update1ActualPromise - const update1Version = update1?.value?.version + const update1 = await untilUpdate1 + const update1Version = update1?.version is(hypercoreid.normalize(update1Version?.key), hypercoreid.normalize(key), 'app updated with matching key') is(update1Version?.fork, 0, 'app version.fork is 0') ok(update1Version?.length > 0, `app version.length is non-zero (v${update1Version?.fork}.${update1Version?.length})`) - comment('releasing') - const update2Promise = await update2LazyPromise - const update2ActualPromise = running.inspector.awaitPromise(update2Promise.objectId) + comment('\treleasing') const releaser = new Helper(rig) - teardown(() => releaser.close()) + teardown(() => releaser.close(), { order: Infinity }) await releaser.ready() const releasing = releaser.release(releaseOpts(testId, key)) + teardown(() => Helper.teardownStream(releasing)) await Helper.pick(releasing, { tag: 'released' }) - teardown(() => releaser.close()) // TODO why is this needed? - comment('waiting for update') - const update2 = await update2ActualPromise - const update2Version = update2?.value?.version + + comment('\twaiting for update') + const update2 = await untilUpdate2 + const update2Version = update2?.version is(hypercoreid.normalize(update2Version?.key), hypercoreid.normalize(key), 'app updated with matching key') is(update2Version?.fork, 0, 'app version.fork is 0') ok(update2Version?.length > update1Version?.length, `app version.length incremented (v${update2Version?.fork}.${update2Version?.length})`) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + + await Helper.untilClose(pipe) }) test('Pear.updates(listener) should notify twice when restaging application twice (same pear instance)', async function (t) { - const { ok, is, plan, comment, timeout, teardown } = t - - timeout(180000) + const { ok, is, plan, comment, teardown } = t plan(7) const testId = Math.floor(Math.random() * 100000) @@ -95,35 +97,38 @@ test('Pear.updates(listener) should notify twice when restaging application twic teardown(() => stager1.close(), { order: Infinity }) await stager1.ready() const staging = stager1.stage(stageOpts(testId)) + teardown(() => Helper.teardownStream(staging)) const until = await Helper.pick(staging, [{ tag: 'staging' }, { tag: 'final' }]) const { key, link } = await until.staging await until.final comment('\trunning') - const running = await Helper.open(link, { tags: ['exit'] }, rig) - const update1Promise = await running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false }) - const update1ActualPromise = running.inspector.awaitPromise(update1Promise.objectId) - const update2LazyPromise = update1ActualPromise.then(() => running.inspector.evaluate(` - new Promise((resolve) => __PEAR_TEST__.sub.once("data", resolve)) - `, { returnByValue: false })) + const { pipe } = await Helper.run({ link }) + const versions = await Helper.untilResult(pipe).then((data) => JSON.parse(data)) + ok(versions?.app, 'updater is ready') + + const untilUpdate1 = Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const untilUpdate2 = untilUpdate1.then(() => Helper.untilResult(pipe)).then((data) => JSON.parse(data)) comment('2. Create new file, restage, and reseed') const file = `${ts()}.tmp` comment(`\tcreating test file (${file})`) - fs.writeFileSync(path.join(harness, file), 'test') + fs.writeFileSync(path.join(updates, file), 'test') comment('\trestaging') const stager2 = new Helper(rig) - teardown(() => stager2.close()) + teardown(() => stager2.close(), { order: Infinity }) await stager2.ready() - await Helper.pick(stager2.stage(stageOpts(testId)), { tag: 'final' }) - fs.unlinkSync(path.join(harness, file)) + const staging2 = stager2.stage(stageOpts(testId)) + teardown(() => Helper.teardownStream(staging2)) + await Helper.pick(staging2, { tag: 'final' }) + fs.unlinkSync(path.join(updates, file)) comment('\twaiting for update') - const update1 = await update1ActualPromise - const update1Version = update1?.value?.version + const update1 = await untilUpdate1 + const update1Version = update1?.version is(hypercoreid.normalize(update1Version?.key), hypercoreid.normalize(key), 'app updated with matching key') is(update1Version?.fork, 0, 'app version.fork is 0') ok(update1Version?.length > 0, `app version.length is non-zero (v${update1Version?.fork}.${update1Version?.length})`) @@ -132,36 +137,33 @@ test('Pear.updates(listener) should notify twice when restaging application twic const file2 = `${ts()}.tmp` comment(`\tcreating another test file (${file2})`) - fs.writeFileSync(path.join(harness, file2), 'test') + fs.writeFileSync(path.join(updates, file2), 'test') comment('\trestaging') - const update2Promise = await update2LazyPromise - const update2ActualPromise = running.inspector.awaitPromise(update2Promise.objectId) - const stager3 = new Helper(rig) - teardown(() => stager3.close()) + teardown(() => stager3.close(), { order: Infinity }) await stager3.ready() - await Helper.pick(stager3.stage(stageOpts(testId)), { tag: 'final' }) + const staging3 = stager3.stage(stageOpts(testId)) + teardown(() => Helper.teardownStream(staging3)) + await Helper.pick(staging3, { tag: 'final' }) - fs.unlinkSync(path.join(harness, file2)) + fs.unlinkSync(path.join(updates, file2)) comment('\twaiting for update') - const update2 = await update2ActualPromise - const update2Version = update2?.value?.version + const update2 = await untilUpdate2 + const update2Version = update2?.version is(hypercoreid.normalize(update2Version?.key), hypercoreid.normalize(key), 'app updated with matching key') is(update2Version?.fork, 0, 'app version.fork is 0') ok(update2Version?.length > update1Version?.length, `app version.length incremented (v${update2Version?.fork}.${update2Version?.length})`) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(pipe) }) test('Pear.updates should notify Platform stage updates (different pear instances)', async function (t) { const { ok, is, plan, timeout, comment, teardown } = t - plan(6) - timeout(180000) + plan(5) + timeout(60_000) + const appStager = new Helper(rig) teardown(() => appStager.close(), { order: Infinity }) await appStager.ready() @@ -169,7 +171,8 @@ test('Pear.updates should notify Platform stage updates (different pear instance const channel = 'test-fixture' comment('staging app') - const appStaging = appStager.stage({ channel, name: channel, dir: harness, dryRun: false, bare: true }) + const appStaging = appStager.stage({ channel, name: channel, dir: updates, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(appStaging)) const appFinal = await Helper.pick(appStaging, { tag: 'final' }) ok(appFinal.success, 'stage succeeded') @@ -177,7 +180,8 @@ test('Pear.updates should notify Platform stage updates (different pear instance const appSeeder = new Helper(rig) teardown(() => appSeeder.close(), { order: Infinity }) await appSeeder.ready() - const appSeeding = appSeeder.seed({ channel, name: channel, dir: harness, key: null, cmdArgs: [] }) + + const appSeeding = appSeeder.seed({ channel, name: channel, dir: updates, key: null, cmdArgs: [] }) teardown(() => Helper.teardownStream(appSeeding)) const untilApp = await Helper.pick(appSeeding, [{ tag: 'key' }, { tag: 'announced' }]) @@ -197,13 +201,12 @@ test('Pear.updates should notify Platform stage updates (different pear instance comment('running app from rcv platform') const link = 'pear://' + appKey - const running = await Helper.open(link, { tags: ['exit'] }, { platformDir: platformDirRcv }) - const { value } = await running.inspector.evaluate('Pear.versions()', { awaitPromise: true }) - const { key: pearVersionKey, length: pearVersionLength } = value?.platform || {} + const { pipe } = await Helper.run({ link, platformDir: platformDirRcv }) + const versions = await Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const { key: pearVersionKey, length: pearVersionLength } = versions?.platform || {} is(pearVersionKey, rig.key, 'platform version key matches staged key') - const updatePromise = await running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false }) - const updateActualPromise = running.inspector.awaitPromise(updatePromise.objectId) + const untilUpdate = Helper.untilResult(pipe, PLATFORM_STAGE_TIMEOUT).then((data) => JSON.parse(data)) const ts = () => new Date().toISOString().replace(/[:.]/g, '-') const file = `${ts()}.tmp` @@ -213,24 +216,22 @@ test('Pear.updates should notify Platform stage updates (different pear instance comment('restaging rig platform') const staging = rig.local.stage({ channel: `test-${rig.id}`, name: `test-${rig.id}`, dir: rig.artefactDir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) await Helper.pick(staging, { tag: 'final' }) comment('rig platform restaged') comment('waiting for update') - const update = await updateActualPromise - const updateVersion = update?.value?.version + const update = await untilUpdate + const updateVersion = update?.version const pearUpdateLength = updateVersion.length ok(pearUpdateLength > pearVersionLength, `platform version.length incremented (v${updateVersion?.fork}.${updateVersion?.length})`) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(pipe) }) test('Pear.updates should notify Platform stage, Platform release updates (different pear instances)', async function (t) { const { ok, is, plan, timeout, comment, teardown } = t - plan(8) - timeout(180000) + plan(7) + timeout(60_000) const appStager = new Helper(rig) teardown(() => appStager.close(), { order: Infinity }) @@ -239,7 +240,8 @@ test('Pear.updates should notify Platform stage, Platform release updates (diffe const channel = 'test-fixture' comment('staging app') - const appStaging = appStager.stage({ channel, name: channel, dir: harness, dryRun: false, bare: true }) + const appStaging = appStager.stage({ channel, name: channel, dir: updates, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(appStaging)) const appFinal = await Helper.pick(appStaging, { tag: 'final' }) ok(appFinal.success, 'stage succeeded') @@ -248,7 +250,7 @@ test('Pear.updates should notify Platform stage, Platform release updates (diffe teardown(() => appSeeder.close(), { order: Infinity }) await appSeeder.ready() - const appSeeding = appSeeder.seed({ channel, name: channel, dir: harness, key: null, cmdArgs: [] }) + const appSeeding = appSeeder.seed({ channel, name: channel, dir: updates, key: null, cmdArgs: [] }) teardown(() => Helper.teardownStream(appSeeding)) const untilApp = await Helper.pick(appSeeding, [{ tag: 'key' }, { tag: 'announced' }]) @@ -268,14 +270,13 @@ test('Pear.updates should notify Platform stage, Platform release updates (diffe comment('running app from rcv platform') const link = 'pear://' + appKey - const running = await Helper.open(link, { tags: ['exit'] }, { platformDir: platformDirRcv }) - const { value } = await running.inspector.evaluate('Pear.versions()', { awaitPromise: true }) - const { key: pearVersionKey, length: pearVersionLength } = value?.platform || {} + const { pipe } = await Helper.run({ link, platformDir: platformDirRcv }) + const versions = await Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const { key: pearVersionKey, length: pearVersionLength } = versions?.platform || {} is(pearVersionKey, rig.key, 'platform version key matches staged key') - const update1Promise = await running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false }) - const update1ActualPromise = running.inspector.awaitPromise(update1Promise.objectId) - const update2LazyPromise = update1ActualPromise.then(() => running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false })) + const untilUpdate1 = Helper.untilResult(pipe, PLATFORM_STAGE_TIMEOUT).then((data) => JSON.parse(data)) + const untilUpdate2 = untilUpdate1.then(() => Helper.untilResult(pipe, PLATFORM_STAGE_TIMEOUT)).then((data) => JSON.parse(data)) const ts = () => new Date().toISOString().replace(/[:.]/g, '-') const file = `${ts()}.tmp` @@ -285,46 +286,45 @@ test('Pear.updates should notify Platform stage, Platform release updates (diffe comment('restaging rig platform') const staging = rig.local.stage({ channel: `test-${rig.id}`, name: `test-${rig.id}`, dir: rig.artefactDir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) await Helper.pick(staging, { tag: 'final' }) comment('rig platform restaged') comment('waiting for update') - const update1 = await update1ActualPromise - const update1Version = update1?.value?.version + const update1 = await untilUpdate1 + const update1Version = update1?.version const pearUpdateLength = update1Version.length ok(pearUpdateLength > pearVersionLength, `platform version.length incremented (v${update1Version?.fork}.${update1Version?.length})`) comment('releasing rig platform') - const update2Promise = await update2LazyPromise - const update2ActualPromise = running.inspector.awaitPromise(update2Promise.objectId) const releasing = rig.local.release({ channel: `test-${rig.id}`, name: `test-${rig.id}`, dir: rig.artefactDir }) + teardown(() => Helper.teardownStream(releasing)) await Helper.pick(releasing, { tag: 'final' }) comment('waiting for platform update notification') - const update2 = await update2ActualPromise - const update2Version = update2?.value?.version + const update2 = await untilUpdate2 + const update2Version = update2?.version const pearUpdate2Key = update2Version.key const pearUpdate2Length = update2Version.length is(pearUpdate2Key, rig.key, 'platform release update matches staging key') ok(pearUpdate2Length > pearUpdateLength, `platform version length incremented (v${update2Version?.fork}.${update2Version?.length})`) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(pipe) }) test('Pear.updates should notify App stage updates (different pear instances)', async function (t) { const { ok, is, plan, timeout, comment, teardown } = t - plan(7) - timeout(180000) + plan(6) + timeout(60_000) + const appStager = new Helper(rig) teardown(() => appStager.close(), { order: Infinity }) await appStager.ready() const channel = 'test-fixture' comment('staging app') - const appStaging = appStager.stage({ channel, name: channel, dir: harness, dryRun: false, bare: true }) + const appStaging = appStager.stage({ channel, name: channel, dir: updates, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(appStaging)) const appFinal = await Helper.pick(appStaging, { tag: 'final' }) ok(appFinal.success, 'stage succeeded') @@ -332,7 +332,7 @@ test('Pear.updates should notify App stage updates (different pear instances)', const appSeeder = new Helper(rig) teardown(() => appSeeder.close(), { order: Infinity }) await appSeeder.ready() - const appSeeding = appSeeder.seed({ channel, name: channel, dir: harness, key: null, cmdArgs: [] }) + const appSeeding = appSeeder.seed({ channel, name: channel, dir: updates, key: null, cmdArgs: [] }) teardown(() => Helper.teardownStream(appSeeding)) const untilApp = await Helper.pick(appSeeding, [{ tag: 'key' }, { tag: 'announced' }]) @@ -351,45 +351,42 @@ test('Pear.updates should notify App stage updates (different pear instances)', comment('rcv platform bootstrapped') comment('running app from rcv platform') - const link = 'pear://' + appKey - const running = await Helper.open(link, { tags: ['exit'] }, { platformDir: platformDirRcv }) - const { value } = await running.inspector.evaluate('Pear.versions()', { awaitPromise: true }) - const { key: appVersionKey, length: appVersionLength } = value?.app || {} + const { pipe } = await Helper.run({ link, platformDir: platformDirRcv }) + const versions = await Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const { key: appVersionKey, length: appVersionLength } = versions?.app || {} is(appVersionKey, appKey, 'app version key matches staged key') - const updatePromise = await running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false }) - const updateActualPromise = running.inspector.awaitPromise(updatePromise.objectId) + const untilUpdate = Helper.untilResult(pipe).then((data) => JSON.parse(data)) const ts = () => new Date().toISOString().replace(/[:.]/g, '-') const file = `${ts()}.tmp` comment(`creating app test file (${file})`) - fs.writeFileSync(path.join(harness, file), 'test') - teardown(() => { fs.unlinkSync(path.join(harness, file)) }, { order: -Infinity }) + fs.writeFileSync(path.join(updates, file), 'test') + teardown(() => { fs.unlinkSync(path.join(updates, file)) }, { order: -Infinity }) comment('restaging app') const appStager2 = new Helper(rig) teardown(() => appStager2.close(), { order: Infinity }) await appStager2.ready() - const appStaging2 = appStager2.stage({ channel, name: channel, dir: harness, dryRun: false, bare: true }) + const appStaging2 = appStager2.stage({ channel, name: channel, dir: updates, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(appStaging2)) const appFinal2 = await Helper.pick(appStaging2, { tag: 'final' }) ok(appFinal2.success, 'stage succeeded') - const update = await updateActualPromise - const updateVersion = update?.value?.version + const update = await untilUpdate + const updateVersion = update?.version const appUpdateLength = updateVersion.length ok(appUpdateLength > appVersionLength, `app version.length incremented (v${updateVersion?.fork}.${updateVersion?.length})`) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(pipe) }) test('Pear.updates should notify App stage, App release updates (different pear instances)', async function (t) { const { ok, is, plan, timeout, comment, teardown } = t - plan(9) - timeout(180000) + plan(8) + timeout(60_000) + const appStager = new Helper(rig) teardown(() => appStager.close(), { order: Infinity }) await appStager.ready() @@ -397,7 +394,8 @@ test('Pear.updates should notify App stage, App release updates (different pear const channel = 'test-fixture' comment('staging app') - const appStaging = appStager.stage({ channel, name: channel, dir: harness, dryRun: false, bare: true }) + const appStaging = appStager.stage({ channel, name: channel, dir: updates, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(appStaging)) const appFinal = await Helper.pick(appStaging, { tag: 'final' }) ok(appFinal.success, 'stage succeeded') @@ -405,7 +403,7 @@ test('Pear.updates should notify App stage, App release updates (different pear const appSeeder = new Helper(rig) teardown(() => appSeeder.close(), { order: Infinity }) await appSeeder.ready() - const appSeeding = appSeeder.seed({ channel, name: channel, dir: harness, key: null, cmdArgs: [] }) + const appSeeding = appSeeder.seed({ channel, name: channel, dir: updates, key: null, cmdArgs: [] }) teardown(() => Helper.teardownStream(appSeeding)) const untilApp = await Helper.pick(appSeeding, [{ tag: 'key' }, { tag: 'announced' }]) @@ -425,56 +423,52 @@ test('Pear.updates should notify App stage, App release updates (different pear comment('running app from rcv platform') const link = 'pear://' + appKey - const running = await Helper.open(link, { tags: ['exit'] }, { platformDir: platformDirRcv }) - const { value } = await running.inspector.evaluate('Pear.versions()', { awaitPromise: true }) - const { key: appVersionKey, length: appVersionLength } = value?.app || {} + const { pipe } = await Helper.run({ link, platformDir: platformDirRcv }) + const versions = await Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const { key: appVersionKey, length: appVersionLength } = versions?.app || {} is(appVersionKey, appKey, 'app version key matches staged key') - const update1Promise = await running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false }) - const update1ActualPromise = running.inspector.awaitPromise(update1Promise.objectId) - const update2LazyPromise = update1ActualPromise.then(() => running.inspector.evaluate('__PEAR_TEST__.nextUpdate()', { returnByValue: false })) + const untilUpdate1 = Helper.untilResult(pipe).then((data) => JSON.parse(data)) + const untilUpdate2 = untilUpdate1.then(() => Helper.untilResult(pipe)).then((data) => JSON.parse(data)) const ts = () => new Date().toISOString().replace(/[:.]/g, '-') const file = `${ts()}.tmp` comment(`creating app test file (${file})`) - fs.writeFileSync(path.join(harness, file), 'test') - teardown(() => { fs.unlinkSync(path.join(harness, file)) }, { order: -Infinity }) + fs.writeFileSync(path.join(updates, file), 'test') + teardown(() => { fs.unlinkSync(path.join(updates, file)) }, { order: -Infinity }) comment('restaging app') const appStager2 = new Helper(rig) teardown(() => appStager2.close(), { order: Infinity }) await appStager2.ready() - const appStaging2 = appStager2.stage({ channel, name: channel, dir: harness, dryRun: false, bare: true }) + const appStaging2 = appStager2.stage({ channel, name: channel, dir: updates, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(appStaging2)) const appFinal2 = await Helper.pick(appStaging2, { tag: 'final' }) ok(appFinal2.success, 'stage succeeded') - const update1 = await update1ActualPromise - const update1Version = update1?.value?.version + const update1 = await untilUpdate1 + const update1Version = update1?.version const appUpdateLength = update1Version.length ok(appUpdateLength > appVersionLength, `app version.length incremented (v${update1Version?.fork}.${update1Version?.length})`) comment('releasing app') - const update2Promise = await update2LazyPromise - const update2ActualPromise = running.inspector.awaitPromise(update2Promise.objectId) const releaser = new Helper(rig) - teardown(() => releaser.close()) + teardown(() => releaser.close(), { order: Infinity }) await releaser.ready() const releasing = releaser.release({ channel, name: channel, key: appKey }) + teardown(() => Helper.teardownStream(releasing)) await Helper.pick(releasing, { tag: 'released' }) comment('waiting for app update notification') - const update2 = await update2ActualPromise - const update2Version = update2?.value?.version + const update2 = await untilUpdate2 + const update2Version = update2?.version const appUpdate2Length = update2Version.length is(hypercoreid.normalize(update2Version?.key), hypercoreid.normalize(appKey), 'app release update matches staging key') ok(appUpdate2Length > appUpdateLength, `app version length incremented (v${update2Version?.fork}.${update2Version?.length})`) - await running.inspector.evaluate('__PEAR_TEST__.close()') - await running.inspector.close() - const { code } = await running.until.exit - is(code, 0, 'exit code is 0') + await Helper.untilClose(pipe) }) test.hook('updates cleanup', rig.cleanup) diff --git a/test/fixtures/harness/.npmrc b/test/fixtures/harness/.npmrc deleted file mode 100644 index 9cf949503..000000000 --- a/test/fixtures/harness/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false \ No newline at end of file diff --git a/test/fixtures/harness/index.js b/test/fixtures/harness/index.js deleted file mode 100644 index 6b196c7f3..000000000 --- a/test/fixtures/harness/index.js +++ /dev/null @@ -1,63 +0,0 @@ -/* global Pear */ -import ReadyResource from 'ready-resource' -import bareInspector from 'bare-inspector' -import { Inspector } from 'pear-inspect' - -class Harness extends ReadyResource { - inspector = null - inspectorKey = null - cmd = null - Helper = null - API = null - ipc = null - sub = null - async _open () { - this.inspector = new Inspector({ inspector: bareInspector }) - this.key = await this.inspector.enable() - this.inspectorKey = this.key.toString('hex') - console.log(`{ "tag": "inspector", "data": { "key": "${this.inspectorKey}" }}`) - } - - async close () { - await this.inspector.disable() - await this.sub?.destroy() - if (this._client) await this._client.close() - this.inspector = null - this.sub = null - this.key = null - this.inspectorKey = null - this.Helper = null - this.cmd = null - this.API = null - this.ipc = null - } - - async client (opts) { - if (this.Helper === null) { - const { default: Helper } = await import('pear/test/helper') - this.Helper = Helper - } - if (this.cmd === null) { - const { default: cmd } = await import('pear/cmd') - this.cmd = cmd - } - return new this.Helper(opts) - } - - nextUpdate () { - if (this.sub === null) this.sub = Pear.updates() - return new Promise((resolve) => { - this.sub.once('data', resolve) - }) - } - - async command (argv) { - if (this.closed) throw new Error('Harness closed') - this._client = await this.client() - return this.cmd(this._client, argv) - } -} -const harness = new Harness() -Pear.teardown(() => harness.close()) -await harness.ready() -global.__PEAR_TEST__ = harness diff --git a/test/fixtures/harness/package.json b/test/fixtures/harness/package.json deleted file mode 100644 index b500f1175..000000000 --- a/test/fixtures/harness/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "test-terminal-app", - "version": "1.0.0", - "description": "", - "main": "index.js", - "type": "module", - "pear": { - "name": "test-terminal-app", - "type": "terminal", - "bin": "test-terminal-app", - "builtinsMap": { - "events": "bare-events" - }, - "stage": { - "ignore": [ - "node_modules/pear/" - ] - } - }, - "keywords": [], - "author": "Holepunch", - "dependencies": { - "bare-inspector": "^3.0.1", - "pear": "file:../../..", - "pear-inspect": "^1.2.2", - "ready-resource": "^1.1.1" - } -} diff --git a/test/fixtures/updates/index.js b/test/fixtures/updates/index.js new file mode 100644 index 000000000..07c2f8766 --- /dev/null +++ b/test/fixtures/updates/index.js @@ -0,0 +1,10 @@ +const pipe = Pear.worker.pipe() + +const updates = Pear.updates((data) => { + pipe.write(JSON.stringify(data)) +}) + +pipe.on('end', () => updates.end()) +pipe.resume() + +Pear.versions().then((versions) => pipe.write(JSON.stringify(versions))) diff --git a/test/fixtures/updates/package.json b/test/fixtures/updates/package.json new file mode 100644 index 000000000..c6cf1d676 --- /dev/null +++ b/test/fixtures/updates/package.json @@ -0,0 +1,8 @@ +{ + "name": "updates", + "main": "index.js", + "pear": { + "name": "updates", + "type": "terminal" + } +} diff --git a/test/helper.js b/test/helper.js index 8e8a9f1b4..98766c021 100644 --- a/test/helper.js +++ b/test/helper.js @@ -5,11 +5,7 @@ const env = require('bare-env') const path = require('bare-path') const { spawn } = require('bare-subprocess') const fs = require('bare-fs') -const ReadyResource = require('ready-resource') const { arch, platform, isWindows } = require('which-runtime') -const { Session } = require('pear-inspect') -const { Readable } = require('streamx') -const NewlineDecoder = require('newline-decoder') const IPC = require('pear-ipc') const sodium = require('sodium-native') const updaterBootstrap = require('pear-updater-bootstrap') @@ -200,49 +196,6 @@ class Helper extends IPC.Client { return res } - static async open (link, { tags = [] } = {}, opts = {}) { - if (!link) throw new Error('Key is missing') - - const dhtBootstrap = Pear.config.dht.bootstrap.map(e => `${e.host}:${e.port}`).join(',') - const args = !opts.encryptionKey ? ['run', '--dht-bootstrap', dhtBootstrap, '-t', link] : ['run', '--dht-bootstrap', dhtBootstrap, '--encryption-key', opts.encryptionKey, '--no-ask', '-t', link] - if (this.log) args.push('--log') - - const platformDir = opts.platformDir || PLATFORM_DIR - const runtime = path.join(platformDir, 'current', BY_ARCH) - const subprocess = spawn(runtime, args, { stdio: ['pipe', 'pipe', 'inherit'] }) - tags = ['inspector', ...tags].map((tag) => ({ tag })) - - const stream = new Readable({ objectMode: true }) - const lineout = opts.lineout ? new Readable({ objectMode: true }) : null - const onLine = (line) => { - if (line.indexOf('teardown') > -1) { - stream.push({ tag: 'teardown', data: line }) - return - } - if (line.indexOf('"tag": "inspector"') > -1) { - stream.push(JSON.parse(line)) - return - } - if (opts.lineout) lineout.push(line) - else console.log('# unexpected', line) - } - const decoder = new NewlineDecoder() - subprocess.stdout.on('data', (data) => { - for (const line of decoder.push(data)) onLine(line.toString().trim()) - }) - subprocess.once('exit', (code, signal) => { - for (const line of decoder.end()) onLine(line.toString().trim()) - stream.push({ tag: 'exit', data: { code, signal } }) - }) - const until = await this.pick(stream, tags) - - const data = await until.inspector - const inspector = new Helper.Inspector(data.key) - await inspector.ready() - - return { inspector, until, subprocess, lineout } - } - static async pick (stream, ptn = {}, by = 'tag') { if (Array.isArray(ptn)) return this.#untils(stream, ptn, by) for await (const output of stream) { @@ -319,54 +272,6 @@ class Helper extends IPC.Client { await fs.promises.rm(dir, { recursive: true }).catch(() => { }) } - - static Inspector = class extends ReadyResource { - #session = null - - constructor (key) { - super() - this.#session = new Session({ inspectorKey: Buffer.from(key, 'hex') }) - } - - async _open () { - this.#session.connect() - } - - async _close () { - await this.evaluate('global.__PEAR_TEST__.inspector.disable()').catch(() => { }) - - this.#session.disconnect() - await this.#session.destroy() - } - - async _unwrap () { - return new Promise((resolve, reject) => { - const handler = ({ result, error }) => { - if (error) reject(error) - else resolve(result?.result) - - this.#session.off('message', handler) - } - - this.#session.on('message', handler) - }) - } - - async evaluate (expression, { awaitPromise = false, returnByValue = true } = {}) { - const reply = this._unwrap() - this.#session.post({ method: 'Runtime.evaluate', params: { expression, awaitPromise, returnByValue } }) - - return reply - } - - async awaitPromise (promiseObjectId, { returnByValue = true } = {}) { - const id = Math.floor(Math.random() * 10000) - const reply = this._unwrap(id) - this.#session.post({ method: 'Runtime.awaitPromise', params: { promiseObjectId, returnByValue } }) - - return reply - } - } } module.exports = Helper From e92fc9a6fb752a692d26ea4e820a0a079e60bada Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 02:37:16 +0100 Subject: [PATCH 30/38] Bump deps (#435) Co-authored-by: GitHub Actions Bot --- package-lock.json | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 094886e6a..6f54af6c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,10 +74,6 @@ "@hyperswarm/testnet": "^3.1.4", "brittle": "^3.5.2", "graceful-goodbye": "^1.3.0", - "hyperbee": "^2.0.1", - "hypercore": "^10.36.4", - "newline-decoder": "^1.0.2", - "port-get": "^1.0.4", "standard": "^17.0.0" } }, @@ -3171,15 +3167,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/newline-decoder": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/newline-decoder/-/newline-decoder-1.0.2.tgz", - "integrity": "sha512-mAktSzvuWBobYUpN8YRJ3O/8IRROOnX03JZNZXzvhqOsoPwgVhjQr5V5JFYKDvEGIhdrXnpMb0EfFwMLTpCu/Q==", - "dev": true, - "dependencies": { - "text-decoder": "^1.0.0" - } - }, "node_modules/node-gyp-build": { "version": "4.8.2", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", @@ -3220,9 +3207,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "engines": { "node": ">= 0.4" @@ -3625,12 +3612,6 @@ "node": ">=4" } }, - "node_modules/port-get": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/port-get/-/port-get-1.0.4.tgz", - "integrity": "sha512-B8RcNfc8Ld+7C31DPaKIQz2aO9dqIs+4sUjhxJ2TSjEaidwyxu05WBbm08FJe+qkVvLiQqPbEAfNw1rB7JbjtA==", - "dev": true - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", From a1b96f565468168cc9baaf5d250a846de9f8c3f4 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:47:30 +0100 Subject: [PATCH 31/38] fixed broken stdin when Ctrl-C a desktop app (#436) --- run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run.js b/run.js index db00c377c..00ecf7343 100644 --- a/run.js +++ b/run.js @@ -137,7 +137,7 @@ module.exports = async function run ({ ipc, args, cmdArgs, link, storage, detach args[indices.args.link] = args[indices.args.link].replace('://', '_||') // for Windows if ((isLinux || isWindows) && !flags.sandbox) args.splice(indices.args.link, 0, '--no-sandbox') args = [constants.BOOT, ...args] - const stdio = detach ? 'ignore' : ['inherit', 'pipe', 'pipe'] + const stdio = detach ? 'ignore' : ['ignore', 'pipe', 'pipe'] const child = spawn(constants.DESKTOP_RUNTIME, args, { stdio, cwd, From 890086eaeb2764bcf2bb41f692ee58dcb1651f4f Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 12 Nov 2024 00:55:19 +1100 Subject: [PATCH 32/38] Fix restart client api in Windows (#437) * fix-restart-client-win * fix-restart-client-win * fix-restart-client-win * fix-restart-client-win * fix-restart-client-win --- subsystems/sidecar/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsystems/sidecar/index.js b/subsystems/sidecar/index.js index 775f08d31..7b3172c8a 100644 --- a/subsystems/sidecar/index.js +++ b/subsystems/sidecar/index.js @@ -522,7 +522,7 @@ class Sidecar extends ReadyResource { if (platform === false) { const { dir, cwd, cmdArgs, env } = client.userData.state const appling = client.userData.state.appling - const opts = { cwd, env, detached: true, stdio: 'ignore' } + const opts = { cwd, env, detached: false, stdio: 'ignore' } if (!client.closed) { await new Promise((resolve) => { if (client.closed) { From 45bae4d0cdd8a80c5f2f862a4ed2c6e3b1a3270f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:50:12 +0100 Subject: [PATCH 33/38] Bump deps (#439) Co-authored-by: GitHub Actions Bot --- package-lock.json | 124 ++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f54af6c0..91911f763 100644 --- a/package-lock.json +++ b/package-lock.json @@ -630,9 +630,9 @@ } }, "node_modules/bare-module": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.1.tgz", - "integrity": "sha512-U5B2DGdiiVGYKzdPBzDOFUNybNwK+Qbg6gMY0J1M+wgLJvlCwLRQHjtrBLvkP00LJvn8RlPWyi71ZnHLY6PiRQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.2.tgz", + "integrity": "sha512-R+sI3Dgdak72mJleoxuLN4MLC0kSJEHn7VCCEtloN2D9xCaAiB2RXwv43vuiONXk/w3p3SUDcJGNHR1GkWCZqg==", "dependencies": { "bare-bundle": "^1.3.0", "bare-module-lexer": "^1.0.0", @@ -650,11 +650,11 @@ } }, "node_modules/bare-module-resolve": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.8.0.tgz", - "integrity": "sha512-3UHBfM3manIQYgh0ximl5dMvX+DW09r69KTrZ9Ibfr85OFVyN4oGMrg67X7MXrdoQeXFkzb++BgGaNKcVmPObw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.8.1.tgz", + "integrity": "sha512-hl4hMnFzH0zrh2PzkOWtP9bCbBgMjnYY9VdHDXW7BrFSwygAuSJilWcTr6eYTCcAzYYfHWYN2iyM2zMzVz6TfQ==", "dependencies": { - "semifies": "^1.0.0" + "bare-semver": "^1.0.0" } }, "node_modules/bare-os": { @@ -682,6 +682,21 @@ "bare-stream": "^2.0.0" } }, + "node_modules/bare-process": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-3.0.0.tgz", + "integrity": "sha512-pqlIEP0pYxgxjWCIMZP5kKCnljOj5kRx7B9aP3KViILzMzOulIt8To7VrFY2hA2AhM/514ZttTfTV/1H4d2XQw==", + "dev": true, + "dependencies": { + "bare-env": "^3.0.0", + "bare-events": "^2.3.1", + "bare-hrtime": "^2.0.0", + "bare-os": "^3.0.1", + "bare-pipe": "^3.1.0", + "bare-signals": "^3.0.0", + "bare-tty": "^4.0.0" + } + }, "node_modules/bare-readline": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/bare-readline/-/bare-readline-1.0.6.tgz", @@ -691,6 +706,11 @@ "bare-stream": "^2.0.0" } }, + "node_modules/bare-semver": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.0.tgz", + "integrity": "sha512-nW9jiT8ePWnCbylz1Xtw1xV4NPwr3TTxAgEMjTC3i/y6VmBCxWzfH4qwN4UWRhpjyIELIz3pfwxCq69b823HCA==" + }, "node_modules/bare-signals": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-3.0.2.tgz", @@ -740,9 +760,9 @@ } }, "node_modules/bare-url": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.8.tgz", - "integrity": "sha512-fnfTsxuCImhvJ04nnekI1n+2/AN837Napp6Z6D0Wyt+Ds7t7u6StcMVSJXwGbq82QGCvSWE5ozIHFLwELOrzsg==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.9.tgz", + "integrity": "sha512-rel9eZD6eZ8mKic9WC2pwGautXcsbSoVCyY+kk4JbDIdKwRsYiy8o3oPT/pmOQTcxgZYwcdmveoCZM3k2oUDlQ==", "dependencies": { "bare-path": "^3.0.0" } @@ -958,9 +978,9 @@ } }, "node_modules/crc-native": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/crc-native/-/crc-native-1.1.4.tgz", - "integrity": "sha512-ZKKd/VY7jSchZ87agNxG/yTc02+W/JDCvOFDVieGU/wwcLNzt95Q4KQLjmmL9dmPsmbBZhjOnsPNZBQ15Df5IA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/crc-native/-/crc-native-1.1.5.tgz", + "integrity": "sha512-toSzpisZ2AhmmfTA6h2Lt0JWOM6G+y0wAGP+JL9bkmLvwpWV2Co4P+DhGEOcGabIeFORZmfIvEs7VAm7kma5vg==", "optional": true, "dependencies": { "node-gyp-build": "^4.8.2" @@ -1102,9 +1122,9 @@ } }, "node_modules/dependency-stream": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/dependency-stream/-/dependency-stream-2.2.3.tgz", - "integrity": "sha512-0UTy298kU2JHYVO0nCXFWzzYa+88kM6WG+8B+HwYrZbBFV9jlv6jtSP2NonuooX3Bha2Dw3iCS7VnEqnbIn6Hg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/dependency-stream/-/dependency-stream-2.2.4.tgz", + "integrity": "sha512-wJ4PgEA2wTr58D9R5dHSFv9937gtfOtMfvhleO7Hq0NxBLdPjU8eVQGp4ipKb9N6fawb6IeCtsoxjL1HcuYM8Q==", "dependencies": { "b4a": "^1.6.4", "bare-module-resolve": "^1.4.4", @@ -1189,9 +1209,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.4.tgz", + "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -1209,7 +1229,7 @@ "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", @@ -1225,10 +1245,10 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", + "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", @@ -2144,11 +2164,12 @@ "dev": true }, "node_modules/graceful-goodbye": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.0.tgz", - "integrity": "sha512-hcZOs20emYlTM7MmUE0FpuZcjlk2GPsR+UYTHDeWxtGjXcbh2CawGi8vlzqsIvspqAbot7mRv3sC/uhgtKc4hQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.2.tgz", + "integrity": "sha512-1UbKPa32HhOUnKSRielAmO2pGpFKO193QRh1rydl+xJesQoRebyGcB3T+13SZXlsETSk4YXMSb8ULdXcLB8bPQ==", "dev": true, "dependencies": { + "bare-process": "^3.0.0", "safety-catch": "^1.0.2" } }, @@ -3168,9 +3189,9 @@ "dev": true }, "node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.3.tgz", + "integrity": "sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -3374,9 +3395,9 @@ } }, "node_modules/paparam": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.6.0.tgz", - "integrity": "sha512-q1l/DIPX9kUIOzFRlqvNz+kukTbladRDeIMGRyEMfO6OZj21Q4v1bALTwxE+d43qQ1BPvKa29IfmsoiAF9953Q==" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.6.1.tgz", + "integrity": "sha512-DBUPol9DzsNjVNh0PwXwzAun5J3H602BVYouLMyRjYZDMt82AG0YCHesgGbCxb+TsdHeHBRSQwOs8igV9+K6Yw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -3706,9 +3727,9 @@ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, "node_modules/quickbit-native": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.3.3.tgz", - "integrity": "sha512-naZ1U2qe883tKZCmIlfvgJXouQW1Av1lQGjhVGZEapxKKqbwbgMMkajHoHABLPF0mUml4ArmkVEGXw8RVJUhDg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.3.4.tgz", + "integrity": "sha512-inl+SbEDqL+NTGFsk/S7nhaFtNEUANpXM1umGeJdOY0gtCLcDTSOZ9sGIXcaKukBgThw9cTD1rgCsYy6sAox+A==", "optional": true, "dependencies": { "b4a": "^1.6.0", @@ -3733,9 +3754,9 @@ "integrity": "sha512-e0k0g0w/8jOCB+7YqCIlOa+OJ38k0wrYS4x18pMSmqOvLKoyhmMhmQyCcvfY6VaP8D75cqkEnlakXs+RYYLqNg==" }, "node_modules/random-access-file": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.1.0.tgz", - "integrity": "sha512-n8uYXv1QXBLIekN6g8ycBqT/3aS955ku/8lTMcqn78EaVLegz/QTsVZoojArijhyZjLyYVHQ4Hu/BKj9G7v4eg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.1.1.tgz", + "integrity": "sha512-HV3zvP4WizFK5jzuuld5kDRT8eW/brujnno00Kg26poMByp9H7hlE1UvpfP7RPjlOel+RVUxoYk/QBBNyFQYjw==", "dependencies": { "random-access-storage": "^3.0.0" }, @@ -3906,9 +3927,9 @@ } }, "node_modules/rocksdb-native": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-2.6.3.tgz", - "integrity": "sha512-836w8wT5E4tbLEWPtV44Hbu4ewRTzIDJjNqqlzj8YSgYtoh8KGAEt6dnF1w1M3qVi8/AFSO/r5IZo1k89f7aKQ==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-2.6.4.tgz", + "integrity": "sha512-Fzn3af1rJ1B74C3tdhR7wM+sGJe7QF2DctzIz7yvif5ZFrvls04IZJVEjq4TcUuhxa4mSMTg+a6AiQFS4MtWIg==", "dependencies": { "b4a": "^1.6.6", "compact-encoding": "^2.15.0", @@ -4007,11 +4028,6 @@ "unix-path-resolve": "^1.0.2" } }, - "node_modules/semifies": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semifies/-/semifies-1.0.0.tgz", - "integrity": "sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==" - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -4117,9 +4133,9 @@ } }, "node_modules/simdle-native": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.3.tgz", - "integrity": "sha512-ZuZ4T71SmunYAZQ3/hg7dy8yUrzjR2VPc50zSKX34JS9RD41QL1wTniJdjp7pq77iNDbekSOCgyYEteDjdyBGw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.4.tgz", + "integrity": "sha512-7fWq9N5wP3ZYdiBcdjdNFHQ+kU/+rxr785HbxMmFjEb8choPbgE9p4fJ5Nm/H2rpSyVkgY9j0E9hYY1RAvBg+A==", "optional": true, "dependencies": { "b4a": "^1.6.0", @@ -4152,9 +4168,9 @@ "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/sodium-native": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.0.tgz", - "integrity": "sha512-OcMgoS0NJx+4yVUlhvL9uZsVZfmyHZ2RpSXkiIoOHMglqvJDeGwn1rUigPrvcNTq3m9hPXtt6syxQbF3vvwmRQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.1.tgz", + "integrity": "sha512-YdP64gAdpIKHfL4ttuX4aIfjeunh9f+hNeQJpE9C8UMndB3zkgZ7YmmGT4J2+v6Ibyp6Wem8D1TcSrtdW0bqtg==", "dependencies": { "node-gyp-build": "^4.8.0" } @@ -4600,9 +4616,9 @@ } }, "node_modules/udx-native": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.2.tgz", - "integrity": "sha512-aPkxfSiSH6QMr7IoGbkf23RY+AHVMTHwA64pCaTLJSQU2qSYsJcNiFPKNP6VFHzXGiE3m+HzLx7/r0orzySobw==", + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.4.tgz", + "integrity": "sha512-1leMazJ1Q9v6hrVvsX10WyqII/fMtqduGW98CPWzDBqyRXKF8wOcFdKzFFM+8FHmlI0jLEiZqYMzxm8CzE8BIQ==", "dependencies": { "b4a": "^1.5.0", "bare-events": "^2.2.0", From f06fd57d3f74e5bb900bb24ecd6bd8db2f751696 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Thu, 14 Nov 2024 10:11:18 +0100 Subject: [PATCH 34/38] Revert "Bump deps (#439)" (#440) This reverts commit 45bae4d0cdd8a80c5f2f862a4ed2c6e3b1a3270f. --- package-lock.json | 124 ++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 91911f763..6f54af6c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -630,9 +630,9 @@ } }, "node_modules/bare-module": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.2.tgz", - "integrity": "sha512-R+sI3Dgdak72mJleoxuLN4MLC0kSJEHn7VCCEtloN2D9xCaAiB2RXwv43vuiONXk/w3p3SUDcJGNHR1GkWCZqg==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-4.6.1.tgz", + "integrity": "sha512-U5B2DGdiiVGYKzdPBzDOFUNybNwK+Qbg6gMY0J1M+wgLJvlCwLRQHjtrBLvkP00LJvn8RlPWyi71ZnHLY6PiRQ==", "dependencies": { "bare-bundle": "^1.3.0", "bare-module-lexer": "^1.0.0", @@ -650,11 +650,11 @@ } }, "node_modules/bare-module-resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.8.1.tgz", - "integrity": "sha512-hl4hMnFzH0zrh2PzkOWtP9bCbBgMjnYY9VdHDXW7BrFSwygAuSJilWcTr6eYTCcAzYYfHWYN2iyM2zMzVz6TfQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.8.0.tgz", + "integrity": "sha512-3UHBfM3manIQYgh0ximl5dMvX+DW09r69KTrZ9Ibfr85OFVyN4oGMrg67X7MXrdoQeXFkzb++BgGaNKcVmPObw==", "dependencies": { - "bare-semver": "^1.0.0" + "semifies": "^1.0.0" } }, "node_modules/bare-os": { @@ -682,21 +682,6 @@ "bare-stream": "^2.0.0" } }, - "node_modules/bare-process": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-3.0.0.tgz", - "integrity": "sha512-pqlIEP0pYxgxjWCIMZP5kKCnljOj5kRx7B9aP3KViILzMzOulIt8To7VrFY2hA2AhM/514ZttTfTV/1H4d2XQw==", - "dev": true, - "dependencies": { - "bare-env": "^3.0.0", - "bare-events": "^2.3.1", - "bare-hrtime": "^2.0.0", - "bare-os": "^3.0.1", - "bare-pipe": "^3.1.0", - "bare-signals": "^3.0.0", - "bare-tty": "^4.0.0" - } - }, "node_modules/bare-readline": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/bare-readline/-/bare-readline-1.0.6.tgz", @@ -706,11 +691,6 @@ "bare-stream": "^2.0.0" } }, - "node_modules/bare-semver": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.0.tgz", - "integrity": "sha512-nW9jiT8ePWnCbylz1Xtw1xV4NPwr3TTxAgEMjTC3i/y6VmBCxWzfH4qwN4UWRhpjyIELIz3pfwxCq69b823HCA==" - }, "node_modules/bare-signals": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-3.0.2.tgz", @@ -760,9 +740,9 @@ } }, "node_modules/bare-url": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.9.tgz", - "integrity": "sha512-rel9eZD6eZ8mKic9WC2pwGautXcsbSoVCyY+kk4JbDIdKwRsYiy8o3oPT/pmOQTcxgZYwcdmveoCZM3k2oUDlQ==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.0.8.tgz", + "integrity": "sha512-fnfTsxuCImhvJ04nnekI1n+2/AN837Napp6Z6D0Wyt+Ds7t7u6StcMVSJXwGbq82QGCvSWE5ozIHFLwELOrzsg==", "dependencies": { "bare-path": "^3.0.0" } @@ -978,9 +958,9 @@ } }, "node_modules/crc-native": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/crc-native/-/crc-native-1.1.5.tgz", - "integrity": "sha512-toSzpisZ2AhmmfTA6h2Lt0JWOM6G+y0wAGP+JL9bkmLvwpWV2Co4P+DhGEOcGabIeFORZmfIvEs7VAm7kma5vg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/crc-native/-/crc-native-1.1.4.tgz", + "integrity": "sha512-ZKKd/VY7jSchZ87agNxG/yTc02+W/JDCvOFDVieGU/wwcLNzt95Q4KQLjmmL9dmPsmbBZhjOnsPNZBQ15Df5IA==", "optional": true, "dependencies": { "node-gyp-build": "^4.8.2" @@ -1122,9 +1102,9 @@ } }, "node_modules/dependency-stream": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/dependency-stream/-/dependency-stream-2.2.4.tgz", - "integrity": "sha512-wJ4PgEA2wTr58D9R5dHSFv9937gtfOtMfvhleO7Hq0NxBLdPjU8eVQGp4ipKb9N6fawb6IeCtsoxjL1HcuYM8Q==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/dependency-stream/-/dependency-stream-2.2.3.tgz", + "integrity": "sha512-0UTy298kU2JHYVO0nCXFWzzYa+88kM6WG+8B+HwYrZbBFV9jlv6jtSP2NonuooX3Bha2Dw3iCS7VnEqnbIn6Hg==", "dependencies": { "b4a": "^1.6.4", "bare-module-resolve": "^1.4.4", @@ -1209,9 +1189,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.4.tgz", - "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -1229,7 +1209,7 @@ "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.4", + "globalthis": "^1.0.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", @@ -1245,10 +1225,10 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.13.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.3", + "regexp.prototype.flags": "^1.5.2", "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", @@ -2164,12 +2144,11 @@ "dev": true }, "node_modules/graceful-goodbye": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.2.tgz", - "integrity": "sha512-1UbKPa32HhOUnKSRielAmO2pGpFKO193QRh1rydl+xJesQoRebyGcB3T+13SZXlsETSk4YXMSb8ULdXcLB8bPQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.0.tgz", + "integrity": "sha512-hcZOs20emYlTM7MmUE0FpuZcjlk2GPsR+UYTHDeWxtGjXcbh2CawGi8vlzqsIvspqAbot7mRv3sC/uhgtKc4hQ==", "dev": true, "dependencies": { - "bare-process": "^3.0.0", "safety-catch": "^1.0.2" } }, @@ -3189,9 +3168,9 @@ "dev": true }, "node_modules/node-gyp-build": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.3.tgz", - "integrity": "sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -3395,9 +3374,9 @@ } }, "node_modules/paparam": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.6.1.tgz", - "integrity": "sha512-DBUPol9DzsNjVNh0PwXwzAun5J3H602BVYouLMyRjYZDMt82AG0YCHesgGbCxb+TsdHeHBRSQwOs8igV9+K6Yw==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.6.0.tgz", + "integrity": "sha512-q1l/DIPX9kUIOzFRlqvNz+kukTbladRDeIMGRyEMfO6OZj21Q4v1bALTwxE+d43qQ1BPvKa29IfmsoiAF9953Q==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -3727,9 +3706,9 @@ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, "node_modules/quickbit-native": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.3.4.tgz", - "integrity": "sha512-inl+SbEDqL+NTGFsk/S7nhaFtNEUANpXM1umGeJdOY0gtCLcDTSOZ9sGIXcaKukBgThw9cTD1rgCsYy6sAox+A==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.3.3.tgz", + "integrity": "sha512-naZ1U2qe883tKZCmIlfvgJXouQW1Av1lQGjhVGZEapxKKqbwbgMMkajHoHABLPF0mUml4ArmkVEGXw8RVJUhDg==", "optional": true, "dependencies": { "b4a": "^1.6.0", @@ -3754,9 +3733,9 @@ "integrity": "sha512-e0k0g0w/8jOCB+7YqCIlOa+OJ38k0wrYS4x18pMSmqOvLKoyhmMhmQyCcvfY6VaP8D75cqkEnlakXs+RYYLqNg==" }, "node_modules/random-access-file": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.1.1.tgz", - "integrity": "sha512-HV3zvP4WizFK5jzuuld5kDRT8eW/brujnno00Kg26poMByp9H7hlE1UvpfP7RPjlOel+RVUxoYk/QBBNyFQYjw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.1.0.tgz", + "integrity": "sha512-n8uYXv1QXBLIekN6g8ycBqT/3aS955ku/8lTMcqn78EaVLegz/QTsVZoojArijhyZjLyYVHQ4Hu/BKj9G7v4eg==", "dependencies": { "random-access-storage": "^3.0.0" }, @@ -3927,9 +3906,9 @@ } }, "node_modules/rocksdb-native": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-2.6.4.tgz", - "integrity": "sha512-Fzn3af1rJ1B74C3tdhR7wM+sGJe7QF2DctzIz7yvif5ZFrvls04IZJVEjq4TcUuhxa4mSMTg+a6AiQFS4MtWIg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-2.6.3.tgz", + "integrity": "sha512-836w8wT5E4tbLEWPtV44Hbu4ewRTzIDJjNqqlzj8YSgYtoh8KGAEt6dnF1w1M3qVi8/AFSO/r5IZo1k89f7aKQ==", "dependencies": { "b4a": "^1.6.6", "compact-encoding": "^2.15.0", @@ -4028,6 +4007,11 @@ "unix-path-resolve": "^1.0.2" } }, + "node_modules/semifies": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semifies/-/semifies-1.0.0.tgz", + "integrity": "sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==" + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -4133,9 +4117,9 @@ } }, "node_modules/simdle-native": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.4.tgz", - "integrity": "sha512-7fWq9N5wP3ZYdiBcdjdNFHQ+kU/+rxr785HbxMmFjEb8choPbgE9p4fJ5Nm/H2rpSyVkgY9j0E9hYY1RAvBg+A==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.3.tgz", + "integrity": "sha512-ZuZ4T71SmunYAZQ3/hg7dy8yUrzjR2VPc50zSKX34JS9RD41QL1wTniJdjp7pq77iNDbekSOCgyYEteDjdyBGw==", "optional": true, "dependencies": { "b4a": "^1.6.0", @@ -4168,9 +4152,9 @@ "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/sodium-native": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.1.tgz", - "integrity": "sha512-YdP64gAdpIKHfL4ttuX4aIfjeunh9f+hNeQJpE9C8UMndB3zkgZ7YmmGT4J2+v6Ibyp6Wem8D1TcSrtdW0bqtg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.0.tgz", + "integrity": "sha512-OcMgoS0NJx+4yVUlhvL9uZsVZfmyHZ2RpSXkiIoOHMglqvJDeGwn1rUigPrvcNTq3m9hPXtt6syxQbF3vvwmRQ==", "dependencies": { "node-gyp-build": "^4.8.0" } @@ -4616,9 +4600,9 @@ } }, "node_modules/udx-native": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.4.tgz", - "integrity": "sha512-1leMazJ1Q9v6hrVvsX10WyqII/fMtqduGW98CPWzDBqyRXKF8wOcFdKzFFM+8FHmlI0jLEiZqYMzxm8CzE8BIQ==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.14.2.tgz", + "integrity": "sha512-aPkxfSiSH6QMr7IoGbkf23RY+AHVMTHwA64pCaTLJSQU2qSYsJcNiFPKNP6VFHzXGiE3m+HzLx7/r0orzySobw==", "dependencies": { "b4a": "^1.5.0", "bare-events": "^2.2.0", From 1f052f4e1acd0bb588288d43ae6adb4804a8b6be Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Fri, 15 Nov 2024 11:30:59 +0100 Subject: [PATCH 35/38] Update version and package json (#441) * version v.1.7.0-rc.0 * updated changelog --- CHANGELOG.md | 18 ++++++++++++++++++ package.json | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e66717ea8..6f01b46d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Pear Runtime Changelog +## v1.7.0 + +### Features + +* CLI - `pear dump --dry-run` flag + +### Fixes + +Desktop - Fix Windows client restart +CLI - Fix broken stdin after Ctrl-C +Internal - Fix Pear-IPC unhandled error +Internal - Fix worker close on parent end + +### Improvements + +Internal - Removed `getMediaSourceId` +Internal - Removed terminal app reload and restart + ## v1.6.0 ### Features diff --git a/package.json b/package.json index 809680947..cac63fb55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pear", - "version": "1.5.0-rc.5", + "version": "1.7.0-rc.0", "main": "./boot.js", "private": true, "scripts": { From 1040c199841bcfcc02715e7729a4d4ba97dd3642 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 18 Nov 2024 22:11:14 +1100 Subject: [PATCH 36/38] run-name (#438) --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d67279bc3..f8b3c4d8d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,8 @@ on: - false - true +run-name: Build ${{ inputs.channel }} + jobs: build: uses: holepunchto/actions/.github/workflows/keet-automation.yml@v1 From 021b89def866d8f620202a607e2f99ce62147d1c Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:26:04 +0100 Subject: [PATCH 37/38] stage throws if invalid main or entrypoint (#443) --- subsystems/sidecar/ops/stage.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsystems/sidecar/ops/stage.js b/subsystems/sidecar/ops/stage.js index cf69e736c..2b68f9dd1 100644 --- a/subsystems/sidecar/ops/stage.js +++ b/subsystems/sidecar/ops/stage.js @@ -117,6 +117,12 @@ module.exports = class Stage extends Opstream { const builtins = terminalBare ? sidecar.gunk.bareBuiltins : sidecar.gunk.builtins const linker = new ScriptLinker(src, { builtins }) const entrypoints = [...(state.manifest.main ? [state.main] : []), ...(state.manifest.pear?.stage?.entrypoints || [])].map((entry) => unixPathResolve('/', entry)) + + for (const entrypoint of entrypoints) { + const entry = await src.entry(entrypoint) + if (!entry) throw ERR_INVALID_CONFIG('Invalid main or stage entrypoint in package.json') + } + const mods = await linker.warmup(entrypoints) for await (const [filename, mod] of mods) src.metadata.put(filename, mod.cache()) const mirror = new Mirror(src, dst, opts) From 9141cec823d889e8aac64194dddaa817da27ee07 Mon Sep 17 00:00:00 2001 From: rafapaezbas <15270736+rafapaezbas@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:41:22 +0100 Subject: [PATCH 38/38] removed stage tracer (#442) * removed stage tracer * pear bundle analyzer integration * added terminal app stage test * corrected warmup test title * added desktop app warmup test * added warmup assets * renamed assets to prefetch * renamed pear-bundle-analyzer to drive-analyzer * renamed terminalBare to isTerminal --- cmd/index.js | 1 - def/run.js | 1 - errors.js | 5 -- examples/desktop/package.json | 3 + gui/gui.js | 13 +-- package-lock.json | 15 +++- package.json | 1 + state.js | 7 +- subsystems/sidecar/index.js | 9 -- subsystems/sidecar/lib/bundle.js | 36 ++------ subsystems/sidecar/lib/tracer.js | 63 -------------- subsystems/sidecar/ops/stage.js | 60 ++++---------- test/07-warmup.test.js | 83 +++++++++++++++++++ test/fixtures/desktop-warmup/app.js | 1 + test/fixtures/desktop-warmup/index.html | 9 ++ test/fixtures/desktop-warmup/package.json | 26 ++++++ .../desktop-warmup/test/index.test.js | 1 + test/fixtures/warmup-with-prefetch/asset.txt | 1 + test/fixtures/warmup-with-prefetch/dep.js | 1 + .../warmup-with-prefetch/entrypoint.js | 1 + test/fixtures/warmup-with-prefetch/index.js | 1 + .../warmup-with-prefetch/package.json | 12 +++ test/fixtures/warmup/dep.js | 1 + test/fixtures/warmup/entrypoint.js | 1 + test/fixtures/warmup/index.js | 1 + test/fixtures/warmup/package.json | 11 +++ test/index.js | 1 + 27 files changed, 196 insertions(+), 169 deletions(-) delete mode 100644 subsystems/sidecar/lib/tracer.js create mode 100644 test/07-warmup.test.js create mode 100644 test/fixtures/desktop-warmup/app.js create mode 100644 test/fixtures/desktop-warmup/index.html create mode 100644 test/fixtures/desktop-warmup/package.json create mode 100644 test/fixtures/desktop-warmup/test/index.test.js create mode 100644 test/fixtures/warmup-with-prefetch/asset.txt create mode 100644 test/fixtures/warmup-with-prefetch/dep.js create mode 100644 test/fixtures/warmup-with-prefetch/entrypoint.js create mode 100644 test/fixtures/warmup-with-prefetch/index.js create mode 100644 test/fixtures/warmup-with-prefetch/package.json create mode 100644 test/fixtures/warmup/dep.js create mode 100644 test/fixtures/warmup/entrypoint.js create mode 100644 test/fixtures/warmup/index.js create mode 100644 test/fixtures/warmup/package.json diff --git a/cmd/index.js b/cmd/index.js index 9634320b1..7060bbe36 100644 --- a/cmd/index.js +++ b/cmd/index.js @@ -73,7 +73,6 @@ module.exports = async (ipc, argv = Bare.argv.slice(1)) => { arg('', 'Channel name or Pear link to stage'), arg('[dir]', 'Project directory path (default: .)'), flag('--dry-run|-d', 'Execute a stage without writing'), - flag('--bare|-b', 'File data only, no warmup optimization'), flag('--ignore ', 'Comma separated file path ignore list'), flag('--truncate ', 'Advanced. Truncate to version length n'), flag('--name ', 'Advanced. Override app name'), diff --git a/def/run.js b/def/run.js index 9f321d938..9209fcdb8 100644 --- a/def/run.js +++ b/def/run.js @@ -23,7 +23,6 @@ module.exports = [ flag('--encryption-key ', 'Application encryption key').hide(), flag('--trusted').hide(), flag('--detach').hide(), - flag('--trace ').hide(), flag('--swap ').hide(), flag('--start-id ').hide(), flag('--sandbox').hide() // electron passthrough diff --git a/errors.js b/errors.js index da55f4d76..e93034682 100644 --- a/errors.js +++ b/errors.js @@ -14,7 +14,6 @@ class PearError extends Error { static ERR_UNSTAGED = ERR_UNSTAGED static ERR_DIR_NONEMPTY = ERR_DIR_NONEMPTY static ERR_OPERATION_FAILED = ERR_OPERATION_FAILED - static ERR_TRACER_FAILED = ERR_TRACER_FAILED static ERR_HTTP_GONE = ERR_HTTP_GONE static ERR_HTTP_BAD_REQUEST = ERR_HTTP_BAD_REQUEST static ERR_HTTP_NOT_FOUND = ERR_HTTP_NOT_FOUND @@ -127,10 +126,6 @@ function ERR_OPERATION_FAILED (msg) { return new PearError(msg, 'ERR_OPERATION_FAILED', ERR_OPERATION_FAILED) } -function ERR_TRACER_FAILED (msg) { - return new PearError(msg, 'ERR_TRACER_FAILED', ERR_TRACER_FAILED) -} - function ERR_ASSERTION (msg) { return new PearError(msg, 'ERR_ASSERTION', ERR_ASSERTION) } diff --git a/examples/desktop/package.json b/examples/desktop/package.json index 41ae10038..fecf99e23 100644 --- a/examples/desktop/package.json +++ b/examples/desktop/package.json @@ -17,6 +17,9 @@ "height": 500, "minWidth": 500, "backgroundColor": "#1F2430" + }, + "stage": { + "entrypoints": ["/app.js"] } }, "devDependencies": { diff --git a/gui/gui.js b/gui/gui.js index 4dee512b5..4ba96dfe3 100644 --- a/gui/gui.js +++ b/gui/gui.js @@ -507,8 +507,8 @@ class App { this.appReady = true } - const { dev, devtools, trace, stage } = state - const show = (!trace && (dev || !stage)) + const { dev, devtools, stage } = state + const show = (dev || !stage) const unfilteredGuiOptions = state.options.gui || state.options const guiOptions = { @@ -584,17 +584,10 @@ class App { }, afterNativeWindowClose: () => this.close(), afterNativeViewCreated: devtools && ((app) => { - if (trace) return app.view.webContents.openDevTools({ mode: 'detach' }) if (app.state.chromeWebrtcInternals) PearGUI.chrome('webrtc-internals') }), - afterNativeViewLoaded: (trace - ? async () => { - await new Promise((resolve) => setTimeout(resolve, 750)) // time for final blocks to be received - this.close() - this.quit() - } - : (isLinux ? (app) => linuxViewSize(app) : null)), + afterNativeViewLoaded: isLinux ? (app) => linuxViewSize(app) : null, interload: async (app) => { state.update({ top: app.win }) try { diff --git a/package-lock.json b/package-lock.json index 6f54af6c0..3b152c25e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pear", - "version": "1.5.0-rc.5", + "version": "1.7.0-rc.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pear", - "version": "1.5.0-rc.5", + "version": "1.7.0-rc.0", "license": "Apache-2.0", "dependencies": { "@fontsource/open-sans": "^5.0.22", @@ -30,6 +30,7 @@ "corestore": "^6.18.3", "crc-universal": "^1.0.4", "debounceify": "^1.1.0", + "drive-analyzer": "^1.0.0", "drive-bundler": "^2.3.3", "framed-stream": "^1.0.1", "fs-native-extensions": "^1.2.7", @@ -1143,6 +1144,16 @@ "node": ">=6.0.0" } }, + "node_modules/drive-analyzer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/drive-analyzer/-/drive-analyzer-1.0.0.tgz", + "integrity": "sha512-+t/ouJNOSa1MF30XWiI/qaTc/QQYiHUuCo8vWiQZtaNzFZv3QcUB1Lzt9ZSiwKAGJHnkVBL0oxyLvjfZwQHfqA==", + "dependencies": { + "bare-path": "^3.0.0", + "dependency-stream": "^2.2.3", + "ready-resource": "^1.1.1" + } + }, "node_modules/drive-bundler": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/drive-bundler/-/drive-bundler-2.3.4.tgz", diff --git a/package.json b/package.json index cac63fb55..9908f6ce8 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "corestore": "^6.18.3", "crc-universal": "^1.0.4", "debounceify": "^1.1.0", + "drive-analyzer": "^1.0.0", "drive-bundler": "^2.3.3", "framed-stream": "^1.0.1", "fs-native-extensions": "^1.2.7", diff --git a/state.js b/state.js index a970aad92..2fec34ae3 100644 --- a/state.js +++ b/state.js @@ -80,9 +80,9 @@ module.exports = class State { } static configFrom (state) { - const { id, key, links, alias, env, options, checkpoint, flags, dev, tier, stage, storage, trace, name, main, dependencies, args, channel, release, applink, fragment, link, linkData, entrypoint, dir, dht } = state + const { id, key, links, alias, env, options, checkpoint, flags, dev, tier, stage, storage, name, main, dependencies, args, channel, release, applink, fragment, link, linkData, entrypoint, dir, dht } = state const pearDir = PLATFORM_DIR - return { id, key, links, alias, env, options, checkpoint, flags, dev, tier, stage, storage, trace, name, main, dependencies, args, channel, release, applink, fragment, link, linkData, entrypoint, dir, dht, pearDir } + return { id, key, links, alias, env, options, checkpoint, flags, dev, tier, stage, storage, name, main, dependencies, args, channel, release, applink, fragment, link, linkData, entrypoint, dir, dht, pearDir } } static isKeetInvite (segment) { @@ -107,7 +107,7 @@ module.exports = class State { const { dht, link, id = null, args = null, env = ENV, dir = CWD, cwd = dir, cmdArgs, onupdate = () => {}, flags, run } = params const { startId, appling, channel, devtools, checkout, links, - dev = false, stage, trace, updates, updatesDiff, + dev = false, stage, updates, updatesDiff, unsafeClearAppStorage, chromeWebrtcInternals } = flags const { drive: { alias = null, key = null }, pathname: route, protocol, hash } = link ? parseLink(link) : { drive: {} } @@ -135,7 +135,6 @@ module.exports = class State { this.updatesDiff = this.dev || updatesDiff this.updates = updates this.stage = stage - this.trace = trace this.fragment = fragment this.entrypoint = entrypoint this.linkData = segment diff --git a/subsystems/sidecar/index.js b/subsystems/sidecar/index.js index 7b3172c8a..0e8476fe6 100644 --- a/subsystems/sidecar/index.js +++ b/subsystems/sidecar/index.js @@ -779,14 +779,6 @@ class Sidecar extends ReadyResource { } } - // if app is being staged, stage command sends over its client id, so tracer - // can get the bundle from that client for tracer data: - const trace = typeof state.trace !== 'undefined' - ? this.ipc.client(state.trace).userData.bundle.tracer - : null - - if (LOG.INF && trace) LOG.info(LOG_RUN_LINK, id, 'tracer mode') - LOG.info(LOG_RUN_LINK, id, 'checking drive for encryption') const corestore = this._getCorestore(state.manifest?.name, state.channel) let drive @@ -814,7 +806,6 @@ class Sidecar extends ReadyResource { name: state.manifest?.name, dir: state.key ? null : state.dir, updatesDiff: state.updatesDiff, - trace, drive, updateNotify: state.updates && ((version, info) => this.updateNotify(version, info)), async failure (err) { diff --git a/subsystems/sidecar/lib/bundle.js b/subsystems/sidecar/lib/bundle.js index 0f1f49128..c9fddf595 100644 --- a/subsystems/sidecar/lib/bundle.js +++ b/subsystems/sidecar/lib/bundle.js @@ -5,20 +5,18 @@ const DriveBundler = require('drive-bundler') const hypercoreid = require('hypercore-id-encoding') const { pathToFileURL } = require('url-file-url') const watch = require('watch-drive') -const Tracer = require('./tracer') const Replicator = require('./replicator') const releaseWatcher = require('./release-watcher') const { SWAP } = require('../../../constants') -const { ERR_TRACER_FAILED } = require('../../../errors') +const DriveAnalyzer = require('drive-analyzer') const noop = Function.prototype module.exports = class Bundle { platformVersion = null - warmup = { blocks: 0, total: 0 } constructor (opts = {}) { const { corestore = false, drive = false, checkout = 'release', appling, - key, channel, trace = null, stage = false, status = noop, failure, + key, channel, stage = false, status = noop, failure, updateNotify, updatesDiff = false, truncate, encryptionKey = null } = opts this.checkout = checkout @@ -30,11 +28,9 @@ module.exports = class Bundle { this.status = status this.failure = failure this.corestore = corestore - this.trace = trace this.stage = stage this.drive = drive || new Hyperdrive(this.corestore, this.key, { encryptionKey }) this.updatesDiff = updatesDiff - this.tracer = null this.link = null this.watchingUpdates = null this.truncate = Number.isInteger(+truncate) ? +truncate : null @@ -66,8 +62,6 @@ module.exports = class Bundle { this.initializing = this.#init() - this._onseq = this.trace ? this.trace.instrument() : null - if (typeof updateNotify === 'function') this.#updates(updateNotify) } @@ -97,18 +91,6 @@ module.exports = class Bundle { } } - startTracing () { - this.tracer = new Tracer() - return this.tracer - } - - async finalizeTracing () { - if (this.opened === false) throw ERR_TRACER_FAILED('Internal Platform Error: Bundle must be opened before warmup can commence') - if (!this.tracer) throw ERR_TRACER_FAILED('Internal Platform Error: Bundle critical called without a tracer present') - const ranges = this.tracer.deflate() - await this.drive.db.put('warmup', ranges) - } - async #init () { await this.drive.ready() if (Number.isInteger(this.truncate)) { @@ -160,7 +142,7 @@ module.exports = class Bundle { } entry (key) { - return this.drive.entry(key, { onseq: this._onseq }) + return this.drive.entry(key) } compare (...args) { @@ -170,9 +152,6 @@ module.exports = class Bundle { async get (key) { const entry = await this.entry(key) const result = await this.drive.get(entry) - if (this.trace && result !== null) { - if (entry.value.blob) this.trace.capture([entry.value.blob.blockLength, entry.value.blob.blockOffset]) - } return result } @@ -186,7 +165,6 @@ module.exports = class Bundle { } streamFrom (meta) { - if (this.trace && meta.value.blob) this.trace.capture([meta.value.blob.blockLength, meta.value.blob.blockOffset]) const stream = this.drive.createReadStream(meta) return stream } @@ -265,7 +243,7 @@ module.exports = class Bundle { async calibrate () { await this.ready() - if (this.stage === false && !this.trace) { + if (this.stage === false) { if (this.checkout === 'release') { this.release = (await this.db.get('release'))?.value if (this.release) this.drive = this.drive.checkout(this.release) @@ -287,8 +265,8 @@ module.exports = class Bundle { const warmup = warmupNode?.value if (warmup) { - this.ranges = Tracer.inflate(warmup.meta, warmup.data) - this.prefetch(this.ranges) + const ranges = DriveAnalyzer.decode(warmup.meta, warmup.data) + this.prefetch(ranges) } } @@ -318,8 +296,6 @@ module.exports = class Bundle { this.closed = true if (this.watchingUpdates) this.watchingUpdates.destroy() await this.leave() - if (this.trace) this.trace.push(null) - if (this.tracer) this.tracer.destroy() await this.drain() await this.drive.close() } diff --git a/subsystems/sidecar/lib/tracer.js b/subsystems/sidecar/lib/tracer.js deleted file mode 100644 index 301c79574..000000000 --- a/subsystems/sidecar/lib/tracer.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' -const { Readable } = require('streamx') - -function deflate (set) { - const array = [...set] - array.sort((a, b) => a - b) - return array.map((n, i) => { - if (i === 0) return n - return n - array[i - 1] - }).filter((n, i) => { - return i === 0 || n > 0 - }) -} - -function inflate (array) { - const { ranges } = array.reduce(({ ranges, sum }, n, i) => { - if (i === 0) { - ranges.push({ start: n, end: n + 1 }) - return { ranges, sum: n } - } - - sum += n - - if (n === 1) ranges[ranges.length - 1].end += 1 - else ranges.push({ start: sum, end: sum + 1 }) - - return { ranges, sum } - }, { ranges: [], sum: 0 }) - - return ranges -} - -module.exports = class Tracer extends Readable { - static META = 0 - static DATA = 1 - - static inflate (meta, data) { return { meta: inflate(meta), data: inflate(data) } } - - constructor () { - super() - this.meta = new Set() - this.data = new Set() - } - - deflate () { return { meta: deflate(this.meta), data: deflate(this.data) } } - - instrument () { - return (seq) => this.capture(seq, this.constructor.META) - } - - capture (seq, core = this.constructor.DATA) { - if (Array.isArray(seq)) { - const [blockLength, blockOffset] = seq - for (let i = 0; i < blockLength; i++) this.capture(i + blockOffset) - } else { - const size = this.meta.size + this.data.size - if (core === this.constructor.META) this.meta.add(seq) - if (core === this.constructor.DATA) this.data.add(seq) - const blocks = this.meta.size + this.data.size - if (size < blocks) this.push({ seq, core, blocks }) - } - } -} diff --git a/subsystems/sidecar/ops/stage.js b/subsystems/sidecar/ops/stage.js index 2b68f9dd1..08f7158f0 100644 --- a/subsystems/sidecar/ops/stage.js +++ b/subsystems/sidecar/ops/stage.js @@ -1,6 +1,4 @@ 'use strict' -const { spawn } = require('bare-subprocess') -const { once } = require('bare-events') const ScriptLinker = require('script-linker') const LocalDrive = require('localdrive') const Hyperdrive = require('hyperdrive') @@ -8,45 +6,17 @@ const Mirror = require('mirror-drive') const unixPathResolve = require('unix-path-resolve') const hypercoreid = require('hypercore-id-encoding') const { randomBytes } = require('hypercore-crypto') +const DriveAnalyzer = require('drive-analyzer') const Opstream = require('../lib/opstream') const Bundle = require('../lib/bundle') const State = require('../state') const Store = require('../lib/store') -const { BOOT, SWAP, DESKTOP_RUNTIME } = require('../../../constants') -const { ERR_TRACER_FAILED, ERR_INVALID_CONFIG, ERR_SECRET_NOT_FOUND, ERR_PERMISSION_REQUIRED } = require('../../../errors') +const { ERR_INVALID_CONFIG, ERR_SECRET_NOT_FOUND, ERR_PERMISSION_REQUIRED } = require('../../../errors') module.exports = class Stage extends Opstream { - static async * trace (bundle, client) { - await bundle.ready() - const tracer = bundle.startTracing() - const sp = spawn( - DESKTOP_RUNTIME, - [BOOT, '--no-sandbox', `--trace=${client.id}`, '--swap', SWAP, 'pear://' + hypercoreid.encode(bundle.drive.key)] - ) - - const onclose = () => sp.kill() - client.on('close', onclose) - - const closed = once(sp, 'exit') - client.off('close', onclose) - - const total = bundle.drive.core.length + (bundle.drive.blobs?.core.length || 0) - for await (const { blocks } of tracer) yield { total, blocks } - - const [status] = await closed - - if (status) { - const err = ERR_TRACER_FAILED('Tracer Failed!') - err.exitCode = status - throw err - } - - await bundle.finalizeTracing() - } - constructor (...args) { super((...args) => this.#op(...args), ...args) } - async #op ({ channel, key, dir, dryRun, name, truncate, bare = false, cmdArgs, ignore = '.git,.github,.DS_Store', ...params }) { + async #op ({ channel, key, dir, dryRun, name, truncate, cmdArgs, ignore = '.git,.github,.DS_Store', ...params }) { const { client, session, sidecar } = this const state = new State({ id: `stager-${randomBytes(16).toString('hex')}`, @@ -99,8 +69,7 @@ module.exports = class Stage extends Opstream { await sidecar.permit({ key: bundle.drive.key, encryptionKey }, client) const type = state.manifest.pear?.type || 'desktop' - const terminalBare = type === 'terminal' - if (terminalBare) bare = true + const isTerminal = type === 'terminal' if (state.manifest.pear?.stage?.ignore) ignore = state.manifest.pear.stage?.ignore else ignore = (Array.isArray(ignore) ? ignore : ignore.split(',')) const release = (await bundle.db.get('release'))?.value || 0 @@ -111,10 +80,10 @@ module.exports = class Stage extends Opstream { if (dryRun) this.push({ tag: 'dry' }) const root = state.dir - const src = new LocalDrive(root, { followLinks: bare === false, metadata: new Map() }) + const src = new LocalDrive(root, { followLinks: !isTerminal, metadata: new Map() }) const dst = bundle.drive const opts = { ignore, dryRun, batch: true } - const builtins = terminalBare ? sidecar.gunk.bareBuiltins : sidecar.gunk.builtins + const builtins = isTerminal ? sidecar.gunk.bareBuiltins : sidecar.gunk.builtins const linker = new ScriptLinker(src, { builtins }) const entrypoints = [...(state.manifest.main ? [state.main] : []), ...(state.manifest.pear?.stage?.entrypoints || [])].map((entry) => unixPathResolve('/', entry)) @@ -154,14 +123,17 @@ module.exports = class Stage extends Opstream { } }) - if (dryRun || bare) { - const reason = dryRun ? 'dry-run' : 'bare' - this.push({ tag: 'skipping', data: { reason, success: true } }) + if (dryRun) { + this.push({ tag: 'skipping', data: { reason: 'dry-run', success: true } }) } else if (mirror.count.add || mirror.count.remove || mirror.count.change) { - for await (const { blocks, total } of this.constructor.trace(bundle, client)) { - this.push({ tag: 'warming', data: { blocks, total } }) - } - this.push({ tag: 'warming', data: { success: true } }) + const analyzer = new DriveAnalyzer(bundle.drive) + await analyzer.ready() + const prefetch = state.manifest.pear?.stage?.prefetch || [] + const warmup = await analyzer.analyze(entrypoints, prefetch) + await bundle.db.put('warmup', warmup) + const total = bundle.drive.core.length + (bundle.drive.blobs?.core.length || 0) + const blocks = warmup.meta.length + warmup.data.length + this.push({ tag: 'warming', data: { total, blocks, success: true } }) } else { this.push({ tag: 'skipping', data: { reason: 'no changes', success: true } }) } diff --git a/test/07-warmup.test.js b/test/07-warmup.test.js new file mode 100644 index 000000000..44a716a27 --- /dev/null +++ b/test/07-warmup.test.js @@ -0,0 +1,83 @@ +'use strict' +const test = require('brittle') +const path = require('bare-path') +const Helper = require('./helper') + +const warmup = path.join(Helper.localDir, 'test', 'fixtures', 'warmup') +const desktop = path.join(Helper.localDir, 'test', 'fixtures', 'desktop-warmup') +const prefetch = path.join(Helper.localDir, 'test', 'fixtures', 'warmup-with-prefetch') + +test('stage warmup with entrypoints', async function ({ ok, is, plan, comment, teardown, timeout }) { + timeout(180000) + plan(4) + + const dir = warmup + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const id = Math.floor(Math.random() * 10000) + + comment('staging') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + + const staged = await Helper.pick(staging, [{ tag: 'warming' }, { tag: 'final' }]) + const warming = await staged.warming + ok((await staged.final).success, 'stage succeeded') + + ok(warming.blocks > 0, 'Warmup contains some blocks') + ok(warming.total > 0, 'Warmup total is correct') + is(warming.success, true, 'Warmup completed') +}) + +test('stage desktop app warmup with entrypoints', async function ({ ok, is, plan, comment, teardown, timeout }) { + timeout(180000) + plan(4) + + const dir = desktop + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const id = Math.floor(Math.random() * 10000) + + comment('staging') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + + const staged = await Helper.pick(staging, [{ tag: 'warming' }, { tag: 'final' }]) + const warming = await staged.warming + ok((await staged.final).success, 'stage succeeded') + + ok(warming.blocks > 0, 'Warmup contains some blocks') + ok(warming.total > 0, 'Warmup total is correct') + is(warming.success, true, 'Warmup completed') +}) + +test('stage warmup with prefetch', async function ({ ok, is, plan, comment, teardown, timeout }) { + timeout(180000) + plan(4) + + const dir = prefetch + + const helper = new Helper() + teardown(() => helper.close(), { order: Infinity }) + await helper.ready() + + const id = Math.floor(Math.random() * 10000) + + comment('staging') + const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true }) + teardown(() => Helper.teardownStream(staging)) + + const staged = await Helper.pick(staging, [{ tag: 'warming' }, { tag: 'final' }]) + const warming = await staged.warming + ok((await staged.final).success, 'stage succeeded') + + ok(warming.blocks > 0, 'Warmup contains some blocks') + ok(warming.total > 0, 'Warmup total is correct') + is(warming.success, true, 'Warmup completed') +}) diff --git a/test/fixtures/desktop-warmup/app.js b/test/fixtures/desktop-warmup/app.js new file mode 100644 index 000000000..4460c8f8c --- /dev/null +++ b/test/fixtures/desktop-warmup/app.js @@ -0,0 +1 @@ +console.log('i am a desktop app entrypoint') diff --git a/test/fixtures/desktop-warmup/index.html b/test/fixtures/desktop-warmup/index.html new file mode 100644 index 000000000..4150479ca --- /dev/null +++ b/test/fixtures/desktop-warmup/index.html @@ -0,0 +1,9 @@ + + + + + + +

desktop

+ + diff --git a/test/fixtures/desktop-warmup/package.json b/test/fixtures/desktop-warmup/package.json new file mode 100644 index 000000000..c58f6a5e4 --- /dev/null +++ b/test/fixtures/desktop-warmup/package.json @@ -0,0 +1,26 @@ +{ + "name": "desktop-warmup", + "main": "index.html", + "pear": { + "name": "desktop-warmup", + "type": "desktop", + "gui": { + "backgroundColor": "#1F2430", + "height": "540", + "width": "720" + }, + "stage": { + "entrypoints": ["/app.js"] + } + }, + "type": "module", + "license": "Apache-2.0", + "scripts": { + "dev": "pear run -d .", + "test": "brittle test/*.test.js" + }, + "devDependencies": { + "brittle": "^3.0.0", + "pear-interface": "^1.0.0" + } +} diff --git a/test/fixtures/desktop-warmup/test/index.test.js b/test/fixtures/desktop-warmup/test/index.test.js new file mode 100644 index 000000000..d9b912ddc --- /dev/null +++ b/test/fixtures/desktop-warmup/test/index.test.js @@ -0,0 +1 @@ +import test from 'brittle' // https://github.com/holepunchto/brittle diff --git a/test/fixtures/warmup-with-prefetch/asset.txt b/test/fixtures/warmup-with-prefetch/asset.txt new file mode 100644 index 000000000..ceb1bfbcb --- /dev/null +++ b/test/fixtures/warmup-with-prefetch/asset.txt @@ -0,0 +1 @@ +this is an asset diff --git a/test/fixtures/warmup-with-prefetch/dep.js b/test/fixtures/warmup-with-prefetch/dep.js new file mode 100644 index 000000000..d74514ca3 --- /dev/null +++ b/test/fixtures/warmup-with-prefetch/dep.js @@ -0,0 +1 @@ +console.log('hello warmup') diff --git a/test/fixtures/warmup-with-prefetch/entrypoint.js b/test/fixtures/warmup-with-prefetch/entrypoint.js new file mode 100644 index 000000000..4d4d1e59f --- /dev/null +++ b/test/fixtures/warmup-with-prefetch/entrypoint.js @@ -0,0 +1 @@ +const dep = require('./dep') diff --git a/test/fixtures/warmup-with-prefetch/index.js b/test/fixtures/warmup-with-prefetch/index.js new file mode 100644 index 000000000..4d4d1e59f --- /dev/null +++ b/test/fixtures/warmup-with-prefetch/index.js @@ -0,0 +1 @@ +const dep = require('./dep') diff --git a/test/fixtures/warmup-with-prefetch/package.json b/test/fixtures/warmup-with-prefetch/package.json new file mode 100644 index 000000000..3c7041386 --- /dev/null +++ b/test/fixtures/warmup-with-prefetch/package.json @@ -0,0 +1,12 @@ +{ + "name": "warmup-with-prefetch", + "main": "index.js", + "pear": { + "name": "warmup-with-prefetch", + "type": "terminal", + "stage": { + "entrypoints": ["/entrypoint.js"], + "prefetch": ["/assets", "/asset.txt"] + } + } +} diff --git a/test/fixtures/warmup/dep.js b/test/fixtures/warmup/dep.js new file mode 100644 index 000000000..d74514ca3 --- /dev/null +++ b/test/fixtures/warmup/dep.js @@ -0,0 +1 @@ +console.log('hello warmup') diff --git a/test/fixtures/warmup/entrypoint.js b/test/fixtures/warmup/entrypoint.js new file mode 100644 index 000000000..4d4d1e59f --- /dev/null +++ b/test/fixtures/warmup/entrypoint.js @@ -0,0 +1 @@ +const dep = require('./dep') diff --git a/test/fixtures/warmup/index.js b/test/fixtures/warmup/index.js new file mode 100644 index 000000000..4d4d1e59f --- /dev/null +++ b/test/fixtures/warmup/index.js @@ -0,0 +1 @@ +const dep = require('./dep') diff --git a/test/fixtures/warmup/package.json b/test/fixtures/warmup/package.json new file mode 100644 index 000000000..b2f567f49 --- /dev/null +++ b/test/fixtures/warmup/package.json @@ -0,0 +1,11 @@ +{ + "name": "warmup", + "main": "index.js", + "pear": { + "name": "warmup", + "type": "terminal", + "stage": { + "entrypoints": ["/entrypoint.js"] + } + } +} diff --git a/test/index.js b/test/index.js index ea6f89fca..aec6fe146 100644 --- a/test/index.js +++ b/test/index.js @@ -13,6 +13,7 @@ async function runTests () { await import('./04-encrypted.test.js') await import('./05-updates.test.js') await import('./06-shutdown.test.js') + await import('./07-warmup.test.js') test.resume() }