@statewalker/httpeers-libp2p 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +173 -0
  3. package/dist/browser.d.ts +33 -0
  4. package/dist/browser.d.ts.map +1 -0
  5. package/dist/browser.js +77 -0
  6. package/dist/duplex.d.ts +86 -0
  7. package/dist/duplex.d.ts.map +1 -0
  8. package/dist/duplex.js +101 -0
  9. package/dist/hop-reserve.d.ts +105 -0
  10. package/dist/hop-reserve.d.ts.map +1 -0
  11. package/dist/hop-reserve.js +269 -0
  12. package/dist/hub-link.d.ts +131 -0
  13. package/dist/hub-link.d.ts.map +1 -0
  14. package/dist/hub-link.js +217 -0
  15. package/dist/hub-relay.d.ts +129 -0
  16. package/dist/hub-relay.d.ts.map +1 -0
  17. package/dist/hub-relay.js +154 -0
  18. package/dist/identity.d.ts +84 -0
  19. package/dist/identity.d.ts.map +1 -0
  20. package/dist/identity.js +91 -0
  21. package/dist/index.d.ts +28 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +26 -0
  24. package/dist/link.d.ts +49 -0
  25. package/dist/link.d.ts.map +1 -0
  26. package/dist/link.js +88 -0
  27. package/dist/multiaddr-parts.d.ts +21 -0
  28. package/dist/multiaddr-parts.d.ts.map +1 -0
  29. package/dist/multiaddr-parts.js +27 -0
  30. package/dist/node.d.ts +33 -0
  31. package/dist/node.d.ts.map +1 -0
  32. package/dist/node.js +60 -0
  33. package/dist/reservation.d.ts +245 -0
  34. package/dist/reservation.d.ts.map +1 -0
  35. package/dist/reservation.js +396 -0
  36. package/dist/serve-peer.d.ts +91 -0
  37. package/dist/serve-peer.d.ts.map +1 -0
  38. package/dist/serve-peer.js +68 -0
  39. package/dist/timers.d.ts +36 -0
  40. package/dist/timers.d.ts.map +1 -0
  41. package/dist/timers.js +38 -0
  42. package/dist/transport.d.ts +314 -0
  43. package/dist/transport.d.ts.map +1 -0
  44. package/dist/transport.js +410 -0
  45. package/package.json +73 -0
  46. package/src/browser.ts +118 -0
  47. package/src/duplex.ts +172 -0
  48. package/src/hop-reserve.ts +295 -0
  49. package/src/hub-link.ts +281 -0
  50. package/src/hub-relay.ts +188 -0
  51. package/src/identity.ts +155 -0
  52. package/src/index.ts +114 -0
  53. package/src/link.ts +143 -0
  54. package/src/multiaddr-parts.ts +29 -0
  55. package/src/node.ts +63 -0
  56. package/src/reservation.ts +564 -0
  57. package/src/serve-peer.ts +141 -0
  58. package/src/timers.ts +47 -0
  59. package/src/transport.ts +538 -0
@@ -0,0 +1,314 @@
1
+ import type { Ed25519PrivateKey, Libp2p } from "@libp2p/interface";
2
+ export type { Ed25519PrivateKey, Libp2p } from "@libp2p/interface";
3
+ import type { FetchHandler, PeerIdStr, Remote } from "@statewalker/httpeers-core";
4
+ import { PeerCallError } from "@statewalker/httpeers-core";
5
+ import { type CallOnLimitedConnection } from "./link.js";
6
+ /**
7
+ * A namespaced protocol id, passed explicitly rather than left at
8
+ * `webrun-streams-libp2p`'s package default (`/webrun-streams/1.0.0`). The
9
+ * protocol id is the demux key libp2p uses to route an inbound stream to a
10
+ * handler on the node: sharing the generic default would collide with any
11
+ * other `webrun-streams` consumer sharing the same libp2p node.
12
+ */
13
+ export declare const PROTOCOL = "/httpeers/1.0.0";
14
+ /**
15
+ * Per-connection concurrent stream cap, applied to both directions — THE
16
+ * SERVER-SIDE CONTRACT (ledger note 18 §6, T-3/Task 18 step 3): libp2p's own
17
+ * default is 32 inbound / 64 outbound streams per protocol per connection;
18
+ * past the inbound number, a new stream is RESET, not queued, and the caller
19
+ * observes that reset as `PeerStreamResetError` (`kind: "stream-reset"`,
20
+ * `errors.ts` row 3b, `mapPeerCallError`'s `TooManyInboundProtocolStreamsError`
21
+ * branch) — never a raw libp2p exception, but still a rejected call with no
22
+ * retry or backoff of its own. 512 is the recorded precedent from the
23
+ * stream-limits task (6a) and its regression tests in
24
+ * `webrun-streams-libp2p`. Raising it moves this cliff outward; it does not
25
+ * remove it, which is why `DEFAULT_MAX_CONCURRENT_OUTBOUND` below exists —
26
+ * see that constant's doc comment for the client-side half of this contract.
27
+ *
28
+ * THE EXPOSURE WINDOW this cap forms together with `DEFAULT_DRAIN_TIMEOUT_MS`
29
+ * (the OTHER half of the same contract, Task 18 step 3): a peer that opens
30
+ * every one of its 512 allowed streams and then stops reading pins
31
+ * `DEFAULT_MAX_STREAMS * DEFAULT_DRAIN_TIMEOUT_MS` = 512 * 15s ≈ 2.1
32
+ * stream-hours of this node's buffer before the last one is dropped. See
33
+ * `DEFAULT_DRAIN_TIMEOUT_MS`'s own doc comment for why 15s (not
34
+ * `webrun-streams-libp2p`'s 5-minute default) was chosen once this cap was
35
+ * raised past libp2p's own default. Both numbers are stated here as ONE
36
+ * contract, not two independently-tunable knobs: changing either without
37
+ * re-deriving this product reopens a cliff of a different shape.
38
+ */
39
+ export declare const DEFAULT_MAX_STREAMS = 512;
40
+ /**
41
+ * How long a served stream waits for a backpressured peer to drain before
42
+ * being dropped. This is the ONLY bound on a peer that requests something
43
+ * and then stops reading without closing — the serving side has no
44
+ * `.return`/abort escape the way `connect`'s caller side does.
45
+ *
46
+ * It multiplies with `DEFAULT_MAX_STREAMS`: a peer that opens the full
47
+ * stream cap and never reads any of them pins `DEFAULT_MAX_STREAMS *
48
+ * drainTimeoutMs` stream-milliseconds of server-side buffer before every one
49
+ * of them is finally dropped. `webrun-streams-libp2p`'s own default (5
50
+ * minutes) times a 512-stream cap is ~42.7 stream-hours of exposure — too
51
+ * generous to leave in force once the cap itself has been raised well past
52
+ * libp2p's default. 15 seconds is chosen instead: long enough that a
53
+ * legitimate reader on a slow or lossy link still has room to drain a
54
+ * response chunk (multiple seconds of headroom even at very low bandwidth),
55
+ * short enough that the worst case — every one of 512 streams held open by a
56
+ * peer that never reads — caps out at 512 * 15s ≈ 2.1 stream-hours and clears
57
+ * within one operational window rather than requiring intervention.
58
+ */
59
+ export declare const DEFAULT_DRAIN_TIMEOUT_MS = 15000;
60
+ /**
61
+ * T-2's request timeout contract: how long `Peer.call()` / `Remote` wait —
62
+ * across queueing for a local concurrency slot (T-3/Task 18, see
63
+ * `DEFAULT_MAX_CONCURRENT_OUTBOUND` below), dialing, protocol negotiation,
64
+ * and the response itself — before giving up and rejecting with
65
+ * `PeerRequestTimeoutError`. This is a CONTRACT, not a tuning knob picked in
66
+ * isolation: no caller of this package may assume an unbounded wait for a
67
+ * response, ever, and this is the number that bounds it by default.
68
+ *
69
+ * T-3 DELIBERATELY DID NOT ADD A SEPARATE QUEUE TIMEOUT. When Task 18 added
70
+ * the outbound semaphore, the queue wait it introduces was placed INSIDE
71
+ * this same race rather than behind its own timer — see
72
+ * `DEFAULT_MAX_CONCURRENT_OUTBOUND`'s doc comment for the reasoning and the
73
+ * worst-case arithmetic that decision avoids.
74
+ *
75
+ * CHOSEN BELOW `DEFAULT_DRAIN_TIMEOUT_MS` (15s) AND `PROTOCOL_NEGOTIATION_TIMEOUT`
76
+ * (10s, libp2p's own default for how long protocol negotiation may take —
77
+ * `libp2p/dist/src/connection-manager/constants.defaults.js`), deliberately:
78
+ * 8s < 10s < 15s. That ordering means THIS timeout is always the first bound
79
+ * to trip. A caller therefore always observes a typed
80
+ * `PeerRequestTimeoutError` for any hang, never a raw libp2p `TimeoutError`
81
+ * leaking through from the negotiation phase, and the drain timeout exists
82
+ * purely as a transport-internal safety net most requests will never reach.
83
+ * The reverse ordering — a request timeout longer than the drain timeout —
84
+ * would mean the transport gives up on a stalled response before the
85
+ * caller's own timeout ever fires, which is a coherent choice only when
86
+ * deliberate; it is not the choice made here.
87
+ *
88
+ * 8 seconds: generous enough that an ordinary handler (token verification,
89
+ * a store lookup, one hop through a relay) never trips it under normal
90
+ * load, short enough that a caller waiting on a mesh peer notices "this
91
+ * peer is not answering" within under two heartbeat intervals (the
92
+ * heartbeat cadence this design assumes is 5s — see `DEFAULT_MINT_TTL_MS`'s
93
+ * doc comment in `peer.ts`) rather than being left hanging indefinitely.
94
+ * Override via `requestTimeoutMs` when a deployment knows better.
95
+ */
96
+ export declare const DEFAULT_REQUEST_TIMEOUT_MS = 8000;
97
+ /**
98
+ * T-3 (Task 18): the CLIENT-SIDE half of the concurrency contract
99
+ * `DEFAULT_MAX_STREAMS` states the server-side half of. Ledger note 18 §6 is
100
+ * explicit that raising `maxInboundStreams`/`maxOutboundStreams` to 512
101
+ * (Task 6a) MOVED the cliff rather than removing it: past the cap, libp2p
102
+ * RESETS the stream instead of queueing it, so a caller sees a rejected
103
+ * promise instead of latency, and nothing retries or backs off. This
104
+ * constant bounds `createRemote`'s own concurrency instead, so a well-behaved
105
+ * `Remote` never has to find that cliff at all: `createRemote` runs every
106
+ * outbound call through a private, in-process semaphore of this width before
107
+ * it ever calls `connect()` (which is what triggers libp2p's own
108
+ * `maxOutboundStreams` check, `TooManyOutboundProtocolStreamsError` --
109
+ * `errors.ts` row 3a). Excess calls QUEUE, in FIFO order, rather than racing
110
+ * each other into that cap.
111
+ *
112
+ * DEFAULTED TO `DEFAULT_MAX_STREAMS`, NOT SOME OTHER NUMBER, DELIBERATELY:
113
+ * this is a per-`Remote` (i.e. per-`Peer`) budget, not per-target-peer, so a
114
+ * `Peer` that only ever calls ONE target sees IDENTICAL admitted concurrency
115
+ * to before -- it will now queue instead of reset at the same threshold,
116
+ * never tighter -- while a `Peer` fanning calls out to MANY targets at once
117
+ * (a relay/hub forwarding on behalf of several callers) gets an additional,
118
+ * new global ceiling on its own total outbound fan-out that did not exist
119
+ * before this task. That second effect is intentional: `DEFAULT_MAX_STREAMS`
120
+ * is a PER-CONNECTION cap, so nothing previously bounded how many
121
+ * connections' worth of streams one `Remote` could have open at once: a
122
+ * `Peer` calling 20 different targets at 512 streams apiece could reach
123
+ * 10,240 concurrent outbound streams without ever touching any single
124
+ * connection's cap. That is exactly the kind of local resource exhaustion a
125
+ * DoS-adjacent control (see `DEFAULT_MAX_STREAMS`'s own doc comment) should
126
+ * not leave open just because it happens to fan out across many peers
127
+ * instead of one.
128
+ *
129
+ * THE AT-LIMIT CONTRACT (the decision ledger note 18 §6 left open --
130
+ * "queue, reject fast, or apply backpressure to the caller"): QUEUE, with a
131
+ * BOUNDED wait, then REJECT with a typed error from Task 17's taxonomy --
132
+ * never a silent reset (that would just be `DEFAULT_MAX_STREAMS`'s cliff
133
+ * again, moved one layer up), and never an unbounded queue (an unfailing
134
+ * queue under sustained overload is a slow-motion version of the same
135
+ * failure the timeout policy already rules out for every other kind of
136
+ * hang). Concretely: the bound is `DEFAULT_REQUEST_TIMEOUT_MS`, not a
137
+ * second, independent timer. `createRemote`'s `withRequestTimeout` race
138
+ * already covers "dial, negotiate, respond"; queueing for a `Semaphore`
139
+ * permit is placed INSIDE that same race (before `connect()` is even
140
+ * called), not layered outside it, specifically so a queued call that never
141
+ * gets a permit rejects with the SAME `PeerRequestTimeoutError` an
142
+ * unresponsive peer would produce, and within the SAME bound. The
143
+ * alternative -- a queue timeout on top of the existing request timeout --
144
+ * was considered and rejected: a caller that waits `requestTimeoutMs` in the
145
+ * queue and then gets a fresh `requestTimeoutMs` for the call itself sees up
146
+ * to 2 * `DEFAULT_REQUEST_TIMEOUT_MS` (16s) worst case, silently doubling a
147
+ * contract Task 17 wrote down as an 8-second promise. Sharing one budget
148
+ * keeps that promise: `Peer.call()` / `Remote` never wait longer than
149
+ * `requestTimeoutMs` for ANY reason, queueing included. Whichever reason
150
+ * wins the race, `mapPeerCallError`'s `if (err instanceof PeerCallError)
151
+ * return err` passes it through unchanged, so this never becomes a new
152
+ * taxonomy row -- `PeerRequestTimeoutError`'s trigger set simply grows to
153
+ * include "gave up waiting for a local concurrency slot," alongside its
154
+ * existing "gave up waiting for a response."
155
+ *
156
+ * A held permit is released in a `finally` (see `createRemote`) regardless
157
+ * of how the call ends -- success, a mapped `PeerCallError`, or the timeout
158
+ * race itself -- so one failing call can never permanently strand a slot.
159
+ */
160
+ export declare const DEFAULT_MAX_CONCURRENT_OUTBOUND = 512;
161
+ /**
162
+ * Map whatever a failed dial/call/timeout actually threw onto this
163
+ * package's own taxonomy (`errors.ts`), so `Peer.call()` / `Remote` keep
164
+ * the contract "you get a `PeerCallError`, never a raw transport
165
+ * exception". Exported so a future transport adapter (or a test) can see
166
+ * exactly which condition maps to which class; see each class's own doc
167
+ * comment in `errors.ts` for the library source each case is grounded in.
168
+ *
169
+ * Matched by `.name` string, not `instanceof`, for three of the cases
170
+ * below (`NoValidAddressesError`, `DialError`/`DialDeniedError`,
171
+ * `TransferLimitError`): none is part of `@libp2p/interface`'s (or any
172
+ * dependency this package actually has) public export surface, so there is
173
+ * no class to import and compare against. `.name` is reliably set on the
174
+ * *instance*, not only the `static name`, in every libp2p error class this
175
+ * was checked against (`@libp2p/interface/dist/src/errors.js`,
176
+ * `libp2p/dist/src/errors.js`), which is what makes the string check sound
177
+ * rather than a guess.
178
+ */
179
+ export declare function mapPeerCallError(err: unknown, peerId: PeerIdStr): PeerCallError;
180
+ export interface CreateNodeInit {
181
+ /**
182
+ * Multiaddrs to listen on. Omit (or pass an empty array) for a dial-only
183
+ * node — one that can call out but accepts no inbound connections, which
184
+ * is a legitimate deployment shape (a client-only edge peer).
185
+ */
186
+ listen?: string[];
187
+ /**
188
+ * The node's own signing key. Omit to let libp2p generate one internally
189
+ * — fine for a peer that never needs to prove that key again once the
190
+ * node exists. `createPeer` generates and RETAINS this key itself (never
191
+ * here) when it needs to mint tokens later, because `createLibp2p` never
192
+ * hands a generated key back out; if the caller doesn't keep the
193
+ * reference before calling this function, it is gone for good.
194
+ */
195
+ privateKey?: Ed25519PrivateKey;
196
+ /**
197
+ * The libp2p transports this node speaks. **Required, and deliberately so.**
198
+ *
199
+ * The prototype hard-coded `tcp()` here, which made importing this module at
200
+ * all pull a Node-only transport into a browser bundle — in a package whose
201
+ * root export is supposed to run on both. There is no sensible default: a
202
+ * server wants `tcp()`, a page wants `webRTC()` and `webSockets()`, and
203
+ * guessing produces a node that cannot dial anything on the platform it
204
+ * actually ran on.
205
+ *
206
+ * `./node` and `./browser` supply the profiles; this stays platform-free.
207
+ */
208
+ transports: TransportFactory[];
209
+ /**
210
+ * Extra libp2p services — `circuitRelayServer()` for a hub, say. Merged
211
+ * over the `identify` this always registers.
212
+ */
213
+ services?: Record<string, unknown>;
214
+ /** A connection gater, e.g. membership. */
215
+ connectionGater?: unknown;
216
+ }
217
+ /**
218
+ * A libp2p transport factory — `tcp()`, `webSockets()`, `webRTC()`.
219
+ *
220
+ * Typed loosely on purpose: naming libp2p's `Transport` here would drag the
221
+ * whole interface package into the signature for no gain, and every caller
222
+ * passes the result of a factory it already imported.
223
+ */
224
+ export type TransportFactory = (components: never) => unknown;
225
+ /**
226
+ * Build a libp2p node with the transport stack this package's tests and
227
+ * `createPeer`'s default construction path both rely on: TCP, Noise
228
+ * (connection encryption — this is what makes `ConnectionContext.remotePeer`
229
+ * trustworthy), Yamux (stream muxing) and identify (address exchange, so a
230
+ * peer dialled once by full multiaddr can be dialled again by bare peerId —
231
+ * see `createRemote`). Not the only file allowed to build a node makes this
232
+ * package's swappable-transport claim false, so this stays inside
233
+ * `transport-duplex.ts`; `peer.ts` calls it, never `createLibp2p` directly.
234
+ */
235
+ export declare function createNode(init: CreateNodeInit): Promise<Libp2p>;
236
+ export interface ServeTransportInit {
237
+ node: Libp2p;
238
+ /** The composed peer router — everything downstream of identity. */
239
+ dispatch: FetchHandler;
240
+ /** Defaults to `PROTOCOL`. */
241
+ protocol?: string;
242
+ /** Defaults to `DEFAULT_DRAIN_TIMEOUT_MS`. See that constant's doc comment. */
243
+ drainTimeoutMs?: number;
244
+ /** Defaults to `DEFAULT_MAX_STREAMS`. See that constant's doc comment. */
245
+ maxInboundStreams?: number;
246
+ /** Defaults to `DEFAULT_MAX_STREAMS`. See that constant's doc comment. */
247
+ maxOutboundStreams?: number;
248
+ /** Accept streams on limited connections too -- serving only. See `Libp2pLinkInit.serveOnLimitedConnection`. */
249
+ runOnLimitedConnection?: boolean;
250
+ }
251
+ /**
252
+ * Register the httpeers protocol handler on `node`. Every inbound stream
253
+ * gets its own `Duplex`, closing over that stream's proven `remotePeer` —
254
+ * `registerPeer` runs before `dispatch` is ever called, so every handler
255
+ * downstream (the binding middleware first) sees the identity the transport
256
+ * itself proved, never anything the peer merely claims.
257
+ *
258
+ * Returns the teardown function `serveConnections` itself returns
259
+ * (`node.unhandle` for this protocol).
260
+ */
261
+ export declare function serveTransport(init: ServeTransportInit): Promise<() => Promise<void>>;
262
+ export interface CreateRemoteInit {
263
+ node: Libp2p;
264
+ /** Defaults to `PROTOCOL`. */
265
+ protocol?: string;
266
+ /** Defaults to `DEFAULT_DRAIN_TIMEOUT_MS`. See that constant's doc comment. */
267
+ drainTimeoutMs?: number;
268
+ /**
269
+ * Defaults to `DEFAULT_MAX_STREAMS`. Set here too, not only on the serving
270
+ * side: a peer both serves and dials (a relay forwards by dialing out), so
271
+ * the outbound cap needs the same headroom as the inbound one.
272
+ */
273
+ maxOutboundStreams?: number;
274
+ /**
275
+ * Defaults to `DEFAULT_REQUEST_TIMEOUT_MS`. See that constant's doc
276
+ * comment for the value, the contract it states, and its relationship to
277
+ * `drainTimeoutMs`.
278
+ */
279
+ requestTimeoutMs?: number;
280
+ /**
281
+ * T-3 (Task 18): the width of this `Remote`'s outbound admission
282
+ * semaphore. Defaults to `DEFAULT_MAX_CONCURRENT_OUTBOUND`. See that
283
+ * constant's doc comment for the full contract -- what "width" bounds
284
+ * (this `Remote`'s total in-flight calls, across every target peer, not
285
+ * per-connection), and why queueing past it shares `requestTimeoutMs`
286
+ * rather than getting its own timer.
287
+ */
288
+ maxConcurrentOutbound?: number;
289
+ /** Open streams on limited connections to the peers this allows. See `CallOnLimitedConnection`. */
290
+ callOnLimitedConnection?: CallOnLimitedConnection;
291
+ }
292
+ /**
293
+ * Build the `Remote` seam `createPeerRouter` forwards through: dial `target`
294
+ * over libp2p and run the request over the resulting `Duplex`. Outbound is
295
+ * definitionally identity-free — nothing here registers a peer binding,
296
+ * because the *caller's* proven identity has no meaning on a connection *we*
297
+ * initiated.
298
+ *
299
+ * Every rejection from the returned function is a `PeerCallError` (see
300
+ * `errors.ts` and `mapPeerCallError` above) — never a raw libp2p exception,
301
+ * and never an unbounded wait: the whole queue-dial-negotiate-respond
302
+ * sequence (T-3/Task 18 added the queueing step) is raced against
303
+ * `requestTimeoutMs`.
304
+ *
305
+ * ONE `Semaphore` PER `Remote`, NOT PER CALL: `createRemote` is called once
306
+ * per `Peer` (see `peer.ts`'s `createPeer`), so the semaphore built here is
307
+ * that peer's single, shared outbound admission gate for as long as the
308
+ * `Peer` lives -- every call through this `Remote`, to every target,
309
+ * competes for the same `maxConcurrentOutbound` permits. See
310
+ * `DEFAULT_MAX_CONCURRENT_OUTBOUND`'s doc comment for why that scope (global
311
+ * to this `Remote`, not per-target-peer) was chosen.
312
+ */
313
+ export declare function createRemote(init: CreateRemoteInit): Remote;
314
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}