Updates
This commit is contained in:
@@ -2,79 +2,84 @@
|
||||
|
||||
**Protocol:** `qos-topic/v1`
|
||||
|
||||
**Export:** `HyperP2PQosTopic`
|
||||
**Export:** `HyperP2PQosTopic`, `PROTOCOL`
|
||||
|
||||
## Overview
|
||||
|
||||
Production p2p module: Hyperswarm discovery + Protomux when `topic` is set.
|
||||
Priority pub/sub with three QoS queues (0–2). Higher QoS messages drain before lower; subscribers declare minimum QoS per channel. Publishes gossip as `qos-publish`.
|
||||
|
||||
## Constructor
|
||||
|
||||
```js
|
||||
const mod = new HyperP2PQosTopic(opts)
|
||||
```
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `topic` | varies | null | topic |
|
||||
| `keyPair` | KeyPair | random Ed25519 | keyPair |
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `topic` | Hyperswarm topic |
|
||||
| `keyPair` | Publisher identity |
|
||||
|
||||
## Methods
|
||||
|
||||
### `subscribe(channel, handler, qos = 0)`
|
||||
### `subscribe(channel, handler, qos?)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:**
|
||||
- `Error: handler must be a function`
|
||||
Default subscriber QoS `0`. Handler receives messages where `msg.qos >= sub.qos`.
|
||||
|
||||
### `publish(channel, payload, opts = {})`
|
||||
### `publish(channel, payload, opts?)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
- **opts.qos** — clamped 0–2
|
||||
- Enqueues then `_drain()` priority order
|
||||
|
||||
### `pending(qos)`
|
||||
### `pending(qos?)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
Queue depth for one level or total.
|
||||
|
||||
### `getStats(—)`
|
||||
### `getStats()` / `ready()` / `close()`
|
||||
|
||||
- **Returns:** `object`
|
||||
- **Throws:** — (none documented in method body)
|
||||
`published`, `delivered`, `gossipIn`, `gossipOut`.
|
||||
|
||||
### `ready(—)`
|
||||
## Wire
|
||||
|
||||
- **Returns:** `Promise`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `close(—)`
|
||||
|
||||
- **Returns:** `Promise<void>`
|
||||
- **Throws:** — (none documented in method body)
|
||||
| type | fields |
|
||||
|------|--------|
|
||||
| `qos-publish` | `channel`, `payload`, `qos`, `from`, `at` |
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Payload |
|
||||
|-------|---------|
|
||||
| `message` | msg |
|
||||
|
||||
## getStats()
|
||||
|
||||
Returns `{ ...this._stats }` — typically `ops`, `errors`, and module-specific counters (`created`, `relays`, `open`, `peers`, etc.).
|
||||
Library-only modules may include `mode: 'local'`.
|
||||
`message`.
|
||||
|
||||
## Errors
|
||||
|
||||
Stable message substrings: see [`../../_shared/ERROR_CODES.md`](../../_shared/ERROR_CODES.md).
|
||||
`assertNonEmpty(channel)`, invalid handler.
|
||||
|
||||
## P2P
|
||||
## Composition
|
||||
|
||||
When `topic` is set, `ready()` joins Hyperswarm and opens Protomux `qos-topic/v1`.
|
||||
`hyper-p2p-topic-channel` for retain; Wave 9 `qos-topic-two-node.js`.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
npm install && npm test
|
||||
```
|
||||
`npm test`, integration smoke.
|
||||
|
||||
Integration: [`../../../real_tests/integration/qos-topic-two-node.js`](../../../real_tests/integration/qos-topic-two-node.js)
|
||||
## Example
|
||||
|
||||
`examples/basic.js`
|
||||
|
||||
## State model
|
||||
|
||||
Three queues `_queues[0..2]`; drain processes highest index first.
|
||||
|
||||
## Performance
|
||||
|
||||
`pending()` walks all queues; bound publish rate if memory grows.
|
||||
|
||||
## Versioning
|
||||
|
||||
`qos-topic/v1` publish type unchanged since Wave 9.
|
||||
|
||||
## Security
|
||||
|
||||
No encryption; use `hyper-p2p-encrypted-topic` for sensitive channels.
|
||||
|
||||
## Related modules
|
||||
|
||||
- `hyper-p2p-topic-channel` — retain and subscribe
|
||||
|
||||
## See also
|
||||
|
||||
[`docs/architecture.md`](architecture.md)
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
# API: hyper-p2p-retained-messages
|
||||
|
||||
**Protocol:** `retained-messages/v1`
|
||||
**Protocol:** `retained-messages/v1` (local store)
|
||||
|
||||
**Export:** `HyperP2PRetainedMessages`
|
||||
**Export:** `HyperP2PRetainedMessages`, `PROTOCOL`
|
||||
|
||||
## Overview
|
||||
|
||||
Production p2p module: Hyperswarm discovery + Protomux when `topic` is set.
|
||||
Per-channel FIFO of retained payloads (default max 32 per channel). Used standalone or behind `hyper-p2p-topic-channel` retain flag.
|
||||
|
||||
## Constructor
|
||||
|
||||
```js
|
||||
const mod = new HyperP2PRetainedMessages(opts)
|
||||
```
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `topic` | `string` | `Buffer` | `null` | Hyperswarm topic; required for P2P `ready()` |
|
||||
| `keyPair` | KeyPair | random | Ed25519 key pair |
|
||||
| `maxPerChannel` | number | 32 | maxPerChannel |
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `maxPerChannel` | `32` | Ring size per channel |
|
||||
|
||||
## Methods
|
||||
|
||||
### `retain(channel, payload, meta = {})`
|
||||
### `retain(channel, payload, meta?)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
Appends entry `{ payload, meta, at }`; emits `retain`.
|
||||
|
||||
### `latest(channel)`
|
||||
### `latest(channel)` / `list(channel, limit?)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `clear(channel?)`
|
||||
|
||||
### `list(channel, limit = 10)`
|
||||
Omit channel to wipe all.
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `getStats()` / `ready()` / `close()`
|
||||
|
||||
### `clear(channel)`
|
||||
`set`, `get`, `cleared`, `channels`, `protocol`.
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
## Wire
|
||||
|
||||
### `getStats(—)`
|
||||
|
||||
- **Returns:** `object`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `ready(—)`
|
||||
|
||||
- **Returns:** `Promise`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `close(—)`
|
||||
|
||||
- **Returns:** `Promise<void>`
|
||||
- **Throws:** — (none documented in method body)
|
||||
None in-module; topic-channel gossips `retained-sync`.
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Payload |
|
||||
|-------|---------|
|
||||
| `retain` | payload object |
|
||||
|
||||
## getStats()
|
||||
|
||||
Returns `{ ...this._stats }` — typically `ops`, `errors`, and module-specific counters (`created`, `relays`, `open`, `peers`, etc.).
|
||||
Library-only modules may include `mode: 'local'`.
|
||||
`retain`.
|
||||
|
||||
## Errors
|
||||
|
||||
Stable message substrings: see [`../../_shared/ERROR_CODES.md`](../../_shared/ERROR_CODES.md).
|
||||
`assertNonEmpty(channel)`.
|
||||
|
||||
## P2P
|
||||
## Composition
|
||||
|
||||
When `topic` is set, `ready()` joins Hyperswarm and opens Protomux `retained-messages/v1`.
|
||||
Pair with `hyper-p2p-topic-channel.publish(..., { retain: true })`.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
npm install && npm test
|
||||
```
|
||||
`npm test`
|
||||
|
||||
## Example
|
||||
|
||||
`examples/basic.js`
|
||||
|
||||
## State model
|
||||
|
||||
Per-channel arrays capped by `maxPerChannel`; `latest` is O(1).
|
||||
|
||||
## Performance
|
||||
|
||||
`list` copies tail slice only; safe for UI replay buffers.
|
||||
|
||||
## Versioning
|
||||
|
||||
Local store; sync via topic-channel gossip separately.
|
||||
|
||||
## Security
|
||||
|
||||
Retained payloads persist in memory until `clear`; scrub secrets on channel delete.
|
||||
|
||||
## Related modules
|
||||
|
||||
- `hyper-p2p-topic-channel` — networked retain sync
|
||||
|
||||
## Changelog
|
||||
|
||||
Wave 9: standalone retain store extracted for composition and tests.
|
||||
|
||||
## See also
|
||||
|
||||
[`docs/architecture.md`](architecture.md)
|
||||
|
||||
@@ -2,85 +2,79 @@
|
||||
|
||||
**Protocol:** `subscription-lease/v1`
|
||||
|
||||
**Export:** `HyperP2PSubscriptionLease`
|
||||
**Export:** `HyperP2PSubscriptionLease`, `PROTOCOL`
|
||||
|
||||
## Overview
|
||||
|
||||
Production p2p module: Hyperswarm discovery + Protomux when `topic` is set.
|
||||
Time-bounded exclusive channel subscription leases. `acquire` fails if another holder’s lease is unexpired; background timer sweeps expired entries when enabled.
|
||||
|
||||
## Constructor
|
||||
|
||||
```js
|
||||
const mod = new HyperP2PSubscriptionLease(opts)
|
||||
```
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `topic` | varies | null | topic |
|
||||
| `keyPair` | KeyPair | random Ed25519 | keyPair |
|
||||
| `leaseMs` | varies | DEFAULT_LEASE_MS | lease (ms) |
|
||||
| `enableBackgroundTimers` | boolean | `false` | Periodic timers (off in tests) |
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `leaseMs` | `60000` | Lease duration |
|
||||
| `enableBackgroundTimers` | `false` | Periodic expiry sweep |
|
||||
|
||||
## Methods
|
||||
|
||||
### `acquire(channel)`
|
||||
### `acquire(channel)` / `renew(channel)` / `release(channel)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `getLease(channel)` / `isActive(channel)`
|
||||
|
||||
### `renew(channel)`
|
||||
### `getStats()` / `ready()` / `close()`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
## Wire
|
||||
|
||||
### `release(channel)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `holder(channel)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `getStats(—)`
|
||||
|
||||
- **Returns:** `object`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `ready(—)`
|
||||
|
||||
- **Returns:** `Promise`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `close(—)`
|
||||
|
||||
- **Returns:** `Promise<void>`
|
||||
- **Throws:** — (none documented in method body)
|
||||
| type | purpose |
|
||||
|------|---------|
|
||||
| `sub-lease` | full lease object |
|
||||
| `sub-release` | `channel`, `holder` |
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Payload |
|
||||
|-------|---------|
|
||||
| `acquire` | lease |
|
||||
| `closed` | no payload |
|
||||
| `expired` | channel |
|
||||
|
||||
## getStats()
|
||||
|
||||
Returns `{ ...this._stats }` — typically `ops`, `errors`, and module-specific counters (`created`, `relays`, `open`, `peers`, etc.).
|
||||
Library-only modules may include `mode: 'local'`.
|
||||
`acquire`, `release`, `expired`.
|
||||
|
||||
## Errors
|
||||
|
||||
Stable message substrings: see [`../../_shared/ERROR_CODES.md`](../../_shared/ERROR_CODES.md).
|
||||
`assertNonEmpty(channel)`; acquire conflict returns `{ ok: false, holder }`.
|
||||
|
||||
## P2P
|
||||
## Composition
|
||||
|
||||
When `topic` is set, `ready()` joins Hyperswarm and opens Protomux `subscription-lease/v1`.
|
||||
`hyper-p2p-topic-channel` subscribe exclusivity.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
npm install && npm test
|
||||
```
|
||||
`npm test`
|
||||
|
||||
## Example
|
||||
|
||||
`examples/basic.js`
|
||||
|
||||
## State model
|
||||
|
||||
`_leases` map channel → `{ holder, expiresAt }`; timer sweeps expired when enabled.
|
||||
|
||||
## Performance
|
||||
|
||||
Acquire is O(1); gossip on every renew — throttle renew frequency.
|
||||
|
||||
## Versioning
|
||||
|
||||
`subscription-lease/v1` wire messages documented in architecture.
|
||||
|
||||
## Security
|
||||
|
||||
Leases are cooperative, not Byzantine-safe; use consensus modules for hard exclusivity.
|
||||
|
||||
## Related modules
|
||||
|
||||
- `hyper-p2p-topic-channel` — delivery path
|
||||
|
||||
## Changelog
|
||||
|
||||
- Wave 9: lease acquire/renew/release with optional background expiry timer.
|
||||
- Default `leaseMs` is 60000 unless overridden in constructor.
|
||||
|
||||
## See also
|
||||
|
||||
[`docs/architecture.md`](architecture.md)
|
||||
|
||||
@@ -2,90 +2,90 @@
|
||||
|
||||
**Protocol:** `topic-channel/v1`
|
||||
|
||||
**Export:** `HyperP2PTopicChannel`
|
||||
**Export:** `HyperP2PTopicChannel`, `PROTOCOL`
|
||||
|
||||
## Overview
|
||||
|
||||
Production p2p module: Hyperswarm discovery + Protomux when `topic` is set.
|
||||
MQTT-style named channels over one Hyperswarm topic: subscribe handlers, publish with optional QoS level and retained last message per channel, plus gossip for subscribe/unsubscribe/publish/retained-sync.
|
||||
|
||||
## Constructor
|
||||
|
||||
```js
|
||||
const mod = new HyperP2PTopicChannel(opts)
|
||||
```
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `topic` | varies | null | topic |
|
||||
| `keyPair` | KeyPair | random Ed25519 | keyPair |
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `topic` | `null` | Shared swarm topic |
|
||||
| `keyPair` | random | Publisher `peerHex` |
|
||||
| `retainMessages` | `true` | Default retain on publish |
|
||||
|
||||
## Methods
|
||||
|
||||
### `subscribe(channel, handler)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:**
|
||||
- `Error: handler must be a function`
|
||||
- **Returns:** unsubscribe function
|
||||
- **Throws:** empty channel, `handler must be a function`
|
||||
- **Side effect:** gossips `subscribe`; replays retained payload if present
|
||||
|
||||
### `unsubscribe(channel)`
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `publish(channel, payload, opts?)`
|
||||
|
||||
### `publish(channel, payload, opts = {})`
|
||||
- **opts.qos** — number tag on message
|
||||
- **opts.retain** — store last message for channel
|
||||
- **Returns:** gossip message object
|
||||
- **Emits:** `message` on all subscribers
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `getRetained(channel)` / `syncRetained(channel)`
|
||||
|
||||
### `getRetained(channel)`
|
||||
Push retained snapshot to peers (`retained-sync`).
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `getStats()`
|
||||
|
||||
### `syncRetained(channel)`
|
||||
`published`, `received`, `subscriptions`, `gossipIn`, `gossipOut`, `channels`, `retained`, `protocol`.
|
||||
|
||||
- **Returns:** `value`
|
||||
- **Throws:** — (none documented in method body)
|
||||
### `ready()` / `close()`
|
||||
|
||||
### `getStats(—)`
|
||||
Protomux `topic-channel/v1`; `close` emits `closed`.
|
||||
|
||||
- **Returns:** `object`
|
||||
- **Throws:** — (none documented in method body)
|
||||
## Wire messages
|
||||
|
||||
### `ready(—)`
|
||||
|
||||
- **Returns:** `Promise`
|
||||
- **Throws:** — (none documented in method body)
|
||||
|
||||
### `close(—)`
|
||||
|
||||
- **Returns:** `Promise<void>`
|
||||
- **Throws:** — (none documented in method body)
|
||||
| type | purpose |
|
||||
|------|---------|
|
||||
| `subscribe` | `channel`, `peer` |
|
||||
| `unsubscribe` | `channel`, `peer` |
|
||||
| `publish` | `channel`, `payload`, `from`, `at`, `qos`, `retain` |
|
||||
| `retained-sync` | last retained payload |
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Payload |
|
||||
|-------|---------|
|
||||
| `closed` | no payload |
|
||||
| `message` | payload object |
|
||||
|
||||
## getStats()
|
||||
|
||||
Returns `{ ...this._stats }` — typically `ops`, `errors`, and module-specific counters (`created`, `relays`, `open`, `peers`, etc.).
|
||||
Library-only modules may include `mode: 'local'`.
|
||||
`message`, `closed`.
|
||||
|
||||
## Errors
|
||||
|
||||
Stable message substrings: see [`../../_shared/ERROR_CODES.md`](../../_shared/ERROR_CODES.md).
|
||||
`assertNonEmpty(channel)`.
|
||||
|
||||
## P2P
|
||||
## Composition
|
||||
|
||||
When `topic` is set, `ready()` joins Hyperswarm and opens Protomux `topic-channel/v1`.
|
||||
`hyper-p2p-qos-topic`, `hyper-p2p-subscription-lease`, `hyper-p2p-retained-messages`, Wave 9 stack.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
npm install && npm test
|
||||
```
|
||||
`npm test`, `topic-channel-two-node.js`, `wave9-stack-two-node.js`.
|
||||
|
||||
Integration: [`../../../real_tests/integration/topic-channel-two-node.js`](../../../real_tests/integration/topic-channel-two-node.js)
|
||||
## Example
|
||||
|
||||
`examples/basic.js`
|
||||
|
||||
## State model
|
||||
|
||||
`_subs` maps channel → handler; `_retained` maps channel → `{ payload, from, at }`. Stats counters increment on publish/delivery/gossip paths only.
|
||||
|
||||
## Performance
|
||||
|
||||
Retained replay is O(1) per subscribe. Gossip fan-out is O(peers) via Protomux; keep payloads small.
|
||||
|
||||
## Versioning
|
||||
|
||||
Protocol string `topic-channel/v1` is stable; bump only with breaking wire shape changes.
|
||||
|
||||
## See also
|
||||
|
||||
[`docs/architecture.md`](architecture.md)
|
||||
|
||||
Reference in New Issue
Block a user