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.
|
* Bare/Node control plane for local Holesail client sessions.
|
||||||
* Runs in the pear-electron Bare entry (index.js), where require.addon works.
|
* 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
|
* Under Bare: require ONLY bare-* packages (never Node builtin names like
|
||||||
* which-runtime dual-load). Do not require bare Node built-ins alone on Bare.
|
* 'process' / 'crypto' — bare-module has no Node core builtins).
|
||||||
|
* Under Node: require Node core (bare-* native addons need Bare's require.addon).
|
||||||
*/
|
*/
|
||||||
'use strict'
|
'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.
|
// Strict split — no cross-fallback (Bare cannot load 'process', Node cannot load bare-abort addons).
|
||||||
function load (bareName, nodeName) {
|
const http = isBare ? require('bare-http1') : require('http')
|
||||||
if (isBare) {
|
const fs = isBare ? require('bare-fs') : require('fs')
|
||||||
try {
|
const path = isBare ? require('bare-path') : require('path')
|
||||||
return require(bareName)
|
const crypto = isBare ? require('bare-crypto') : require('crypto')
|
||||||
} catch {
|
const net = isBare ? require('bare-net') : require('net')
|
||||||
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 b4a = require('b4a')
|
||||||
const Holesail = require('holesail')
|
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 }>} */
|
/** @type {Map<string, { instance: any, localPort: number, host: string, url: string, info: object }>} */
|
||||||
const localClients = new Map()
|
const localClients = new Map()
|
||||||
|
|
||||||
@@ -74,7 +74,6 @@ async function connect(urlOrKey, opts = {}) {
|
|||||||
log: false,
|
log: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Race ready against a timeout so the UI never hangs forever
|
|
||||||
const readyMs = Number(opts.readyTimeoutMs) || 45000
|
const readyMs = Number(opts.readyTimeoutMs) || 45000
|
||||||
await Promise.race([
|
await Promise.race([
|
||||||
instance.ready(),
|
instance.ready(),
|
||||||
@@ -159,6 +158,12 @@ function sendJson(res, status, body) {
|
|||||||
res.end(raw)
|
res.end(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeToken() {
|
||||||
|
// bare-crypto and Node crypto both expose randomBytes
|
||||||
|
const bytes = crypto.randomBytes(16)
|
||||||
|
return b4a.toString(bytes, 'hex')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{
|
* @param {{
|
||||||
* statePath?: string,
|
* statePath?: string,
|
||||||
@@ -168,12 +173,11 @@ function sendJson(res, status, body) {
|
|||||||
* }} [opts]
|
* }} [opts]
|
||||||
*/
|
*/
|
||||||
async function start(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 host = opts.host || '127.0.0.1'
|
||||||
const pid = process.pid
|
const pid = getPid()
|
||||||
|
|
||||||
const server = http.createServer(async (req, res) => {
|
const server = http.createServer(async (req, res) => {
|
||||||
// CORS preflight (UI fetch from pear-bridge origin)
|
|
||||||
if (req.method === 'OPTIONS') {
|
if (req.method === 'OPTIONS') {
|
||||||
res.statusCode = 204
|
res.statusCode = 204
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*')
|
res.setHeader('Access-Control-Allow-Origin', '*')
|
||||||
@@ -184,16 +188,19 @@ async function start(opts = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// bare-url / WHATWG URL
|
|
||||||
const url = new URL(req.url || '/', `http://${host}`)
|
const url = new URL(req.url || '/', `http://${host}`)
|
||||||
const pathname = url.pathname
|
const pathname = url.pathname
|
||||||
|
|
||||||
if (pathname === '/health' && req.method === 'GET') {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// All mutating / privileged routes need the token
|
|
||||||
if (pathname !== '/health') {
|
if (pathname !== '/health') {
|
||||||
const hdr = req.headers['x-peardock-token']
|
const hdr = req.headers['x-peardock-token']
|
||||||
const q = url.searchParams.get('token')
|
const q = url.searchParams.get('token')
|
||||||
@@ -245,7 +252,7 @@ async function start(opts = {}) {
|
|||||||
const addr = server.address()
|
const addr = server.address()
|
||||||
const port = typeof addr === 'object' && addr ? addr.port : 0
|
const port = typeof addr === 'object' && addr ? addr.port : 0
|
||||||
const baseUrl = `http://${host}:${port}`
|
const baseUrl = `http://${host}:${port}`
|
||||||
const meta = { port, host, token, baseUrl, pid }
|
const meta = { port, host, token, baseUrl, pid, bare: isBare }
|
||||||
|
|
||||||
if (opts.statePath) {
|
if (opts.statePath) {
|
||||||
try {
|
try {
|
||||||
@@ -262,9 +269,9 @@ async function start(opts = {}) {
|
|||||||
...meta,
|
...meta,
|
||||||
server,
|
server,
|
||||||
async close() {
|
async close() {
|
||||||
for (const url of [...localClients.keys()]) {
|
for (const u of [...localClients.keys()]) {
|
||||||
try {
|
try {
|
||||||
await disconnect(url)
|
await disconnect(u)
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user