Add 20 Pear/Bare platform modules replacing deprecated pear run.

Introduces hyper-bare-entry-runner, pear-runtime embed/link/config stack,
and scaffold helpers for argv, storage, OTA, Electron, and headless UI.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-21 01:29:28 -04:00
co-authored by Cursor
parent ad3fc106f1
commit 64a2a824b5
187 changed files with 28587 additions and 21 deletions
+1
View File
@@ -2,6 +2,7 @@
node_modules/ node_modules/
*-storage/ *-storage/
*-storage*/ *-storage*/
!pear-platform/hyper-pear-storage-layout/
real_tests-integration-storage/ real_tests-integration-storage/
**/*.log **/*.log
+22 -2
View File
@@ -1,6 +1,6 @@
# Module categories (v2) # Module categories (v2)
186 modules in **31** category directories (**166** production + **16** media-streaming scaffold + **4** media-streaming production). 206 modules in **31** category directories.
Source of truth: [`MODULE_REGISTRY.yaml`](MODULE_REGISTRY.yaml). Source of truth: [`MODULE_REGISTRY.yaml`](MODULE_REGISTRY.yaml).
@@ -175,12 +175,32 @@ Source of truth: [`MODULE_REGISTRY.yaml`](MODULE_REGISTRY.yaml).
- 🟢 **hyper-p2p-decentralized-oracle**`decentralized-oracle/v1` (production) - 🟢 **hyper-p2p-decentralized-oracle**`decentralized-oracle/v1` (production)
## Pear / Bare platform (`pear-platform`) — 4 modules ## Pear / Bare platform (`pear-platform`) — 24 modules
- 🟢 **hyper-bare-entry-runner**`bare-entry-runner/v1` (production) — **pear run replacement**
- 🟢 **hyper-pear-runtime-embed**`pear-runtime-embed/v1` (production)
- 🟢 **hyper-pear-link-resolver**`pear-link-resolver/v1` (production)
- 🟢 **hyper-pear-applink-config**`pear-applink-config/v1` (production)
- 🟢 **hyper-bare-bundle-bridge**`bare-bundle-bridge/v1` (production) - 🟢 **hyper-bare-bundle-bridge**`bare-bundle-bridge/v1` (production)
- 🟢 **hyper-bare-distributable-hint**`bare-distributable-hint/v1` (production) - 🟢 **hyper-bare-distributable-hint**`bare-distributable-hint/v1` (production)
- 🟢 **hyper-pear-runtime-session**`pear-runtime-session/v1` (production) - 🟢 **hyper-pear-runtime-session**`pear-runtime-session/v1` (production)
- 🟢 **hyper-pear-update-gossip**`pear-update-gossip/v1` (production) - 🟢 **hyper-pear-update-gossip**`pear-update-gossip/v1` (production)
- 🟢 **hyper-bare-process-spawn**`bare-process-spawn/v1` (scaffold)
- 🟢 **hyper-pear-preflight-sync**`pear-preflight-sync/v1` (scaffold)
- 🟢 **hyper-pear-dev-profile**`pear-dev-profile/v1` (scaffold)
- 🟢 **hyper-bare-argv-bridge**`bare-argv-bridge/v1` (scaffold)
- 🟢 **hyper-pear-storage-layout**`pear-storage-layout/v1` (scaffold)
- 🟢 **hyper-pear-trust-gate**`pear-trust-gate/v1` (scaffold)
- 🟢 **hyper-pear-deep-link**`pear-deep-link/v1` (scaffold)
- 🟢 **hyper-bare-addon-resolve**`bare-addon-resolve/v1` (scaffold)
- 🟢 **hyper-pear-worker-pipe**`pear-worker-pipe/v1` (scaffold)
- 🟢 **hyper-pear-channel-registry**`pear-channel-registry/v1` (scaffold)
- 🟢 **hyper-bare-import-map**`bare-import-map/v1` (scaffold)
- 🟢 **hyper-pear-ota-state**`pear-ota-state/v1` (scaffold)
- 🟢 **hyper-pear-electron-bridge**`pear-electron-bridge/v1` (scaffold)
- 🟢 **hyper-bare-target-matrix**`bare-target-matrix/v1` (scaffold)
- 🟢 **hyper-pear-detached-registry**`pear-detached-registry/v1` (scaffold)
- 🟢 **hyper-bare-headless-ui**`bare-headless-ui/v1` (scaffold)
## Routing & paths (`routing-paths`) — 4 modules ## Routing & paths (`routing-paths`) — 4 modules
+231 -1
View File
@@ -1,4 +1,4 @@
# Module registry — source of truth (186 modules) # Module registry — source of truth (206 modules)
# tiers: production | scaffold # tiers: production | scaffold
version: 1 version: 1
categories: { categories: {
@@ -1290,6 +1290,236 @@ modules:
- pear-runtime-updater - pear-runtime-updater
composes_with: composes_with:
- hyper-p2p-gossip-mesh - hyper-p2p-gossip-mesh
- name: hyper-bare-entry-runner
category: pear-platform
tier: production
status: implemented
protocol: bare-entry-runner/v1
class: HyperP2PBareEntryRunner
summary: Programmatic pear run replacement — plan Bare/Pear app launches for pear-runtime.
holepunch_refs:
- pear-run
- pear-runtime
composes_with:
- hyper-pear-runtime-embed
- hyper-pear-link-resolver
- hyper-pear-applink-config
- hyper-bare-process-spawn
- name: hyper-pear-runtime-embed
category: pear-platform
tier: production
status: implemented
protocol: pear-runtime-embed/v1
class: HyperP2PPearRuntimeEmbed
summary: Embeddable pear-runtime lifecycle, storage, and corestore paths.
holepunch_refs:
- pear-runtime
composes_with:
- hyper-bare-entry-runner
- hyper-pear-storage-layout
- name: hyper-pear-link-resolver
category: pear-platform
tier: production
status: implemented
protocol: pear-link-resolver/v1
class: HyperP2PPearLinkResolver
summary: Parse and serialize pear:// application links.
holepunch_refs:
- pear-link
composes_with:
- hyper-pear-deep-link
- hyper-bare-entry-runner
- name: hyper-pear-applink-config
category: pear-platform
tier: production
status: implemented
protocol: pear-applink-config/v1
class: HyperP2PPearApplinkConfig
summary: Load package.json pear.* applink, links, and stage config.
holepunch_refs:
- pear
composes_with:
- hyper-bare-entry-runner
- hyper-pear-channel-registry
- name: hyper-bare-process-spawn
category: pear-platform
tier: scaffold
status: implemented
protocol: bare-process-spawn/v1
class: HyperP2PBareProcessSpawn
summary: Track Bare runtime child spawn argv plans.
holepunch_refs:
- pear-run
composes_with:
- hyper-bare-entry-runner
- name: hyper-pear-preflight-sync
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-preflight-sync/v1
class: HyperP2PPearPreflightSync
summary: Preflight asset sync before app execution.
holepunch_refs:
- pear
composes_with:
- hyper-bare-entry-runner
- name: hyper-pear-dev-profile
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-dev-profile/v1
class: HyperP2PPearDevProfile
summary: Dev mode and CLI flags (--dev, devtools, updates-diff).
holepunch_refs:
- pear
composes_with:
- hyper-bare-entry-runner
- name: hyper-bare-argv-bridge
category: pear-platform
tier: scaffold
status: implemented
protocol: bare-argv-bridge/v1
class: HyperP2PBareArgvBridge
summary: CLI argv and flag parsing for Bare-hosted Pear commands.
holepunch_refs:
- pear-cmd
composes_with:
- hyper-bare-entry-runner
- name: hyper-pear-storage-layout
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-storage-layout/v1
class: HyperP2PPearStorageLayout
summary: Per-app storage, prefs, and corestore directory layout.
holepunch_refs:
- pear-runtime
composes_with:
- hyper-pear-runtime-embed
- name: hyper-pear-trust-gate
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-trust-gate/v1
class: HyperP2PPearTrustGate
summary: Trusted application key allowlist for launches.
holepunch_refs:
- pear
composes_with:
- hyper-bare-entry-runner
- name: hyper-pear-deep-link
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-deep-link/v1
class: HyperP2PPearDeepLink
summary: Deep-link entrypoint and subpath routing.
holepunch_refs:
- pear
composes_with:
- hyper-pear-link-resolver
- name: hyper-bare-addon-resolve
category: pear-platform
tier: scaffold
status: implemented
protocol: bare-addon-resolve/v1
class: HyperP2PBareAddonResolve
summary: Per-platform native addon path resolution.
holepunch_refs:
- bare-addon-resolve
composes_with:
- hyper-bare-target-matrix
- name: hyper-pear-worker-pipe
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-worker-pipe/v1
class: HyperP2PPearWorkerPipe
summary: Worker stdio pipe message buffer (pear-run IPC pattern).
holepunch_refs:
- pear-run
composes_with:
- hyper-bare-headless-ui
- name: hyper-pear-channel-registry
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-channel-registry/v1
class: HyperP2PPearChannelRegistry
summary: Channel name registry and touch metadata.
holepunch_refs:
- pear
composes_with:
- hyper-pear-applink-config
- name: hyper-bare-import-map
category: pear-platform
tier: scaffold
status: implemented
protocol: bare-import-map/v1
class: HyperP2PBareImportMap
summary: package.json imports map resolution for Bare.
holepunch_refs:
- bare
composes_with:
- hyper-bare-bundle-bridge
- name: hyper-pear-ota-state
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-ota-state/v1
class: HyperP2PPearOtaState
summary: OTA updater phase and progress state machine.
holepunch_refs:
- pear-runtime-updater
composes_with:
- hyper-pear-update-gossip
- name: hyper-pear-electron-bridge
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-electron-bridge/v1
class: HyperP2PPearElectronBridge
summary: Electron renderer IPC bridge for pear-runtime run().
holepunch_refs:
- hello-pear-electron
- pear-runtime
composes_with:
- hyper-bare-entry-runner
- name: hyper-bare-target-matrix
category: pear-platform
tier: scaffold
status: implemented
protocol: bare-target-matrix/v1
class: HyperP2PBareTargetMatrix
summary: Cross-platform pear-runtime build target matrix.
holepunch_refs:
- pear
composes_with:
- hyper-bare-distributable-hint
- name: hyper-pear-detached-registry
category: pear-platform
tier: scaffold
status: implemented
protocol: pear-detached-registry/v1
class: HyperP2PPearDetachedRegistry
summary: Detached app instance registration and wake.
holepunch_refs:
- pear
composes_with:
- hyper-pear-runtime-session
- name: hyper-bare-headless-ui
category: pear-platform
tier: scaffold
status: implemented
protocol: bare-headless-ui/v1
class: HyperP2PBareHeadlessUi
summary: Headless Pearend backend with optional UI worker pipe.
holepunch_refs:
- pear
- pear-electron
composes_with:
- hyper-pear-worker-pipe
- hyper-pear-electron-bridge
- name: hyper-p2p-whiteboard-op - name: hyper-p2p-whiteboard-op
category: applications-collab category: applications-collab
tier: production tier: production
+3 -3
View File
@@ -1,6 +1,6 @@
# Hyper-P2P module workspace # Hyper-P2P module workspace
This directory is the **module library** for the repository: **186** independent npm packages for [Bare](https://github.com/holepunchto/bare) and Pear. Each package is a small, composable peer-to-peer primitive—discovery, messaging, storage, coordination, security, or application logic—built on shared Hyperswarm and Protomux conventions. This directory is the **module library** for the repository: **206** independent npm packages for [Bare](https://github.com/holepunchto/bare) and Pear. Each package is a small, composable peer-to-peer primitive—discovery, messaging, storage, coordination, security, or application logic—built on shared Hyperswarm and Protomux conventions.
The parent repository adds cross-cutting guides under `docs/`, composition examples under `examples/`, and the unified test runner under `real_tests/`. Start at the [repository README](../README.md) for clone, CI, and top-level commands. The parent repository adds cross-cutting guides under `docs/`, composition examples under `examples/`, and the unified test runner under `real_tests/`. Start at the [repository README](../README.md) for clone, CI, and top-level commands.
@@ -56,11 +56,11 @@ Packages live under **31 functional categories** (one folder per category). Cate
| Applications (collaboration) | 4 | Collab rooms, cursors, line locks, whiteboard ops | | Applications (collaboration) | 4 | Collab rooms, cursors, line locks, whiteboard ops |
| Applications (economy) | 3 | Auctions, credit ledger, marketplace listings | | Applications (economy) | 3 | Auctions, credit ledger, marketplace listings |
| Experimental | 16 | Research primitives (entropy, trails, void channel, memetic spread, …) | | Experimental | 16 | Research primitives (entropy, trails, void channel, memetic spread, …) |
| Pear / Bare platform | 4 | Bundles, distributables, Pear runtime session, update gossip | | Pear / Bare platform | 24 | pear run replacement, pear-runtime embed, links, OTA, headless UI |
| Oracles | 1 | Decentralized oracle gossip | | Oracles | 1 | Decentralized oracle gossip |
| Time & ordering | 1 | Temporal index | | Time & ordering | 1 | Temporal index |
**186** modules total. The authoritative list with protocol ids and paths is in **`MODULE_REGISTRY.yaml`**; **`module-paths.json`** maps package name → category path for tooling and tests. **206** modules total. The authoritative list with protocol ids and paths is in **`MODULE_REGISTRY.yaml`**; **`module-paths.json`** maps package name → category path for tooling and tests.
For a per-module index with protocol ids, use **`MODULE_CATEGORIES.md`** in this directory. For a per-module index with protocol ids, use **`MODULE_CATEGORIES.md`** in this directory.
+35
View File
@@ -0,0 +1,35 @@
'use strict'
const LINK_PREFIX = 'pear://'
const FILE_PREFIX = 'file://'
function assertId (id, label = 'id') {
if (id == null || String(id).length === 0) throw new Error(`${label} required`)
return String(id)
}
function platformStats (base, protocol, extra = {}) {
return { ...base, protocol, mode: 'local', ...extra }
}
function classifyTarget (target) {
const t = String(target)
if (t.startsWith(LINK_PREFIX)) {
return { kind: 'pear-link', href: t, key: t.slice(LINK_PREFIX.length).split('/')[0] }
}
if (t.startsWith(FILE_PREFIX)) {
return { kind: 'file', href: t, path: t.slice(FILE_PREFIX.length) }
}
if (t.startsWith('/')) {
return { kind: 'absolute-path', path: t }
}
return { kind: 'relative-path', path: t }
}
module.exports = {
LINK_PREFIX,
FILE_PREFIX,
assertId,
platformStats,
classifyTarget
}
+20
View File
@@ -1,6 +1,13 @@
{ {
"hyper-bare-addon-resolve": "pear-platform/hyper-bare-addon-resolve",
"hyper-bare-argv-bridge": "pear-platform/hyper-bare-argv-bridge",
"hyper-bare-bundle-bridge": "pear-platform/hyper-bare-bundle-bridge", "hyper-bare-bundle-bridge": "pear-platform/hyper-bare-bundle-bridge",
"hyper-bare-distributable-hint": "pear-platform/hyper-bare-distributable-hint", "hyper-bare-distributable-hint": "pear-platform/hyper-bare-distributable-hint",
"hyper-bare-entry-runner": "pear-platform/hyper-bare-entry-runner",
"hyper-bare-headless-ui": "pear-platform/hyper-bare-headless-ui",
"hyper-bare-import-map": "pear-platform/hyper-bare-import-map",
"hyper-bare-process-spawn": "pear-platform/hyper-bare-process-spawn",
"hyper-bare-target-matrix": "pear-platform/hyper-bare-target-matrix",
"hyper-p2p-activity-queue": "scheduling-queues/hyper-p2p-activity-queue", "hyper-p2p-activity-queue": "scheduling-queues/hyper-p2p-activity-queue",
"hyper-p2p-agent-memory": "agents-workflows/hyper-p2p-agent-memory", "hyper-p2p-agent-memory": "agents-workflows/hyper-p2p-agent-memory",
"hyper-p2p-anycast-selector": "network-stack/hyper-p2p-anycast-selector", "hyper-p2p-anycast-selector": "network-stack/hyper-p2p-anycast-selector",
@@ -182,7 +189,20 @@
"hyper-p2p-wire-registry": "encoding-wire/hyper-p2p-wire-registry", "hyper-p2p-wire-registry": "encoding-wire/hyper-p2p-wire-registry",
"hyper-p2p-work-stealer": "supercomputer/hyper-p2p-work-stealer", "hyper-p2p-work-stealer": "supercomputer/hyper-p2p-work-stealer",
"hyper-p2p-workflow-graph": "agents-workflows/hyper-p2p-workflow-graph", "hyper-p2p-workflow-graph": "agents-workflows/hyper-p2p-workflow-graph",
"hyper-pear-applink-config": "pear-platform/hyper-pear-applink-config",
"hyper-pear-channel-registry": "pear-platform/hyper-pear-channel-registry",
"hyper-pear-deep-link": "pear-platform/hyper-pear-deep-link",
"hyper-pear-detached-registry": "pear-platform/hyper-pear-detached-registry",
"hyper-pear-dev-profile": "pear-platform/hyper-pear-dev-profile",
"hyper-pear-electron-bridge": "pear-platform/hyper-pear-electron-bridge",
"hyper-pear-link-resolver": "pear-platform/hyper-pear-link-resolver",
"hyper-pear-ota-state": "pear-platform/hyper-pear-ota-state",
"hyper-pear-preflight-sync": "pear-platform/hyper-pear-preflight-sync",
"hyper-pear-runtime-embed": "pear-platform/hyper-pear-runtime-embed",
"hyper-pear-runtime-session": "pear-platform/hyper-pear-runtime-session", "hyper-pear-runtime-session": "pear-platform/hyper-pear-runtime-session",
"hyper-pear-storage-layout": "pear-platform/hyper-pear-storage-layout",
"hyper-pear-trust-gate": "pear-platform/hyper-pear-trust-gate",
"hyper-pear-update-gossip": "pear-platform/hyper-pear-update-gossip", "hyper-pear-update-gossip": "pear-platform/hyper-pear-update-gossip",
"hyper-pear-worker-pipe": "pear-platform/hyper-pear-worker-pipe",
"hyper-spatial-index": "indexes-search/hyper-spatial-index" "hyper-spatial-index": "indexes-search/hyper-spatial-index"
} }
+64 -15
View File
@@ -1,29 +1,78 @@
# Pear / Bare platform # Pear / Bare platform
**Path:** `modules/pear-platform/` · **Modules:** 4 (production) **Path:** `modules/pear-platform/` · **Modules:** 24
Pear runtime and Bare distribution helpers — sessions, update gossip, bundle bridge, distributable hints. Helpers for **Bare** and **Pear** runtimes after `pear run` deprecation — use embeddable **`pear-runtime`** plus these composable modules.
## Modules Investigation source: `holepunch-repos/holepunchto_repos/pear` (CHANGELOG: `pear run` **DEPRECATED**`pear-runtime` module), `pear-run`, `pear-runtime`, `hello-pear-electron`.
| Module | Protocol | Highlights | Shared: [`../_shared/pear-platform-base.js`](../_shared/pear-platform-base.js)
|--------|----------|------------|
| [hyper-pear-runtime-session](./hyper-pear-runtime-session/) | `pear-runtime-session/v1` | `listSessionIds()`, active session tracking |
| [hyper-pear-update-gossip](./hyper-pear-update-gossip/) | `pear-update-gossip/v1` | Version hints over mesh |
| [hyper-bare-bundle-bridge](./hyper-bare-bundle-bridge/) | `bare-bundle-bridge/v1` | Bundle manifest bridge |
| [hyper-bare-distributable-hint](./hyper-bare-distributable-hint/) | `bare-distributable-hint/v1` | Distributable metadata hints |
## Quick start ## pear run replacement stack
```text
hyper-pear-applink-config → read package.json pear.*
hyper-pear-link-resolver → parse pear:// links
hyper-bare-entry-runner → planRun() replaces `pear run`
hyper-pear-runtime-embed → pear-runtime dir layout + open()
hyper-bare-process-spawn → track child runtime argv
hyper-pear-dev-profile → --dev / devtools flags
hyper-pear-preflight-sync → --preflight asset warmup
hyper-pear-trust-gate → trusted keys
hyper-bare-headless-ui → Pearend + optional UI worker
```
```js ```js
const { HyperPearRuntimeSession } = require('hyper-pear-runtime-session') const { HyperPearApplinkConfig } = require('hyper-pear-applink-config')
const sess = new HyperPearRuntimeSession() const { HyperBareEntryRunner } = require('hyper-bare-entry-runner')
const { id } = sess.startSession({ app: 'demo' }) const { HyperPearRuntimeEmbed } = require('hyper-pear-runtime-embed')
console.log(sess.listSessionIds(), sess.getStats())
const cfg = new HyperPearApplinkConfig()
cfg.load(require('./package.json'))
const embed = new HyperPearRuntimeEmbed({ dir: process.cwd() })
await embed.ready()
const runner = new HyperBareEntryRunner()
const plan = runner.planRun(cfg.get('applink') || './index.js', process.argv.slice(2), {
dev: true,
trusted: true
})
// plan.runtimeArgv → hand to bare/pear-runtime binary
``` ```
## All modules (24)
| Module | Protocol | Tier | Role |
|--------|----------|------|------|
| hyper-bare-entry-runner | `bare-entry-runner/v1` | production | **pear run replacement** — plan & track launches |
| hyper-pear-runtime-embed | `pear-runtime-embed/v1` | production | Embeddable runtime paths + `planRun` |
| hyper-pear-link-resolver | `pear-link-resolver/v1` | production | `pear://` parse/serialize |
| hyper-pear-applink-config | `pear-applink-config/v1` | production | `package.json` `pear.*` loader |
| hyper-pear-runtime-session | `pear-runtime-session/v1` | production | Session tracking |
| hyper-pear-update-gossip | `pear-update-gossip/v1` | production | Update gossip |
| hyper-bare-bundle-bridge | `bare-bundle-bridge/v1` | production | Bundle manifests |
| hyper-bare-distributable-hint | `bare-distributable-hint/v1` | production | Distributable layout |
| hyper-bare-process-spawn | `bare-process-spawn/v1` | scaffold | Spawn plan tracking |
| hyper-pear-preflight-sync | `pear-preflight-sync/v1` | scaffold | Preflight sync |
| hyper-pear-dev-profile | `pear-dev-profile/v1` | scaffold | Dev/prod flags |
| hyper-bare-argv-bridge | `bare-argv-bridge/v1` | scaffold | CLI argv parsing |
| hyper-pear-storage-layout | `pear-storage-layout/v1` | scaffold | Storage layout |
| hyper-pear-trust-gate | `pear-trust-gate/v1` | scaffold | Trusted keys |
| hyper-pear-deep-link | `pear-deep-link/v1` | scaffold | Deep links |
| hyper-bare-addon-resolve | `bare-addon-resolve/v1` | scaffold | Native addons |
| hyper-pear-worker-pipe | `pear-worker-pipe/v1` | scaffold | Worker pipes |
| hyper-pear-channel-registry | `pear-channel-registry/v1` | scaffold | Channel registry |
| hyper-bare-import-map | `bare-import-map/v1` | scaffold | `imports` map |
| hyper-pear-ota-state | `pear-ota-state/v1` | scaffold | OTA phases |
| hyper-pear-electron-bridge | `pear-electron-bridge/v1` | scaffold | Electron IPC |
| hyper-bare-target-matrix | `bare-target-matrix/v1` | scaffold | Build targets |
| hyper-pear-detached-registry | `pear-detached-registry/v1` | scaffold | Detached instances |
| hyper-bare-headless-ui | `bare-headless-ui/v1` | scaffold | Headless + UI |
## Test ## Test
```bash ```bash
cd hyper-pear-runtime-session && npm test cd hyper-bare-entry-runner && npm test
for d in hyper-*/; do (cd "$d" && npm test) || exit 1; done
``` ```
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-addon-resolve
**Protocol:** `bare-addon-resolve/v1`
Per-platform native addon resolution. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-bare-addon-resolve
**Protocol:** `bare-addon-resolve/v1` · **Export:** `{ HyperBareAddonResolve, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-addon-resolve
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareAddonResolve } = require('../index.js')
async function main () {
const m = new HyperBareAddonResolve()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,46 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-addon-resolve/v1'
class HyperBareAddonResolve extends EventEmitter {
constructor (opts = {}) {
super()
this.platform = opts.platform || 'darwin-arm64'
this._addons = new Map()
this._stats = { registered: 0, resolved: 0 }
}
register (name, spec) {
if (!name) throw new Error('name required')
const entry = { name: String(name), ...spec, at: Date.now() }
this._addons.set(entry.name, entry)
this._stats.registered++
return entry
}
resolve (name) {
const e = this._addons.get(String(name))
if (!e) return null
const file = e[this.platform] || e.path || null
this._stats.resolved++
return file ? { name: e.name, path: file, platform: this.platform } : null
}
setPlatform (platform) {
this.platform = String(platform)
return this.platform
}
listNames () { return [...this._addons.keys()] }
getStats () {
return platformStats(this._stats, PROTOCOL, { addons: this._addons.size, platform: this.platform })
}
async ready () { return this }
async close () { this._addons.clear(); this.emit('closed') }
}
module.exports = { HyperBareAddonResolve, HyperP2PBareAddonResolve: HyperBareAddonResolve, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-addon-resolve",
"version": "0.0.0-scaffold",
"description": "Per-platform native addon resolution.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,10 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareAddonResolve } = require('../index.js')
test('resolve addon', async (t) => {
const a = new HyperBareAddonResolve()
a.register('binding', { 'darwin-arm64': '/lib/binding.node' })
t.ok(a.resolve('binding'))
await a.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-argv-bridge
**Protocol:** `bare-argv-bridge/v1`
CLI argv and flag parsing for Bare apps. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-bare-argv-bridge
**Protocol:** `bare-argv-bridge/v1` · **Export:** `{ HyperBareArgvBridge, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-argv-bridge
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareArgvBridge } = require('../index.js')
async function main () {
const m = new HyperBareArgvBridge()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,60 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-argv-bridge/v1'
class HyperBareArgvBridge extends EventEmitter {
constructor (opts = {}) {
super()
this._argv = opts.argv ? [...opts.argv] : []
this._rest = []
this._flags = new Map()
this._stats = { parsed: 0 }
}
setArgv (argv) {
this._argv = Array.isArray(argv) ? [...argv] : []
this._parse()
return { flags: Object.fromEntries(this._flags), rest: [...this._rest] }
}
_parse () {
this._flags.clear()
this._rest = []
const a = this._argv
for (let i = 0; i < a.length; i++) {
const tok = a[i]
if (tok.startsWith('--')) {
const eq = tok.indexOf('=')
if (eq > 0) {
this._flags.set(tok.slice(2, eq), tok.slice(eq + 1))
} else {
const next = a[i + 1]
if (next && !next.startsWith('-')) {
this._flags.set(tok.slice(2), next)
i++
} else {
this._flags.set(tok.slice(2), true)
}
}
} else if (!tok.startsWith('-')) {
this._rest.push(tok)
}
}
this._stats.parsed++
}
flag (name) { return this._flags.get(name) }
rest () { return [...this._rest] }
hasFlag (name) { return this._flags.has(name) }
getStats () {
return platformStats(this._stats, PROTOCOL, { flags: this._flags.size, rest: this._rest.length })
}
async ready () { return this }
async close () { this.emit('closed') }
}
module.exports = { HyperBareArgvBridge, HyperP2PBareArgvBridge: HyperBareArgvBridge, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-argv-bridge",
"version": "0.0.0-scaffold",
"description": "CLI argv and flag parsing for Bare apps.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,11 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareArgvBridge } = require('../index.js')
test('parse argv', async (t) => {
const a = new HyperBareArgvBridge()
a.setArgv(['run', '--dev=true', 'pear://x', 'extra'])
t.is(a.flag('dev'), 'true')
t.ok(a.rest().includes('pear://x'))
await a.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.3.1
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-entry-runner
**Protocol:** `bare-entry-runner/v1`
Programmatic pear run replacement for Bare CLI apps. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,50 @@
# API: hyper-bare-entry-runner
**Protocol:** `bare-entry-runner/v1`
**Export:** `{ HyperBareEntryRunner, HyperP2PBareEntryRunner, PROTOCOL }`
## Overview
Programmatic replacement for deprecated **`pear run`**. Plans Bare/Pear application launches the way `pear-runtime` expects: resolves `pear://`, `file://`, and filesystem paths, builds runtime argv (`run`, `--dev`, `--preflight`, `--trusted`), and tracks run lifecycle without shelling to the Pear CLI.
Holepunch direction ([pear CHANGELOG](https://github.com/holepunchto/pear)): use the **`pear-runtime`** module for embeddable runtime + P2P OTA; this module is the in-process launch planner.
## Constructor
```js
const runner = new HyperBareEntryRunner({ baseDir, trustedOnly })
```
## Methods
| Method | Description |
|--------|-------------|
| `resolveTarget(target)` | Classify link/path (`pear-link`, `file`, `absolute-path`, `relative-path`) |
| `planRun(target, args?, flags?)` | Build run plan: `runId`, `runtimeArgv`, `entrypoint`, `mode` |
| `startRun(runId)` | Mark run as started |
| `completeRun(runId, exitCode?)` | Mark run completed |
| `getRun(runId)` | Fetch run record |
| `listRuns(status?)` | List runs, optional filter by status |
### Flags (planRun)
| Flag | Maps to |
|------|---------|
| `dev` | `--dev` + development mode |
| `preflight` | `--preflight` warmup-only |
| `trusted` | `--trusted` (required if `trustedOnly`) |
| `entrypoint` | Override parsed entrypoint |
## Compose with
- `hyper-pear-runtime-embed` — storage/corestore paths
- `hyper-bare-process-spawn` — child argv tracking
- `hyper-pear-applink-config``package.json` pear.* metadata
- `hyper-pear-trust-gate` — trusted keys
## Testing
```bash
npm install && npm test
```
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-entry-runner
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareEntryRunner } = require('../index.js')
async function main () {
const m = new HyperBareEntryRunner()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,121 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const b4a = require('b4a')
const crypto = require('hypercore-crypto')
const { assertId, classifyTarget, platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-entry-runner/v1'
/**
* Programmatic replacement for deprecated `pear run` — plans and tracks Bare/Pear
* app launches via pear-runtime-style entrypoints (path, file://, pear://).
*/
class HyperBareEntryRunner extends EventEmitter {
constructor (opts = {}) {
super()
this.baseDir = opts.baseDir || null
this.trustedOnly = opts.trustedOnly === true
this._runs = new Map()
this._stats = { planned: 0, started: 0, completed: 0 }
}
resolveTarget (target) {
if (target == null || String(target).length === 0) {
throw new Error('target required')
}
return classifyTarget(target)
}
planRun (target, args = [], flags = {}) {
const resolved = this.resolveTarget(target)
const runId = b4a.toString(crypto.hash(b4a.from(JSON.stringify({ target, t: Date.now() }))), 'hex').slice(0, 16)
const dev = !!(flags.dev || flags.development)
const plan = {
runId,
resolved,
args: [...args],
flags: { ...flags, dev },
entrypoint: this._entrypointFor(resolved, flags),
runtimeArgv: this._runtimeArgv(resolved, args, flags),
mode: dev ? 'dev' : 'production',
preflight: !!flags.preflight,
trusted: flags.trusted !== false,
plannedAt: Date.now()
}
if (this.trustedOnly && !plan.trusted) {
throw new Error('trusted flag required when trustedOnly is enabled')
}
this._runs.set(runId, { ...plan, status: 'planned', exitCode: null })
this._stats.planned++
this.emit('plan', plan)
return plan
}
_entrypointFor (resolved, flags) {
if (resolved.kind === 'pear-link') {
const sub = resolved.href.slice(`pear://${resolved.key}`.length)
return sub.startsWith('/') ? sub.slice(1) : (flags.entrypoint || 'index.js')
}
if (resolved.kind === 'file') return flags.entrypoint || 'index.js'
return flags.entrypoint || resolved.path
}
_runtimeArgv (resolved, args, flags) {
const argv = ['run']
if (flags.dev) argv.push('--dev')
if (flags.preflight) argv.push('--preflight')
if (flags.trusted) argv.push('--trusted')
if (resolved.kind === 'pear-link') argv.push(resolved.href)
else if (resolved.kind === 'file') argv.push(resolved.href)
else argv.push(resolved.path)
return [...argv, ...args]
}
startRun (runId) {
const run = this._runs.get(assertId(runId, 'runId'))
if (!run) throw new Error(`run not found: ${runId}`)
if (run.status === 'running') return run
run.status = 'running'
run.startedAt = Date.now()
this._stats.started++
this.emit('start', run)
return run
}
completeRun (runId, exitCode = 0) {
const run = this._runs.get(assertId(runId, 'runId'))
if (!run) return false
run.status = 'completed'
run.exitCode = exitCode | 0
run.endedAt = Date.now()
this._stats.completed++
this.emit('complete', run)
return true
}
getRun (runId) {
return this._runs.get(assertId(runId, 'runId')) || null
}
listRuns (status = null) {
const all = [...this._runs.values()]
if (!status) return all
return all.filter((r) => r.status === status)
}
getStats () {
return platformStats(this._stats, PROTOCOL, {
active: this.listRuns('running').length,
runs: this._runs.size
})
}
async ready () { return this }
async close () {
this._runs.clear()
this.emit('closed')
}
}
module.exports = { HyperBareEntryRunner, HyperP2PBareEntryRunner: HyperBareEntryRunner, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-entry-runner",
"version": "0.3.1",
"description": "Programmatic pear run replacement for Bare CLI apps.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,25 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareEntryRunner, PROTOCOL } = require('../index.js')
test('exports', (t) => {
t.ok(HyperBareEntryRunner)
t.is(PROTOCOL, 'bare-entry-runner/v1')
})
test('plan pear run replacement', async (t) => {
const r = new HyperBareEntryRunner()
const plan = r.planRun('pear://myapp/index.js', ['--foo'], { dev: true, trusted: true })
t.is(plan.resolved.kind, 'pear-link')
t.ok(plan.runtimeArgv.includes('--dev'))
r.startRun(plan.runId)
t.ok(r.completeRun(plan.runId, 0))
await r.close()
})
test('file and path targets', async (t) => {
const r = new HyperBareEntryRunner()
const f = r.planRun('file:///tmp/app', [], { trusted: true })
t.is(f.resolved.kind, 'file')
await r.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-headless-ui
**Protocol:** `bare-headless-ui/v1`
Headless Pearend with optional UI worker. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-bare-headless-ui
**Protocol:** `bare-headless-ui/v1` · **Export:** `{ HyperBareHeadlessUi, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-headless-ui
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareHeadlessUi } = require('../index.js')
async function main () {
const m = new HyperBareHeadlessUi()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,84 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { assertId, platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-headless-ui/v1'
/**
* Models Pear's headless Pearend + optional UI worker architecture
* (entrypoint spawns UI over pipe when configured).
*/
class HyperBareHeadlessUi extends EventEmitter {
constructor (opts = {}) {
super()
this.uiEnabled = opts.uiEnabled === true
this._backend = null
this._ui = null
this._pipe = null
this._stats = { starts: 0, uiSpawns: 0 }
}
startBackend (entrypoint, meta = {}) {
this._backend = {
entrypoint: String(entrypoint),
meta: meta || {},
startedAt: Date.now(),
role: 'pearend'
}
this._stats.starts++
this.emit('backend', this._backend)
return this._backend
}
attachUi (uiEntry, opts = {}) {
if (!this._backend) throw new Error('startBackend first')
this._ui = {
entrypoint: String(uiEntry),
opts: opts || {},
role: 'ui',
spawnedAt: Date.now()
}
this._pipe = { id: String(Date.now()), open: true }
this._stats.uiSpawns++
this.emit('ui-spawn', { backend: this._backend.entrypoint, ui: this._ui.entrypoint })
return { backend: this._backend, ui: this._ui, pipe: this._pipe }
}
sendToUi (channel, payload) {
if (!this._pipe || !this._pipe.open) return false
this.emit('to-ui', { channel, payload })
return true
}
sendToBackend (channel, payload) {
if (!this._pipe || !this._pipe.open) return false
this.emit('to-backend', { channel, payload })
return true
}
teardown () {
if (this._pipe) this._pipe.open = false
this._ui = null
this._backend = null
this._pipe = null
this.emit('teardown')
}
snapshot () {
return {
uiEnabled: this.uiEnabled,
backend: this._backend,
ui: this._ui,
pipeOpen: !!(this._pipe && this._pipe.open)
}
}
getStats () {
return platformStats(this._stats, PROTOCOL, this.snapshot())
}
async ready () { return this }
async close () { this.teardown(); this.emit('closed') }
}
module.exports = { HyperBareHeadlessUi, HyperP2PBareHeadlessUi: HyperBareHeadlessUi, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-headless-ui",
"version": "0.0.0-scaffold",
"description": "Headless Pearend with optional UI worker.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,12 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareHeadlessUi } = require('../index.js')
test('backend and ui pipe', async (t) => {
const h = new HyperBareHeadlessUi({ uiEnabled: true })
h.startBackend('index.js')
h.attachUi('ui.js')
t.ok(h.sendToUi('ready', {}))
h.teardown()
await h.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-import-map
**Protocol:** `bare-import-map/v1`
package.json imports map for Bare. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-bare-import-map
**Protocol:** `bare-import-map/v1` · **Export:** `{ HyperBareImportMap, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-import-map
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareImportMap } = require('../index.js')
async function main () {
const m = new HyperBareImportMap()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,45 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-import-map/v1'
class HyperBareImportMap extends EventEmitter {
constructor (opts = {}) {
super()
this._imports = {}
this._stats = { loaded: 0, resolved: 0 }
}
loadFromPackage (pkg) {
if (!pkg || typeof pkg !== 'object') throw new Error('package object required')
this._imports = { ...(pkg.imports || {}) }
this._stats.loaded++
this.emit('load', { count: Object.keys(this._imports).length })
return this._imports
}
resolve (specifier) {
const hit = this._imports[specifier]
if (!hit) return null
const target = typeof hit === 'string' ? hit : hit.default || hit.bare || null
this._stats.resolved++
return target
}
map () { return { ...this._imports } }
set (specifier, target) {
this._imports[String(specifier)] = target
return target
}
getStats () {
return platformStats(this._stats, PROTOCOL, { entries: Object.keys(this._imports).length })
}
async ready () { return this }
async close () { this._imports = {}; this.emit('closed') }
}
module.exports = { HyperBareImportMap, HyperP2PBareImportMap: HyperBareImportMap, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-import-map",
"version": "0.0.0-scaffold",
"description": "package.json imports map for Bare.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,10 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareImportMap } = require('../index.js')
test('imports map', async (t) => {
const m = new HyperBareImportMap()
m.loadFromPackage({ imports: { fs: { bare: 'bare-fs' } } })
t.is(m.resolve('fs'), 'bare-fs')
await m.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-process-spawn
**Protocol:** `bare-process-spawn/v1`
Track Bare runtime child spawn plans. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-bare-process-spawn
**Protocol:** `bare-process-spawn/v1` · **Export:** `{ HyperBareProcessSpawn, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-process-spawn
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareProcessSpawn } = require('../index.js')
async function main () {
const m = new HyperBareProcessSpawn()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,53 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { assertId, platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-process-spawn/v1'
class HyperBareProcessSpawn extends EventEmitter {
constructor (opts = {}) {
super()
this.runtimeBin = opts.runtimeBin || 'bare'
this._children = new Map()
this._stats = { spawned: 0, exited: 0 }
}
spawnPlan (plan) {
if (!plan || !plan.runtimeArgv) throw new Error('plan with runtimeArgv required')
const id = plan.runId || String(Date.now())
const child = {
id,
argv: [this.runtimeBin, ...plan.runtimeArgv],
status: 'spawned',
pid: null,
spawnedAt: Date.now(),
exitCode: null
}
this._children.set(id, child)
this._stats.spawned++
this.emit('spawn', child)
return child
}
markExit (id, exitCode = 0) {
const c = this._children.get(assertId(id))
if (!c) return false
c.status = 'exited'
c.exitCode = exitCode | 0
c.endedAt = Date.now()
this._stats.exited++
this.emit('exit', c)
return true
}
listChildren () { return [...this._children.values()] }
getStats () {
return platformStats(this._stats, PROTOCOL, { children: this._children.size })
}
async ready () { return this }
async close () { this._children.clear(); this.emit('closed') }
}
module.exports = { HyperBareProcessSpawn, HyperP2PBareProcessSpawn: HyperBareProcessSpawn, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-process-spawn",
"version": "0.0.0-scaffold",
"description": "Track Bare runtime child spawn plans.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,11 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareProcessSpawn } = require('../index.js')
test('spawn plan', async (t) => {
const s = new HyperBareProcessSpawn()
const child = s.spawnPlan({ runId: 'r1', runtimeArgv: ['run', 'file:///app'] })
t.ok(child.argv.length >= 2)
t.ok(s.markExit('r1', 0))
await s.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-bare-target-matrix
**Protocol:** `bare-target-matrix/v1`
Cross-platform build target matrix. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-bare-target-matrix
**Protocol:** `bare-target-matrix/v1` · **Export:** `{ HyperBareTargetMatrix, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-bare-target-matrix
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperBareTargetMatrix } = require('../index.js')
async function main () {
const m = new HyperBareTargetMatrix()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,54 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'bare-target-matrix/v1'
const DEFAULT_TARGETS = [
{ id: 'darwin-arm64', os: 'darwin', arch: 'arm64' },
{ id: 'darwin-x64', os: 'darwin', arch: 'x64' },
{ id: 'linux-arm64', os: 'linux', arch: 'arm64' },
{ id: 'linux-x64', os: 'linux', arch: 'x64' },
{ id: 'android-arm64', os: 'android', arch: 'arm64' },
{ id: 'ios-arm64', os: 'ios', arch: 'arm64' }
]
class HyperBareTargetMatrix extends EventEmitter {
constructor (opts = {}) {
super()
this._targets = [...(opts.targets || DEFAULT_TARGETS)]
this.host = opts.host || 'darwin-arm64'
this._stats = { selects: 0 }
}
list () { return [...this._targets] }
select (id) {
const t = this._targets.find((x) => x.id === id)
if (!t) throw new Error(`unknown target: ${id}`)
this.host = t.id
this._stats.selects++
this.emit('select', t)
return t
}
current () {
return this._targets.find((x) => x.id === this.host) || null
}
artifactName (binary = 'pear-runtime') {
const t = this.current()
if (!t) return binary
const ext = t.os === 'darwin' || t.os === 'linux' ? '' : '.exe'
return `${binary}-${t.id}${ext}`
}
getStats () {
return platformStats(this._stats, PROTOCOL, { host: this.host, count: this._targets.length })
}
async ready () { return this }
async close () { this.emit('closed') }
}
module.exports = { HyperBareTargetMatrix, HyperP2PBareTargetMatrix: HyperBareTargetMatrix, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-bare-target-matrix",
"version": "0.0.0-scaffold",
"description": "Cross-platform build target matrix.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,10 @@
require('bare-process/global')
const test = require('brittle')
const { HyperBareTargetMatrix } = require('../index.js')
test('select target', async (t) => {
const m = new HyperBareTargetMatrix()
m.select('linux-arm64')
t.ok(m.artifactName().includes('linux-arm64'))
await m.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.3.1
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-pear-applink-config
**Protocol:** `pear-applink-config/v1`
package.json pear.* config loader. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-pear-applink-config
**Protocol:** `pear-applink-config/v1` · **Export:** `{ HyperPearApplinkConfig, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-pear-applink-config
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperPearApplinkConfig } = require('../index.js')
async function main () {
const m = new HyperPearApplinkConfig()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,62 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'pear-applink-config/v1'
class HyperPearApplinkConfig extends EventEmitter {
constructor (opts = {}) {
super()
this._config = null
this._stats = { loaded: 0 }
}
load (pkg) {
if (!pkg || typeof pkg !== 'object') throw new Error('package.json object required')
const pear = pkg.pear || {}
this._config = {
name: pkg.name,
main: pkg.main || pear.main || 'index.js',
applink: pear.applink || pear.link || null,
links: pear.links || {},
stage: pear.stage || {},
pre: pear.pre || null,
flags: pear.flags || {}
}
this._stats.loaded++
this.emit('load', this._config)
return this._config
}
get (path) {
if (!this._config) return null
const parts = String(path).split('.')
let cur = this._config
for (const p of parts) {
if (cur == null) return null
cur = cur[p]
}
return cur
}
entrypoint () {
return this._config ? this._config.main : null
}
linkOverrides () {
return this._config ? { ...this._config.links } : {}
}
hasPreApp () {
return !!(this._config && this._config.pre)
}
getStats () {
return platformStats(this._stats, PROTOCOL, { loaded: !!this._config })
}
async ready () { return this }
async close () { this._config = null; this.emit('closed') }
}
module.exports = { HyperPearApplinkConfig, HyperP2PPearApplinkConfig: HyperPearApplinkConfig, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-pear-applink-config",
"version": "0.3.1",
"description": "package.json pear.* config loader.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,11 @@
require('bare-process/global')
const test = require('brittle')
const { HyperPearApplinkConfig } = require('../index.js')
test('load package pear config', async (t) => {
const c = new HyperPearApplinkConfig()
c.load({ name: 'demo', main: 'boot.js', pear: { applink: 'pear://x', links: { a: 'b' } } })
t.is(c.entrypoint(), 'boot.js')
t.is(c.get('links').a, 'b')
await c.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-pear-channel-registry
**Protocol:** `pear-channel-registry/v1`
Channel alias registry and touch. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-pear-channel-registry
**Protocol:** `pear-channel-registry/v1` · **Export:** `{ HyperPearChannelRegistry, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-pear-channel-registry
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperPearChannelRegistry } = require('../index.js')
async function main () {
const m = new HyperPearChannelRegistry()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,46 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { assertId, platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'pear-channel-registry/v1'
class HyperPearChannelRegistry extends EventEmitter {
constructor (opts = {}) {
super()
this._channels = new Map()
this._stats = { registered: 0 }
}
register (name, meta = {}) {
const n = assertId(name, 'name')
if (this._channels.has(n)) throw new Error('channel exists')
const ch = { name: n, key: meta.key || null, alias: meta.alias || null, touchedAt: Date.now(), meta }
this._channels.set(n, ch)
this._stats.registered++
this.emit('register', ch)
return ch
}
touch (name) {
const ch = this._channels.get(assertId(name))
if (!ch) return null
ch.touchedAt = Date.now()
this.emit('touch', ch)
return ch
}
get (name) {
return this._channels.get(assertId(name)) || null
}
list () { return [...this._channels.values()] }
getStats () {
return platformStats(this._stats, PROTOCOL, { channels: this._channels.size })
}
async ready () { return this }
async close () { this._channels.clear(); this.emit('closed') }
}
module.exports = { HyperPearChannelRegistry, HyperP2PPearChannelRegistry: HyperPearChannelRegistry, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-pear-channel-registry",
"version": "0.0.0-scaffold",
"description": "Channel alias registry and touch.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,10 @@
require('bare-process/global')
const test = require('brittle')
const { HyperPearChannelRegistry } = require('../index.js')
test('register touch', async (t) => {
const c = new HyperPearChannelRegistry()
c.register('main', { key: 'abc' })
t.ok(c.touch('main'))
await c.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-pear-deep-link
**Protocol:** `pear-deep-link/v1`
Deep-link entrypoint routing. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-pear-deep-link
**Protocol:** `pear-deep-link/v1` · **Export:** `{ HyperPearDeepLink, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.
@@ -0,0 +1,3 @@
# Architecture: hyper-pear-deep-link
Pear/Bare platform module. Replaces or complements deprecated `pear run` flows via embeddable `pear-runtime`.
@@ -0,0 +1,9 @@
require('bare-process/global')
const { HyperPearDeepLink } = require('../index.js')
async function main () {
const m = new HyperPearDeepLink()
await m.ready()
console.log(m.getStats())
await m.close()
}
main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,51 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const { classifyTarget, LINK_PREFIX, platformStats } = require('../../_shared/pear-platform-base.js')
const PROTOCOL = 'pear-deep-link/v1'
class HyperPearDeepLink extends EventEmitter {
constructor (opts = {}) {
super()
this.defaultEntry = opts.defaultEntry || 'index.js'
this._stats = { opened: 0 }
}
open (link) {
const c = classifyTarget(link)
let entrypoint = this.defaultEntry
let route = '/'
if (c.kind === 'pear-link') {
const rest = c.href.slice(LINK_PREFIX.length)
const slash = rest.indexOf('/')
if (slash >= 0) {
const sub = rest.slice(slash + 1)
const parts = sub.split('/')
entrypoint = parts[0] || this.defaultEntry
route = '/' + parts.slice(1).join('/')
}
} else if (c.kind === 'file' || c.kind === 'absolute-path') {
entrypoint = c.path.split('/').pop() || this.defaultEntry
}
const out = { link, entrypoint, route, resolved: c, at: Date.now() }
this._stats.opened++
this.emit('open', out)
return out
}
build (key, entrypoint, route = '/') {
let href = `${LINK_PREFIX}${key}`
if (entrypoint) href += `/${entrypoint}`
if (route && route !== '/') href += route.startsWith('/') ? route : `/${route}`
return href
}
getStats () {
return platformStats(this._stats, PROTOCOL, {})
}
async ready () { return this }
async close () { this.emit('closed') }
}
module.exports = { HyperPearDeepLink, HyperP2PPearDeepLink: HyperPearDeepLink, PROTOCOL }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
{
"name": "hyper-pear-deep-link",
"version": "0.0.0-scaffold",
"description": "Deep-link entrypoint routing.",
"main": "index.js",
"type": "commonjs",
"license": "Apache-2.0",
"scripts": { "test": "brittle-bare test/test.js" },
"dependencies": {
"bare-events": "^2.8.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": { "bare": ">=1.0.0" },
"devDependencies": { "brittle": "^3.0.0" },
"imports": {
"process": { "bare": "bare-process", "default": "process" },
"events": { "bare": "bare-events", "default": "events" }
}
}
@@ -0,0 +1,10 @@
require('bare-process/global')
const test = require('brittle')
const { HyperPearDeepLink } = require('../index.js')
test('open deep link', async (t) => {
const d = new HyperPearDeepLink()
const o = d.open('pear://key/ui/page.js/sub')
t.ok(o.entrypoint)
await d.close()
})
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0-scaffold
- Initial Pear platform module.
@@ -0,0 +1,9 @@
# hyper-pear-detached-registry
**Protocol:** `pear-detached-registry/v1`
Detached app instance wake registry. See [`docs/api.md`](docs/api.md).
```bash
npm install && npm test
```
@@ -0,0 +1,5 @@
# API: hyper-pear-detached-registry
**Protocol:** `pear-detached-registry/v1` · **Export:** `{ HyperPearDetachedRegistry, PROTOCOL }`
See [`index.js`](../index.js) for methods and `getStats()`.

Some files were not shown because too many files have changed in this diff Show More