Stop falling back to Node builtin names (process/crypto/…) which bare-module cannot resolve. Detect Bare via globalThis.Bare and drop bare-process (use global pid instead).
This commit is contained in:
@@ -1,40 +1,40 @@
|
||||
/**
|
||||
* 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).
|
||||
* The UI renderer talks to this over http://127.0.0.1:<port>.
|
||||
*
|
||||
* 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.
|
||||
* Under Bare: require ONLY bare-* packages (never Node builtin names like
|
||||
* 'process' / 'crypto' — bare-module has no Node core builtins).
|
||||
* Under Node: require Node core (bare-* native addons need Bare's require.addon).
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { isBare } = require('which-runtime')
|
||||
const isBare = typeof globalThis.Bare !== 'undefined'
|
||||
|
||||
// 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')
|
||||
// Strict split — no cross-fallback (Bare cannot load 'process', Node cannot load bare-abort addons).
|
||||
const http = isBare ? require('bare-http1') : require('http')
|
||||
const fs = isBare ? require('bare-fs') : require('fs')
|
||||
const path = isBare ? require('bare-path') : require('path')
|
||||
const crypto = isBare ? require('bare-crypto') : require('crypto')
|
||||
const net = isBare ? require('bare-net') : require('net')
|
||||
const b4a = require('b4a')
|
||||
const Holesail = require('holesail')
|
||||
|
||||
// Avoid bare-process / Node 'process' entirely
|
||||
function getPid() {
|
||||
try {
|
||||
if (typeof globalThis.process?.pid === 'number') return globalThis.process.pid
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
if (typeof globalThis.Bare?.pid === 'number') return globalThis.Bare.pid
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/** @type {Map<string, { instance: any, localPort: number, host: string, url: string, info: object }>} */
|
||||
const localClients = new Map()
|
||||
|
||||
@@ -74,7 +74,6 @@ async function connect(urlOrKey, opts = {}) {
|
||||
log: false,
|
||||
})
|
||||
|
||||
// Race ready against a timeout so the UI never hangs forever
|
||||
const readyMs = Number(opts.readyTimeoutMs) || 45000
|
||||
await Promise.race([
|
||||
instance.ready(),
|
||||
@@ -159,6 +158,12 @@ function sendJson(res, status, body) {
|
||||
res.end(raw)
|
||||
}
|
||||
|
||||
function makeToken() {
|
||||
// bare-crypto and Node crypto both expose randomBytes
|
||||
const bytes = crypto.randomBytes(16)
|
||||
return b4a.toString(bytes, 'hex')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* statePath?: string,
|
||||
@@ -168,12 +173,11 @@ function sendJson(res, status, body) {
|
||||
* }} [opts]
|
||||
*/
|
||||
async function start(opts = {}) {
|
||||
const token = opts.token || crypto.randomBytes(16).toString('hex')
|
||||
const token = opts.token || makeToken()
|
||||
const host = opts.host || '127.0.0.1'
|
||||
const pid = process.pid
|
||||
const pid = getPid()
|
||||
|
||||
const server = http.createServer(async (req, res) => {
|
||||
// CORS preflight (UI fetch from pear-bridge origin)
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.statusCode = 204
|
||||
res.setHeader('Access-Control-Allow-Origin', '*')
|
||||
@@ -184,16 +188,19 @@ async function start(opts = {}) {
|
||||
}
|
||||
|
||||
try {
|
||||
// bare-url / WHATWG URL
|
||||
const url = new URL(req.url || '/', `http://${host}`)
|
||||
const pathname = url.pathname
|
||||
|
||||
if (pathname === '/health' && req.method === 'GET') {
|
||||
sendJson(res, 200, { ok: true, service: 'holesail-local', clients: localClients.size })
|
||||
sendJson(res, 200, {
|
||||
ok: true,
|
||||
service: 'holesail-local',
|
||||
clients: localClients.size,
|
||||
bare: isBare,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// All mutating / privileged routes need the token
|
||||
if (pathname !== '/health') {
|
||||
const hdr = req.headers['x-peardock-token']
|
||||
const q = url.searchParams.get('token')
|
||||
@@ -245,7 +252,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 }
|
||||
const meta = { port, host, token, baseUrl, pid, bare: isBare }
|
||||
|
||||
if (opts.statePath) {
|
||||
try {
|
||||
@@ -262,9 +269,9 @@ async function start(opts = {}) {
|
||||
...meta,
|
||||
server,
|
||||
async close() {
|
||||
for (const url of [...localClients.keys()]) {
|
||||
for (const u of [...localClients.keys()]) {
|
||||
try {
|
||||
await disconnect(url)
|
||||
await disconnect(u)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user