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:
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
@@ -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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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 }
|
||||||
+1286
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
Reference in New Issue
Block a user