@libp2p/multistream-select 4.0.6-0f5c305af → 4.0.6-3dee5df4d
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 +1 -1
- package/dist/index.min.js +12 -2
- package/dist/src/handle.d.ts +3 -5
- package/dist/src/handle.d.ts.map +1 -1
- package/dist/src/handle.js +65 -18
- package/dist/src/handle.js.map +1 -1
- package/dist/src/index.d.ts +4 -12
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/multistream.d.ts +14 -9
- package/dist/src/multistream.d.ts.map +1 -1
- package/dist/src/multistream.js +14 -52
- package/dist/src/multistream.js.map +1 -1
- package/dist/src/select.d.ts +4 -7
- package/dist/src/select.d.ts.map +1 -1
- package/dist/src/select.js +107 -69
- package/dist/src/select.js.map +1 -1
- package/package.json +8 -14
- package/src/handle.ts +27 -24
- package/src/index.ts +4 -13
- package/src/multistream.ts +19 -71
- package/src/select.ts +69 -74
package/src/select.ts
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { CodeError } from '@libp2p/interface/errors'
|
|
2
|
-
import {
|
|
3
|
-
import { handshake } from 'it-handshake'
|
|
4
|
-
import merge from 'it-merge'
|
|
5
|
-
import { pushable } from 'it-pushable'
|
|
6
|
-
import { reader } from 'it-reader'
|
|
7
|
-
import { Uint8ArrayList } from 'uint8arraylist'
|
|
2
|
+
import { lpStream } from 'it-length-prefixed-stream'
|
|
8
3
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
4
|
+
import { MAX_PROTOCOL_LENGTH } from './constants.js'
|
|
9
5
|
import * as multistream from './multistream.js'
|
|
10
6
|
import { PROTOCOL_ID } from './index.js'
|
|
11
|
-
import type {
|
|
12
|
-
import type { Duplex
|
|
13
|
-
|
|
14
|
-
const log = logger('libp2p:mss:select')
|
|
7
|
+
import type { MultistreamSelectInit, ProtocolStream } from './index.js'
|
|
8
|
+
import type { Duplex } from 'it-stream-types'
|
|
15
9
|
|
|
16
10
|
/**
|
|
17
11
|
* Negotiate a protocol to use from a list of protocols.
|
|
@@ -56,52 +50,51 @@ const log = logger('libp2p:mss:select')
|
|
|
56
50
|
* // }
|
|
57
51
|
* ```
|
|
58
52
|
*/
|
|
59
|
-
export async function select (stream:
|
|
60
|
-
export async function select (stream: Duplex<AsyncGenerator<Uint8ArrayList | Uint8Array>, Source<Uint8ArrayList | Uint8Array>>, protocols: string | string[], options?: ByteListInit): Promise<ProtocolStream<Uint8ArrayList, Uint8ArrayList | Uint8Array>>
|
|
61
|
-
export async function select (stream: any, protocols: string | string[], options: MultistreamSelectInit = {}): Promise<ProtocolStream<any>> {
|
|
53
|
+
export async function select <Stream extends Duplex<any, any, any>> (stream: Stream, protocols: string | string[], options: MultistreamSelectInit): Promise<ProtocolStream<Stream>> {
|
|
62
54
|
protocols = Array.isArray(protocols) ? [...protocols] : [protocols]
|
|
63
|
-
const
|
|
64
|
-
|
|
55
|
+
const lp = lpStream(stream, {
|
|
56
|
+
maxDataLength: MAX_PROTOCOL_LENGTH
|
|
57
|
+
})
|
|
65
58
|
const protocol = protocols.shift()
|
|
66
59
|
|
|
67
60
|
if (protocol == null) {
|
|
68
61
|
throw new Error('At least one protocol must be specified')
|
|
69
62
|
}
|
|
70
63
|
|
|
71
|
-
log.trace('select: write ["%s", "%s"]', PROTOCOL_ID, protocol)
|
|
72
|
-
const p1 = uint8ArrayFromString(PROTOCOL_ID)
|
|
73
|
-
const p2 = uint8ArrayFromString(protocol)
|
|
74
|
-
multistream.writeAll(
|
|
64
|
+
options?.log.trace('select: write ["%s", "%s"]', PROTOCOL_ID, protocol)
|
|
65
|
+
const p1 = uint8ArrayFromString(`${PROTOCOL_ID}\n`)
|
|
66
|
+
const p2 = uint8ArrayFromString(`${protocol}\n`)
|
|
67
|
+
await multistream.writeAll(lp, [p1, p2], options)
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
options?.log.trace('select: reading multistream-select header')
|
|
70
|
+
let response = await multistream.readString(lp, options)
|
|
71
|
+
options?.log.trace('select: read "%s"', response)
|
|
78
72
|
|
|
79
73
|
// Read the protocol response if we got the protocolId in return
|
|
80
74
|
if (response === PROTOCOL_ID) {
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
options?.log.trace('select: reading protocol response')
|
|
76
|
+
response = await multistream.readString(lp, options)
|
|
77
|
+
options?.log.trace('select: read "%s"', response)
|
|
83
78
|
}
|
|
84
79
|
|
|
85
80
|
// We're done
|
|
86
81
|
if (response === protocol) {
|
|
87
|
-
|
|
88
|
-
return { stream: shakeStream, protocol }
|
|
82
|
+
return { stream: lp.unwrap(), protocol }
|
|
89
83
|
}
|
|
90
84
|
|
|
91
85
|
// We haven't gotten a valid ack, try the other protocols
|
|
92
86
|
for (const protocol of protocols) {
|
|
93
|
-
log.trace('select: write "%s"', protocol)
|
|
94
|
-
multistream.write(
|
|
95
|
-
|
|
96
|
-
|
|
87
|
+
options?.log.trace('select: write "%s"', protocol)
|
|
88
|
+
await multistream.write(lp, uint8ArrayFromString(`${protocol}\n`), options)
|
|
89
|
+
options?.log.trace('select: reading protocol response')
|
|
90
|
+
const response = await multistream.readString(lp, options)
|
|
91
|
+
options?.log.trace('select: read "%s" for "%s"', response, protocol)
|
|
97
92
|
|
|
98
93
|
if (response === protocol) {
|
|
99
|
-
|
|
100
|
-
return { stream: shakeStream, protocol }
|
|
94
|
+
return { stream: lp.unwrap(), protocol }
|
|
101
95
|
}
|
|
102
96
|
}
|
|
103
97
|
|
|
104
|
-
rest()
|
|
105
98
|
throw new CodeError('protocol selection failed', 'ERR_UNSUPPORTED_PROTOCOL')
|
|
106
99
|
}
|
|
107
100
|
|
|
@@ -113,49 +106,51 @@ export async function select (stream: any, protocols: string | string[], options
|
|
|
113
106
|
*
|
|
114
107
|
* Use when it is known that the receiver supports the desired protocol.
|
|
115
108
|
*/
|
|
116
|
-
export function lazySelect (stream:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
109
|
+
export function lazySelect <Stream extends Duplex<any, any, any>> (stream: Stream, protocol: string, options: MultistreamSelectInit): ProtocolStream<Stream> {
|
|
110
|
+
const originalSink = stream.sink.bind(stream)
|
|
111
|
+
const originalSource = stream.source
|
|
112
|
+
|
|
113
|
+
const lp = lpStream({
|
|
114
|
+
sink: originalSink,
|
|
115
|
+
source: originalSource
|
|
116
|
+
}, {
|
|
117
|
+
maxDataLength: MAX_PROTOCOL_LENGTH
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
stream.sink = async source => {
|
|
121
|
+
options?.log.trace('lazy: write ["%s", "%s"]', PROTOCOL_ID, protocol)
|
|
122
|
+
|
|
123
|
+
await lp.writeV([
|
|
124
|
+
uint8ArrayFromString(`${PROTOCOL_ID}\n`),
|
|
125
|
+
uint8ArrayFromString(`${protocol}\n`)
|
|
126
|
+
])
|
|
127
|
+
|
|
128
|
+
options?.log.trace('lazy: writing rest of "%s" stream', protocol)
|
|
129
|
+
await lp.unwrap().sink(source)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
stream.source = (async function * () {
|
|
133
|
+
options?.log.trace('lazy: reading multistream select header')
|
|
134
|
+
|
|
135
|
+
let response = await multistream.readString(lp, options)
|
|
136
|
+
options?.log.trace('lazy: read multistream select header "%s"', response)
|
|
137
|
+
|
|
138
|
+
if (response === PROTOCOL_ID) {
|
|
139
|
+
response = await multistream.readString(lp, options)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
options?.log.trace('lazy: read protocol "%s", expecting "%s"', response, protocol)
|
|
143
|
+
|
|
144
|
+
if (response !== protocol) {
|
|
145
|
+
throw new CodeError('protocol selection failed', 'ERR_UNSUPPORTED_PROTOCOL')
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
options?.log.trace('lazy: reading rest of "%s" stream', protocol)
|
|
149
|
+
yield * lp.unwrap().source
|
|
150
|
+
})()
|
|
151
|
+
|
|
123
152
|
return {
|
|
124
|
-
stream
|
|
125
|
-
sink: async source => {
|
|
126
|
-
await stream.sink((async function * () {
|
|
127
|
-
let first = true
|
|
128
|
-
for await (const chunk of merge(source, negotiateTrigger)) {
|
|
129
|
-
if (first) {
|
|
130
|
-
first = false
|
|
131
|
-
negotiated = true
|
|
132
|
-
negotiateTrigger.end()
|
|
133
|
-
const p1 = uint8ArrayFromString(PROTOCOL_ID)
|
|
134
|
-
const p2 = uint8ArrayFromString(protocol)
|
|
135
|
-
const list = new Uint8ArrayList(multistream.encode(p1), multistream.encode(p2))
|
|
136
|
-
if (chunk.length > 0) list.append(chunk)
|
|
137
|
-
yield * list
|
|
138
|
-
} else {
|
|
139
|
-
yield chunk
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
})())
|
|
143
|
-
},
|
|
144
|
-
source: (async function * () {
|
|
145
|
-
if (!negotiated) negotiateTrigger.push(new Uint8Array())
|
|
146
|
-
const byteReader = reader(stream.source)
|
|
147
|
-
let response = await multistream.readString(byteReader)
|
|
148
|
-
if (response === PROTOCOL_ID) {
|
|
149
|
-
response = await multistream.readString(byteReader)
|
|
150
|
-
}
|
|
151
|
-
if (response !== protocol) {
|
|
152
|
-
throw new CodeError('protocol selection failed', 'ERR_UNSUPPORTED_PROTOCOL')
|
|
153
|
-
}
|
|
154
|
-
for await (const chunk of byteReader) {
|
|
155
|
-
yield * chunk
|
|
156
|
-
}
|
|
157
|
-
})()
|
|
158
|
-
},
|
|
153
|
+
stream,
|
|
159
154
|
protocol
|
|
160
155
|
}
|
|
161
156
|
}
|