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:
@@ -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()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user