Map Node builtins to bare-* via package.json imports and dual-load with which-runtime so holesailBareControl runs on Bare without MODULE_NOT_FOUND for crypto/fs/http/net.
This commit is contained in:
@@ -2,14 +2,37 @@
|
||||
* Bare/Node control plane for local Holesail client sessions.
|
||||
* Runs in the pear-electron Bare entry (index.js), where require.addon works.
|
||||
* The UI renderer talks to this over http://127.0.0.1:<port> (never loads bare-tcp itself).
|
||||
*
|
||||
* Uses Bare modules under Pear (via package.json "imports" bare conditions and
|
||||
* which-runtime dual-load). Do not require bare Node built-ins alone on Bare.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const http = require('http')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const crypto = require('crypto')
|
||||
const net = require('net')
|
||||
const { isBare } = require('which-runtime')
|
||||
|
||||
// Prefer package.json imports maps; dual-load as fallback for older resolvers.
|
||||
function load (bareName, nodeName) {
|
||||
if (isBare) {
|
||||
try {
|
||||
return require(bareName)
|
||||
} catch {
|
||||
return require(nodeName)
|
||||
}
|
||||
}
|
||||
try {
|
||||
return require(nodeName)
|
||||
} catch {
|
||||
return require(bareName)
|
||||
}
|
||||
}
|
||||
|
||||
const http = load('bare-http1', 'http')
|
||||
const fs = load('bare-fs', 'fs')
|
||||
const path = load('bare-path', 'path')
|
||||
const crypto = load('bare-crypto', 'crypto')
|
||||
const net = load('bare-net', 'net')
|
||||
const process = load('bare-process', 'process')
|
||||
const b4a = require('b4a')
|
||||
const Holesail = require('holesail')
|
||||
|
||||
/** @type {Map<string, { instance: any, localPort: number, host: string, url: string, info: object }>} */
|
||||
@@ -112,12 +135,13 @@ function list() {
|
||||
function readJson(req) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = []
|
||||
req.on('data', (c) => chunks.push(c))
|
||||
req.on('data', (c) => chunks.push(typeof c === 'string' ? b4a.from(c) : c))
|
||||
req.on('end', () => {
|
||||
if (!chunks.length) return resolve({})
|
||||
try {
|
||||
resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')))
|
||||
} catch (err) {
|
||||
const raw = b4a.toString(chunks.length === 1 ? chunks[0] : b4a.concat(chunks))
|
||||
resolve(JSON.parse(raw || '{}'))
|
||||
} catch {
|
||||
reject(new Error('Invalid JSON body'))
|
||||
}
|
||||
})
|
||||
@@ -146,6 +170,7 @@ function sendJson(res, status, body) {
|
||||
async function start(opts = {}) {
|
||||
const token = opts.token || crypto.randomBytes(16).toString('hex')
|
||||
const host = opts.host || '127.0.0.1'
|
||||
const pid = process.pid
|
||||
|
||||
const server = http.createServer(async (req, res) => {
|
||||
// CORS preflight (UI fetch from pear-bridge origin)
|
||||
@@ -159,6 +184,7 @@ async function start(opts = {}) {
|
||||
}
|
||||
|
||||
try {
|
||||
// bare-url / WHATWG URL
|
||||
const url = new URL(req.url || '/', `http://${host}`)
|
||||
const pathname = url.pathname
|
||||
|
||||
@@ -219,7 +245,7 @@ async function start(opts = {}) {
|
||||
const addr = server.address()
|
||||
const port = typeof addr === 'object' && addr ? addr.port : 0
|
||||
const baseUrl = `http://${host}:${port}`
|
||||
const meta = { port, host, token, baseUrl, pid: process.pid }
|
||||
const meta = { port, host, token, baseUrl, pid }
|
||||
|
||||
if (opts.statePath) {
|
||||
try {
|
||||
@@ -230,7 +256,7 @@ async function start(opts = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[holesail-control] listening on ${baseUrl}`)
|
||||
console.log(`[holesail-control] listening on ${baseUrl} (bare=${isBare})`)
|
||||
|
||||
return {
|
||||
...meta,
|
||||
|
||||
@@ -84,6 +84,7 @@ npx holesail 'hs://s000…'
|
||||
2. **Client-side local proxy** — Tunnels → plug icon runs the **real `holesail` package**.
|
||||
Under pear-electron the UI renderer cannot load bare-tcp (`require.addon is not a function`). Real holesail runs in the **Bare main process**:
|
||||
- Bare entry `index.js` starts `client/holesailBareControl.cjs` (`require('holesail')`) on `http://127.0.0.1:<port>`
|
||||
- Control code uses **Bare modules** (`bare-crypto`, `bare-fs`, `bare-http1`, `bare-net`, …) via `package.json` `imports` maps + `which-runtime`
|
||||
- Endpoint + token written to `<Pear.config.storage>/peardock-holesail-local.json`
|
||||
- UI `client/holesailLocal.js` POSTs `/connect` / `/disconnect` (never loads bare-tcp)
|
||||
- Node tests / non-Pear: in-process `require('holesail')`
|
||||
|
||||
Generated
+43
-68
@@ -10,6 +10,16 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"b4a": "^1.8.1",
|
||||
"bare-crypto": "^1.15.3",
|
||||
"bare-events": "^2.9.1",
|
||||
"bare-fs": "^4.7.4",
|
||||
"bare-http1": "^4.5.7",
|
||||
"bare-net": "^2.3.2",
|
||||
"bare-os": "^3.9.3",
|
||||
"bare-path": "^3.1.1",
|
||||
"bare-process": "^4.5.1",
|
||||
"bare-subprocess": "^5.2.3",
|
||||
"bare-url": "^2.4.5",
|
||||
"compact-encoding": "^3.3.0",
|
||||
"dockerode": "^5.0.1",
|
||||
"dotenv": "^17.4.2",
|
||||
@@ -25,6 +35,7 @@
|
||||
"protomux": "^3.11.0",
|
||||
"protomux-rpc": "^1.10.0",
|
||||
"safety-catch": "^1.0.3",
|
||||
"which-runtime": "^1.4.0",
|
||||
"z32": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -421,7 +432,6 @@
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.15.3.tgz",
|
||||
"integrity": "sha512-macV9lbyJTsLPRXJkBtz8ivTGEo3LCyJInLT9IB/PWJ7pRXwvHs/FP4bx/fWw+HZkiepIYCAV2cuU5CR92XWCw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-assert": "^1.2.0",
|
||||
"bare-stream": "^2.6.3"
|
||||
@@ -500,7 +510,6 @@
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz",
|
||||
"integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"bare-abort-controller": "*"
|
||||
},
|
||||
@@ -523,7 +532,6 @@
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.4.tgz",
|
||||
"integrity": "sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-events": "^2.5.4",
|
||||
"bare-path": "^3.0.0",
|
||||
@@ -559,7 +567,6 @@
|
||||
"version": "4.5.7",
|
||||
"resolved": "https://registry.npmjs.org/bare-http1/-/bare-http1-4.5.7.tgz",
|
||||
"integrity": "sha512-PRuzs9ywt4vUvrC3mnHhQyaQfLYzdFy8XKOH0oKeKmYfyYYUqXBkdbJE2csESLBxJEbKDBjxPGLU+Qa0l1ds4A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-events": "^2.6.0",
|
||||
"bare-http-parser": "^1.1.1",
|
||||
@@ -692,7 +699,6 @@
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.3.2.tgz",
|
||||
"integrity": "sha512-I+yz+pqbYsBkxDsnu5vkKvy7RSNY9CcAvu2jZT6PsmdXJQG1i3dmD5V7xc3334OVp2absgtUEYLmmuNFlphBzg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-events": "^2.2.2",
|
||||
"bare-pipe": "^4.0.0",
|
||||
@@ -704,7 +710,6 @@
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.3.tgz",
|
||||
"integrity": "sha512-fF4Q7QsyKVF5Rj0qvI8BgUNjqzC2JvQlpTaPLjVJVxYVUX5Zr9un+y3w1HmA4nNKdFmRBT8z/WmrjvXzXVerKQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"bare": ">=1.14.0"
|
||||
}
|
||||
@@ -712,8 +717,7 @@
|
||||
"node_modules/bare-path": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.1.tgz",
|
||||
"integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==",
|
||||
"license": "Apache-2.0"
|
||||
"integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ=="
|
||||
},
|
||||
"node_modules/bare-pipe": {
|
||||
"version": "4.2.2",
|
||||
@@ -738,7 +742,6 @@
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.5.1.tgz",
|
||||
"integrity": "sha512-CaAvy1trputD49mtwfJ6G75vydhnirLrW/F3Sznp4H556e1uZn8YMo9ELicBTrGYy7RBNUgPl9bpB/ERzRCiDw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-abort": "^2.0.13",
|
||||
"bare-env": "^3.0.0",
|
||||
@@ -848,18 +851,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bare-subprocess": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-6.1.0.tgz",
|
||||
"integrity": "sha512-8L6KtbmreDy4Fc1BdDqaDo9fg0nbedUmTSFQxYPV0uHIM2BBAX8+E0LyMDKgkk0I+mlKto80WYzOnIhT8VDdOg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.3.tgz",
|
||||
"integrity": "sha512-07wwswlV7M3sC9IykbZRZ/jHAkrXFWVLqdBWGv1y0ojCimtRD9hGwxdHmR5FUFmDUZLNsBmTYJNQqgio5+A85Q==",
|
||||
"dependencies": {
|
||||
"bare-env": "^3.0.0",
|
||||
"bare-events": "^2.5.4",
|
||||
"bare-os": "^3.0.1",
|
||||
"bare-pipe": "^4.2.0",
|
||||
"bare-structured-clone": "^1.5.2",
|
||||
"bare-tcp": "^2.4.1",
|
||||
"bare-pipe": "^4.0.0",
|
||||
"bare-url": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
@@ -954,7 +953,6 @@
|
||||
"version": "2.4.5",
|
||||
"resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz",
|
||||
"integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-path": "^3.0.0"
|
||||
}
|
||||
@@ -1163,6 +1161,32 @@
|
||||
"brittle-node": "brittle-node.js"
|
||||
}
|
||||
},
|
||||
"node_modules/brittle/node_modules/bare-subprocess": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-6.1.0.tgz",
|
||||
"integrity": "sha512-8L6KtbmreDy4Fc1BdDqaDo9fg0nbedUmTSFQxYPV0uHIM2BBAX8+E0LyMDKgkk0I+mlKto80WYzOnIhT8VDdOg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bare-env": "^3.0.0",
|
||||
"bare-events": "^2.5.4",
|
||||
"bare-os": "^3.0.1",
|
||||
"bare-pipe": "^4.2.0",
|
||||
"bare-structured-clone": "^1.5.2",
|
||||
"bare-tcp": "^2.4.1",
|
||||
"bare-url": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"bare": ">=1.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bare-buffer": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bare-buffer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
@@ -2234,30 +2258,6 @@
|
||||
"which-runtime": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/pear-electron/node_modules/bare-subprocess": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.3.tgz",
|
||||
"integrity": "sha512-07wwswlV7M3sC9IykbZRZ/jHAkrXFWVLqdBWGv1y0ojCimtRD9hGwxdHmR5FUFmDUZLNsBmTYJNQqgio5+A85Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-env": "^3.0.0",
|
||||
"bare-events": "^2.5.4",
|
||||
"bare-os": "^3.0.1",
|
||||
"bare-pipe": "^4.0.0",
|
||||
"bare-url": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"bare": ">=1.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bare-buffer": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bare-buffer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pear-electron/node_modules/compact-encoding": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-2.19.2.tgz",
|
||||
@@ -2444,30 +2444,6 @@
|
||||
"which-runtime": "^1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/pear-run/node_modules/bare-subprocess": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.3.tgz",
|
||||
"integrity": "sha512-07wwswlV7M3sC9IykbZRZ/jHAkrXFWVLqdBWGv1y0ojCimtRD9hGwxdHmR5FUFmDUZLNsBmTYJNQqgio5+A85Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bare-env": "^3.0.0",
|
||||
"bare-events": "^2.5.4",
|
||||
"bare-os": "^3.0.1",
|
||||
"bare-pipe": "^4.0.0",
|
||||
"bare-url": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"bare": ">=1.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bare-buffer": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bare-buffer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pear-stamp": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pear-stamp/-/pear-stamp-1.0.2.tgz",
|
||||
@@ -3277,8 +3253,7 @@
|
||||
"node_modules/which-runtime": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.4.0.tgz",
|
||||
"integrity": "sha512-0ugbP4CJW4e2D20jvEcC4973dCgIaHI4Rw1PT+26U9zEve7FyYdWAIwUnoeOYvoCfn+wXHoHTKb1KhkYlb60Pw==",
|
||||
"license": "Apache-2.0"
|
||||
"integrity": "sha512-0ugbP4CJW4e2D20jvEcC4973dCgIaHI4Rw1PT+26U9zEve7FyYdWAIwUnoeOYvoCfn+wXHoHTKb1KhkYlb60Pw=="
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
|
||||
@@ -5,6 +5,48 @@
|
||||
"type": "module",
|
||||
"license": "Apache-2.0",
|
||||
"main": "index.js",
|
||||
"imports": {
|
||||
"crypto": {
|
||||
"bare": "bare-crypto",
|
||||
"default": "crypto"
|
||||
},
|
||||
"fs": {
|
||||
"bare": "bare-fs",
|
||||
"default": "fs"
|
||||
},
|
||||
"path": {
|
||||
"bare": "bare-path",
|
||||
"default": "path"
|
||||
},
|
||||
"http": {
|
||||
"bare": "bare-http1",
|
||||
"default": "http"
|
||||
},
|
||||
"net": {
|
||||
"bare": "bare-net",
|
||||
"default": "net"
|
||||
},
|
||||
"process": {
|
||||
"bare": "bare-process",
|
||||
"default": "process"
|
||||
},
|
||||
"events": {
|
||||
"bare": "bare-events",
|
||||
"default": "events"
|
||||
},
|
||||
"os": {
|
||||
"bare": "bare-os",
|
||||
"default": "os"
|
||||
},
|
||||
"child_process": {
|
||||
"bare": "bare-subprocess",
|
||||
"default": "child_process"
|
||||
},
|
||||
"url": {
|
||||
"bare": "bare-url",
|
||||
"default": "url"
|
||||
}
|
||||
},
|
||||
"pear": {
|
||||
"pre": "pear-electron/pre",
|
||||
"name": "peardock",
|
||||
@@ -38,6 +80,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"b4a": "^1.8.1",
|
||||
"bare-crypto": "^1.15.3",
|
||||
"bare-events": "^2.9.1",
|
||||
"bare-fs": "^4.7.4",
|
||||
"bare-http1": "^4.5.7",
|
||||
"bare-net": "^2.3.2",
|
||||
"bare-os": "^3.9.3",
|
||||
"bare-path": "^3.1.1",
|
||||
"bare-process": "^4.5.1",
|
||||
"bare-subprocess": "^5.2.3",
|
||||
"bare-url": "^2.4.5",
|
||||
"compact-encoding": "^3.3.0",
|
||||
"dockerode": "^5.0.1",
|
||||
"dotenv": "^17.4.2",
|
||||
@@ -53,6 +105,7 @@
|
||||
"protomux": "^3.11.0",
|
||||
"protomux-rpc": "^1.10.0",
|
||||
"safety-catch": "^1.0.3",
|
||||
"which-runtime": "^1.4.0",
|
||||
"z32": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
Reference in New Issue
Block a user