@libp2p/yamux 7.0.4-0f07e3df5
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/README.md +127 -0
- package/dist/index.min.js +4 -0
- package/dist/index.min.js.map +7 -0
- package/dist/src/config.d.ts +30 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +41 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/constants.d.ts +12 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +22 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/decode.d.ts +34 -0
- package/dist/src/decode.d.ts.map +1 -0
- package/dist/src/decode.js +76 -0
- package/dist/src/decode.js.map +1 -0
- package/dist/src/encode.d.ts +3 -0
- package/dist/src/encode.d.ts.map +1 -0
- package/dist/src/encode.js +19 -0
- package/dist/src/encode.js.map +1 -0
- package/dist/src/errors.d.ts +40 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +70 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/frame.d.ts +54 -0
- package/dist/src/frame.d.ts.map +1 -0
- package/dist/src/frame.js +36 -0
- package/dist/src/frame.js.map +1 -0
- package/dist/src/index.d.ts +85 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +84 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/muxer.d.ts +91 -0
- package/dist/src/muxer.d.ts.map +1 -0
- package/dist/src/muxer.js +428 -0
- package/dist/src/muxer.js.map +1 -0
- package/dist/src/stream.d.ts +96 -0
- package/dist/src/stream.d.ts.map +1 -0
- package/dist/src/stream.js +253 -0
- package/dist/src/stream.js.map +1 -0
- package/package.json +95 -0
- package/src/config.ts +72 -0
- package/src/constants.ts +25 -0
- package/src/decode.ts +105 -0
- package/src/encode.ts +26 -0
- package/src/errors.ts +89 -0
- package/src/frame.ts +64 -0
- package/src/index.ts +90 -0
- package/src/muxer.ts +507 -0
- package/src/stream.ts +313 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { InvalidParametersError } from '@libp2p/interface';
|
|
2
|
+
import { INITIAL_STREAM_WINDOW, MAX_STREAM_WINDOW } from './constants.js';
|
|
3
|
+
export const defaultConfig = {
|
|
4
|
+
enableKeepAlive: true,
|
|
5
|
+
keepAliveInterval: 30_000,
|
|
6
|
+
maxInboundStreams: 1_000,
|
|
7
|
+
maxOutboundStreams: 1_000,
|
|
8
|
+
maxMessageSize: 64 * 1024,
|
|
9
|
+
maxEarlyStreams: 10,
|
|
10
|
+
streamOptions: {
|
|
11
|
+
initialStreamWindowSize: INITIAL_STREAM_WINDOW,
|
|
12
|
+
maxStreamWindowSize: MAX_STREAM_WINDOW,
|
|
13
|
+
inactivityTimeout: 120_000,
|
|
14
|
+
maxReadBufferLength: 4_194_304,
|
|
15
|
+
maxWriteBufferLength: Infinity
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
export function verifyConfig(config) {
|
|
19
|
+
if (config.keepAliveInterval != null && config.keepAliveInterval <= 0) {
|
|
20
|
+
throw new InvalidParametersError('keep-alive interval must be positive');
|
|
21
|
+
}
|
|
22
|
+
if (config.maxInboundStreams != null && config.maxInboundStreams < 0) {
|
|
23
|
+
throw new InvalidParametersError('max inbound streams must be larger or equal 0');
|
|
24
|
+
}
|
|
25
|
+
if (config.maxOutboundStreams != null && config.maxOutboundStreams < 0) {
|
|
26
|
+
throw new InvalidParametersError('max outbound streams must be larger or equal 0');
|
|
27
|
+
}
|
|
28
|
+
if (config.maxMessageSize != null && config.maxMessageSize < 1024) {
|
|
29
|
+
throw new InvalidParametersError('MaxMessageSize must be greater than a kilobyte');
|
|
30
|
+
}
|
|
31
|
+
if (config.streamOptions?.initialStreamWindowSize != null && config.streamOptions?.initialStreamWindowSize < INITIAL_STREAM_WINDOW) {
|
|
32
|
+
throw new InvalidParametersError('InitialStreamWindowSize must be larger or equal 256 kB');
|
|
33
|
+
}
|
|
34
|
+
if (config.streamOptions?.maxStreamWindowSize != null && config.streamOptions?.initialStreamWindowSize != null && config.streamOptions?.maxStreamWindowSize < config.streamOptions?.initialStreamWindowSize) {
|
|
35
|
+
throw new InvalidParametersError('MaxStreamWindowSize must be larger than the InitialStreamWindowSize');
|
|
36
|
+
}
|
|
37
|
+
if (config.streamOptions?.maxStreamWindowSize != null && config.streamOptions?.maxStreamWindowSize > 2 ** 32 - 1) {
|
|
38
|
+
throw new InvalidParametersError('MaxStreamWindowSize must be less than equal MAX_UINT32');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAgCzE,MAAM,CAAC,MAAM,aAAa,GAAuE;IAC/F,eAAe,EAAE,IAAI;IACrB,iBAAiB,EAAE,MAAM;IACzB,iBAAiB,EAAE,KAAK;IACxB,kBAAkB,EAAE,KAAK;IACzB,cAAc,EAAE,EAAE,GAAG,IAAI;IACzB,eAAe,EAAE,EAAE;IACnB,aAAa,EAAE;QACb,uBAAuB,EAAE,qBAAqB;QAC9C,mBAAmB,EAAE,iBAAiB;QACtC,iBAAiB,EAAE,OAAO;QAC1B,mBAAmB,EAAE,SAAS;QAC9B,oBAAoB,EAAE,QAAQ;KAC/B;CACF,CAAA;AAED,MAAM,UAAU,YAAY,CAAE,MAAc;IAC1C,IAAI,MAAM,CAAC,iBAAiB,IAAI,IAAI,IAAI,MAAM,CAAC,iBAAiB,IAAI,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,sBAAsB,CAAC,sCAAsC,CAAC,CAAA;IAC1E,CAAC;IACD,IAAI,MAAM,CAAC,iBAAiB,IAAI,IAAI,IAAI,MAAM,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,sBAAsB,CAAC,+CAA+C,CAAC,CAAA;IACnF,CAAC;IACD,IAAI,MAAM,CAAC,kBAAkB,IAAI,IAAI,IAAI,MAAM,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,sBAAsB,CAAC,gDAAgD,CAAC,CAAA;IACpF,CAAC;IACD,IAAI,MAAM,CAAC,cAAc,IAAI,IAAI,IAAI,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,CAAC;QAClE,MAAM,IAAI,sBAAsB,CAAC,gDAAgD,CAAC,CAAA;IACpF,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,EAAE,uBAAuB,IAAI,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE,uBAAuB,GAAG,qBAAqB,EAAE,CAAC;QACnI,MAAM,IAAI,sBAAsB,CAAC,wDAAwD,CAAC,CAAA;IAC5F,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,EAAE,mBAAmB,IAAI,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE,uBAAuB,IAAI,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE,mBAAmB,GAAG,MAAM,CAAC,aAAa,EAAE,uBAAuB,EAAE,CAAC;QAC5M,MAAM,IAAI,sBAAsB,CAAC,qEAAqE,CAAC,CAAA;IACzG,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,EAAE,mBAAmB,IAAI,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE,mBAAmB,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACjH,MAAM,IAAI,sBAAsB,CAAC,wDAAwD,CAAC,CAAA;IAC5F,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PROTOCOL_ERRORS: Set<string>;
|
|
2
|
+
/**
|
|
3
|
+
* INITIAL_STREAM_WINDOW is the initial stream window size.
|
|
4
|
+
*
|
|
5
|
+
* Not an implementation choice, this is defined in the specification
|
|
6
|
+
*/
|
|
7
|
+
export declare const INITIAL_STREAM_WINDOW: number;
|
|
8
|
+
/**
|
|
9
|
+
* Default max stream window
|
|
10
|
+
*/
|
|
11
|
+
export declare const MAX_STREAM_WINDOW: number;
|
|
12
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,aAQ1B,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAa,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAmB,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Protocol violation errors
|
|
2
|
+
import { BothClientsError, DecodeInvalidVersionError, InvalidFrameError, NotMatchingPingError, ReceiveWindowExceededError, StreamAlreadyExistsError, UnRequestedPingError } from './errors.js';
|
|
3
|
+
export const PROTOCOL_ERRORS = new Set([
|
|
4
|
+
InvalidFrameError.name,
|
|
5
|
+
UnRequestedPingError.name,
|
|
6
|
+
NotMatchingPingError.name,
|
|
7
|
+
StreamAlreadyExistsError.name,
|
|
8
|
+
DecodeInvalidVersionError.name,
|
|
9
|
+
BothClientsError.name,
|
|
10
|
+
ReceiveWindowExceededError.name
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* INITIAL_STREAM_WINDOW is the initial stream window size.
|
|
14
|
+
*
|
|
15
|
+
* Not an implementation choice, this is defined in the specification
|
|
16
|
+
*/
|
|
17
|
+
export const INITIAL_STREAM_WINDOW = 256 * 1024;
|
|
18
|
+
/**
|
|
19
|
+
* Default max stream window
|
|
20
|
+
*/
|
|
21
|
+
export const MAX_STREAM_WINDOW = 16 * 1024 * 1024;
|
|
22
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAE9L,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IACrC,iBAAiB,CAAC,IAAI;IACtB,oBAAoB,CAAC,IAAI;IACzB,oBAAoB,CAAC,IAAI;IACzB,wBAAwB,CAAC,IAAI;IAC7B,yBAAyB,CAAC,IAAI;IAC9B,gBAAgB,CAAC,IAAI;IACrB,0BAA0B,CAAC,IAAI;CAChC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,GAAG,IAAI,CAAA;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Uint8ArrayList } from 'uint8arraylist';
|
|
2
|
+
import type { FrameHeader } from './frame.js';
|
|
3
|
+
export interface Frame {
|
|
4
|
+
header: FrameHeader;
|
|
5
|
+
data?: Uint8ArrayList;
|
|
6
|
+
}
|
|
7
|
+
export interface DataFrame {
|
|
8
|
+
header: FrameHeader;
|
|
9
|
+
data: Uint8ArrayList;
|
|
10
|
+
}
|
|
11
|
+
export declare function isDataFrame(frame: Frame): frame is DataFrame;
|
|
12
|
+
/**
|
|
13
|
+
* Decode a header from the front of a buffer
|
|
14
|
+
*
|
|
15
|
+
* @param data - Assumed to have enough bytes for a header
|
|
16
|
+
*/
|
|
17
|
+
export declare function decodeHeader(data: Uint8Array): FrameHeader;
|
|
18
|
+
/**
|
|
19
|
+
* Decodes yamux frames from a source
|
|
20
|
+
*/
|
|
21
|
+
export declare class Decoder {
|
|
22
|
+
/** Buffer for in-progress frames */
|
|
23
|
+
private readonly buffer;
|
|
24
|
+
constructor();
|
|
25
|
+
/**
|
|
26
|
+
* Emits frames from the decoder source.
|
|
27
|
+
*
|
|
28
|
+
* Note: If `readData` is emitted, it _must_ be called before the next iteration
|
|
29
|
+
* Otherwise an error is thrown
|
|
30
|
+
*/
|
|
31
|
+
emitFrames(buf: Uint8Array | Uint8ArrayList): Generator<Frame>;
|
|
32
|
+
private readFrame;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=decode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/decode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,EAAE,cAAc,CAAA;CACrB;AAED,wBAAgB,WAAW,CAAE,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,SAAS,CAE7D;AAOD;;;;GAIG;AACH,wBAAgB,YAAY,CAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAW3D;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;;IAMvC;;;;;OAKG;IACD,UAAU,CAAE,GAAG,EAAE,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC;IAgBjE,OAAO,CAAC,SAAS;CA6BlB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Uint8ArrayList } from 'uint8arraylist';
|
|
2
|
+
import { InvalidFrameError } from './errors.js';
|
|
3
|
+
import { FrameType, HEADER_LENGTH, YAMUX_VERSION } from './frame.js';
|
|
4
|
+
export function isDataFrame(frame) {
|
|
5
|
+
return frame.header.type === FrameType.Data && frame.data !== null;
|
|
6
|
+
}
|
|
7
|
+
// used to bit shift in decoding
|
|
8
|
+
// native bit shift can overflow into a negative number, so we bit shift by
|
|
9
|
+
// multiplying by a power of 2
|
|
10
|
+
const twoPow24 = 2 ** 24;
|
|
11
|
+
/**
|
|
12
|
+
* Decode a header from the front of a buffer
|
|
13
|
+
*
|
|
14
|
+
* @param data - Assumed to have enough bytes for a header
|
|
15
|
+
*/
|
|
16
|
+
export function decodeHeader(data) {
|
|
17
|
+
if (data[0] !== YAMUX_VERSION) {
|
|
18
|
+
throw new InvalidFrameError('Invalid frame version');
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
type: data[1],
|
|
22
|
+
flag: (data[2] << 8) + data[3],
|
|
23
|
+
streamID: (data[4] * twoPow24) + (data[5] << 16) + (data[6] << 8) + data[7],
|
|
24
|
+
length: (data[8] * twoPow24) + (data[9] << 16) + (data[10] << 8) + data[11]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Decodes yamux frames from a source
|
|
29
|
+
*/
|
|
30
|
+
export class Decoder {
|
|
31
|
+
/** Buffer for in-progress frames */
|
|
32
|
+
buffer;
|
|
33
|
+
constructor() {
|
|
34
|
+
this.buffer = new Uint8ArrayList();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Emits frames from the decoder source.
|
|
38
|
+
*
|
|
39
|
+
* Note: If `readData` is emitted, it _must_ be called before the next iteration
|
|
40
|
+
* Otherwise an error is thrown
|
|
41
|
+
*/
|
|
42
|
+
*emitFrames(buf) {
|
|
43
|
+
this.buffer.append(buf);
|
|
44
|
+
// Loop to consume as many bytes from the buffer as possible
|
|
45
|
+
// Eg: when a single chunk contains several frames
|
|
46
|
+
while (true) {
|
|
47
|
+
const frame = this.readFrame();
|
|
48
|
+
if (frame === undefined) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
yield frame;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
readFrame() {
|
|
55
|
+
let frameSize = HEADER_LENGTH;
|
|
56
|
+
if (this.buffer.byteLength < HEADER_LENGTH) {
|
|
57
|
+
// not enough data yet
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// TODO: use sublist?
|
|
61
|
+
const header = decodeHeader(this.buffer.subarray(0, HEADER_LENGTH));
|
|
62
|
+
if (header.type === FrameType.Data) {
|
|
63
|
+
frameSize += header.length;
|
|
64
|
+
if (this.buffer.byteLength < frameSize) {
|
|
65
|
+
// not enough data yet
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const data = this.buffer.sublist(HEADER_LENGTH, frameSize);
|
|
69
|
+
this.buffer.consume(frameSize);
|
|
70
|
+
return { header, data };
|
|
71
|
+
}
|
|
72
|
+
this.buffer.consume(frameSize);
|
|
73
|
+
return { header };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=decode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/decode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/encode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,wBAAgB,YAAY,CAAE,MAAM,EAAE,WAAW,GAAG,UAAU,CAsB7D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HEADER_LENGTH } from './frame.js';
|
|
2
|
+
export function encodeHeader(header) {
|
|
3
|
+
const frame = new Uint8Array(HEADER_LENGTH);
|
|
4
|
+
// always assume version 0
|
|
5
|
+
// frameView.setUint8(0, header.version)
|
|
6
|
+
frame[1] = header.type;
|
|
7
|
+
frame[2] = header.flag >>> 8;
|
|
8
|
+
frame[3] = header.flag;
|
|
9
|
+
frame[4] = header.streamID >>> 24;
|
|
10
|
+
frame[5] = header.streamID >>> 16;
|
|
11
|
+
frame[6] = header.streamID >>> 8;
|
|
12
|
+
frame[7] = header.streamID;
|
|
13
|
+
frame[8] = header.length >>> 24;
|
|
14
|
+
frame[9] = header.length >>> 16;
|
|
15
|
+
frame[10] = header.length >>> 8;
|
|
16
|
+
frame[11] = header.length;
|
|
17
|
+
return frame;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=encode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/encode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG1C,MAAM,UAAU,YAAY,CAAE,MAAmB;IAC/C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAA;IAE3C,0BAA0B;IAC1B,wCAAwC;IAExC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAA;IAEtB,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA;IAC5B,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAA;IAEtB,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,KAAK,EAAE,CAAA;IACjC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,KAAK,EAAE,CAAA;IACjC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAA;IAChC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAA;IAE1B,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,EAAE,CAAA;IAC/B,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,EAAE,CAAA;IAC/B,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAA;IAC/B,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAA;IAEzB,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { GoAwayCode } from './frame.ts';
|
|
2
|
+
export declare class ProtocolError extends Error {
|
|
3
|
+
static name: string;
|
|
4
|
+
reason: GoAwayCode;
|
|
5
|
+
constructor(message: string, reason: GoAwayCode);
|
|
6
|
+
}
|
|
7
|
+
export declare function isProtocolError(err?: any): err is ProtocolError;
|
|
8
|
+
export declare class InvalidFrameError extends ProtocolError {
|
|
9
|
+
static name: string;
|
|
10
|
+
constructor(message?: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class UnRequestedPingError extends ProtocolError {
|
|
13
|
+
static name: string;
|
|
14
|
+
constructor(message?: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class NotMatchingPingError extends ProtocolError {
|
|
17
|
+
static name: string;
|
|
18
|
+
constructor(message?: string);
|
|
19
|
+
}
|
|
20
|
+
export declare class InvalidStateError extends Error {
|
|
21
|
+
static name: string;
|
|
22
|
+
constructor(message?: string);
|
|
23
|
+
}
|
|
24
|
+
export declare class StreamAlreadyExistsError extends ProtocolError {
|
|
25
|
+
static name: string;
|
|
26
|
+
constructor(message?: string);
|
|
27
|
+
}
|
|
28
|
+
export declare class DecodeInvalidVersionError extends ProtocolError {
|
|
29
|
+
static name: string;
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
export declare class BothClientsError extends ProtocolError {
|
|
33
|
+
static name: string;
|
|
34
|
+
constructor(message?: string);
|
|
35
|
+
}
|
|
36
|
+
export declare class ReceiveWindowExceededError extends ProtocolError {
|
|
37
|
+
static name: string;
|
|
38
|
+
constructor(message?: string);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,qBAAa,aAAc,SAAQ,KAAK;IACtC,MAAM,CAAC,IAAI,SAAkB;IAEtB,MAAM,EAAE,UAAU,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU;CAKjD;AAED,wBAAgB,eAAe,CAAE,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,IAAI,aAAa,CAEhE;AAED,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,MAAM,CAAC,IAAI,SAAsB;gBAEpB,OAAO,SAA0B;CAI/C;AAED,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,MAAM,CAAC,IAAI,SAAyB;gBAEvB,OAAO,SAA4B;CAIjD;AAED,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,MAAM,CAAC,IAAI,SAAyB;gBAEvB,OAAO,SAA4B;CAIjD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,MAAM,CAAC,IAAI,SAAsB;gBAEpB,OAAO,SAAkB;CAIvC;AAED,qBAAa,wBAAyB,SAAQ,aAAa;IACzD,MAAM,CAAC,IAAI,SAA6B;gBAE3B,OAAO,SAA0B;CAI/C;AAED,qBAAa,yBAA0B,SAAQ,aAAa;IAC1D,MAAM,CAAC,IAAI,SAA8B;gBAE5B,OAAO,SAA2B;CAIhD;AAED,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,MAAM,CAAC,IAAI,SAAqB;gBAEnB,OAAO,SAAiB;CAItC;AAED,qBAAa,0BAA2B,SAAQ,aAAa;IAC3D,MAAM,CAAC,IAAI,SAA+B;gBAE7B,OAAO,SAA4B;CAIjD"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { GoAwayCode } from "./frame.js";
|
|
2
|
+
export class ProtocolError extends Error {
|
|
3
|
+
static name = 'ProtocolError';
|
|
4
|
+
reason;
|
|
5
|
+
constructor(message, reason) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'ProtocolError';
|
|
8
|
+
this.reason = reason;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function isProtocolError(err) {
|
|
12
|
+
return err?.reason !== null;
|
|
13
|
+
}
|
|
14
|
+
export class InvalidFrameError extends ProtocolError {
|
|
15
|
+
static name = 'InvalidFrameError';
|
|
16
|
+
constructor(message = 'The frame was invalid') {
|
|
17
|
+
super(message, GoAwayCode.ProtocolError);
|
|
18
|
+
this.name = 'InvalidFrameError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class UnRequestedPingError extends ProtocolError {
|
|
22
|
+
static name = 'UnRequestedPingError';
|
|
23
|
+
constructor(message = 'Un-requested ping error') {
|
|
24
|
+
super(message, GoAwayCode.ProtocolError);
|
|
25
|
+
this.name = 'UnRequestedPingError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class NotMatchingPingError extends ProtocolError {
|
|
29
|
+
static name = 'NotMatchingPingError';
|
|
30
|
+
constructor(message = 'Not matching ping error') {
|
|
31
|
+
super(message, GoAwayCode.ProtocolError);
|
|
32
|
+
this.name = 'NotMatchingPingError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class InvalidStateError extends Error {
|
|
36
|
+
static name = 'InvalidStateError';
|
|
37
|
+
constructor(message = 'Invalid state') {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = 'InvalidStateError';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export class StreamAlreadyExistsError extends ProtocolError {
|
|
43
|
+
static name = 'StreamAlreadyExistsError';
|
|
44
|
+
constructor(message = 'Stream already exists') {
|
|
45
|
+
super(message, GoAwayCode.ProtocolError);
|
|
46
|
+
this.name = 'StreamAlreadyExistsError';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class DecodeInvalidVersionError extends ProtocolError {
|
|
50
|
+
static name = 'DecodeInvalidVersionError';
|
|
51
|
+
constructor(message = 'Decode invalid version') {
|
|
52
|
+
super(message, GoAwayCode.ProtocolError);
|
|
53
|
+
this.name = 'DecodeInvalidVersionError';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export class BothClientsError extends ProtocolError {
|
|
57
|
+
static name = 'BothClientsError';
|
|
58
|
+
constructor(message = 'Both clients') {
|
|
59
|
+
super(message, GoAwayCode.ProtocolError);
|
|
60
|
+
this.name = 'BothClientsError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class ReceiveWindowExceededError extends ProtocolError {
|
|
64
|
+
static name = 'ReceiveWindowExceededError';
|
|
65
|
+
constructor(message = 'Receive window exceeded') {
|
|
66
|
+
super(message, GoAwayCode.ProtocolError);
|
|
67
|
+
this.name = 'ReceiveWindowExceededError';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,MAAM,CAAC,IAAI,GAAG,eAAe,CAAA;IAEtB,MAAM,CAAY;IAEzB,YAAa,OAAe,EAAE,MAAkB;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;;AAGH,MAAM,UAAU,eAAe,CAAE,GAAS;IACxC,OAAO,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;AAC7B,CAAC;AAED,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAClD,MAAM,CAAC,IAAI,GAAG,mBAAmB,CAAA;IAEjC,YAAa,OAAO,GAAG,uBAAuB;QAC5C,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IACjC,CAAC;;AAGH,MAAM,OAAO,oBAAqB,SAAQ,aAAa;IACrD,MAAM,CAAC,IAAI,GAAG,sBAAsB,CAAA;IAEpC,YAAa,OAAO,GAAG,yBAAyB;QAC9C,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAA;IACpC,CAAC;;AAGH,MAAM,OAAO,oBAAqB,SAAQ,aAAa;IACrD,MAAM,CAAC,IAAI,GAAG,sBAAsB,CAAA;IAEpC,YAAa,OAAO,GAAG,yBAAyB;QAC9C,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAA;IACpC,CAAC;;AAGH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,MAAM,CAAC,IAAI,GAAG,mBAAmB,CAAA;IAEjC,YAAa,OAAO,GAAG,eAAe;QACpC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IACjC,CAAC;;AAGH,MAAM,OAAO,wBAAyB,SAAQ,aAAa;IACzD,MAAM,CAAC,IAAI,GAAG,0BAA0B,CAAA;IAExC,YAAa,OAAO,GAAG,uBAAuB;QAC5C,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;IACxC,CAAC;;AAGH,MAAM,OAAO,yBAA0B,SAAQ,aAAa;IAC1D,MAAM,CAAC,IAAI,GAAG,2BAA2B,CAAA;IAEzC,YAAa,OAAO,GAAG,wBAAwB;QAC7C,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAA;IACzC,CAAC;;AAGH,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IACjD,MAAM,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAEhC,YAAa,OAAO,GAAG,cAAc;QACnC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,CAAC;;AAGH,MAAM,OAAO,0BAA2B,SAAQ,aAAa;IAC3D,MAAM,CAAC,IAAI,GAAG,4BAA4B,CAAA;IAE1C,YAAa,OAAO,GAAG,yBAAyB;QAC9C,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAA;IAC1C,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare enum FrameType {
|
|
2
|
+
/** Used to transmit data. May transmit zero length payloads depending on the flags. */
|
|
3
|
+
Data = 0,
|
|
4
|
+
/** Used to updated the senders receive window size. This is used to implement per-session flow control. */
|
|
5
|
+
WindowUpdate = 1,
|
|
6
|
+
/** Used to measure RTT. It can also be used to heart-beat and do keep-alive over TCP. */
|
|
7
|
+
Ping = 2,
|
|
8
|
+
/** Used to close a session. */
|
|
9
|
+
GoAway = 3
|
|
10
|
+
}
|
|
11
|
+
export declare enum Flag {
|
|
12
|
+
/** Signals the start of a new stream. May be sent with a data or window update message. Also sent with a ping to indicate outbound. */
|
|
13
|
+
SYN = 1,
|
|
14
|
+
/** Acknowledges the start of a new stream. May be sent with a data or window update message. Also sent with a ping to indicate response. */
|
|
15
|
+
ACK = 2,
|
|
16
|
+
/** Performs a half-close of a stream. May be sent with a data message or window update. */
|
|
17
|
+
FIN = 4,
|
|
18
|
+
/** Reset a stream immediately. May be sent with a data or window update message. */
|
|
19
|
+
RST = 8
|
|
20
|
+
}
|
|
21
|
+
export declare const YAMUX_VERSION = 0;
|
|
22
|
+
export declare enum GoAwayCode {
|
|
23
|
+
NormalTermination = 0,
|
|
24
|
+
ProtocolError = 1,
|
|
25
|
+
InternalError = 2
|
|
26
|
+
}
|
|
27
|
+
export declare const HEADER_LENGTH = 12;
|
|
28
|
+
export interface FrameHeader {
|
|
29
|
+
/**
|
|
30
|
+
* The version field is used for future backward compatibility.
|
|
31
|
+
* At the current time, the field is always set to 0, to indicate the initial version.
|
|
32
|
+
*/
|
|
33
|
+
version?: number;
|
|
34
|
+
/** The type field is used to switch the frame message type. */
|
|
35
|
+
type: FrameType;
|
|
36
|
+
/** The flags field is used to provide additional information related to the message type. */
|
|
37
|
+
flag: number;
|
|
38
|
+
/**
|
|
39
|
+
* The StreamID field is used to identify the logical stream the frame is addressing.
|
|
40
|
+
* The client side should use odd ID's, and the server even.
|
|
41
|
+
* This prevents any collisions. Additionally, the 0 ID is reserved to represent the session.
|
|
42
|
+
*/
|
|
43
|
+
streamID: number;
|
|
44
|
+
/**
|
|
45
|
+
* The meaning of the length field depends on the message type:
|
|
46
|
+
* Data - provides the length of bytes following the header
|
|
47
|
+
* Window update - provides a delta update to the window size
|
|
48
|
+
* Ping - Contains an opaque value, echoed back
|
|
49
|
+
* Go Away - Contains an error code
|
|
50
|
+
*/
|
|
51
|
+
length: number;
|
|
52
|
+
}
|
|
53
|
+
export declare function stringifyHeader(header: FrameHeader): string;
|
|
54
|
+
//# sourceMappingURL=frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/frame.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,uFAAuF;IACvF,IAAI,IAAM;IACV,2GAA2G;IAC3G,YAAY,IAAM;IAClB,yFAAyF;IACzF,IAAI,IAAM;IACV,+BAA+B;IAC/B,MAAM,IAAM;CACb;AAED,oBAAY,IAAI;IACd,uIAAuI;IACvI,GAAG,IAAM;IACT,4IAA4I;IAC5I,GAAG,IAAM;IACT,2FAA2F;IAC3F,GAAG,IAAM;IACT,oFAAoF;IACpF,GAAG,IAAM;CACV;AAID,eAAO,MAAM,aAAa,IAAI,CAAA;AAE9B,oBAAY,UAAU;IACpB,iBAAiB,IAAM;IACvB,aAAa,IAAM;IACnB,aAAa,IAAM;CACpB;AAED,eAAO,MAAM,aAAa,KAAK,CAAA;AAE/B,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,+DAA+D;IAC/D,IAAI,EAAE,SAAS,CAAA;IACf,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,eAAe,CAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAG5D"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export var FrameType;
|
|
2
|
+
(function (FrameType) {
|
|
3
|
+
/** Used to transmit data. May transmit zero length payloads depending on the flags. */
|
|
4
|
+
FrameType[FrameType["Data"] = 0] = "Data";
|
|
5
|
+
/** Used to updated the senders receive window size. This is used to implement per-session flow control. */
|
|
6
|
+
FrameType[FrameType["WindowUpdate"] = 1] = "WindowUpdate";
|
|
7
|
+
/** Used to measure RTT. It can also be used to heart-beat and do keep-alive over TCP. */
|
|
8
|
+
FrameType[FrameType["Ping"] = 2] = "Ping";
|
|
9
|
+
/** Used to close a session. */
|
|
10
|
+
FrameType[FrameType["GoAway"] = 3] = "GoAway";
|
|
11
|
+
})(FrameType || (FrameType = {}));
|
|
12
|
+
export var Flag;
|
|
13
|
+
(function (Flag) {
|
|
14
|
+
/** Signals the start of a new stream. May be sent with a data or window update message. Also sent with a ping to indicate outbound. */
|
|
15
|
+
Flag[Flag["SYN"] = 1] = "SYN";
|
|
16
|
+
/** Acknowledges the start of a new stream. May be sent with a data or window update message. Also sent with a ping to indicate response. */
|
|
17
|
+
Flag[Flag["ACK"] = 2] = "ACK";
|
|
18
|
+
/** Performs a half-close of a stream. May be sent with a data message or window update. */
|
|
19
|
+
Flag[Flag["FIN"] = 4] = "FIN";
|
|
20
|
+
/** Reset a stream immediately. May be sent with a data or window update message. */
|
|
21
|
+
Flag[Flag["RST"] = 8] = "RST";
|
|
22
|
+
})(Flag || (Flag = {}));
|
|
23
|
+
const flagCodes = Object.values(Flag).filter((x) => typeof x !== 'string');
|
|
24
|
+
export const YAMUX_VERSION = 0;
|
|
25
|
+
export var GoAwayCode;
|
|
26
|
+
(function (GoAwayCode) {
|
|
27
|
+
GoAwayCode[GoAwayCode["NormalTermination"] = 0] = "NormalTermination";
|
|
28
|
+
GoAwayCode[GoAwayCode["ProtocolError"] = 1] = "ProtocolError";
|
|
29
|
+
GoAwayCode[GoAwayCode["InternalError"] = 2] = "InternalError";
|
|
30
|
+
})(GoAwayCode || (GoAwayCode = {}));
|
|
31
|
+
export const HEADER_LENGTH = 12;
|
|
32
|
+
export function stringifyHeader(header) {
|
|
33
|
+
const flags = flagCodes.filter(f => (header.flag & f) === f).map(f => Flag[f]).join('|');
|
|
34
|
+
return `streamID=${header.streamID} type=${FrameType[header.type]} flag=${flags} length=${header.length}`;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/frame.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,SASX;AATD,WAAY,SAAS;IACnB,uFAAuF;IACvF,yCAAU,CAAA;IACV,2GAA2G;IAC3G,yDAAkB,CAAA;IAClB,yFAAyF;IACzF,yCAAU,CAAA;IACV,+BAA+B;IAC/B,6CAAY,CAAA;AACd,CAAC,EATW,SAAS,KAAT,SAAS,QASpB;AAED,MAAM,CAAN,IAAY,IASX;AATD,WAAY,IAAI;IACd,uIAAuI;IACvI,6BAAS,CAAA;IACT,4IAA4I;IAC5I,6BAAS,CAAA;IACT,2FAA2F;IAC3F,6BAAS,CAAA;IACT,oFAAoF;IACpF,6BAAS,CAAA;AACX,CAAC,EATW,IAAI,KAAJ,IAAI,QASf;AAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAW,CAAA;AAEpF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAA;AAE9B,MAAM,CAAN,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,qEAAuB,CAAA;IACvB,6DAAmB,CAAA;IACnB,6DAAmB,CAAA;AACrB,CAAC,EAJW,UAAU,KAAV,UAAU,QAIrB;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAA;AA4B/B,MAAM,UAAU,eAAe,CAAE,MAAmB;IAClD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACxF,OAAO,YAAY,MAAM,CAAC,QAAQ,SAAS,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,WAAW,MAAM,CAAC,MAAM,EAAE,CAAA;AAC3G,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* This module is a JavaScript implementation of [Yamux from Hashicorp](https://github.com/hashicorp/yamux/blob/master/spec.md) designed to be used with [js-libp2p](https://github.com/libp2p/js-libp2p).
|
|
5
|
+
*
|
|
6
|
+
* @example Configure libp2p with Yamux
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createLibp2p } from 'libp2p'
|
|
10
|
+
* import { yamux } from '@libp2p/yamux'
|
|
11
|
+
*
|
|
12
|
+
* const node = await createLibp2p({
|
|
13
|
+
* // ... other options
|
|
14
|
+
* streamMuxers: [
|
|
15
|
+
* yamux()
|
|
16
|
+
* ]
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @example Using the low-level API
|
|
21
|
+
*
|
|
22
|
+
* ```js
|
|
23
|
+
* import { yamux } from '@libp2p/yamux'
|
|
24
|
+
* import { pipe } from 'it-pipe'
|
|
25
|
+
* import { duplexPair } from 'it-pair/duplex'
|
|
26
|
+
* import all from 'it-all'
|
|
27
|
+
*
|
|
28
|
+
* // Connect two yamux muxers to demo basic stream multiplexing functionality
|
|
29
|
+
*
|
|
30
|
+
* const clientMuxer = yamux({
|
|
31
|
+
* client: true,
|
|
32
|
+
* onIncomingStream: stream => {
|
|
33
|
+
* // echo data on incoming streams
|
|
34
|
+
* pipe(stream, stream)
|
|
35
|
+
* },
|
|
36
|
+
* onStreamEnd: stream => {
|
|
37
|
+
* // do nothing
|
|
38
|
+
* }
|
|
39
|
+
* })()
|
|
40
|
+
*
|
|
41
|
+
* const serverMuxer = yamux({
|
|
42
|
+
* client: false,
|
|
43
|
+
* onIncomingStream: stream => {
|
|
44
|
+
* // echo data on incoming streams
|
|
45
|
+
* pipe(stream, stream)
|
|
46
|
+
* },
|
|
47
|
+
* onStreamEnd: stream => {
|
|
48
|
+
* // do nothing
|
|
49
|
+
* }
|
|
50
|
+
* })()
|
|
51
|
+
*
|
|
52
|
+
* // `p` is our "connections", what we use to connect the two sides
|
|
53
|
+
* // In a real application, a connection is usually to a remote computer
|
|
54
|
+
* const p = duplexPair()
|
|
55
|
+
*
|
|
56
|
+
* // connect the muxers together
|
|
57
|
+
* pipe(p[0], clientMuxer, p[0])
|
|
58
|
+
* pipe(p[1], serverMuxer, p[1])
|
|
59
|
+
*
|
|
60
|
+
* // now either side can open streams
|
|
61
|
+
* const stream0 = clientMuxer.newStream()
|
|
62
|
+
* const stream1 = serverMuxer.newStream()
|
|
63
|
+
*
|
|
64
|
+
* // Send some data to the other side
|
|
65
|
+
* const encoder = new TextEncoder()
|
|
66
|
+
* const data = [encoder.encode('hello'), encoder.encode('world')]
|
|
67
|
+
* pipe(data, stream0)
|
|
68
|
+
*
|
|
69
|
+
* // Receive data back
|
|
70
|
+
* const result = await pipe(stream0, all)
|
|
71
|
+
*
|
|
72
|
+
* // close a stream
|
|
73
|
+
* stream1.close()
|
|
74
|
+
*
|
|
75
|
+
* // close the muxer
|
|
76
|
+
* clientMuxer.close()
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
import type { YamuxMuxer, YamuxMuxerInit } from './muxer.js';
|
|
80
|
+
import type { StreamMuxerFactory } from '@libp2p/interface';
|
|
81
|
+
export { GoAwayCode } from './frame.js';
|
|
82
|
+
export type { FrameHeader, FrameType } from './frame.js';
|
|
83
|
+
export type { YamuxMuxerInit };
|
|
84
|
+
export declare function yamux(init?: YamuxMuxerInit): () => StreamMuxerFactory<YamuxMuxer>;
|
|
85
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,wBAAgB,KAAK,CAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAEtF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* This module is a JavaScript implementation of [Yamux from Hashicorp](https://github.com/hashicorp/yamux/blob/master/spec.md) designed to be used with [js-libp2p](https://github.com/libp2p/js-libp2p).
|
|
5
|
+
*
|
|
6
|
+
* @example Configure libp2p with Yamux
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createLibp2p } from 'libp2p'
|
|
10
|
+
* import { yamux } from '@libp2p/yamux'
|
|
11
|
+
*
|
|
12
|
+
* const node = await createLibp2p({
|
|
13
|
+
* // ... other options
|
|
14
|
+
* streamMuxers: [
|
|
15
|
+
* yamux()
|
|
16
|
+
* ]
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @example Using the low-level API
|
|
21
|
+
*
|
|
22
|
+
* ```js
|
|
23
|
+
* import { yamux } from '@libp2p/yamux'
|
|
24
|
+
* import { pipe } from 'it-pipe'
|
|
25
|
+
* import { duplexPair } from 'it-pair/duplex'
|
|
26
|
+
* import all from 'it-all'
|
|
27
|
+
*
|
|
28
|
+
* // Connect two yamux muxers to demo basic stream multiplexing functionality
|
|
29
|
+
*
|
|
30
|
+
* const clientMuxer = yamux({
|
|
31
|
+
* client: true,
|
|
32
|
+
* onIncomingStream: stream => {
|
|
33
|
+
* // echo data on incoming streams
|
|
34
|
+
* pipe(stream, stream)
|
|
35
|
+
* },
|
|
36
|
+
* onStreamEnd: stream => {
|
|
37
|
+
* // do nothing
|
|
38
|
+
* }
|
|
39
|
+
* })()
|
|
40
|
+
*
|
|
41
|
+
* const serverMuxer = yamux({
|
|
42
|
+
* client: false,
|
|
43
|
+
* onIncomingStream: stream => {
|
|
44
|
+
* // echo data on incoming streams
|
|
45
|
+
* pipe(stream, stream)
|
|
46
|
+
* },
|
|
47
|
+
* onStreamEnd: stream => {
|
|
48
|
+
* // do nothing
|
|
49
|
+
* }
|
|
50
|
+
* })()
|
|
51
|
+
*
|
|
52
|
+
* // `p` is our "connections", what we use to connect the two sides
|
|
53
|
+
* // In a real application, a connection is usually to a remote computer
|
|
54
|
+
* const p = duplexPair()
|
|
55
|
+
*
|
|
56
|
+
* // connect the muxers together
|
|
57
|
+
* pipe(p[0], clientMuxer, p[0])
|
|
58
|
+
* pipe(p[1], serverMuxer, p[1])
|
|
59
|
+
*
|
|
60
|
+
* // now either side can open streams
|
|
61
|
+
* const stream0 = clientMuxer.newStream()
|
|
62
|
+
* const stream1 = serverMuxer.newStream()
|
|
63
|
+
*
|
|
64
|
+
* // Send some data to the other side
|
|
65
|
+
* const encoder = new TextEncoder()
|
|
66
|
+
* const data = [encoder.encode('hello'), encoder.encode('world')]
|
|
67
|
+
* pipe(data, stream0)
|
|
68
|
+
*
|
|
69
|
+
* // Receive data back
|
|
70
|
+
* const result = await pipe(stream0, all)
|
|
71
|
+
*
|
|
72
|
+
* // close a stream
|
|
73
|
+
* stream1.close()
|
|
74
|
+
*
|
|
75
|
+
* // close the muxer
|
|
76
|
+
* clientMuxer.close()
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
import { Yamux } from './muxer.js';
|
|
80
|
+
export { GoAwayCode } from './frame.js';
|
|
81
|
+
export function yamux(init = {}) {
|
|
82
|
+
return () => new Yamux(init);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAIlC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIvC,MAAM,UAAU,KAAK,CAAE,OAAuB,EAAE;IAC9C,OAAO,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAA;AAC9B,CAAC"}
|