@libp2p/mplex 1.0.1 → 1.0.2

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.
@@ -1,63 +1,11 @@
1
- import { Pushable } from 'it-pushable';
2
- import { Message } from './message-types.js';
3
- import type { Sink } from 'it-stream-types';
4
- import type { Muxer, MuxerOptions } from '@libp2p/interfaces/stream-muxer';
5
- import type { Stream } from '@libp2p/interfaces/connection';
6
- import type { ComponentMetricsTracker } from '@libp2p/interfaces/metrics';
7
- export interface MplexStream extends Stream {
8
- source: Pushable<Uint8Array>;
9
- }
10
- export interface MplexOptions extends MuxerOptions {
1
+ import type { Components } from '@libp2p/interfaces/components';
2
+ import type { StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interfaces/stream-muxer';
3
+ import { MplexStreamMuxer } from './mplex.js';
4
+ export interface MplexInit extends StreamMuxerInit {
11
5
  maxMsgSize?: number;
12
- metrics?: ComponentMetricsTracker;
13
6
  }
14
- export declare class Mplex implements Muxer {
15
- static multicodec: string;
16
- sink: Sink<Uint8Array>;
17
- source: AsyncIterable<Uint8Array>;
18
- private _streamId;
19
- private readonly _streams;
20
- private readonly _options;
21
- private readonly _source;
22
- constructor(options?: MplexOptions);
23
- /**
24
- * Returns a Map of streams and their ids
25
- */
26
- get streams(): Stream[];
27
- /**
28
- * Initiate a new stream with the given name. If no name is
29
- * provided, the id of the stream will be used.
30
- */
31
- newStream(name?: string): Stream;
32
- /**
33
- * Called whenever an inbound stream is created
34
- */
35
- _newReceiverStream(options: {
36
- id: number;
37
- name: string;
38
- }): MplexStream;
39
- _newStream(options: {
40
- id: number;
41
- name: string;
42
- type: 'initiator' | 'receiver';
43
- registry: Map<number, MplexStream>;
44
- }): MplexStream;
45
- /**
46
- * Creates a sink with an abortable source. Incoming messages will
47
- * also have their size restricted. All messages will be varint decoded.
48
- */
49
- _createSink(): Sink<Uint8Array, Promise<void>>;
50
- /**
51
- * Creates a source that restricts outgoing message sizes
52
- * and varint encodes them
53
- */
54
- _createSource(): AsyncGenerator<Uint8Array, void, undefined> & {
55
- push: (value: Message) => import("it-pushable").PushableV<Message>;
56
- end: (err?: Error | undefined) => import("it-pushable").PushableV<Message>;
57
- return: () => {
58
- done: boolean;
59
- };
60
- };
61
- _handleIncoming(message: Message): void;
7
+ export declare class Mplex implements StreamMuxerFactory {
8
+ protocol: string;
9
+ createStreamMuxer(components: Components, init?: MplexInit): MplexStreamMuxer;
62
10
  }
63
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAA;AAKjD,OAAO,EAAkC,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAK5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AAsBzE,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,uBAAuB,CAAA;CAClC;AAED,qBAAa,KAAM,YAAW,KAAK;IACjC,MAAM,CAAC,UAAU,SAAiB;IAE3B,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IACtB,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAExC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+E;IACxG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8D;gBAEzE,OAAO,CAAC,EAAE,YAAY;IA6BnC;;OAEG;IACH,IAAI,OAAO,aAUV;IAED;;;OAGG;IACH,SAAS,CAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAOjC;;OAEG;IACH,kBAAkB,CAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAMzD,UAAU,CAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;KAAE;IAmCrH;;;OAGG;IACH,WAAW;IA+BX;;;OAGG;IACH,aAAa;;;;;;;IAoBb,eAAe,CAAE,OAAO,EAAE,OAAO;CA0ClC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,WAAW,SAAU,SAAQ,eAAe;IAChD,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,KAAM,YAAW,kBAAkB;IACvC,QAAQ,SAAiB;IAEhC,iBAAiB,CAAE,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS;CAG5D"}
package/dist/src/index.js CHANGED
@@ -1,196 +1,10 @@
1
- import { pipe } from 'it-pipe';
2
- import { pushableV } from 'it-pushable';
3
- import { abortableSource } from 'abortable-iterator';
4
- import { encode } from './encode.js';
5
- import { decode } from './decode.js';
6
- import { restrictSize } from './restrict-size.js';
7
- import { MessageTypes, MessageTypeNames } from './message-types.js';
8
- import { createStream } from './stream.js';
9
- import { toString as uint8ArrayToString } from 'uint8arrays';
10
- import { trackedMap } from '@libp2p/tracked-map';
11
- import { logger } from '@libp2p/logger';
12
- import each from 'it-foreach';
13
- const log = logger('libp2p:mplex');
14
- function printMessage(msg) {
15
- const output = {
16
- ...msg,
17
- type: `${MessageTypeNames[msg.type]} (${msg.type})`
18
- };
19
- if (msg.type === MessageTypes.NEW_STREAM) {
20
- output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice());
21
- }
22
- if (msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
23
- output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice(), 'base16');
24
- }
25
- return output;
26
- }
1
+ import { MplexStreamMuxer } from './mplex.js';
27
2
  export class Mplex {
28
- constructor(options) {
29
- options = options ?? {};
30
- this._streamId = 0;
31
- this._streams = {
32
- /**
33
- * Stream to ids map
34
- */
35
- initiators: trackedMap({ metrics: options.metrics, component: 'mplex', metric: 'initiatorStreams' }),
36
- /**
37
- * Stream to ids map
38
- */
39
- receivers: trackedMap({ metrics: options.metrics, component: 'mplex', metric: 'receiverStreams' })
40
- };
41
- this._options = options;
42
- /**
43
- * An iterable sink
44
- */
45
- this.sink = this._createSink();
46
- /**
47
- * An iterable source
48
- */
49
- const source = this._createSource();
50
- this._source = source;
51
- this.source = source;
52
- }
53
- /**
54
- * Returns a Map of streams and their ids
55
- */
56
- get streams() {
57
- // Inbound and Outbound streams may have the same ids, so we need to make those unique
58
- const streams = [];
59
- this._streams.initiators.forEach(stream => {
60
- streams.push(stream);
61
- });
62
- this._streams.receivers.forEach(stream => {
63
- streams.push(stream);
64
- });
65
- return streams;
66
- }
67
- /**
68
- * Initiate a new stream with the given name. If no name is
69
- * provided, the id of the stream will be used.
70
- */
71
- newStream(name) {
72
- const id = this._streamId++;
73
- name = name == null ? id.toString() : name.toString();
74
- const registry = this._streams.initiators;
75
- return this._newStream({ id, name, type: 'initiator', registry });
76
- }
77
- /**
78
- * Called whenever an inbound stream is created
79
- */
80
- _newReceiverStream(options) {
81
- const { id, name } = options;
82
- const registry = this._streams.receivers;
83
- return this._newStream({ id, name, type: 'receiver', registry });
84
- }
85
- _newStream(options) {
86
- const { id, name, type, registry } = options;
87
- log('new %s stream %s %s', type, id, name);
88
- if (registry.has(id)) {
89
- throw new Error(`${type} stream ${id} already exists!`);
90
- }
91
- const send = (msg) => {
92
- if (log.enabled) {
93
- log('%s stream %s send', type, id, printMessage(msg));
94
- }
95
- if (msg.type === MessageTypes.NEW_STREAM || msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
96
- msg.data = msg.data instanceof Uint8Array ? msg.data : msg.data.slice();
97
- }
98
- this._source.push(msg);
99
- };
100
- const onEnd = () => {
101
- log('%s stream %s %s ended', type, id, name);
102
- registry.delete(id);
103
- if (this._options.onStreamEnd != null) {
104
- this._options.onStreamEnd(stream);
105
- }
106
- };
107
- const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._options.maxMsgSize });
108
- registry.set(id, stream);
109
- return stream;
110
- }
111
- /**
112
- * Creates a sink with an abortable source. Incoming messages will
113
- * also have their size restricted. All messages will be varint decoded.
114
- */
115
- _createSink() {
116
- const sink = async (source) => {
117
- if (this._options.signal != null) {
118
- source = abortableSource(source, this._options.signal);
119
- }
120
- try {
121
- await pipe(source, source => each(source, (buf) => {
122
- // console.info('incoming', uint8ArrayToString(buf, 'base64'))
123
- }), decode, restrictSize(this._options.maxMsgSize), async (source) => {
124
- for await (const msg of source) {
125
- this._handleIncoming(msg);
126
- }
127
- });
128
- this._source.end();
129
- }
130
- catch (err) {
131
- log('error in sink', err);
132
- this._source.end(err); // End the source with an error
133
- }
134
- };
135
- return sink;
136
- }
137
- /**
138
- * Creates a source that restricts outgoing message sizes
139
- * and varint encodes them
140
- */
141
- _createSource() {
142
- const onEnd = (err) => {
143
- const { initiators, receivers } = this._streams;
144
- // Abort all the things!
145
- for (const s of initiators.values()) {
146
- s.abort(err);
147
- }
148
- for (const s of receivers.values()) {
149
- s.abort(err);
150
- }
151
- };
152
- const source = pushableV({ onEnd });
153
- return Object.assign(encode(source), {
154
- push: source.push,
155
- end: source.end,
156
- return: source.return
157
- });
3
+ constructor() {
4
+ this.protocol = '/mplex/6.7.0';
158
5
  }
159
- _handleIncoming(message) {
160
- const { id, type } = message;
161
- if (log.enabled) {
162
- log('incoming message', printMessage(message));
163
- }
164
- // Create a new stream?
165
- if (message.type === MessageTypes.NEW_STREAM) {
166
- const stream = this._newReceiverStream({ id, name: uint8ArrayToString(message.data instanceof Uint8Array ? message.data : message.data.slice()) });
167
- if (this._options.onIncomingStream != null) {
168
- this._options.onIncomingStream(stream);
169
- }
170
- return;
171
- }
172
- const list = (type & 1) === 1 ? this._streams.initiators : this._streams.receivers;
173
- const stream = list.get(id);
174
- if (stream == null) {
175
- return log('missing stream %s', id);
176
- }
177
- switch (type) {
178
- case MessageTypes.MESSAGE_INITIATOR:
179
- case MessageTypes.MESSAGE_RECEIVER:
180
- stream.source.push(message.data.slice());
181
- break;
182
- case MessageTypes.CLOSE_INITIATOR:
183
- case MessageTypes.CLOSE_RECEIVER:
184
- stream.close();
185
- break;
186
- case MessageTypes.RESET_INITIATOR:
187
- case MessageTypes.RESET_RECEIVER:
188
- stream.reset();
189
- break;
190
- default:
191
- log('unknown message type %s', type);
192
- }
6
+ createStreamMuxer(components, init) {
7
+ return new MplexStreamMuxer(components, init);
193
8
  }
194
9
  }
195
- Mplex.multicodec = '/mplex/6.7.0';
196
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAM7C,MAAM,OAAO,KAAK;IAAlB;QACS,aAAQ,GAAG,cAAc,CAAA;IAKlC,CAAC;IAHC,iBAAiB,CAAE,UAAsB,EAAE,IAAgB;QACzD,OAAO,IAAI,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IAC/C,CAAC;CACF"}
@@ -0,0 +1,63 @@
1
+ import { Pushable } from 'it-pushable';
2
+ import { Message } from './message-types.js';
3
+ import type { Components } from '@libp2p/interfaces/components';
4
+ import type { Sink } from 'it-stream-types';
5
+ import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interfaces/stream-muxer';
6
+ import type { Stream } from '@libp2p/interfaces/connection';
7
+ export interface MplexStream extends Stream {
8
+ source: Pushable<Uint8Array>;
9
+ }
10
+ export interface MplexInit extends StreamMuxerInit {
11
+ maxMsgSize?: number;
12
+ }
13
+ export declare class MplexStreamMuxer implements StreamMuxer {
14
+ protocol: string;
15
+ sink: Sink<Uint8Array>;
16
+ source: AsyncIterable<Uint8Array>;
17
+ private _streamId;
18
+ private readonly _streams;
19
+ private readonly _init;
20
+ private readonly _source;
21
+ constructor(components: Components, init?: MplexInit);
22
+ init(components: Components): void;
23
+ /**
24
+ * Returns a Map of streams and their ids
25
+ */
26
+ get streams(): Stream[];
27
+ /**
28
+ * Initiate a new stream with the given name. If no name is
29
+ * provided, the id of the stream will be used.
30
+ */
31
+ newStream(name?: string): Stream;
32
+ /**
33
+ * Called whenever an inbound stream is created
34
+ */
35
+ _newReceiverStream(options: {
36
+ id: number;
37
+ name: string;
38
+ }): MplexStream;
39
+ _newStream(options: {
40
+ id: number;
41
+ name: string;
42
+ type: 'initiator' | 'receiver';
43
+ registry: Map<number, MplexStream>;
44
+ }): MplexStream;
45
+ /**
46
+ * Creates a sink with an abortable source. Incoming messages will
47
+ * also have their size restricted. All messages will be varint decoded.
48
+ */
49
+ _createSink(): Sink<Uint8Array, Promise<void>>;
50
+ /**
51
+ * Creates a source that restricts outgoing message sizes
52
+ * and varint encodes them
53
+ */
54
+ _createSource(): AsyncGenerator<Uint8Array, void, undefined> & {
55
+ push: (value: Message) => import("it-pushable").PushableV<Message>;
56
+ end: (err?: Error | undefined) => import("it-pushable").PushableV<Message>;
57
+ return: () => {
58
+ done: boolean;
59
+ };
60
+ };
61
+ _handleIncoming(message: Message): void;
62
+ }
63
+ //# sourceMappingURL=mplex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mplex.d.ts","sourceRoot":"","sources":["../../src/mplex.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAA;AAKjD,OAAO,EAAkC,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAK5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAqB3D,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,SAAU,SAAQ,eAAe;IAChD,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,gBAAiB,YAAW,WAAW;IAC3C,QAAQ,SAAiB;IAEzB,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IACtB,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAExC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+E;IACxG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8D;gBAEzE,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS;IA6BrD,IAAI,CAAE,UAAU,EAAE,UAAU;IAI5B;;OAEG;IACH,IAAI,OAAO,aAUV;IAED;;;OAGG;IACH,SAAS,CAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAOjC;;OAEG;IACH,kBAAkB,CAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAMzD,UAAU,CAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;KAAE;IAmCrH;;;OAGG;IACH,WAAW;IA4BX;;;OAGG;IACH,aAAa;;;;;;;IAoBb,eAAe,CAAE,OAAO,EAAE,OAAO;CA0ClC"}
@@ -0,0 +1,195 @@
1
+ import { pipe } from 'it-pipe';
2
+ import { pushableV } from 'it-pushable';
3
+ import { abortableSource } from 'abortable-iterator';
4
+ import { encode } from './encode.js';
5
+ import { decode } from './decode.js';
6
+ import { restrictSize } from './restrict-size.js';
7
+ import { MessageTypes, MessageTypeNames } from './message-types.js';
8
+ import { createStream } from './stream.js';
9
+ import { toString as uint8ArrayToString } from 'uint8arrays';
10
+ import { trackedMap } from '@libp2p/tracked-map';
11
+ import { logger } from '@libp2p/logger';
12
+ const log = logger('libp2p:mplex');
13
+ function printMessage(msg) {
14
+ const output = {
15
+ ...msg,
16
+ type: `${MessageTypeNames[msg.type]} (${msg.type})`
17
+ };
18
+ if (msg.type === MessageTypes.NEW_STREAM) {
19
+ output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice());
20
+ }
21
+ if (msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
22
+ output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice(), 'base16');
23
+ }
24
+ return output;
25
+ }
26
+ export class MplexStreamMuxer {
27
+ constructor(components, init) {
28
+ this.protocol = '/mplex/6.7.0';
29
+ init = init ?? {};
30
+ this._streamId = 0;
31
+ this._streams = {
32
+ /**
33
+ * Stream to ids map
34
+ */
35
+ initiators: trackedMap({ metrics: components.getMetrics(), component: 'mplex', metric: 'initiatorStreams' }),
36
+ /**
37
+ * Stream to ids map
38
+ */
39
+ receivers: trackedMap({ metrics: components.getMetrics(), component: 'mplex', metric: 'receiverStreams' })
40
+ };
41
+ this._init = init;
42
+ /**
43
+ * An iterable sink
44
+ */
45
+ this.sink = this._createSink();
46
+ /**
47
+ * An iterable source
48
+ */
49
+ const source = this._createSource();
50
+ this._source = source;
51
+ this.source = source;
52
+ }
53
+ init(components) {
54
+ }
55
+ /**
56
+ * Returns a Map of streams and their ids
57
+ */
58
+ get streams() {
59
+ // Inbound and Outbound streams may have the same ids, so we need to make those unique
60
+ const streams = [];
61
+ this._streams.initiators.forEach(stream => {
62
+ streams.push(stream);
63
+ });
64
+ this._streams.receivers.forEach(stream => {
65
+ streams.push(stream);
66
+ });
67
+ return streams;
68
+ }
69
+ /**
70
+ * Initiate a new stream with the given name. If no name is
71
+ * provided, the id of the stream will be used.
72
+ */
73
+ newStream(name) {
74
+ const id = this._streamId++;
75
+ name = name == null ? id.toString() : name.toString();
76
+ const registry = this._streams.initiators;
77
+ return this._newStream({ id, name, type: 'initiator', registry });
78
+ }
79
+ /**
80
+ * Called whenever an inbound stream is created
81
+ */
82
+ _newReceiverStream(options) {
83
+ const { id, name } = options;
84
+ const registry = this._streams.receivers;
85
+ return this._newStream({ id, name, type: 'receiver', registry });
86
+ }
87
+ _newStream(options) {
88
+ const { id, name, type, registry } = options;
89
+ log('new %s stream %s %s', type, id, name);
90
+ if (registry.has(id)) {
91
+ throw new Error(`${type} stream ${id} already exists!`);
92
+ }
93
+ const send = (msg) => {
94
+ if (log.enabled) {
95
+ log.trace('%s stream %s send', type, id, printMessage(msg));
96
+ }
97
+ if (msg.type === MessageTypes.NEW_STREAM || msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
98
+ msg.data = msg.data instanceof Uint8Array ? msg.data : msg.data.slice();
99
+ }
100
+ this._source.push(msg);
101
+ };
102
+ const onEnd = () => {
103
+ log('%s stream %s %s ended', type, id, name);
104
+ registry.delete(id);
105
+ if (this._init.onStreamEnd != null) {
106
+ this._init.onStreamEnd(stream);
107
+ }
108
+ };
109
+ const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._init.maxMsgSize });
110
+ registry.set(id, stream);
111
+ return stream;
112
+ }
113
+ /**
114
+ * Creates a sink with an abortable source. Incoming messages will
115
+ * also have their size restricted. All messages will be varint decoded.
116
+ */
117
+ _createSink() {
118
+ const sink = async (source) => {
119
+ if (this._init.signal != null) {
120
+ source = abortableSource(source, this._init.signal);
121
+ }
122
+ try {
123
+ await pipe(source, decode, restrictSize(this._init.maxMsgSize), async (source) => {
124
+ for await (const msg of source) {
125
+ this._handleIncoming(msg);
126
+ }
127
+ });
128
+ this._source.end();
129
+ }
130
+ catch (err) {
131
+ log('error in sink', err);
132
+ this._source.end(err); // End the source with an error
133
+ }
134
+ };
135
+ return sink;
136
+ }
137
+ /**
138
+ * Creates a source that restricts outgoing message sizes
139
+ * and varint encodes them
140
+ */
141
+ _createSource() {
142
+ const onEnd = (err) => {
143
+ const { initiators, receivers } = this._streams;
144
+ // Abort all the things!
145
+ for (const s of initiators.values()) {
146
+ s.abort(err);
147
+ }
148
+ for (const s of receivers.values()) {
149
+ s.abort(err);
150
+ }
151
+ };
152
+ const source = pushableV({ onEnd });
153
+ return Object.assign(encode(source), {
154
+ push: source.push,
155
+ end: source.end,
156
+ return: source.return
157
+ });
158
+ }
159
+ _handleIncoming(message) {
160
+ const { id, type } = message;
161
+ if (log.enabled) {
162
+ log.trace('incoming message', printMessage(message));
163
+ }
164
+ // Create a new stream?
165
+ if (message.type === MessageTypes.NEW_STREAM) {
166
+ const stream = this._newReceiverStream({ id, name: uint8ArrayToString(message.data instanceof Uint8Array ? message.data : message.data.slice()) });
167
+ if (this._init.onIncomingStream != null) {
168
+ this._init.onIncomingStream(stream);
169
+ }
170
+ return;
171
+ }
172
+ const list = (type & 1) === 1 ? this._streams.initiators : this._streams.receivers;
173
+ const stream = list.get(id);
174
+ if (stream == null) {
175
+ return log('missing stream %s', id);
176
+ }
177
+ switch (type) {
178
+ case MessageTypes.MESSAGE_INITIATOR:
179
+ case MessageTypes.MESSAGE_RECEIVER:
180
+ stream.source.push(message.data.slice());
181
+ break;
182
+ case MessageTypes.CLOSE_INITIATOR:
183
+ case MessageTypes.CLOSE_RECEIVER:
184
+ stream.close();
185
+ break;
186
+ case MessageTypes.RESET_INITIATOR:
187
+ case MessageTypes.RESET_RECEIVER:
188
+ stream.reset();
189
+ break;
190
+ default:
191
+ log('unknown message type %s', type);
192
+ }
193
+ }
194
+ }
195
+ //# sourceMappingURL=mplex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mplex.js","sourceRoot":"","sources":["../../src/mplex.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { Message } from './message-types.js';
2
- import type { MplexStream } from './index.js';
2
+ import type { MplexStream } from './mplex.js';
3
3
  export interface Options {
4
4
  id: number;
5
5
  send: (msg: Message) => void;
@@ -28,7 +28,7 @@ export function createStream(options) {
28
28
  return;
29
29
  }
30
30
  sourceEnded = true;
31
- log('%s stream %s source end', type, streamName, err);
31
+ log.trace('%s stream %s source end', type, streamName, err);
32
32
  if (err != null && endErr == null) {
33
33
  endErr = err;
34
34
  }
@@ -44,7 +44,7 @@ export function createStream(options) {
44
44
  return;
45
45
  }
46
46
  sinkEnded = true;
47
- log('%s stream %s sink end - err: %o', type, streamName, err);
47
+ log.trace('%s stream %s sink end - err: %o', type, streamName, err);
48
48
  if (err != null && endErr == null) {
49
49
  endErr = err;
50
50
  }
@@ -62,7 +62,7 @@ export function createStream(options) {
62
62
  },
63
63
  // Close for reading and writing (local error)
64
64
  abort: (err) => {
65
- log('%s stream %s abort', type, streamName, err);
65
+ log.trace('%s stream %s abort', type, streamName, err);
66
66
  // End the source with the passed error
67
67
  stream.source.end(err);
68
68
  abortController.abort();
@@ -112,15 +112,15 @@ export function createStream(options) {
112
112
  }
113
113
  // Send no more data if this stream was remotely reset
114
114
  if (err.code === ERR_MPLEX_STREAM_RESET) {
115
- log('%s stream %s reset', type, name);
115
+ log.trace('%s stream %s reset', type, name);
116
116
  }
117
117
  else {
118
- log('%s stream %s error', type, name, err);
118
+ log.trace('%s stream %s error', type, name, err);
119
119
  try {
120
120
  send({ id, type: Types.RESET });
121
121
  }
122
122
  catch (err) {
123
- log('%s stream %s error sending reset', type, name, err);
123
+ log.trace('%s stream %s error sending reset', type, name, err);
124
124
  }
125
125
  }
126
126
  stream.source.end(err);
@@ -131,7 +131,7 @@ export function createStream(options) {
131
131
  send({ id, type: Types.CLOSE });
132
132
  }
133
133
  catch (err) {
134
- log('%s stream %s error sending close', type, name, err);
134
+ log.trace('%s stream %s error sending close', type, name, err);
135
135
  }
136
136
  onSinkEnd();
137
137
  },
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/mplex",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "JavaScript implementation of https://github.com/libp2p/mplex",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p-mplex#readme",
@@ -127,10 +127,10 @@
127
127
  },
128
128
  "scripts": {
129
129
  "lint": "aegir lint",
130
- "dep-check": "aegir dep-check",
130
+ "dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
131
131
  "build": "tsc",
132
132
  "pretest": "npm run build",
133
- "test": "aegir test -f ./dist/test",
133
+ "test": "aegir test -f \"./dist/test/**/*.js\"",
134
134
  "test:chrome": "npm run test -- -t browser --cov",
135
135
  "test:chrome-webworker": "npm run test -- -t webworker",
136
136
  "test:firefox": "npm run test -- -t browser -- --browser firefox",
@@ -140,24 +140,24 @@
140
140
  "release": "semantic-release"
141
141
  },
142
142
  "dependencies": {
143
- "@libp2p/logger": "^1.0.3",
144
- "@libp2p/tracked-map": "^1.0.1",
143
+ "@libp2p/logger": "^1.1.2",
144
+ "@libp2p/tracked-map": "^1.0.4",
145
145
  "abortable-iterator": "^4.0.2",
146
146
  "any-signal": "^3.0.0",
147
147
  "err-code": "^3.0.1",
148
148
  "it-pipe": "^2.0.3",
149
149
  "it-pushable": "^2.0.1",
150
150
  "it-stream-types": "^1.0.4",
151
- "uint8arraylist": "^1.2.0",
151
+ "uint8arraylist": "^1.4.0",
152
152
  "varint": "^6.0.0"
153
153
  },
154
154
  "devDependencies": {
155
- "@libp2p/interface-compliance-tests": "^1.0.7",
156
- "@libp2p/interfaces": "^1.1.1",
155
+ "@libp2p/interface-compliance-tests": "^1.1.16",
156
+ "@libp2p/interfaces": "^1.3.14",
157
157
  "@types/varint": "^6.0.0",
158
158
  "aegir": "^36.1.3",
159
- "cborg": "^1.2.1",
160
- "iso-random-stream": "^2.0.0",
159
+ "cborg": "^1.8.1",
160
+ "iso-random-stream": "^2.0.2",
161
161
  "it-all": "^1.0.6",
162
162
  "it-drain": "^1.0.5",
163
163
  "it-foreach": "^0.1.1",
package/src/index.ts CHANGED
@@ -1,257 +1,15 @@
1
- import { pipe } from 'it-pipe'
2
- import { Pushable, pushableV } from 'it-pushable'
3
- import { abortableSource } from 'abortable-iterator'
4
- import { encode } from './encode.js'
5
- import { decode } from './decode.js'
6
- import { restrictSize } from './restrict-size.js'
7
- import { MessageTypes, MessageTypeNames, Message } from './message-types.js'
8
- import { createStream } from './stream.js'
9
- import { toString as uint8ArrayToString } from 'uint8arrays'
10
- import { trackedMap } from '@libp2p/tracked-map'
11
- import { logger } from '@libp2p/logger'
12
- import type { Sink } from 'it-stream-types'
13
- import type { Muxer, MuxerOptions } from '@libp2p/interfaces/stream-muxer'
14
- import type { Stream } from '@libp2p/interfaces/connection'
15
- import type { ComponentMetricsTracker } from '@libp2p/interfaces/metrics'
16
- import each from 'it-foreach'
1
+ import type { Components } from '@libp2p/interfaces/components'
2
+ import type { StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interfaces/stream-muxer'
3
+ import { MplexStreamMuxer } from './mplex.js'
17
4
 
18
- const log = logger('libp2p:mplex')
19
-
20
- function printMessage (msg: Message) {
21
- const output: any = {
22
- ...msg,
23
- type: `${MessageTypeNames[msg.type]} (${msg.type})`
24
- }
25
-
26
- if (msg.type === MessageTypes.NEW_STREAM) {
27
- output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice())
28
- }
29
-
30
- if (msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
31
- output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice(), 'base16')
32
- }
33
-
34
- return output
35
- }
36
-
37
- export interface MplexStream extends Stream {
38
- source: Pushable<Uint8Array>
39
- }
40
-
41
- export interface MplexOptions extends MuxerOptions {
5
+ export interface MplexInit extends StreamMuxerInit {
42
6
  maxMsgSize?: number
43
- metrics?: ComponentMetricsTracker
44
7
  }
45
8
 
46
- export class Mplex implements Muxer {
47
- static multicodec = '/mplex/6.7.0'
48
-
49
- public sink: Sink<Uint8Array>
50
- public source: AsyncIterable<Uint8Array>
51
-
52
- private _streamId: number
53
- private readonly _streams: { initiators: Map<number, MplexStream>, receivers: Map<number, MplexStream> }
54
- private readonly _options: MplexOptions
55
- private readonly _source: { push: (val: Message) => void, end: (err?: Error) => void }
56
-
57
- constructor (options?: MplexOptions) {
58
- options = options ?? {}
59
-
60
- this._streamId = 0
61
- this._streams = {
62
- /**
63
- * Stream to ids map
64
- */
65
- initiators: trackedMap<number, MplexStream>({ metrics: options.metrics, component: 'mplex', metric: 'initiatorStreams' }),
66
- /**
67
- * Stream to ids map
68
- */
69
- receivers: trackedMap<number, MplexStream>({ metrics: options.metrics, component: 'mplex', metric: 'receiverStreams' })
70
- }
71
- this._options = options
72
-
73
- /**
74
- * An iterable sink
75
- */
76
- this.sink = this._createSink()
77
-
78
- /**
79
- * An iterable source
80
- */
81
- const source = this._createSource()
82
- this._source = source
83
- this.source = source
84
- }
85
-
86
- /**
87
- * Returns a Map of streams and their ids
88
- */
89
- get streams () {
90
- // Inbound and Outbound streams may have the same ids, so we need to make those unique
91
- const streams: Stream[] = []
92
- this._streams.initiators.forEach(stream => {
93
- streams.push(stream)
94
- })
95
- this._streams.receivers.forEach(stream => {
96
- streams.push(stream)
97
- })
98
- return streams
99
- }
100
-
101
- /**
102
- * Initiate a new stream with the given name. If no name is
103
- * provided, the id of the stream will be used.
104
- */
105
- newStream (name?: string): Stream {
106
- const id = this._streamId++
107
- name = name == null ? id.toString() : name.toString()
108
- const registry = this._streams.initiators
109
- return this._newStream({ id, name, type: 'initiator', registry })
110
- }
111
-
112
- /**
113
- * Called whenever an inbound stream is created
114
- */
115
- _newReceiverStream (options: { id: number, name: string }) {
116
- const { id, name } = options
117
- const registry = this._streams.receivers
118
- return this._newStream({ id, name, type: 'receiver', registry })
119
- }
120
-
121
- _newStream (options: { id: number, name: string, type: 'initiator' | 'receiver', registry: Map<number, MplexStream> }) {
122
- const { id, name, type, registry } = options
123
-
124
- log('new %s stream %s %s', type, id, name)
125
-
126
- if (registry.has(id)) {
127
- throw new Error(`${type} stream ${id} already exists!`)
128
- }
129
-
130
- const send = (msg: Message) => {
131
- if (log.enabled) {
132
- log('%s stream %s send', type, id, printMessage(msg))
133
- }
134
-
135
- if (msg.type === MessageTypes.NEW_STREAM || msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
136
- msg.data = msg.data instanceof Uint8Array ? msg.data : msg.data.slice()
137
- }
138
-
139
- this._source.push(msg)
140
- }
141
-
142
- const onEnd = () => {
143
- log('%s stream %s %s ended', type, id, name)
144
- registry.delete(id)
145
-
146
- if (this._options.onStreamEnd != null) {
147
- this._options.onStreamEnd(stream)
148
- }
149
- }
150
-
151
- const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._options.maxMsgSize })
152
- registry.set(id, stream)
153
- return stream
154
- }
155
-
156
- /**
157
- * Creates a sink with an abortable source. Incoming messages will
158
- * also have their size restricted. All messages will be varint decoded.
159
- */
160
- _createSink () {
161
- const sink: Sink<Uint8Array> = async source => {
162
- if (this._options.signal != null) {
163
- source = abortableSource(source, this._options.signal)
164
- }
165
-
166
- try {
167
- await pipe(
168
- source,
169
- source => each(source, (buf) => {
170
- // console.info('incoming', uint8ArrayToString(buf, 'base64'))
171
- }),
172
- decode,
173
- restrictSize(this._options.maxMsgSize),
174
- async source => {
175
- for await (const msg of source) {
176
- this._handleIncoming(msg)
177
- }
178
- }
179
- )
180
-
181
- this._source.end()
182
- } catch (err: any) {
183
- log('error in sink', err)
184
- this._source.end(err) // End the source with an error
185
- }
186
- }
187
-
188
- return sink
189
- }
190
-
191
- /**
192
- * Creates a source that restricts outgoing message sizes
193
- * and varint encodes them
194
- */
195
- _createSource () {
196
- const onEnd = (err?: Error) => {
197
- const { initiators, receivers } = this._streams
198
- // Abort all the things!
199
- for (const s of initiators.values()) {
200
- s.abort(err)
201
- }
202
- for (const s of receivers.values()) {
203
- s.abort(err)
204
- }
205
- }
206
- const source = pushableV<Message>({ onEnd })
207
-
208
- return Object.assign(encode(source), {
209
- push: source.push,
210
- end: source.end,
211
- return: source.return
212
- })
213
- }
214
-
215
- _handleIncoming (message: Message) {
216
- const { id, type } = message
217
-
218
- if (log.enabled) {
219
- log('incoming message', printMessage(message))
220
- }
221
-
222
- // Create a new stream?
223
- if (message.type === MessageTypes.NEW_STREAM) {
224
- const stream = this._newReceiverStream({ id, name: uint8ArrayToString(message.data instanceof Uint8Array ? message.data : message.data.slice()) })
225
-
226
- if (this._options.onIncomingStream != null) {
227
- this._options.onIncomingStream(stream)
228
- }
229
-
230
- return
231
- }
232
-
233
- const list = (type & 1) === 1 ? this._streams.initiators : this._streams.receivers
234
- const stream = list.get(id)
235
-
236
- if (stream == null) {
237
- return log('missing stream %s', id)
238
- }
9
+ export class Mplex implements StreamMuxerFactory {
10
+ public protocol = '/mplex/6.7.0'
239
11
 
240
- switch (type) {
241
- case MessageTypes.MESSAGE_INITIATOR:
242
- case MessageTypes.MESSAGE_RECEIVER:
243
- stream.source.push(message.data.slice())
244
- break
245
- case MessageTypes.CLOSE_INITIATOR:
246
- case MessageTypes.CLOSE_RECEIVER:
247
- stream.close()
248
- break
249
- case MessageTypes.RESET_INITIATOR:
250
- case MessageTypes.RESET_RECEIVER:
251
- stream.reset()
252
- break
253
- default:
254
- log('unknown message type %s', type)
255
- }
12
+ createStreamMuxer (components: Components, init?: MplexInit) {
13
+ return new MplexStreamMuxer(components, init)
256
14
  }
257
15
  }
package/src/mplex.ts ADDED
@@ -0,0 +1,256 @@
1
+ import { pipe } from 'it-pipe'
2
+ import { Pushable, pushableV } from 'it-pushable'
3
+ import { abortableSource } from 'abortable-iterator'
4
+ import { encode } from './encode.js'
5
+ import { decode } from './decode.js'
6
+ import { restrictSize } from './restrict-size.js'
7
+ import { MessageTypes, MessageTypeNames, Message } from './message-types.js'
8
+ import { createStream } from './stream.js'
9
+ import { toString as uint8ArrayToString } from 'uint8arrays'
10
+ import { trackedMap } from '@libp2p/tracked-map'
11
+ import { logger } from '@libp2p/logger'
12
+ import type { Components } from '@libp2p/interfaces/components'
13
+ import type { Sink } from 'it-stream-types'
14
+ import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interfaces/stream-muxer'
15
+ import type { Stream } from '@libp2p/interfaces/connection'
16
+
17
+ const log = logger('libp2p:mplex')
18
+
19
+ function printMessage (msg: Message) {
20
+ const output: any = {
21
+ ...msg,
22
+ type: `${MessageTypeNames[msg.type]} (${msg.type})`
23
+ }
24
+
25
+ if (msg.type === MessageTypes.NEW_STREAM) {
26
+ output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice())
27
+ }
28
+
29
+ if (msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
30
+ output.data = uint8ArrayToString(msg.data instanceof Uint8Array ? msg.data : msg.data.slice(), 'base16')
31
+ }
32
+
33
+ return output
34
+ }
35
+
36
+ export interface MplexStream extends Stream {
37
+ source: Pushable<Uint8Array>
38
+ }
39
+
40
+ export interface MplexInit extends StreamMuxerInit {
41
+ maxMsgSize?: number
42
+ }
43
+
44
+ export class MplexStreamMuxer implements StreamMuxer {
45
+ public protocol = '/mplex/6.7.0'
46
+
47
+ public sink: Sink<Uint8Array>
48
+ public source: AsyncIterable<Uint8Array>
49
+
50
+ private _streamId: number
51
+ private readonly _streams: { initiators: Map<number, MplexStream>, receivers: Map<number, MplexStream> }
52
+ private readonly _init: MplexInit
53
+ private readonly _source: { push: (val: Message) => void, end: (err?: Error) => void }
54
+
55
+ constructor (components: Components, init?: MplexInit) {
56
+ init = init ?? {}
57
+
58
+ this._streamId = 0
59
+ this._streams = {
60
+ /**
61
+ * Stream to ids map
62
+ */
63
+ initiators: trackedMap<number, MplexStream>({ metrics: components.getMetrics(), component: 'mplex', metric: 'initiatorStreams' }),
64
+ /**
65
+ * Stream to ids map
66
+ */
67
+ receivers: trackedMap<number, MplexStream>({ metrics: components.getMetrics(), component: 'mplex', metric: 'receiverStreams' })
68
+ }
69
+ this._init = init
70
+
71
+ /**
72
+ * An iterable sink
73
+ */
74
+ this.sink = this._createSink()
75
+
76
+ /**
77
+ * An iterable source
78
+ */
79
+ const source = this._createSource()
80
+ this._source = source
81
+ this.source = source
82
+ }
83
+
84
+ init (components: Components) {
85
+
86
+ }
87
+
88
+ /**
89
+ * Returns a Map of streams and their ids
90
+ */
91
+ get streams () {
92
+ // Inbound and Outbound streams may have the same ids, so we need to make those unique
93
+ const streams: Stream[] = []
94
+ this._streams.initiators.forEach(stream => {
95
+ streams.push(stream)
96
+ })
97
+ this._streams.receivers.forEach(stream => {
98
+ streams.push(stream)
99
+ })
100
+ return streams
101
+ }
102
+
103
+ /**
104
+ * Initiate a new stream with the given name. If no name is
105
+ * provided, the id of the stream will be used.
106
+ */
107
+ newStream (name?: string): Stream {
108
+ const id = this._streamId++
109
+ name = name == null ? id.toString() : name.toString()
110
+ const registry = this._streams.initiators
111
+ return this._newStream({ id, name, type: 'initiator', registry })
112
+ }
113
+
114
+ /**
115
+ * Called whenever an inbound stream is created
116
+ */
117
+ _newReceiverStream (options: { id: number, name: string }) {
118
+ const { id, name } = options
119
+ const registry = this._streams.receivers
120
+ return this._newStream({ id, name, type: 'receiver', registry })
121
+ }
122
+
123
+ _newStream (options: { id: number, name: string, type: 'initiator' | 'receiver', registry: Map<number, MplexStream> }) {
124
+ const { id, name, type, registry } = options
125
+
126
+ log('new %s stream %s %s', type, id, name)
127
+
128
+ if (registry.has(id)) {
129
+ throw new Error(`${type} stream ${id} already exists!`)
130
+ }
131
+
132
+ const send = (msg: Message) => {
133
+ if (log.enabled) {
134
+ log.trace('%s stream %s send', type, id, printMessage(msg))
135
+ }
136
+
137
+ if (msg.type === MessageTypes.NEW_STREAM || msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) {
138
+ msg.data = msg.data instanceof Uint8Array ? msg.data : msg.data.slice()
139
+ }
140
+
141
+ this._source.push(msg)
142
+ }
143
+
144
+ const onEnd = () => {
145
+ log('%s stream %s %s ended', type, id, name)
146
+ registry.delete(id)
147
+
148
+ if (this._init.onStreamEnd != null) {
149
+ this._init.onStreamEnd(stream)
150
+ }
151
+ }
152
+
153
+ const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._init.maxMsgSize })
154
+ registry.set(id, stream)
155
+ return stream
156
+ }
157
+
158
+ /**
159
+ * Creates a sink with an abortable source. Incoming messages will
160
+ * also have their size restricted. All messages will be varint decoded.
161
+ */
162
+ _createSink () {
163
+ const sink: Sink<Uint8Array> = async source => {
164
+ if (this._init.signal != null) {
165
+ source = abortableSource(source, this._init.signal)
166
+ }
167
+
168
+ try {
169
+ await pipe(
170
+ source,
171
+ decode,
172
+ restrictSize(this._init.maxMsgSize),
173
+ async source => {
174
+ for await (const msg of source) {
175
+ this._handleIncoming(msg)
176
+ }
177
+ }
178
+ )
179
+
180
+ this._source.end()
181
+ } catch (err: any) {
182
+ log('error in sink', err)
183
+ this._source.end(err) // End the source with an error
184
+ }
185
+ }
186
+
187
+ return sink
188
+ }
189
+
190
+ /**
191
+ * Creates a source that restricts outgoing message sizes
192
+ * and varint encodes them
193
+ */
194
+ _createSource () {
195
+ const onEnd = (err?: Error) => {
196
+ const { initiators, receivers } = this._streams
197
+ // Abort all the things!
198
+ for (const s of initiators.values()) {
199
+ s.abort(err)
200
+ }
201
+ for (const s of receivers.values()) {
202
+ s.abort(err)
203
+ }
204
+ }
205
+ const source = pushableV<Message>({ onEnd })
206
+
207
+ return Object.assign(encode(source), {
208
+ push: source.push,
209
+ end: source.end,
210
+ return: source.return
211
+ })
212
+ }
213
+
214
+ _handleIncoming (message: Message) {
215
+ const { id, type } = message
216
+
217
+ if (log.enabled) {
218
+ log.trace('incoming message', printMessage(message))
219
+ }
220
+
221
+ // Create a new stream?
222
+ if (message.type === MessageTypes.NEW_STREAM) {
223
+ const stream = this._newReceiverStream({ id, name: uint8ArrayToString(message.data instanceof Uint8Array ? message.data : message.data.slice()) })
224
+
225
+ if (this._init.onIncomingStream != null) {
226
+ this._init.onIncomingStream(stream)
227
+ }
228
+
229
+ return
230
+ }
231
+
232
+ const list = (type & 1) === 1 ? this._streams.initiators : this._streams.receivers
233
+ const stream = list.get(id)
234
+
235
+ if (stream == null) {
236
+ return log('missing stream %s', id)
237
+ }
238
+
239
+ switch (type) {
240
+ case MessageTypes.MESSAGE_INITIATOR:
241
+ case MessageTypes.MESSAGE_RECEIVER:
242
+ stream.source.push(message.data.slice())
243
+ break
244
+ case MessageTypes.CLOSE_INITIATOR:
245
+ case MessageTypes.CLOSE_RECEIVER:
246
+ stream.close()
247
+ break
248
+ case MessageTypes.RESET_INITIATOR:
249
+ case MessageTypes.RESET_RECEIVER:
250
+ stream.reset()
251
+ break
252
+ default:
253
+ log('unknown message type %s', type)
254
+ }
255
+ }
256
+ }
package/src/stream.ts CHANGED
@@ -10,7 +10,7 @@ import { logger } from '@libp2p/logger'
10
10
  import type { Message } from './message-types.js'
11
11
  import type { Timeline } from '@libp2p/interfaces/connection'
12
12
  import type { Source } from 'it-stream-types'
13
- import type { MplexStream } from './index.js'
13
+ import type { MplexStream } from './mplex.js'
14
14
 
15
15
  const log = logger('libp2p:mplex:stream')
16
16
 
@@ -49,7 +49,7 @@ export function createStream (options: Options): MplexStream {
49
49
  }
50
50
 
51
51
  sourceEnded = true
52
- log('%s stream %s source end', type, streamName, err)
52
+ log.trace('%s stream %s source end', type, streamName, err)
53
53
 
54
54
  if (err != null && endErr == null) {
55
55
  endErr = err
@@ -70,7 +70,7 @@ export function createStream (options: Options): MplexStream {
70
70
  }
71
71
 
72
72
  sinkEnded = true
73
- log('%s stream %s sink end - err: %o', type, streamName, err)
73
+ log.trace('%s stream %s sink end - err: %o', type, streamName, err)
74
74
 
75
75
  if (err != null && endErr == null) {
76
76
  endErr = err
@@ -92,7 +92,7 @@ export function createStream (options: Options): MplexStream {
92
92
  },
93
93
  // Close for reading and writing (local error)
94
94
  abort: (err?: Error) => {
95
- log('%s stream %s abort', type, streamName, err)
95
+ log.trace('%s stream %s abort', type, streamName, err)
96
96
  // End the source with the passed error
97
97
  stream.source.end(err)
98
98
  abortController.abort()
@@ -148,13 +148,13 @@ export function createStream (options: Options): MplexStream {
148
148
 
149
149
  // Send no more data if this stream was remotely reset
150
150
  if (err.code === ERR_MPLEX_STREAM_RESET) {
151
- log('%s stream %s reset', type, name)
151
+ log.trace('%s stream %s reset', type, name)
152
152
  } else {
153
- log('%s stream %s error', type, name, err)
153
+ log.trace('%s stream %s error', type, name, err)
154
154
  try {
155
155
  send({ id, type: Types.RESET })
156
156
  } catch (err) {
157
- log('%s stream %s error sending reset', type, name, err)
157
+ log.trace('%s stream %s error sending reset', type, name, err)
158
158
  }
159
159
  }
160
160
 
@@ -166,7 +166,7 @@ export function createStream (options: Options): MplexStream {
166
166
  try {
167
167
  send({ id, type: Types.CLOSE })
168
168
  } catch (err) {
169
- log('%s stream %s error sending close', type, name, err)
169
+ log.trace('%s stream %s error sending close', type, name, err)
170
170
  }
171
171
 
172
172
  onSinkEnd()