pear-electron 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,9 +4,6 @@ if (!global.Pear && global.process) {
4
4
  const { status } = require('child_process').spawnSync('pear', process.argv.slice(1), { stdio: 'inherit', shell: true })
5
5
  process.exit(status)
6
6
  }
7
- const installed = Pear.config.entrypoint.startsWith('/node_modules/.bin/')
8
7
  if (Pear.pipe === undefined) throw new Error('Incompatible with current Pear version (must be v2+)')
9
- const bin = Pear.pipe === null
10
- ? (installed ? require('../pear-electron/bin/bootstrap') : require('./bootstrap'))
11
- : require('../pear-electron/bin/configure')
12
- bin().catch(console.error)
8
+ if (Pear.pipe === null) throw new Error('This is a via bin: must have Pear.pipe')
9
+ require('../pear-electron/via')
package/package.json CHANGED
@@ -1,30 +1,29 @@
1
1
  {
2
2
  "name": "pear-electron",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Pear User-Interface Library for Electron",
5
5
  "main": "index.js",
6
- "bin": "bin/index.js",
6
+ "bin": "bin.js",
7
7
  "scripts": {
8
- "bootstrap": "pear run bin/index.js",
8
+ "bootstrap": "pear run scripts/bootstrap.js",
9
9
  "decal": "pear run scripts/decal.js",
10
10
  "bundle": "pear run scripts/bundle.js",
11
- "prepare": "npm --ignore-scripts i && npm run decal && npm run bundle",
12
- "prestage": "npm run bootstrap && npm run bundle",
11
+ "prestage": "npm run bootstrap && npm run decal && npm run bundle",
13
12
  "lint": "standard"
14
13
  },
15
14
  "files": [
16
- "bin/",
17
- "boot.bundle",
18
15
  "bootstrap.js",
19
16
  "index.js",
20
- "runtime.js"
17
+ "runtime.js",
18
+ "via.js"
21
19
  ],
22
20
  "pear": {
23
21
  "name": "pear-electron",
24
- "bootstrap": "pear://0.949.yceb7sjhgfzsnza7oc38hy3oxu9dhnywi3mzxdm9ubc48kjnxqgo",
22
+ "bootstrap": "pear://0.2585.yceb7sjhgfzsnza7oc38hy3oxu9dhnywi3mzxdm9ubc48kjnxqgo",
25
23
  "stage": {
26
24
  "skipWarmup": "true",
27
25
  "only": [
26
+ "boot.bundle",
28
27
  "by-arch",
29
28
  "prebuilds"
30
29
  ]
@@ -52,8 +51,8 @@
52
51
  "iambus": "^1.0.3",
53
52
  "localdrive": "^1.12.1",
54
53
  "paparam": "^1.6.1",
55
- "pear-api": "^1.6.20",
56
- "pear-ipc": "^3.2.0",
54
+ "pear-api": "^1.9.0",
55
+ "pear-ipc": "^6.1.0",
57
56
  "script-linker": "^2.5.3",
58
57
  "streamx": "^2.20.2",
59
58
  "url-file-url": "^1.0.4",
package/runtime.js CHANGED
@@ -12,24 +12,29 @@ const constants = require('pear-api/constants')
12
12
  const parseLink = require('pear-api/parse-link')
13
13
  const Logger = require('pear-api/logger')
14
14
  const { ERR_INVALID_INPUT, ERR_INVALID_APPLING } = require('pear-api/errors')
15
- const { ansi, byteSize } = require('pear-api/terminal')
15
+ const { ansi, byteSize, byteDiff, outputter } = require('pear-api/terminal')
16
16
  const run = require('pear-api/cmd/run')
17
17
  const pear = require('pear-api/cmd')
18
- const bootstrap = require('./bootstrap')
19
- const EXEC = isWindows
20
- ? 'pear-runtime-app\\Pear Runtime.exe'
21
- : isLinux
22
- ? 'pear-runtime-app/pear-runtime'
23
- : 'Pear Runtime.app/Contents/MacOS/Pear Runtime'
18
+ const pkg = require('./package.json')
19
+
20
+ const bin = () => {
21
+ const name = Pear.config.name[0].toUpperCase() + Pear.config.name.slice(1)
22
+ const app = isMac ? name + ' Runtime.app' : Pear.config.name + '-runtime-app'
23
+ const exe = isWindows ? name + 'Runtime.exe' : (isMac ? 'Contents/MacOS/' + name + ' Runtime' : Pear.config.name + '-runtime')
24
+ return isWindows ? 'bin\\' + app + '\\' + exe : (isMac ? 'bin/' + app + '/' + exe : 'bin/' + app + '/' + exe)
25
+ }
26
+
27
+ const BIN = isWindows
28
+ ? 'bin\\pear-runtime-app\\Pear Runtime.exe'
29
+ : isMac
30
+ ? 'bin/Pear Runtime.app/Contents/MacOS/Pear Runtime'
31
+ : 'bin/pear-runtime-app/pear-runtime'
24
32
 
25
33
  class PearElectron {
26
34
  constructor () {
27
35
  this.ipc = Pear[Pear.constructor.IPC]
28
- this.arch = '/node_modules/pear-electron/by-arch/' + require.addon.host
29
- this.prebuilds = '/node_modules/pear-electron/prebuilds/' + require.addon.host
30
- this.boot = '/node_modules/pear-electron/boot.bundle'
31
36
  this.applink = new URL(Pear.config.applink)
32
- this.LOG = new Logger({ labels: ['runtime-bootstrap'] })
37
+ this.LOG = new Logger({ labels: [pkg.name] })
33
38
  Pear.teardown(() => this.ipc.close())
34
39
  }
35
40
 
@@ -41,34 +46,42 @@ class PearElectron {
41
46
  const ul = upload.total + upload.speed === 0 ? '' : `[${ansi.up} ${byteSize(upload.total)} - ${byteSize(upload.speed)}/s ] `
42
47
  return {
43
48
  output: 'status',
44
- message: `Bootstrapping Runtime [ Peers: ${peers} ] ${dl}${ul}`
49
+ message: `Syncing Runtime [ Peers: ${peers} ] ${dl}${ul}`
45
50
  }
51
+ },
52
+ final (asset) {
53
+ if (asset.forced === false && asset.inserted === false) return {}
54
+ return 'Sync Complete'
46
55
  }
47
56
  }
48
57
  }
49
58
  return {
50
- dumping: ({ link, dir, list }) => list > -1 ? '' : { message: ['Bootstrapping runtime from peers', 'from: ' + link, 'into: ' + dir] },
59
+ dumping: ({ link, dir }) => 'Syncing runtime from peers\nfrom: ' + link + '\ninto: ' + dir + '\n',
60
+ byteDiff,
51
61
  file: ({ key }) => key,
52
- complete: () => 'Bootstrap complete',
53
- error: (err) => `Bootstrap Failure (code: ${err.code || 'none'}) ${err.stack}`
62
+ complete: () => 'Asset fetch complete',
63
+ error: (err) => `Asset fetch Failure (code: ${err.code || 'none'}) ${err.stack}`
54
64
  }
55
65
  }
56
66
 
67
+ async #asset (opts, force = false) {
68
+ const output = outputter('asset', this.#outs())
69
+ const json = false
70
+ const bootstrap = opts.bootstrap ?? pkg.pear.bootstrap
71
+ const executable = opts.bootstrap ? bin() : BIN
72
+ const stream = Pear.asset(bootstrap, {
73
+ only: ['/boot.bundle', '/by-arch/' + require.addon.host, '/prebuilds/' + require.addon.host],
74
+ force
75
+ })
76
+ const asset = await output(json, stream)
77
+ if (asset === null) throw new Error('Failed to determine runtime asset from sidecar')
78
+ return path.join(asset.path, 'by-arch', require.addon.host, executable)
79
+ }
80
+
57
81
  async start (opts = {}) {
58
- if (this.applink.protocol === 'pear:') {
59
- const base = path.join(Pear.config.storage, 'pear-runtimes')
60
- await bootstrap({
61
- id: Pear.id,
62
- link: Pear.config.applink,
63
- only: [this.arch, this.prebuilds, this.boot],
64
- dir: base,
65
- force: true,
66
- log: (msg) => this.LOG.info('runtime-bootstrap', msg)
67
- }, this.#outs())
68
- this.bin = path.join(base, 'node_modules', 'pear-electron', 'by-arch', require.addon.host, 'bin', EXEC)
69
- } else {
70
- this.bin = path.join(this.applink.pathname, 'node_modules', 'pear-electron', 'by-arch', require.addon.host, 'bin', EXEC)
71
- }
82
+ this.bin = await this.#asset(opts)
83
+ // if disk tampered then resync:
84
+ if (fs.existsSync(this.bin) === false) this.bin = await this.#asset(opts, true)
72
85
  const parsed = pear(Pear.argv.slice(1))
73
86
  const cmd = command('run', ...run)
74
87
  let argv = parsed.rest
@@ -108,7 +121,7 @@ class PearElectron {
108
121
  dir
109
122
  })
110
123
 
111
- argv = [require.resolve('./boot.bundle'), '--rti', info, ...argv]
124
+ argv = ['boot.bundle', '--rti', info, ...argv]
112
125
  const stdio = args.detach ? ['ignore', 'ignore', 'ignore', 'overlapped'] : ['ignore', 'inherit', 'pipe', 'overlapped']
113
126
  const options = {
114
127
  stdio,
@@ -129,7 +142,9 @@ class PearElectron {
129
142
  if (isMac) spawn('open', [applingApp, '--args', ...argv], options).unref()
130
143
  else spawn(applingApp, argv, options).unref()
131
144
  }
132
- sp.on('exit', (code) => { Pear.exit(code) })
145
+
146
+ // TODO: teardown flow
147
+
133
148
  const pipe = sp.stdio[3]
134
149
  if (args.detach) return pipe
135
150
 
@@ -10,12 +10,10 @@ function srcs (html) {
10
10
 
11
11
  async function configure (options) {
12
12
  const { stage = {} } = options
13
- const ignore = ['/node_modules/**/prebuilds', '!/node_modules/pear-electron/prebuilds']
14
13
  const { pathname } = new URL(global.Pear.config.applink + '/')
15
14
  const drive = new Localdrive(pathname)
16
15
  const html = (await drive.get(options.gui.main)).toString()
17
16
  const entrypoints = srcs(html)
18
- stage.ignore = Array.isArray(stage.ignore) ? [...stage.ignore, ...ignore] : ignore
19
17
  stage.entrypoints = Array.isArray(stage.entrypoints) ? [...stage.entrypoints, ...entrypoints] : entrypoints
20
18
 
21
19
  options.via = undefined
@@ -24,15 +22,13 @@ async function configure (options) {
24
22
  return options
25
23
  }
26
24
 
27
- module.exports = () => new Promise((resolve, reject) => {
28
- Pear.pipe.on('end', () => {
29
- Pear.pipe.end()
30
- resolve()
31
- })
32
- Pear.pipe.once('data', (options) => {
33
- configure(JSON.parse(options)).then((config) => {
34
- Pear.pipe.end(JSON.stringify(config))
35
- resolve()
36
- }, reject)
25
+ Pear.pipe.on('end', () => { Pear.pipe.end() })
26
+
27
+ Pear.pipe.once('data', (options) => {
28
+ configure(JSON.parse(options)).then((config) => {
29
+ Pear.pipe.end(JSON.stringify(config))
30
+ }, (err) => {
31
+ Pear.pipe.destroy()
32
+ console.error(err)
37
33
  })
38
34
  })
package/bin/bootstrap.js DELETED
@@ -1,19 +0,0 @@
1
- 'use strict'
2
- /* global Pear */
3
- const path = require('bare-path')
4
- const installed = Pear.config.entrypoint.startsWith('/node_modules/.bin/')
5
- const { pear } = installed ? require('../../pear-electron/package.json') : require('../package.json')
6
- const { isTTY } = require('pear-api/terminal')
7
- const bootstrap = installed ? require('../../pear-electron/bootstrap') : require('../bootstrap')
8
-
9
- const { pathname } = new URL(Pear.config.applink)
10
- const opts = {
11
- id: Pear.pid,
12
- dir: installed ? path.join(pathname, 'node_modules', 'pear-electron') : pathname,
13
- link: pear.bootstrap,
14
- only: installed ? ['/by-arch', '/prebuilds'] : ['/by-arch'],
15
- json: !isTTY,
16
- force: true
17
- }
18
-
19
- module.exports = () => bootstrap(opts)