Deepen all 16 pear-platform scaffolds to production APIs.

Expands spawn, argv, preflight, trust, OTA, pipes, and headless UI modules;
bumps to 0.3.1 with fuller tests and registry tier updates.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-21 01:35:15 -04:00
co-authored by Cursor
parent 64a2a824b5
commit 83a0ee684c
51 changed files with 982 additions and 178 deletions
+39 -5
View File
@@ -7,39 +7,69 @@ const PROTOCOL = 'pear-worker-pipe/v1'
class HyperPearWorkerPipe extends EventEmitter {
constructor (opts = {}) {
super()
this.maxBuffer = opts.maxBuffer ?? 4096
this._pipes = new Map()
this._stats = { created: 0, messages: 0 }
this._stats = { created: 0, messages: 0, pairs: 0 }
}
create (id = null) {
const pipeId = id || String(Date.now())
const pipe = { id: pipeId, open: true, buffer: [], createdAt: Date.now() }
const pipe = { id: pipeId, open: true, buffer: [], peerId: null, createdAt: Date.now() }
this._pipes.set(pipeId, pipe)
this._stats.created++
this.emit('create', pipe)
return pipe
}
createLinkedPair (prefix = 'pipe') {
const a = this.create(`${prefix}-a-${Date.now()}`)
const b = this.create(`${prefix}-b-${Date.now()}`)
const pa = this._pipes.get(a.id)
const pb = this._pipes.get(b.id)
pa.peerId = b.id
pb.peerId = a.id
this._stats.pairs++
this.emit('pair', { a: a.id, b: b.id })
return { a, b }
}
send (pipeId, msg) {
const p = this._pipes.get(assertId(pipeId))
if (!p || !p.open) return false
if (p.buffer.length >= this.maxBuffer) throw new Error('pipe buffer full')
p.buffer.push({ msg, at: Date.now() })
this._stats.messages++
this.emit('message', { pipeId, msg })
if (p.peerId) {
const peer = this._pipes.get(p.peerId)
if (peer && peer.open) {
peer.buffer.push({ msg, from: pipeId, at: Date.now() })
this.emit('message', { pipeId: p.peerId, msg, from: pipeId })
}
}
return true
}
drain (pipeId) {
const p = this._pipes.get(assertId(pipeId))
if (!p) return []
const out = p.buffer.splice(0, p.buffer.length)
return out
return p.buffer.splice(0, p.buffer.length)
}
broadcast (pipeIds, msg) {
let n = 0
for (const id of pipeIds) if (this.send(id, msg)) n++
return n
}
close (pipeId) {
const p = this._pipes.get(assertId(pipeId))
if (!p) return false
p.open = false
if (p.peerId) {
const peer = this._pipes.get(p.peerId)
if (peer) peer.peerId = null
}
this.emit('close', { pipeId })
return true
}
@@ -49,7 +79,11 @@ class HyperPearWorkerPipe extends EventEmitter {
}
async ready () { return this }
async close () { this._pipes.clear(); this.emit('closed') }
async close () {
this._pipes.clear()
this.emit('closed')
}
}
module.exports = { HyperPearWorkerPipe, HyperP2PPearWorkerPipe: HyperPearWorkerPipe, PROTOCOL }
@@ -1,6 +1,6 @@
{
"name": "hyper-pear-worker-pipe",
"version": "0.0.0-scaffold",
"version": "0.3.1",
"description": "Worker stdio pipe messaging.",
"main": "index.js",
"type": "commonjs",
@@ -4,8 +4,17 @@ const { HyperPearWorkerPipe } = require('../index.js')
test('pipe messages', async (t) => {
const p = new HyperPearWorkerPipe()
const pipe = p.create('p1')
p.send('p1', { hello: 1 })
t.is(p.drain('p1').length, 1)
const pipe = p.create('main')
p.send('main', { hello: 1 })
t.is(p.drain('main')[0].msg.hello, 1)
await p.close()
})
test('linked pair', async (t) => {
const p = new HyperPearWorkerPipe()
const { a, b } = p.createLinkedPair()
p.send(a.id, 'ping')
const got = p.drain(b.id)
t.is(got[0].msg, 'ping')
await p.close()
})