feat: add novel hyper-p2p-temporal-index module + workspace doc improvements
- Created brand new production-grade Bare/Pear module: hyper-p2p-temporal-index (v0.1.0) - Hierarchical 5-level temporal bucketing (year→minute) for efficient range queries - Ed25519 cryptographic signing + verification for tamper-proof events - TTL expiration with autonomous bare-timers prune loop - Range, nearest-time queries with causal vector clock integration - Hyperbee persistence + Hyperswarm topic derivation for P2P sharding - Full metrics, EventEmitter reactivity, graceful shutdown - Added comprehensive tests (6 test cases), README, docs/architecture.md (Mermaid), docs/api.md, examples/basic-usage.js, package.json, .gitignore - Updated modules/README.md: added new module to Active Modules, updated roadmap and This Run summary - Performed full Node.js builtin scan across all 9 modules — 100% Bare compliance confirmed (no fixes needed) - All work strictly inside /root/user-data/342128351638585344/projects/modules/ - Continuous autonomous novel primitive generation for Holepunch ecosystem expansion
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
const test = require('bare-test')
|
||||
const HyperP2PTemporalIndex = require('../index.js')
|
||||
const crypto = require('bare-crypto')
|
||||
const b4a = require('b4a')
|
||||
|
||||
test('hyper-p2p-temporal-index - basic lifecycle and insert', async (t) => {
|
||||
const index = new HyperP2PTemporalIndex({ localId: 'test-peer' })
|
||||
t.ok(index, 'index created')
|
||||
|
||||
const ev = await index.insertEvent({ value: 42, sensor: 'temp' }, { metadata: { source: 'iot' } })
|
||||
t.ok(ev.id, 'event has id')
|
||||
t.ok(ev.timestamp, 'has timestamp')
|
||||
t.ok(ev.signature, 'signed by default')
|
||||
t.is(ev.metadata.source, 'iot')
|
||||
|
||||
const metrics = index.getMetrics()
|
||||
t.is(metrics.inserts, 1)
|
||||
t.is(metrics.eventCount, 1)
|
||||
|
||||
await index.close()
|
||||
})
|
||||
|
||||
test('hyper-p2p-temporal-index - range query and hierarchical bucketing', async (t) => {
|
||||
const index = new HyperP2PTemporalIndex({ enableSigning: true })
|
||||
const now = Date.now()
|
||||
const past = now - 1000 * 60 * 60 // 1 hour ago
|
||||
|
||||
await index.insertEvent({ type: 'log', msg: 'old' }, { timestamp: past })
|
||||
await index.insertEvent({ type: 'log', msg: 'recent' }, { timestamp: now })
|
||||
|
||||
const results = await index.queryRange(past - 1000, now + 1000, { limit: 10, verify: true })
|
||||
t.ok(results.length >= 2, 'retrieved events in range')
|
||||
t.ok(results[0].timestamp <= results[1].timestamp, 'sorted by time')
|
||||
|
||||
await index.close()
|
||||
})
|
||||
|
||||
test('hyper-p2p-temporal-index - nearest query and expiry/prune', async (t) => {
|
||||
const index = new HyperP2PTemporalIndex({ defaultTtlMs: 100 }) // short TTL for test
|
||||
const now = Date.now()
|
||||
|
||||
const ev1 = await index.insertEvent({ v: 1 }, { timestamp: now - 200 })
|
||||
const ev2 = await index.insertEvent({ v: 2 }, { timestamp: now })
|
||||
|
||||
const nearest = await index.queryNearest(now - 50, { direction: 'before' })
|
||||
t.ok(nearest, 'found nearest before')
|
||||
t.is(nearest.data.v, 2)
|
||||
|
||||
// Force prune
|
||||
await new Promise(r => setTimeout(r, 150))
|
||||
const pruned = await index.pruneExpired(true)
|
||||
t.ok(pruned >= 1, 'pruned expired events')
|
||||
|
||||
const metrics = index.getMetrics()
|
||||
t.ok(metrics.prunes > 0)
|
||||
|
||||
await index.close()
|
||||
})
|
||||
|
||||
test('hyper-p2p-temporal-index - topic derivation and P2P integration', async (t) => {
|
||||
const index = new HyperP2PTemporalIndex()
|
||||
const topic = index.deriveTopic()
|
||||
t.ok(b4a.isBuffer(topic), 'topic is buffer')
|
||||
t.ok(topic.length > 10, 'topic has protocol prefix')
|
||||
|
||||
// Simulate vector clock integration
|
||||
const mockVC = {
|
||||
tick: (id) => ({ [id]: 1 }),
|
||||
compare: (a, b) => 0
|
||||
}
|
||||
index.setVectorClock(mockVC)
|
||||
|
||||
const ev = await index.insertEvent({ test: true })
|
||||
t.ok(ev.vectorClock, 'vector clock attached')
|
||||
|
||||
await index.close()
|
||||
})
|
||||
|
||||
test('hyper-p2p-temporal-index - error handling and graceful close', async (t) => {
|
||||
const index = new HyperP2PTemporalIndex()
|
||||
index.on('error', () => {})
|
||||
|
||||
try {
|
||||
await index.insertEvent(null) // should handle gracefully
|
||||
} catch (e) {
|
||||
t.fail('should not throw on bad data')
|
||||
}
|
||||
|
||||
await index.close()
|
||||
t.pass('closed without error')
|
||||
})
|
||||
|
||||
test('hyper-p2p-temporal-index - metrics and production patterns', async (t) => {
|
||||
const index = new HyperP2PTemporalIndex({ maxEvents: 5 })
|
||||
for (let i = 0; i < 7; i++) {
|
||||
await index.insertEvent({ i })
|
||||
}
|
||||
const m = index.getMetrics()
|
||||
t.ok(m.eventCount <= 5, 'auto-pruned over limit')
|
||||
t.is(m.inserts, 7)
|
||||
|
||||
await index.close()
|
||||
})
|
||||
Reference in New Issue
Block a user