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
@@ -8,41 +8,78 @@ class HyperPearStorageLayout extends EventEmitter {
constructor (opts = {}) {
super()
this.root = opts.root || '.'
this.defaultApp = opts.defaultApp || null
this._apps = new Map()
this._stats = { registered: 0 }
this._stats = { registered: 0, ensured: 0 }
}
registerApp (appKey, layout = {}) {
const key = assertId(appKey, 'appKey')
const entry = {
appKey: key,
storage: layout.storage || `${this.root}/storage/${key}`,
prefs: layout.prefs || `${this.root}/prefs/${key}`,
core: layout.core || `${this.root}/pear-runtime/corestore`,
at: Date.now()
}
const entry = this._buildEntry(key, layout)
this._apps.set(key, entry)
this._stats.registered++
this.emit('register', entry)
return entry
}
_buildEntry (key, layout) {
return {
appKey: key,
storage: layout.storage || `${this.root}/storage/${key}`,
prefs: layout.prefs || `${this.root}/prefs/${key}`,
core: layout.core || `${this.root}/pear-runtime/corestore`,
cache: layout.cache || `${this.root}/cache/${key}`,
at: Date.now()
}
}
pathsFor (appKey) {
return this._apps.get(assertId(appKey, 'appKey')) || null
}
ensureApp (appKey, layout = {}) {
let entry = this.pathsFor(appKey)
if (!entry) entry = this.registerApp(appKey, layout)
this._stats.ensured++
this.emit('ensure', entry)
return entry
}
migrateApp (appKey, fromLayout) {
const key = assertId(appKey, 'appKey')
const prev = this._apps.get(key)
const entry = this._buildEntry(key, { ...(prev || {}), ...fromLayout })
this._apps.set(key, entry)
this.emit('migrate', { appKey: key, from: prev, to: entry })
return entry
}
resolveActive (appKey = null) {
const key = appKey || this.defaultApp
if (!key) throw new Error('appKey or defaultApp required')
return this.ensureApp(key)
}
clearApp (appKey) {
return this._apps.delete(assertId(appKey, 'appKey'))
}
listApps () { return [...this._apps.keys()] }
allPaths () {
return [...this._apps.values()].flatMap((e) => [e.storage, e.prefs, e.core, e.cache])
}
getStats () {
return platformStats(this._stats, PROTOCOL, { apps: this._apps.size })
}
async ready () { return this }
async close () { this._apps.clear(); this.emit('closed') }
async close () {
this._apps.clear()
this.emit('closed')
}
}
module.exports = { HyperPearStorageLayout, HyperP2PPearStorageLayout: HyperPearStorageLayout, PROTOCOL }
@@ -1,6 +1,6 @@
{
"name": "hyper-pear-storage-layout",
"version": "0.0.0-scaffold",
"version": "0.3.1",
"description": "App storage and corestore path layout.",
"main": "index.js",
"type": "commonjs",
@@ -3,8 +3,17 @@ const test = require('brittle')
const { HyperPearStorageLayout } = require('../index.js')
test('paths', async (t) => {
const s = new HyperPearStorageLayout({ root: '/r' })
const p = s.registerApp('app1')
t.ok(p.storage.includes('app1'))
const s = new HyperPearStorageLayout({ root: '/data' })
const e = s.ensureApp('myapp')
t.ok(e.storage.includes('myapp'))
t.ok(s.allPaths().length >= 4)
await s.close()
})
test('migrate', async (t) => {
const s = new HyperPearStorageLayout({ root: '/x' })
s.registerApp('a', { storage: '/old' })
const m = s.migrateApp('a', { storage: '/new' })
t.is(m.storage, '/new')
await s.close()
})