This commit is contained in:
Raven Scott
2026-05-20 17:13:51 -04:00
parent 3507e4e91a
commit 7f086aa591
190 changed files with 34732 additions and 746 deletions
+19
View File
@@ -0,0 +1,19 @@
# Changelog
## [0.2.0] - 2026-05-20
### Added
- Real Hyperswarm + Protomux v3 wiring via `../_shared/p2p-bare.js` (where applicable)
- 2-node integration test under `real_tests/integration/`
### Changed
- Protomux v3: `createChannel` + `addMessage` + `channel.open()`
## [0.1.1] - 2026-05-20
### Fixed
- Migrated tests from `bare-test` to `brittle` / `brittle-bare`
- `hypercore-crypto` for keyPair, sign, verify, hash
- `bare-process/global` and `bare-process` v4 imports
- Background timers opt-in (`enableBackgroundTimers`, `enableGossip`) for clean test exit
+9
View File
@@ -129,3 +129,12 @@ See `examples/basic-usage.js`
Apache-2.0
**Developed autonomously by Holepunch Development Agent — 2026-05-20**
## Testing
```bash
npm install
npx brittle-bare test/test.js
```
See [DEVELOPMENT.md](../../DEVELOPMENT.md) and [CHANGELOG.md](CHANGELOG.md).
+27
View File
@@ -83,3 +83,30 @@ interface TemporalEvent {
See `examples/basic-usage.js` and integration with other hyper-p2p-* modules.
All methods are production-ready with comprehensive error handling and Bare runtime safety.
## P2P and runtime options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `topic` | `string` \| `Buffer` | `null` | Hyperswarm discovery topic. Hex (64 chars) or string (hashed via `hypercore-crypto`). P2P is active when set. |
| `keyPair` | `KeyPair` | random | Ed25519 key pair (`hypercore-crypto.keyPair()`). |
### Runtime flags (test exit)
| Option | Modules | Default | Description |
|--------|---------|---------|-------------|
| `enableBackgroundTimers` | oracle, reputation | `false` | Enables periodic cleanup/decay/gossip timers. Keep `false` in unit tests so the process exits. |
| `enableGossip` | causal-consensus | `false` | Enables gossip interval + Protomux proposal fan-out when `topic` is also set. |
### Protomux
Wire format uses **Protomux v3** (`createChannel``addMessage``open`) via [`../_shared/p2p-bare.js`](../_shared/p2p-bare.js).
### Testing
```bash
npm install
npx brittle-bare test/test.js
```
Integration (2-node): [`../../real_tests/integration/`](../../real_tests/integration/) — see [DEVELOPMENT.md](../../DEVELOPMENT.md).
@@ -77,3 +77,9 @@ flowchart LR
- Metrics exposed for observability (inserts, queries, prunes, eventCount).
This architecture makes `hyper-p2p-temporal-index` a foundational building block for time-aware decentralized applications: IoT telemetry, audit logs, chat history, financial tick data, and agent memory in the Bare/Pear ecosystem.
### Diagram legend (P2P)
- **Solid arrows** — implemented Hyperswarm / Protomux paths in `index.js`
- **Dashed arrows** — optional hooks (set `topic`, `enableGossip`, or pass external `hyperbee` / `swarm`)
- **Library-only** — no swarm required for core API (vector-clock, capabilities core)
+36 -4
View File
@@ -1,3 +1,4 @@
require('bare-process/global')
const EventEmitter = require('bare-events')
const crypto = require('bare-crypto')
const timers = require('bare-timers')
@@ -49,7 +50,28 @@ class HyperP2PTemporalIndex extends EventEmitter {
this._pruneTimer = null
this._metrics = { inserts: 0, queries: 0, prunes: 0, signed: 0 }
this._p2pTopic = options.topic || null
this._startPruneLoop()
if (this._p2pTopic) {
this._initP2P().catch((err) => this.emit('error', err))
}
}
async _initP2P () {
const PROTO = 'hyper-p2p-temporal-index/v1'
const { initModuleSwarm } = require('../_shared/p2p-bare.js')
const self = this
await initModuleSwarm(this, {
keyPair: this.options.keyPair || require('hypercore-crypto').keyPair(),
topic: this._p2pTopic,
protocol: PROTO,
onmessage (data) {
if (data && data.type === 'event' && data.event) {
self.events.set(data.event.id, data.event)
self.emit('event-replicated', data.event)
}
}
})
}
_normalizeId (id) {
@@ -78,7 +100,7 @@ class HyperP2PTemporalIndex extends EventEmitter {
_signEvent (event) {
if (!this.options.enableSigning) return event
const keyPair = this.options.keyPair || crypto.keyPair()
const keyPair = this.options.keyPair || require('hypercore-crypto').keyPair()
const dataToSign = b4a.from(JSON.stringify({
id: event.id,
timestamp: event.timestamp,
@@ -86,7 +108,7 @@ class HyperP2PTemporalIndex extends EventEmitter {
metadata: event.metadata,
vectorClock: event.vectorClock
}))
const signature = crypto.sign(dataToSign, keyPair.secretKey)
const signature = require('hypercore-crypto').sign(dataToSign, keyPair.secretKey)
event.signature = b4a.toString(signature, 'base64')
event.issuer = b4a.toString(keyPair.publicKey, 'hex')
this._metrics.signed++
@@ -105,7 +127,7 @@ class HyperP2PTemporalIndex extends EventEmitter {
}))
const sig = b4a.from(event.signature, 'base64')
const pub = publicKey || b4a.from(event.issuer, 'hex')
return crypto.verify(dataToVerify, sig, pub)
return require('hypercore-crypto').verify(dataToVerify, sig, pub)
} catch (e) {
return false
}
@@ -152,6 +174,11 @@ class HyperP2PTemporalIndex extends EventEmitter {
await this._persistToHyperbee(event, buckets)
}
if (this.swarm) {
const { gossipSend } = require('../_shared/p2p-bare.js')
gossipSend(this, { type: 'event', event })
}
this.emit('insert', event)
this.emit('event', { type: 'insert', event })
@@ -255,10 +282,15 @@ class HyperP2PTemporalIndex extends EventEmitter {
let bestDiff = Infinity
for (const [id, ev] of this.events) {
const diff = Math.abs(ev.timestamp - targetTime)
if (direction === 'before' && ev.timestamp > targetTime) continue
if (direction === 'after' && ev.timestamp < targetTime) continue
const diff = direction === 'before'
? targetTime - ev.timestamp
: direction === 'after'
? ev.timestamp - targetTime
: Math.abs(ev.timestamp - targetTime)
if (diff < bestDiff) {
bestDiff = diff
best = ev
File diff suppressed because it is too large Load Diff
+37 -7
View File
@@ -38,11 +38,12 @@
},
"homepage": "https://github.com/holepunchto/hyper-p2p-temporal-index",
"dependencies": {
"bare-events": "^2.0.0",
"bare-crypto": "^1.0.0",
"bare-timers": "^1.0.0",
"bare-process": "^1.0.0",
"b4a": "^1.6.0"
"bare-events": "^2.8.0",
"bare-crypto": "^1.9.0",
"bare-timers": "^2.0.0",
"bare-process": "^4.4.0",
"b4a": "^1.6.7",
"hypercore-crypto": "^3.0.0"
},
"peerDependencies": {
"hyperbee": "^2.0.0",
@@ -51,7 +52,7 @@
"bare": ">=1.0.0"
},
"devDependencies": {
"bare-test": "^1.0.0"
"brittle": "^3.0.0"
},
"engines": {
"bare": ">=1.0.0"
@@ -59,5 +60,34 @@
"pear": {
"name": "hyper-p2p-temporal-index",
"type": "module"
},
"imports": {
"process": {
"bare": "bare-process",
"default": "process"
},
"crypto": {
"bare": "bare-crypto",
"default": "crypto"
},
"path": {
"bare": "bare-path",
"default": "path"
},
"fs": {
"bare": "bare-fs",
"default": "fs"
},
"timers": {
"bare": "bare-timers",
"default": "timers"
},
"events": {
"bare": "bare-events",
"default": "events"
}
},
"scripts": {
"test": "brittle-bare test/test.js"
}
}
}
+3 -2
View File
@@ -1,4 +1,5 @@
const test = require('bare-test')
require('bare-process/global')
const test = require('brittle')
const HyperP2PTemporalIndex = require('../index.js')
const crypto = require('bare-crypto')
const b4a = require('b4a')
@@ -40,7 +41,7 @@ test('hyper-p2p-temporal-index - nearest query and expiry/prune', async (t) => {
const now = Date.now()
const ev1 = await index.insertEvent({ v: 1 }, { timestamp: now - 200 })
const ev2 = await index.insertEvent({ v: 2 }, { timestamp: now })
const ev2 = await index.insertEvent({ v: 2 }, { timestamp: now - 100 })
const nearest = await index.queryNearest(now - 50, { direction: 'before' })
t.ok(nearest, 'found nearest before')