@statewalker/webrun-streams-libp2p 0.1.1
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.
- package/LICENSE +21 -0
- package/README.md +82 -0
- package/dist/connect-serve.d.ts +96 -0
- package/dist/connect-serve.d.ts.map +1 -0
- package/dist/duplex-over-stream.d.ts +68 -0
- package/dist/duplex-over-stream.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +405 -0
- package/package.json +61 -0
- package/src/connect-serve.ts +309 -0
- package/src/duplex-over-stream.ts +367 -0
- package/src/index.ts +15 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2026 statewalker
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @statewalker/webrun-streams-libp2p
|
|
2
|
+
|
|
3
|
+
libp2p native multi-stream `Connect` / `Serve` adapter. Each `call(input)` opens a new libp2p `Stream` via `node.dialProtocol(peer, [protocol])`; the responder registers via `node.handle(protocol, ...)`. Default protocol id: `/webrun-streams/1.0.0`. Targets libp2p 3.x.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { connect, serve } from "@statewalker/webrun-streams-libp2p";
|
|
7
|
+
|
|
8
|
+
const { call, close } = await connect({ node, peer, protocol: "/my-app/1.0.0" });
|
|
9
|
+
const stop = await serve({ node, protocol: "/my-app/1.0.0" }, handler);
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Knowing who is calling
|
|
13
|
+
|
|
14
|
+
`Duplex` is bytes-only and gains no new parameter, so the serving side exposes identity through a separate entry point: `serveConnections` builds a handler **per inbound stream** and hands it the connection libp2p authenticated.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { serveConnections } from "@statewalker/webrun-streams-libp2p";
|
|
18
|
+
|
|
19
|
+
const stop = await serveConnections({ node }, (context) => {
|
|
20
|
+
const who = context.remotePeer; // PeerId, from the Noise handshake
|
|
21
|
+
return async function* handler(input) {
|
|
22
|
+
for await (const chunk of input) yield respondTo(who, chunk);
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`context.remotePeer` is `connection.remotePeer` — the peer id libp2p proved when the connection was encrypted. It is the one identity claim on the serving side a request payload cannot forge, and it reaches the handler by closure rather than by argument, so no caller can influence it. Build any per-peer state inside `makeHandler`, not outside it: the function runs once per stream, and reusing one handler for every connection is exactly how identity-by-closure gets broken.
|
|
28
|
+
|
|
29
|
+
`serve` is `serveConnections` with the context ignored, so both share the same framing, teardown and failure handling.
|
|
30
|
+
|
|
31
|
+
## Stream limits
|
|
32
|
+
|
|
33
|
+
libp2p caps how many streams for one protocol may be open at once **per connection**, and past the cap a new stream is reset rather than queued. This adapter opens one stream per `call`, so a caller with more concurrent requests than the cap starts seeing rejected calls with no other symptom. The three knobs below are passed straight through to `node.dialProtocol` / `node.handle` — this package sets no defaults of its own, and an option left unset is omitted from the options object entirely so libp2p's own default applies.
|
|
34
|
+
|
|
35
|
+
| Option | On | libp2p default (3.3.8) |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| `maxInboundStreams` | `serve` / `serveConnections` | **32** |
|
|
38
|
+
| `maxOutboundStreams` | `connect`, `serve` / `serveConnections` | **64** |
|
|
39
|
+
| `runOnLimitedConnection` | `connect`, `serve` / `serveConnections` | unset — libp2p refuses this protocol on a limited connection |
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const stop = await serve({ node, maxInboundStreams: 128 }, handler);
|
|
43
|
+
const { call } = await connect({ node, peer, maxOutboundStreams: 128 });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`runOnLimitedConnection` opts in to running over a connection with limits on how much data can be transferred or how long it can stay open — a relayed circuit being the usual case. This package does not decide that trade-off for you; it only exposes the knob. `tests/stream-limits.test.ts` pins both halves: a raised `maxInboundStreams` really does admit more than 32 concurrent streams, and an unconfigured server still stops at exactly 32.
|
|
47
|
+
|
|
48
|
+
## Framing
|
|
49
|
+
|
|
50
|
+
The adapter puts a small frame on top of the libp2p stream:
|
|
51
|
+
|
|
52
|
+
[type:1][length:varint][payload]
|
|
53
|
+
|
|
54
|
+
`DATA` (`0x00`) carries body bytes; `ERROR` (`0x02`) carries a JSON-serialised `Error`. The error frame exists because yamux's native `StreamResetError` discards the message — without it, a handler that throws reaches the caller as an anonymous reset. Normal end-of-input is libp2p's own `close()`, not a frame.
|
|
55
|
+
|
|
56
|
+
## Flow control, and what libp2p 3.x does not give you for free
|
|
57
|
+
|
|
58
|
+
libp2p 3.x streams are **push-based**: `stream.send(chunk)` returns `false` when the write buffer is full, and the stream emits `'drain'` when it can take more. (2.x's pull-based `sink(AsyncIterable)` is gone, and with it the illusion that yamux's credit window applies backpressure to a source on its own.) The outbound pump therefore honours `send()`'s return value and waits for the real `'drain'` event.
|
|
59
|
+
|
|
60
|
+
It deliberately does **not** use `stream.onDrain()`: that method memoises one promise for the stream's whole lifetime and never clears it (`@libp2p/utils@7.3.2`), so past the first backpressure cycle it resolves immediately while the buffer is still full — a write loop built on it floods the buffer without bound. `tests/backpressure.test.ts` is a regression test for exactly that.
|
|
61
|
+
|
|
62
|
+
Two bounds keep a misbehaving peer from parking a long-lived server:
|
|
63
|
+
|
|
64
|
+
- **Drain timeout** — `DEFAULT_DRAIN_TIMEOUT_MS` (5 minutes), overridable per connection via `drainTimeoutMs` on `connect`/`serve`/`serveConnections` params. A peer that requests something and then stops reading, without closing or resetting, produces no event at all; unbounded, it parks the serving side's pump, the handler and everything buffered behind it forever. The bound is generous on purpose — resetting a slow-but-alive peer is the thing backpressure exists to avoid — and expiry is logged, then unwound by aborting the stream.
|
|
65
|
+
- **Close timeout** — 5 s (2.x's own `DEFAULT_SEND_CLOSE_WRITE_TIMEOUT`) around the graceful `stream.close()`, falling back to `abort()`. Because the pump awaits drain before every `send()`, at most the final chunk is outstanding at close time. A trip is logged, including that the peer may see truncated data.
|
|
66
|
+
|
|
67
|
+
## Failure handling
|
|
68
|
+
|
|
69
|
+
One inbound stream failing never takes down the serving process. `duplexOverStream` rejects on the read side when a peer sends an `ERROR` frame or resets mid-request — which happens in ordinary use, a browser tab closed mid-request being enough — and `serveConnections` catches that per stream and logs it. Callers see their own errors as usual: cancelling a `call` (i.e. `.return()` on the returned generator) sends a reset, and `close()` on the connection aborts every stream it still holds open.
|
|
70
|
+
|
|
71
|
+
## Tests
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pnpm test # backpressure, drain timeout, identity, resilience
|
|
75
|
+
WEBRUN_STREAMS_LIBP2P=1 pnpm test # + the framing/conformance suite
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The conformance suite is opt-in because it spins up two real libp2p TCP nodes in-process.
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Libp2p, PeerId } from "@libp2p/interface";
|
|
2
|
+
import type { Multiaddr } from "@multiformats/multiaddr";
|
|
3
|
+
import type { Connect, Duplex, Serve } from "@statewalker/webrun-streams";
|
|
4
|
+
export declare const DEFAULT_PROTOCOL = "/webrun-streams/1.0.0";
|
|
5
|
+
export interface ConnectLibp2pParams {
|
|
6
|
+
node: Libp2p;
|
|
7
|
+
peer: PeerId | Multiaddr;
|
|
8
|
+
/** libp2p protocol id; defaults to `/webrun-streams/1.0.0`. */
|
|
9
|
+
protocol?: string;
|
|
10
|
+
/**
|
|
11
|
+
* How long to wait for a backpressured stream to drain before dropping the
|
|
12
|
+
* peer; defaults to `DEFAULT_DRAIN_TIMEOUT_MS` (5 minutes).
|
|
13
|
+
*/
|
|
14
|
+
drainTimeoutMs?: number;
|
|
15
|
+
/**
|
|
16
|
+
* How many outgoing streams for this protocol libp2p allows to be open at
|
|
17
|
+
* the same time on one connection; passed through to `node.dialProtocol`.
|
|
18
|
+
* Left unset, libp2p's own default (64) applies.
|
|
19
|
+
*/
|
|
20
|
+
maxOutboundStreams?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Opt-in to dialing over a connection with limits on how much data can be
|
|
23
|
+
* transferred or how long it can be open for (e.g. a relayed circuit);
|
|
24
|
+
* passed through to `node.dialProtocol`. Left unset, libp2p refuses to open
|
|
25
|
+
* this protocol's stream on such a connection — this package does not
|
|
26
|
+
* decide that trade-off for the caller, it only exposes the knob.
|
|
27
|
+
*/
|
|
28
|
+
runOnLimitedConnection?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface ServeLibp2pParams {
|
|
31
|
+
node: Libp2p;
|
|
32
|
+
/** libp2p protocol id; defaults to `/webrun-streams/1.0.0`. */
|
|
33
|
+
protocol?: string;
|
|
34
|
+
/**
|
|
35
|
+
* How long to wait for a backpressured stream to drain before dropping the
|
|
36
|
+
* peer; defaults to `DEFAULT_DRAIN_TIMEOUT_MS` (5 minutes). This is the only
|
|
37
|
+
* bound on a peer that requests something and then stops reading without
|
|
38
|
+
* closing, since the caller-side `.return`/abort escape does not exist here.
|
|
39
|
+
*/
|
|
40
|
+
drainTimeoutMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* How many incoming streams for this protocol libp2p allows to be open at
|
|
43
|
+
* the same time on one connection; passed through to `node.handle`. Left
|
|
44
|
+
* unset, libp2p's own default (32) applies — past it, a new inbound stream
|
|
45
|
+
* is reset rather than queued, so a caller that opens one stream per
|
|
46
|
+
* in-flight request will start seeing rejected calls above that count.
|
|
47
|
+
*/
|
|
48
|
+
maxInboundStreams?: number;
|
|
49
|
+
/**
|
|
50
|
+
* How many outgoing streams for this protocol libp2p allows to be open at
|
|
51
|
+
* the same time on one connection; passed through to `node.handle`. Left
|
|
52
|
+
* unset, libp2p's own default (64) applies.
|
|
53
|
+
*/
|
|
54
|
+
maxOutboundStreams?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Opt-in to accepting streams for this protocol over a connection with
|
|
57
|
+
* limits on how much data can be transferred or how long it can be open
|
|
58
|
+
* for (e.g. a relayed circuit); passed through to `node.handle`. Left
|
|
59
|
+
* unset, libp2p refuses to open this protocol's stream on such a
|
|
60
|
+
* connection — this package does not decide that trade-off for the
|
|
61
|
+
* consumer, it only exposes the knob.
|
|
62
|
+
*/
|
|
63
|
+
runOnLimitedConnection?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Caller-side: each `call(input)` opens a new libp2p `Stream` via
|
|
67
|
+
* `node.dialProtocol(peer, [protocol])` and runs the call over it.
|
|
68
|
+
*/
|
|
69
|
+
export declare const connect: Connect<ConnectLibp2pParams>;
|
|
70
|
+
/**
|
|
71
|
+
* Server-side: registers `node.handle(protocol, ...)`. Each inbound stream is
|
|
72
|
+
* wrapped as a `Duplex` and handed to `handler`. Identity-unaware; use
|
|
73
|
+
* `serveConnections` when the handler needs to know who is calling.
|
|
74
|
+
*/
|
|
75
|
+
export declare const serve: Serve<ServeLibp2pParams>;
|
|
76
|
+
/** What the serving side knows about the connection a stream arrived on. */
|
|
77
|
+
export interface ConnectionContext {
|
|
78
|
+
/**
|
|
79
|
+
* The peer id libp2p's Noise handshake proved for this connection. This is
|
|
80
|
+
* the only identity claim on the serving side that cannot be forged by the
|
|
81
|
+
* request payload.
|
|
82
|
+
*/
|
|
83
|
+
remotePeer: PeerId;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Builds a handler for one inbound connection. Called once per stream, so the
|
|
87
|
+
* connection stays reachable in the returned Duplex's closure — `Duplex` is
|
|
88
|
+
* bytes-only (ADR-0004) and gains no new parameter.
|
|
89
|
+
*/
|
|
90
|
+
export type ServeConnectionsHandler = (context: ConnectionContext) => Duplex;
|
|
91
|
+
/**
|
|
92
|
+
* Like `serve`, but the handler is built per inbound stream and is told which
|
|
93
|
+
* peer libp2p proved on that connection.
|
|
94
|
+
*/
|
|
95
|
+
export declare function serveConnections({ node, protocol, drainTimeoutMs, maxInboundStreams, maxOutboundStreams, runOnLimitedConnection, }: ServeLibp2pParams, makeHandler: ServeConnectionsHandler): Promise<() => Promise<void>>;
|
|
96
|
+
//# sourceMappingURL=connect-serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-serve.d.ts","sourceRoot":"","sources":["../src/connect-serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,MAAM,EACN,MAAM,EAGP,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAG1E,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAqBD;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAuEhD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,iBAAiB,CACF,CAAC;AAE1C,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,MAAM,CAAC;AAE7E;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,EACE,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACvB,EAAE,iBAAiB,EACpB,WAAW,EAAE,uBAAuB,GACnC,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAiD9B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Stream } from "@libp2p/interface";
|
|
2
|
+
/**
|
|
3
|
+
* Default bound for {@link waitForDrain}'s wait for the peer to make room in
|
|
4
|
+
* its receive window. Without a bound, a peer that requests something and then
|
|
5
|
+
* simply stops reading — alive, so no `close` event ever fires — parks the
|
|
6
|
+
* serving side's outbound pump forever, holding the stream, the handler and
|
|
7
|
+
* whatever the handler buffered. On the serving side there is no escape hatch:
|
|
8
|
+
* `connect`'s `.return`/abort override is a *caller*-side affordance.
|
|
9
|
+
*
|
|
10
|
+
* The number is deliberately generous, because a bound that is too tight
|
|
11
|
+
* resets a slow-but-alive peer mid-transfer — exactly what backpressure exists
|
|
12
|
+
* to avoid. Five minutes covers a peer draining a full yamux receive window
|
|
13
|
+
* (256 KiB by default) at under 1 KiB/s, i.e. slower than any link on which
|
|
14
|
+
* the transfer would complete anyway; a peer slower than that is
|
|
15
|
+
* indistinguishable from one that has stopped reading altogether. Override via
|
|
16
|
+
* `drainTimeoutMs` when a deployment knows better.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_DRAIN_TIMEOUT_MS = 300000;
|
|
19
|
+
/**
|
|
20
|
+
* Options for {@link duplexOverStream}. The `onPeerInputEnd` hook is the seam
|
|
21
|
+
* that lets the server side close its input queue as soon as the peer's source
|
|
22
|
+
* exhausts — without it, the server-side `serve` would deadlock waiting for the
|
|
23
|
+
* outbound pump to finish, which itself waits for the handler, which waits for
|
|
24
|
+
* inputQueue.done.
|
|
25
|
+
*/
|
|
26
|
+
export interface DuplexOverStreamOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Fired when the peer's source ends (peer closed write, sent an ERROR frame,
|
|
29
|
+
* or the stream itself was torn down). Idempotent. The optional `err`
|
|
30
|
+
* argument carries the deserialized error from an ERROR frame, if any.
|
|
31
|
+
*/
|
|
32
|
+
onPeerInputEnd?(err?: Error): void;
|
|
33
|
+
/**
|
|
34
|
+
* Fired only when the peer's source ended naturally — i.e., consumer did not
|
|
35
|
+
* `.return()` mid-stream. Connect/serve uses this to decide whether to
|
|
36
|
+
* gracefully close vs forcibly abort the underlying stream on teardown.
|
|
37
|
+
*/
|
|
38
|
+
onSourceCompleted?(): void;
|
|
39
|
+
/**
|
|
40
|
+
* How long to wait for a backpressured stream to drain before giving up on
|
|
41
|
+
* the peer. Defaults to {@link DEFAULT_DRAIN_TIMEOUT_MS}.
|
|
42
|
+
*/
|
|
43
|
+
drainTimeoutMs?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Drive one `Duplex` over one libp2p `Stream` using a small in-band framing
|
|
47
|
+
* protocol:
|
|
48
|
+
*
|
|
49
|
+
* [1-byte type][varint length][payload bytes]
|
|
50
|
+
*
|
|
51
|
+
* Types are `DATA` (0x00, body bytes) and `ERROR` (0x02, followed by a
|
|
52
|
+
* JSON-serialised `Error`). Normal end-of-input is signalled by libp2p's
|
|
53
|
+
* `close()`. The frame layer exists so we can preserve `Error` fidelity
|
|
54
|
+
* across the wire (yamux's native stream reset only carries "stream reset").
|
|
55
|
+
*/
|
|
56
|
+
export declare function duplexOverStream(stream: Stream, input: AsyncIterable<Uint8Array> | Iterable<Uint8Array>, opts?: DuplexOverStreamOptions): AsyncGenerator<Uint8Array>;
|
|
57
|
+
/**
|
|
58
|
+
* Close a `Stream`'s writable end, bounded by `timeoutMs`. Plain
|
|
59
|
+
* `stream.close()` awaits the write queue draining and the peer
|
|
60
|
+
* acknowledging with no bound of its own — a peer that stops reading
|
|
61
|
+
* without resetting (a suspended tab, a paused container, `SIGSTOP`) means
|
|
62
|
+
* it never settles, which would otherwise hang every caller waiting on it
|
|
63
|
+
* (the outbound pump here, and `connect`/`serve`'s teardown in
|
|
64
|
+
* `connect-serve.ts`). On timeout we fall back to a hard `abort()` so the
|
|
65
|
+
* caller is never left hanging.
|
|
66
|
+
*/
|
|
67
|
+
export declare function closeStream(stream: Stream, timeoutMs?: number): Promise<void>;
|
|
68
|
+
//# sourceMappingURL=duplex-over-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplex-over-stream.d.ts","sourceRoot":"","sources":["../src/duplex-over-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAoB,MAAM,mBAAmB,CAAC;AAclE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,SAAU,CAAC;AAKhD;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,IAAI,CAAC;IAC3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAuB,gBAAgB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,EACvD,IAAI,GAAE,uBAA4B,GACjC,cAAc,CAAC,UAAU,CAAC,CAoF5B;AA2CD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAiC,GAC3C,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { type ConnectionContext, type ConnectLibp2pParams, connect, DEFAULT_PROTOCOL, type ServeConnectionsHandler, type ServeLibp2pParams, serve, serveConnections, } from "./connect-serve.js";
|
|
2
|
+
export { DEFAULT_DRAIN_TIMEOUT_MS, type DuplexOverStreamOptions, duplexOverStream, } from "./duplex-over-stream.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,OAAO,EACP,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,EACL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,wBAAwB,EACxB,KAAK,uBAAuB,EAC5B,gBAAgB,GACjB,MAAM,yBAAyB,CAAC"}
|