Add isEmpty() helpers across all modules with clearable state.

Seventh expansion pass: domain-specific isEmpty() after moduleSnapshot on every module that has clearAll(), using existing count/snapshot helpers (async variants for temporal, spatial, semantic-vector, and reactive-state indexes).

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-21 04:58:23 -04:00
co-authored by Cursor
parent f509060710
commit b3c6059598
205 changed files with 857 additions and 0 deletions
@@ -462,6 +462,10 @@ class HyperP2PAgentMemory extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.memoryCount() === 0
}
async storeMemoryBatch (entries) { async storeMemoryBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
const out = [] const out = []
@@ -467,6 +467,10 @@ class HyperP2PTaskOrchestrator extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.tasks.size === 0
}
getStats () { getStats () {
const counts = this.taskCounts() const counts = this.taskCounts()
return { return {
@@ -197,6 +197,10 @@ class HyperP2PWorkflowGraph extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.nodeCount() === 0
}
nodeIds () { nodeIds () {
return [...this._nodes.keys()] return [...this._nodes.keys()]
} }
@@ -176,6 +176,10 @@ class HyperP2PCollabRoom extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.roomCount() === 0
}
_onGossip (data) { _onGossip (data) {
if (!data || !data.type) return if (!data || !data.type) return
this._stats.gossipIn++ this._stats.gossipIn++
@@ -122,6 +122,10 @@ class HyperP2PCursorPresence extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.cursorCount() === 0
}
_onGossip (data) { _onGossip (data) {
if (!data) return if (!data) return
this._stats.gossipIn++ this._stats.gossipIn++
@@ -116,6 +116,10 @@ class HyperP2PDocumentLineLock extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.lockCount() === 0
}
acquireBatch (entries) { acquireBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.acquire(e.docId, e.line)) return entries.map((e) => this.acquire(e.docId, e.line))
@@ -114,6 +114,10 @@ class HyperP2PWhiteboardOp extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.opCount() === 0
}
applyBatch (entries) { applyBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.apply(e.roomId, e.op)) return entries.map((e) => this.apply(e.roomId, e.op))
@@ -149,6 +149,10 @@ class HyperP2PAuctionGossip extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().auctions === 0
}
openAuctionBatch (entries) { openAuctionBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.openAuction(e.auctionId, e.meta || {})) return entries.map((e) => this.openAuction(e.auctionId, e.meta || {}))
@@ -118,6 +118,10 @@ class HyperP2PCreditLedger extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.accountCount() === 0
}
_apply (accountId, delta, kind, reason) { _apply (accountId, delta, kind, reason) {
assertNonEmpty(accountId, 'accountId') assertNonEmpty(accountId, 'accountId')
const acct = this._accounts.get(accountId) const acct = this._accounts.get(accountId)
@@ -129,6 +129,10 @@ class HyperP2PMarketplaceListing extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().listings === 0
}
createListingBatch (entries) { createListingBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.createListing(e.listingId, e.listing)) return entries.map((e) => this.createListing(e.listingId, e.listing))
@@ -445,6 +445,10 @@ class HyperP2PCausalConsensus extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.proposals.size === 0 && this.decidedOrders.size === 0
}
async proposeBatch (entries) { async proposeBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
const out = [] const out = []
@@ -386,6 +386,10 @@ class HyperP2PDistributedLock extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.lockCount() === 0
}
async acquireBatch (entries) { async acquireBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
const out = [] const out = []
@@ -160,6 +160,10 @@ class HyperP2PLeaderLease extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return !this._leader && this.followerCount() === 0
}
_gossipSync () { _gossipSync () {
gossipSend(this, { gossipSend(this, {
type: 'leader-lease-sync', type: 'leader-lease-sync',
@@ -210,6 +210,10 @@ class HyperP2PQuorumPool extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.proposalCount() === 0
}
proposeBatch (payloads, opts = {}) { proposeBatch (payloads, opts = {}) {
if (!Array.isArray(payloads)) throw new Error('payloads array required') if (!Array.isArray(payloads)) throw new Error('payloads array required')
return payloads.map((payload) => this.propose(payload, opts)) return payloads.map((payload) => this.propose(payload, opts))
@@ -99,6 +99,10 @@ class HyperP2PRaftLite extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().logLength === 0
}
logEntryAt (index) { logEntryAt (index) {
return this._log[index] || null return this._log[index] || null
} }
@@ -279,6 +279,11 @@ class CapabilityManager extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.issued === 0 && s.received === 0 && s.revoked === 0
}
issueBatch (entries) { issueBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.issue(e.subjectPubKey, e.resource, e.actions, e.ttlMs)) return entries.map((e) => this.issue(e.subjectPubKey, e.resource, e.actions, e.ttlMs))
@@ -364,6 +364,10 @@ class HyperP2PPresence extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.peers.size <= 1
}
announceNow () { announceNow () {
this._broadcastPresence() this._broadcastPresence()
return this.getSelf() return this.getSelf()
@@ -160,6 +160,10 @@ class RPCServer extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.connectionCount() === 0 && this.pendingCount() === 0
}
connectionCount () { return this.connections.size } connectionCount () { return this.connections.size }
getStats () { getStats () {
@@ -97,6 +97,10 @@ class HyperP2PSessionBridge extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.pairCount() === 0
}
async createPairBatch (count = 1) { async createPairBatch (count = 1) {
const n = Math.max(1, count | 0) const n = Math.max(1, count | 0)
const out = [] const out = []
@@ -357,6 +357,10 @@ class HyperP2PVectorClock extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.peerCount() === 0
}
clearAll () { clearAll () {
const n = this.clock.size const n = this.clock.size
this.clock.clear() this.clock.clear()
@@ -97,6 +97,11 @@ class HyperP2PCompactCodecBridge extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this._stats
return s.encode === 0 && s.decode === 0 && s.frames === 0
}
getStats () { getStats () {
return { return {
...this._stats, ...this._stats,
@@ -129,6 +129,11 @@ class HyperP2PMessageEnvelope extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this._stats
return s.wrapped === 0 && s.unwrapped === 0 && s.encoded === 0 && s.decoded === 0 && s.failed === 0
}
getStats () { getStats () {
return { ...this._stats, protocol: PROTOCOL } return { ...this._stats, protocol: PROTOCOL }
} }
@@ -122,6 +122,10 @@ class HyperP2PSchemaValidator extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.listSchemas().length === 0
}
registerSchemaBatch (entries) { registerSchemaBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.register(e.name, e.schema)) return entries.map((e) => this.register(e.name, e.schema))
@@ -158,6 +158,10 @@ class HyperP2PWireRegistry extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this._codecs.size === 0 && this._protocols.size === 0
}
clearAll () { clearAll () {
const codecs = this.clearAllCodecs() const codecs = this.clearAllCodecs()
const protocols = this.unregisterAllProtocols() const protocols = this.unregisterAllProtocols()
@@ -149,6 +149,10 @@ class HyperP2PContradictionGraph extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this._claims.length === 0
}
async ready () { async ready () {
if (this.swarm || !this.topic) return this if (this.swarm || !this.topic) return this
await initModuleSwarm(this, { await initModuleSwarm(this, {
@@ -93,6 +93,10 @@ class HyperP2PEntropyBeacon extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().contributions === 0
}
contributionCount () { contributionCount () {
return this._contributions return this._contributions
} }
@@ -71,6 +71,10 @@ class HyperP2PEntropySpiral extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().samples.length === 0
}
sampleBatch (seeds) { sampleBatch (seeds) {
if (!Array.isArray(seeds)) throw new Error('seeds array required') if (!Array.isArray(seeds)) throw new Error('seeds array required')
return seeds.map((seed) => this.sampleEntropy(seed)) return seeds.map((seed) => this.sampleEntropy(seed))
@@ -128,6 +128,10 @@ class HyperP2PGravityWell extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().wells.length === 0
}
async ready () { async ready () {
if (this.swarm || !this.topic) return this if (this.swarm || !this.topic) return this
await initModuleSwarm(this, { await initModuleSwarm(this, {
@@ -112,6 +112,10 @@ class HyperP2PMemeticSpread extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().totalMemes === 0
}
_gossip (data) { _gossip (data) {
if (!this._peerMsgs) return if (!this._peerMsgs) return
gossipSend(this, data) gossipSend(this, data)
@@ -151,6 +151,11 @@ class HyperP2PMirrorRealm extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.realmA.length === 0 && s.realmB.length === 0
}
async ready () { async ready () {
if (this.swarm || !this.topic) return this if (this.swarm || !this.topic) return this
await initModuleSwarm(this, { await initModuleSwarm(this, {
@@ -130,6 +130,10 @@ class HyperP2PMyceliumPool extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().balances.length === 0
}
donateBatch (entries) { donateBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.donate(e.peerId, e.credits)) return entries.map((e) => this.donate(e.peerId, e.credits))
@@ -129,6 +129,10 @@ class HyperP2PParadoxClock extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().stamps.length === 0
}
stampBatch (eventIds, opts = {}) { stampBatch (eventIds, opts = {}) {
if (!Array.isArray(eventIds)) throw new Error('eventIds array required') if (!Array.isArray(eventIds)) throw new Error('eventIds array required')
return eventIds.map((id) => this.stamp(id, opts)) return eventIds.map((id) => this.stamp(id, opts))
@@ -105,6 +105,11 @@ class HyperP2PParadoxMerge extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.open === 0 && s.resolved === 0
}
branchBatch (entries) { branchBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.branch(e.id, e.value)) return entries.map((e) => this.branch(e.id, e.value))
@@ -116,6 +116,10 @@ class HyperP2PPhaseShiftClock extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return Object.keys(this.snapshot().peers).length === 0
}
shiftBatch (entries) { shiftBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.shift(e.phaseMs)) return entries.map((e) => this.shift(e.phaseMs))
@@ -126,6 +126,10 @@ class HyperP2PPheromoneTrail extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.trailCount() === 0
}
depositBatch (entries) { depositBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.deposit(e.pathId, e.strength, e.dest)) return entries.map((e) => this.deposit(e.pathId, e.strength, e.dest))
@@ -120,6 +120,10 @@ class HyperP2PSilenceProtocol extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.listAbsent().length === 0
}
async ready () { async ready () {
if (this.swarm || !this.topic) return this if (this.swarm || !this.topic) return this
await initModuleSwarm(this, { await initModuleSwarm(this, {
@@ -165,6 +165,10 @@ class HyperP2PTensionField extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().cells === 0
}
getStats () { getStats () {
return experimentalStats(this._stats, PROTOCOL, { return experimentalStats(this._stats, PROTOCOL, {
cells: this._field.size, cells: this._field.size,
@@ -164,6 +164,10 @@ class HyperP2PTimeCapsule extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().total === 0
}
sealBatch (entries) { sealBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.seal(e.payload, e.opts || {})) return entries.map((e) => this.seal(e.payload, e.opts || {}))
@@ -92,6 +92,10 @@ class HyperP2PVoidChannel extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().voids.length === 0
}
unsubscribeAll () { unsubscribeAll () {
const n = this._subs.size const n = this._subs.size
this._subs.clear() this._subs.clear()
@@ -111,6 +111,10 @@ class HyperP2PWhisperMesh extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().seen === 0
}
async ready () { async ready () {
if (this.swarm || !this.topic) return this if (this.swarm || !this.topic) return this
await initModuleSwarm(this, { await initModuleSwarm(this, {
@@ -118,6 +118,10 @@ class HyperP2PBloomGossip extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().size === 0
}
addBatch (keys) { addBatch (keys) {
if (!Array.isArray(keys)) throw new Error('keys array required') if (!Array.isArray(keys)) throw new Error('keys array required')
return keys.map((k) => this.add(k)) return keys.map((k) => this.add(k))
@@ -165,6 +165,10 @@ class HyperP2PFulltextLite extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().documents === 0
}
searchBatch (queries, mode = 'and') { searchBatch (queries, mode = 'and') {
if (!Array.isArray(queries)) throw new Error('queries array required') if (!Array.isArray(queries)) throw new Error('queries array required')
return queries.map((q) => this.search(q, mode)) return queries.map((q) => this.search(q, mode))
@@ -163,6 +163,10 @@ class HyperP2PGraphIndex extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().edges.length === 0
}
addEdgeBatch (edges) { addEdgeBatch (edges) {
if (!Array.isArray(edges)) throw new Error('edges array required') if (!Array.isArray(edges)) throw new Error('edges array required')
return edges.map((e) => this.addEdge(e.from, e.to)) return edges.map((e) => this.addEdge(e.from, e.to))
@@ -142,6 +142,10 @@ class HyperP2PInvertedIndex extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().documents === 0
}
indexBatch (entries) { indexBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.index(e.docId, e.terms)) return entries.map((e) => this.index(e.docId, e.terms))
@@ -656,6 +656,11 @@ class HyperP2PSemanticVectorIndex extends EventEmitter {
async moduleSnapshot () { async moduleSnapshot () {
return this.snapshot() return this.snapshot()
} }
async isEmpty () {
const s = await this.snapshot()
return s.vectorIds === 0
}
} }
module.exports = HyperP2PSemanticVectorIndex module.exports = HyperP2PSemanticVectorIndex
@@ -182,6 +182,11 @@ class HyperP2PSimilarityLsh extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.vectors === 0 && s.buckets === 0
}
getStats () { getStats () {
return { return {
...this._stats, ...this._stats,
@@ -141,6 +141,10 @@ class HyperP2PTriePrefix extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().words === 0
}
getStats () { getStats () {
return { return {
...this._stats, ...this._stats,
@@ -287,6 +287,11 @@ class SpatialIndex extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
async isEmpty () {
const s = await this.snapshot()
return s.points === 0
}
getStats () { getStats () {
return { return {
...this._stats, ...this._stats,
@@ -48,6 +48,10 @@ class HyperP2PBucketRateLimit extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return Object.keys(this.snapshot().buckets).length === 0
}
_bucketSnapshot () { _bucketSnapshot () {
const out = {} const out = {}
for (const [peerId, b] of this._buckets) { for (const [peerId, b] of this._buckets) {
@@ -100,6 +100,10 @@ class HyperP2PHistogramGossip extends EventEmitter {
} }
} }
isEmpty () {
return this._metrics.size === 0
}
toJSON () { toJSON () {
return this.moduleSnapshot() return this.moduleSnapshot()
} }
@@ -126,6 +126,10 @@ class HyperP2PPercentileSketch extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().samples === 0
}
summarize () { summarize () {
this._sort() this._sort()
if (!this._sorted.length) return null if (!this._sorted.length) return null
@@ -119,6 +119,10 @@ class HyperP2PSlaBudget extends EventEmitter {
} }
} }
isEmpty () {
return this.serviceCount() === 0
}
toJSON () { toJSON () {
return this.moduleSnapshot() return this.moduleSnapshot()
} }
@@ -137,6 +137,10 @@ class HyperP2PAdaptiveStreamingEngine extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().bufferMs === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { recommendation: this._recommendation }) return mediaStats(this._stats, PROTOCOL, { recommendation: this._recommendation })
} }
@@ -143,6 +143,10 @@ class HyperP2PBandwidthAggregator extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.sourceCount() === 0
}
sourceCount () { sourceCount () {
return this._sources.size return this._sources.size
} }
@@ -102,6 +102,10 @@ class HyperP2PBufferHealthPredictor extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().samples === 0
}
sampleCount () { sampleCount () {
return this._samples.length return this._samples.length
} }
@@ -121,6 +121,10 @@ class HyperP2PChunkSchedulerMedia extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().pending === 0
}
enqueueBatch (chunks) { enqueueBatch (chunks) {
if (!Array.isArray(chunks)) throw new Error('chunks array required') if (!Array.isArray(chunks)) throw new Error('chunks array required')
return chunks.map((chunk) => this.enqueue(chunk)) return chunks.map((chunk) => this.enqueue(chunk))
@@ -121,6 +121,10 @@ class HyperP2PContentProtection extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().keys === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { activeKeyId: this._activeKeyId, keys: this._keys.size }) return mediaStats(this._stats, PROTOCOL, { activeKeyId: this._activeKeyId, keys: this._keys.size })
} }
@@ -110,6 +110,10 @@ class HyperP2PContributionLedger extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().contributors === 0
}
_gossip (payload) { _gossip (payload) {
if (this._peerMsgs) { if (this._peerMsgs) {
gossipSend(this, payload) gossipSend(this, payload)
@@ -130,6 +130,10 @@ class HyperP2PEnterpriseOrchestrator extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().count === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { regions: this._regions.size }) return mediaStats(this._stats, PROTOCOL, { regions: this._regions.size })
} }
@@ -119,6 +119,10 @@ class HyperP2PFecVideo extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().groups === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { groups: this._groups.size }) return mediaStats(this._stats, PROTOCOL, { groups: this._groups.size })
} }
@@ -129,6 +129,10 @@ class HyperP2PHelperSwarmCoordinator extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().helpers === 0
}
registerHelperBatch (entries) { registerHelperBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.registerHelper(e.peerId, e.capacityBps)) return entries.map((e) => this.registerHelper(e.peerId, e.capacityBps))
@@ -107,6 +107,10 @@ class HyperP2PLatencyOptimizer extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().paths === 0
}
measureBatch (entries) { measureBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries must be an array') if (!Array.isArray(entries)) throw new Error('entries must be an array')
return entries.map((e) => this.measurePath(e.pathId, e.hops || [])) return entries.map((e) => this.measurePath(e.pathId, e.hops || []))
@@ -108,6 +108,10 @@ class HyperP2PLiveEdgeManager extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().count === 0
}
setLiveEdgeBatch (entries) { setLiveEdgeBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.setLiveEdge(e.streamId, e.seq, e.wallAt)) return entries.map((e) => this.setLiveEdge(e.streamId, e.seq, e.wallAt))
@@ -145,6 +145,10 @@ class HyperP2PMediaChunker extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().stored === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { stored: this._chunks.size }) return mediaStats(this._stats, PROTOCOL, { stored: this._chunks.size })
} }
@@ -180,6 +180,10 @@ class HyperP2PMediaTreeOrchestrator extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().nodes === 0
}
_gossip (payload) { _gossip (payload) {
if (!this._peerMsgs) return if (!this._peerMsgs) return
gossipSend(this, payload) gossipSend(this, payload)
@@ -116,6 +116,10 @@ class HyperP2POriginHybridBridge extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().streams === 0
}
registerOriginBatch (entries) { registerOriginBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.registerOrigin(e.streamId, e.url, e.weight)) return entries.map((e) => this.registerOrigin(e.streamId, e.url, e.weight))
@@ -138,6 +138,10 @@ class HyperP2PPeerSelectorStreaming extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().peers === 0
}
registerPeerBatch (entries) { registerPeerBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.registerPeer(e.peerId, e.stats || {})) return entries.map((e) => this.registerPeer(e.peerId, e.stats || {}))
@@ -118,6 +118,10 @@ class HyperP2PQualityLadder extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().ladders === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { ladders: this._ladders.size }) return mediaStats(this._stats, PROTOCOL, { ladders: this._ladders.size })
} }
@@ -103,6 +103,10 @@ class HyperP2PRetransmissionMedia extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().pending === 0
}
nackBatch (entries) { nackBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.nack(e.streamId, e.seq, e.reason)) return entries.map((e) => this.nack(e.streamId, e.seq, e.reason))
@@ -124,6 +124,10 @@ class HyperP2PStreamAccessControl extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().total === 0
}
grantCapabilityBatch (entries) { grantCapabilityBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.grantCapability(e.streamId, e.subject, e.ttlMs)) return entries.map((e) => this.grantCapability(e.streamId, e.subject, e.ttlMs))
@@ -121,6 +121,10 @@ class HyperP2PStreamManifest extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().count === 0
}
buildManifestBatch (entries) { buildManifestBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.buildManifest(e.streamId, e.meta || {})) return entries.map((e) => this.buildManifest(e.streamId, e.meta || {}))
@@ -140,6 +140,10 @@ class HyperP2PStreamTelemetry extends EventEmitter {
return this.clusterSnapshot() return this.clusterSnapshot()
} }
isEmpty () {
return this.sessionCount() === 0
}
getStats () { getStats () {
return mediaStats(this._stats, PROTOCOL, { sessions: this._sessions.size }) return mediaStats(this._stats, PROTOCOL, { sessions: this._sessions.size })
} }
@@ -167,6 +167,10 @@ class HyperP2PDedupFilter extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().size === 0
}
restoreSnapshot (snap) { restoreSnapshot (snap) {
if (!snap || !Array.isArray(snap.ids)) throw new Error('invalid snapshot') if (!snap || !Array.isArray(snap.ids)) throw new Error('invalid snapshot')
this._seen = new Set(snap.ids) this._seen = new Set(snap.ids)
@@ -394,6 +394,11 @@ class HyperP2PDistributedEventBus extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.topics === 0 && s.subscribers === 0 && this.seenEvents.size === 0
}
hasSeen (eventId) { hasSeen (eventId) {
return this.seenEvents.has(String(eventId)) return this.seenEvents.has(String(eventId))
} }
@@ -162,6 +162,10 @@ class HyperP2PGossipMesh extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.seenCount() === 0
}
hasSeen (id) { hasSeen (id) {
return this._seen.has(String(id)) return this._seen.has(String(id))
} }
@@ -137,6 +137,12 @@ class HyperP2PQosTopic extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.channels.length === 0 && s.handlers === 0 &&
Object.values(s.queueDepths).every((n) => n === 0)
}
_onGossip (data) { _onGossip (data) {
if (!data || data.type !== 'qos-publish') return if (!data || data.type !== 'qos-publish') return
this._stats.gossipIn++ this._stats.gossipIn++
@@ -109,6 +109,10 @@ class HyperP2PRetainedMessages extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().total === 0
}
retainBatch (entries) { retainBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.retain(e.channel, e.payload, e.opts || {})) return entries.map((e) => this.retain(e.channel, e.payload, e.opts || {}))
@@ -157,6 +157,10 @@ class HyperP2PSubscriptionLease extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().leases === 0
}
acquireBatch (channels) { acquireBatch (channels) {
if (!Array.isArray(channels)) throw new Error('channels array required') if (!Array.isArray(channels)) throw new Error('channels array required')
return channels.map((ch) => this.acquire(ch)) return channels.map((ch) => this.acquire(ch))
@@ -128,6 +128,11 @@ class HyperP2PTopicChannel extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.channels === 0 && s.retained === 0
}
_deliverLocal (channel, payload, meta) { _deliverLocal (channel, payload, meta) {
const handler = this._subs.get(channel) const handler = this._subs.get(channel)
if (handler) { if (handler) {
@@ -108,6 +108,11 @@ class HyperP2PStreamBackpressure extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.bytes === 0 && !s.paused
}
writeBatch (chunks) { writeBatch (chunks) {
if (!Array.isArray(chunks)) throw new Error('chunks array required') if (!Array.isArray(chunks)) throw new Error('chunks array required')
return chunks.map((chunk) => this.write(chunk)) return chunks.map((chunk) => this.write(chunk))
@@ -67,6 +67,10 @@ class HyperP2PStreamChunker extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().pending === 0
}
flush () { flush () {
if (!this._pending.length) return null if (!this._pending.length) return null
const tail = this._pending const tail = this._pending
@@ -139,6 +139,10 @@ class HyperP2PStreamMultiplex extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().open === 0
}
openStreamBatch (ids) { openStreamBatch (ids) {
if (!Array.isArray(ids)) throw new Error('ids array required') if (!Array.isArray(ids)) throw new Error('ids array required')
return ids.map((id) => this.openStream(id)) return ids.map((id) => this.openStream(id))
@@ -132,6 +132,10 @@ class HyperP2PStreamResumeToken extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().tokens === 0
}
writeBatch (chunks) { writeBatch (chunks) {
if (!Array.isArray(chunks)) throw new Error('chunks array required') if (!Array.isArray(chunks)) throw new Error('chunks array required')
return chunks.map((c) => this.write(c)) return chunks.map((c) => this.write(c))
@@ -107,6 +107,10 @@ class HyperP2PStreamTee extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().branches === 0
}
addBranchBatch (names) { addBranchBatch (names) {
if (!Array.isArray(names)) throw new Error('names array required') if (!Array.isArray(names)) throw new Error('names array required')
return names.map((name) => this.addBranch(name)) return names.map((name) => this.addBranch(name))
@@ -102,6 +102,10 @@ class HyperP2PStreamTransform extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().pending === 0
}
writeBatch (chunks) { writeBatch (chunks) {
if (!Array.isArray(chunks)) throw new Error('chunks must be an array') if (!Array.isArray(chunks)) throw new Error('chunks must be an array')
let ok = 0 let ok = 0
@@ -83,6 +83,10 @@ class HyperP2PCapabilityDiscovery extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().capabilities === 0
}
registerCapabilityBatch (entries) { registerCapabilityBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.registerCapability(e.name, e.meta || {})) return entries.map((e) => this.registerCapability(e.name, e.meta || {}))
@@ -99,6 +99,10 @@ class HyperP2PDiscoveryHealth extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().peers === 0
}
reportPeerBatch (entries) { reportPeerBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.reportPeer(e.peerId, e.status || {})) return entries.map((e) => this.reportPeer(e.peerId, e.status || {}))
@@ -89,6 +89,10 @@ class HyperP2PPeerBootstrapStore extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().bootstraps === 0
}
_gossip (data) { _gossip (data) {
if (!this._peerMsgs) return if (!this._peerMsgs) return
gossipSend(this, data) gossipSend(this, data)
@@ -102,6 +102,10 @@ class HyperP2PSeederRegistry extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().topics === 0
}
_gossip (data) { _gossip (data) {
if (!this._peerMsgs) return if (!this._peerMsgs) return
gossipSend(this, data) gossipSend(this, data)
@@ -91,6 +91,10 @@ class HyperP2PTopicAnnouncer extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().count === 0
}
_gossip (data) { _gossip (data) {
if (!this._peerMsgs) return if (!this._peerMsgs) return
gossipSend(this, data) gossipSend(this, data)
@@ -110,6 +110,11 @@ class HyperP2PAnycastSelector extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.tags === 0 && s.latencyPeers === 0
}
getStats () { getStats () {
return { ...this._stats, tags: this._tags.size, latencyPeers: this._latency.size, protocol: PROTOCOL } return { ...this._stats, tags: this._tags.size, latencyPeers: this._latency.size, protocol: PROTOCOL }
} }
@@ -100,6 +100,10 @@ class HyperP2PBandwidthBroker extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().peers === 0
}
grantBatch (entries) { grantBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.grant(e.peerId, e.bytes)) return entries.map((e) => this.grant(e.peerId, e.bytes))
@@ -127,6 +127,10 @@ class HyperP2PCircuitLoom extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().total === 0
}
hopCount (circuitId) { hopCount (circuitId) {
const c = this._circuits.get(circuitId) const c = this._circuits.get(circuitId)
return c ? c.hops.length : 0 return c ? c.hops.length : 0
@@ -96,6 +96,10 @@ class HyperP2PCongestionSignal extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().peers === 0
}
reportSampleBatch (entries) { reportSampleBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.reportSample(e.peerId, e.rttMs, e.loss)) return entries.map((e) => this.reportSample(e.peerId, e.rttMs, e.loss))
@@ -101,6 +101,10 @@ class HyperP2PConnectionPool extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().total === 0
}
acquireBatch (peerIds) { acquireBatch (peerIds) {
if (!Array.isArray(peerIds)) throw new Error('peerIds array required') if (!Array.isArray(peerIds)) throw new Error('peerIds array required')
return peerIds.map((peerId) => this.acquire(peerId)) return peerIds.map((peerId) => this.acquire(peerId))
@@ -121,6 +121,10 @@ class HyperP2PFlowShaper extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().queued === 0
}
getStats () { getStats () {
return { return {
...this._stats, ...this._stats,
@@ -104,6 +104,10 @@ class HyperP2PLinkProbe extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().entries === 0
}
probeBatch (peerIds) { probeBatch (peerIds) {
if (!Array.isArray(peerIds)) throw new Error('peerIds array required') if (!Array.isArray(peerIds)) throw new Error('peerIds array required')
return peerIds.map((id) => this.probe(id)) return peerIds.map((id) => this.probe(id))
@@ -113,6 +113,10 @@ class HyperP2PMultipathFanout extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.pendingCount() === 0
}
fanoutBatch (entries) { fanoutBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.fanout(e.payload, e.pathCount)) return entries.map((e) => this.fanout(e.payload, e.pathCount))
@@ -100,6 +100,10 @@ class HyperP2POverlayTopology extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
return this.snapshot().degree === 0
}
getStats () { getStats () {
return { ...this._stats, degree: this._neighbors.size, protocol: PROTOCOL } return { ...this._stats, degree: this._neighbors.size, protocol: PROTOCOL }
} }
@@ -103,6 +103,11 @@ class HyperP2PProtocolHandshake extends EventEmitter {
return this.snapshot() return this.snapshot()
} }
isEmpty () {
const s = this.snapshot()
return s.pending === 0 && s.agreed === 0
}
offerBatch (entries) { offerBatch (entries) {
if (!Array.isArray(entries)) throw new Error('entries array required') if (!Array.isArray(entries)) throw new Error('entries array required')
return entries.map((e) => this.offer(e.features || {})) return entries.map((e) => this.offer(e.features || {}))

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