@libp2p/utils 6.7.2 → 7.0.0-55b7e5fea

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +16 -1
  2. package/dist/index.min.js +7 -1
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/abstract-message-stream.d.ts +129 -0
  5. package/dist/src/abstract-message-stream.d.ts.map +1 -0
  6. package/dist/src/abstract-message-stream.js +393 -0
  7. package/dist/src/abstract-message-stream.js.map +1 -0
  8. package/dist/src/abstract-multiaddr-connection.d.ts +26 -0
  9. package/dist/src/abstract-multiaddr-connection.d.ts.map +1 -0
  10. package/dist/src/abstract-multiaddr-connection.js +66 -0
  11. package/dist/src/abstract-multiaddr-connection.js.map +1 -0
  12. package/dist/src/abstract-stream-muxer.d.ts +53 -0
  13. package/dist/src/abstract-stream-muxer.d.ts.map +1 -0
  14. package/dist/src/abstract-stream-muxer.js +169 -0
  15. package/dist/src/abstract-stream-muxer.js.map +1 -0
  16. package/dist/src/abstract-stream.d.ts +14 -130
  17. package/dist/src/abstract-stream.d.ts.map +1 -1
  18. package/dist/src/abstract-stream.js +39 -321
  19. package/dist/src/abstract-stream.js.map +1 -1
  20. package/dist/src/errors.d.ts +8 -0
  21. package/dist/src/errors.d.ts.map +1 -1
  22. package/dist/src/errors.js +8 -0
  23. package/dist/src/errors.js.map +1 -1
  24. package/dist/src/get-thin-waist-addresses.browser.d.ts +1 -1
  25. package/dist/src/get-thin-waist-addresses.browser.d.ts.map +1 -1
  26. package/dist/src/get-thin-waist-addresses.browser.js +4 -3
  27. package/dist/src/get-thin-waist-addresses.browser.js.map +1 -1
  28. package/dist/src/get-thin-waist-addresses.d.ts +1 -1
  29. package/dist/src/get-thin-waist-addresses.d.ts.map +1 -1
  30. package/dist/src/get-thin-waist-addresses.js +7 -9
  31. package/dist/src/get-thin-waist-addresses.js.map +1 -1
  32. package/dist/src/index.d.ts +31 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +31 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/length-prefixed-decoder.d.ts +37 -0
  37. package/dist/src/length-prefixed-decoder.d.ts.map +1 -0
  38. package/dist/src/length-prefixed-decoder.js +64 -0
  39. package/dist/src/length-prefixed-decoder.js.map +1 -0
  40. package/dist/src/message-queue.d.ts +61 -0
  41. package/dist/src/message-queue.d.ts.map +1 -0
  42. package/dist/src/message-queue.js +93 -0
  43. package/dist/src/message-queue.js.map +1 -0
  44. package/dist/src/mock-muxer.d.ts +57 -0
  45. package/dist/src/mock-muxer.d.ts.map +1 -0
  46. package/dist/src/mock-muxer.js +204 -0
  47. package/dist/src/mock-muxer.js.map +1 -0
  48. package/dist/src/mock-stream.d.ts +31 -0
  49. package/dist/src/mock-stream.d.ts.map +1 -0
  50. package/dist/src/mock-stream.js +69 -0
  51. package/dist/src/mock-stream.js.map +1 -0
  52. package/dist/src/multiaddr/get-net-config.d.ts +55 -0
  53. package/dist/src/multiaddr/get-net-config.d.ts.map +1 -0
  54. package/dist/src/multiaddr/get-net-config.js +54 -0
  55. package/dist/src/multiaddr/get-net-config.js.map +1 -0
  56. package/dist/src/multiaddr/index.d.ts +7 -0
  57. package/dist/src/multiaddr/index.d.ts.map +1 -0
  58. package/dist/src/multiaddr/index.js +7 -0
  59. package/dist/src/multiaddr/index.js.map +1 -0
  60. package/dist/src/multiaddr/is-global-unicast.d.ts.map +1 -1
  61. package/dist/src/multiaddr/is-global-unicast.js +8 -9
  62. package/dist/src/multiaddr/is-global-unicast.js.map +1 -1
  63. package/dist/src/multiaddr/is-link-local.d.ts.map +1 -1
  64. package/dist/src/multiaddr/is-link-local.js +11 -16
  65. package/dist/src/multiaddr/is-link-local.js.map +1 -1
  66. package/dist/src/multiaddr/is-loopback.d.ts.map +1 -1
  67. package/dist/src/multiaddr/is-loopback.js +12 -5
  68. package/dist/src/multiaddr/is-loopback.js.map +1 -1
  69. package/dist/src/multiaddr/is-network-address.d.ts.map +1 -1
  70. package/dist/src/multiaddr/is-network-address.js +4 -16
  71. package/dist/src/multiaddr/is-network-address.js.map +1 -1
  72. package/dist/src/multiaddr/is-private.d.ts.map +1 -1
  73. package/dist/src/multiaddr/is-private.js +9 -10
  74. package/dist/src/multiaddr/is-private.js.map +1 -1
  75. package/dist/src/multiaddr/utils.d.ts +5 -0
  76. package/dist/src/multiaddr/utils.d.ts.map +1 -0
  77. package/dist/src/multiaddr/utils.js +32 -0
  78. package/dist/src/multiaddr/utils.js.map +1 -0
  79. package/dist/src/multiaddr-connection-pair.d.ts +25 -0
  80. package/dist/src/multiaddr-connection-pair.d.ts.map +1 -0
  81. package/dist/src/multiaddr-connection-pair.js +103 -0
  82. package/dist/src/multiaddr-connection-pair.js.map +1 -0
  83. package/dist/src/queue/index.d.ts +3 -6
  84. package/dist/src/queue/index.d.ts.map +1 -1
  85. package/dist/src/queue/index.js +20 -4
  86. package/dist/src/queue/index.js.map +1 -1
  87. package/dist/src/rate-limiter.d.ts +1 -15
  88. package/dist/src/rate-limiter.d.ts.map +1 -1
  89. package/dist/src/rate-limiter.js +1 -14
  90. package/dist/src/rate-limiter.js.map +1 -1
  91. package/dist/src/stream-pair.d.ts +42 -0
  92. package/dist/src/stream-pair.d.ts.map +1 -0
  93. package/dist/src/stream-pair.js +40 -0
  94. package/dist/src/stream-pair.js.map +1 -0
  95. package/dist/src/stream-utils.d.ts +191 -0
  96. package/dist/src/stream-utils.d.ts.map +1 -0
  97. package/dist/src/stream-utils.js +371 -0
  98. package/dist/src/stream-utils.js.map +1 -0
  99. package/package.json +15 -162
  100. package/src/abstract-message-stream.ts +553 -0
  101. package/src/abstract-multiaddr-connection.ts +93 -0
  102. package/src/abstract-stream-muxer.ts +239 -0
  103. package/src/abstract-stream.ts +51 -464
  104. package/src/errors.ts +10 -0
  105. package/src/get-thin-waist-addresses.browser.ts +5 -4
  106. package/src/get-thin-waist-addresses.ts +8 -12
  107. package/src/index.ts +31 -1
  108. package/src/length-prefixed-decoder.ts +98 -0
  109. package/src/message-queue.ts +156 -0
  110. package/src/mock-muxer.ts +304 -0
  111. package/src/mock-stream.ts +101 -0
  112. package/src/multiaddr/get-net-config.ts +112 -0
  113. package/src/multiaddr/index.ts +6 -0
  114. package/src/multiaddr/is-global-unicast.ts +8 -11
  115. package/src/multiaddr/is-link-local.ts +11 -20
  116. package/src/multiaddr/is-loopback.ts +12 -7
  117. package/src/multiaddr/is-network-address.ts +4 -19
  118. package/src/multiaddr/is-private.ts +9 -14
  119. package/src/multiaddr/utils.ts +46 -0
  120. package/src/multiaddr-connection-pair.ts +147 -0
  121. package/src/queue/index.ts +24 -11
  122. package/src/rate-limiter.ts +3 -30
  123. package/src/stream-pair.ts +90 -0
  124. package/src/stream-utils.ts +866 -0
  125. package/dist/src/abort-options.d.ts +0 -7
  126. package/dist/src/abort-options.d.ts.map +0 -1
  127. package/dist/src/abort-options.js +0 -14
  128. package/dist/src/abort-options.js.map +0 -1
  129. package/dist/src/array-equals.d.ts +0 -24
  130. package/dist/src/array-equals.d.ts.map +0 -1
  131. package/dist/src/array-equals.js +0 -31
  132. package/dist/src/array-equals.js.map +0 -1
  133. package/dist/src/close-source.d.ts +0 -4
  134. package/dist/src/close-source.d.ts.map +0 -1
  135. package/dist/src/close-source.js +0 -11
  136. package/dist/src/close-source.js.map +0 -1
  137. package/dist/src/close.d.ts +0 -21
  138. package/dist/src/close.d.ts.map +0 -1
  139. package/dist/src/close.js +0 -49
  140. package/dist/src/close.js.map +0 -1
  141. package/dist/src/merge-options.d.ts +0 -7
  142. package/dist/src/merge-options.d.ts.map +0 -1
  143. package/dist/src/merge-options.js +0 -128
  144. package/dist/src/merge-options.js.map +0 -1
  145. package/dist/src/multiaddr/is-ip-based.d.ts +0 -6
  146. package/dist/src/multiaddr/is-ip-based.d.ts.map +0 -1
  147. package/dist/src/multiaddr/is-ip-based.js +0 -18
  148. package/dist/src/multiaddr/is-ip-based.js.map +0 -1
  149. package/dist/src/stream-to-ma-conn.d.ts +0 -23
  150. package/dist/src/stream-to-ma-conn.d.ts.map +0 -1
  151. package/dist/src/stream-to-ma-conn.js +0 -75
  152. package/dist/src/stream-to-ma-conn.js.map +0 -1
  153. package/dist/typedoc-urls.json +0 -147
  154. package/src/abort-options.ts +0 -20
  155. package/src/array-equals.ts +0 -34
  156. package/src/close-source.ts +0 -14
  157. package/src/close.ts +0 -65
  158. package/src/merge-options.ts +0 -161
  159. package/src/multiaddr/is-ip-based.ts +0 -21
  160. package/src/stream-to-ma-conn.ts +0 -106
@@ -0,0 +1,239 @@
1
+ import { MuxerClosedError, TypedEventEmitter } from '@libp2p/interface'
2
+ import { raceSignal } from 'race-signal'
3
+ import { MaxEarlyStreamsError } from './errors.ts'
4
+ import { isPromise } from './is-promise.ts'
5
+ import type { AbstractStream } from './abstract-stream.ts'
6
+ import type { AbortOptions, CounterGroup, CreateStreamOptions, EventHandler, Logger, MessageStream, Stream, StreamCloseEvent, StreamMessageEvent, StreamMuxer, StreamMuxerEvents, StreamMuxerOptions, StreamMuxerStatus, StreamOptions } from '@libp2p/interface'
7
+ import type { Uint8ArrayList } from 'uint8arraylist'
8
+
9
+ export interface AbstractStreamMuxerInit extends StreamMuxerOptions {
10
+ /**
11
+ * The protocol name for the muxer
12
+ */
13
+ protocol: string
14
+
15
+ /**
16
+ * The name of the muxer, used to create a new logging scope from the passed
17
+ * connection's logger
18
+ */
19
+ name: string
20
+
21
+ /**
22
+ * A counter for muxer metrics
23
+ */
24
+ metrics?: CounterGroup
25
+ }
26
+
27
+ export abstract class AbstractStreamMuxer <MuxedStream extends AbstractStream = AbstractStream> extends TypedEventEmitter<StreamMuxerEvents<MuxedStream>> implements StreamMuxer<MuxedStream> {
28
+ public streams: MuxedStream[]
29
+ public protocol: string
30
+ public status: StreamMuxerStatus
31
+
32
+ protected log: Logger
33
+ protected maConn: MessageStream
34
+ protected streamOptions?: StreamOptions
35
+ protected earlyStreams: MuxedStream[]
36
+ protected maxEarlyStreams: number
37
+
38
+ private readonly metrics?: CounterGroup
39
+
40
+ constructor (maConn: MessageStream, init: AbstractStreamMuxerInit) {
41
+ super()
42
+
43
+ this.maConn = maConn
44
+ this.protocol = init.protocol
45
+ this.streams = []
46
+ this.earlyStreams = []
47
+ this.status = 'open'
48
+ this.log = maConn.log.newScope(init.name)
49
+ this.streamOptions = init.streamOptions
50
+ this.maxEarlyStreams = init.maxEarlyStreams ?? 10
51
+ this.metrics = init.metrics
52
+
53
+ // read/write all data from/to underlying maConn
54
+ const muxerMaConnOnMessage = (evt: StreamMessageEvent): void => {
55
+ try {
56
+ this.onData(evt.data)
57
+ } catch (err: any) {
58
+ this.abort(err)
59
+ this.maConn.abort(err)
60
+ }
61
+ }
62
+ this.maConn.addEventListener('message', muxerMaConnOnMessage)
63
+
64
+ // signal stream writers when the underlying connection can accept more data
65
+ const muxerMaConnOnDrain = (): void => {
66
+ this.log('underlying stream drained, signal %d streams to continue writing', this.streams.length)
67
+
68
+ this.streams.forEach(stream => {
69
+ stream.onMuxerDrain()
70
+ })
71
+ }
72
+ this.maConn.addEventListener('drain', muxerMaConnOnDrain)
73
+
74
+ const muxerOnMaConnClose = (): void => {
75
+ this.log('underlying stream closed with status %s and %d streams', this.status, this.streams.length)
76
+ this.onTransportClosed()
77
+ }
78
+ this.maConn.addEventListener('close', muxerOnMaConnClose)
79
+ }
80
+
81
+ send (data: Uint8Array | Uint8ArrayList): boolean {
82
+ const result = this.maConn.send(data)
83
+
84
+ if (result === false) {
85
+ this.log('underlying stream saturated, signal %d streams to pause writing', this.streams.length)
86
+
87
+ this.streams.forEach(stream => {
88
+ stream.onMuxerNeedsDrain()
89
+ })
90
+ }
91
+
92
+ return result
93
+ }
94
+
95
+ async close (options?: AbortOptions): Promise<void> {
96
+ if (this.status === 'closed' || this.status === 'closing') {
97
+ return
98
+ }
99
+
100
+ this.status = 'closing'
101
+
102
+ await raceSignal(Promise.all(
103
+ [...this.streams].map(async s => {
104
+ await s.close(options)
105
+ })
106
+ ), options?.signal)
107
+
108
+ this.status = 'closed'
109
+ }
110
+
111
+ abort (err: Error): void {
112
+ if (this.status === 'closed') {
113
+ return
114
+ }
115
+
116
+ this.status = 'closing'
117
+
118
+ ;[...this.streams].forEach(s => {
119
+ s.abort(err)
120
+ })
121
+
122
+ this.status = 'closed'
123
+ }
124
+
125
+ onTransportClosed (err?: Error): void {
126
+ this.status = 'closing'
127
+
128
+ try {
129
+ [...this.streams].forEach(stream => {
130
+ stream.onTransportClosed(err)
131
+ })
132
+ } catch (err: any) {
133
+ this.abort(err)
134
+ }
135
+
136
+ this.status = 'closed'
137
+ }
138
+
139
+ async createStream (options?: CreateStreamOptions): Promise<MuxedStream> {
140
+ if (this.status !== 'open') {
141
+ throw new MuxerClosedError()
142
+ }
143
+
144
+ let stream = this.onCreateStream({
145
+ ...this.streamOptions,
146
+ ...options
147
+ })
148
+
149
+ if (isPromise(stream)) {
150
+ stream = await stream
151
+ }
152
+
153
+ this.streams.push(stream)
154
+ this.cleanUpStream(stream)
155
+
156
+ return stream
157
+ }
158
+
159
+ /**
160
+ * Extending classes should invoke this method when a new stream was created
161
+ * by the remote muxer
162
+ */
163
+ onRemoteStream (stream: MuxedStream): void {
164
+ this.streams.push(stream)
165
+ this.cleanUpStream(stream)
166
+
167
+ if (this.listenerCount('stream') === 0) {
168
+ // no listener has been added for the stream event yet, store the stream
169
+ // to emit it later
170
+ this.earlyStreams.push(stream)
171
+
172
+ if (this.earlyStreams.length > this.maxEarlyStreams) {
173
+ this.abort(new MaxEarlyStreamsError(`Too many early streams were opened - ${this.earlyStreams.length}/${this.maxEarlyStreams}`))
174
+ }
175
+
176
+ return
177
+ }
178
+
179
+ this.safeDispatchEvent('stream', {
180
+ detail: stream
181
+ })
182
+ }
183
+
184
+ private cleanUpStream (stream: Stream): void {
185
+ const muxerOnStreamEnd = (evt: StreamCloseEvent): void => {
186
+ const index = this.streams.findIndex(s => s === stream)
187
+
188
+ if (index !== -1) {
189
+ this.streams.splice(index, 1)
190
+ }
191
+
192
+ if (evt.error != null) {
193
+ if (evt.local) {
194
+ this.metrics?.increment({ [`${stream.direction}_stream_reset`]: true })
195
+ } else {
196
+ this.metrics?.increment({ [`${stream.direction}_stream_abort`]: true })
197
+ }
198
+ } else {
199
+ this.metrics?.increment({ [`${stream.direction}_stream_end`]: true })
200
+ }
201
+ }
202
+ stream.addEventListener('close', muxerOnStreamEnd)
203
+
204
+ this.metrics?.increment({ [`${stream.direction}_stream`]: true })
205
+ }
206
+
207
+ addEventListener<K extends keyof StreamMuxerEvents<MuxedStream>>(type: K, listener: EventHandler<StreamMuxerEvents<MuxedStream>[K]> | null, options?: boolean | AddEventListenerOptions): void
208
+ addEventListener (type: string, listener: EventHandler<Event>, options?: boolean | AddEventListenerOptions): void
209
+ addEventListener (...args: any[]): void {
210
+ // @ts-expect-error cannot ensure args has enough members
211
+ super.addEventListener.apply(this, args)
212
+
213
+ // if a 'stream' listener is being added and we have early streams, emit
214
+ // them
215
+ if (args[0] === 'stream' && this.earlyStreams.length > 0) {
216
+ // event listeners can be added in constructors and often use object
217
+ // properties - if this the case we can access a class member before it
218
+ // has been initialized so dispatch the message in the microtask queue
219
+ queueMicrotask(() => {
220
+ this.earlyStreams.forEach(stream => {
221
+ this.safeDispatchEvent('stream', {
222
+ detail: stream
223
+ })
224
+ })
225
+ this.earlyStreams = []
226
+ })
227
+ }
228
+ }
229
+
230
+ /**
231
+ * A new outgoing stream needs to be created
232
+ */
233
+ abstract onCreateStream (options: CreateStreamOptions): MuxedStream | Promise<MuxedStream>
234
+
235
+ /**
236
+ * Multiplexed data was received from the remote muxer
237
+ */
238
+ abstract onData (data: Uint8Array | Uint8ArrayList): void
239
+ }