@libp2p/interface 0.0.1 → 0.1.0-e66f4891

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 (44) hide show
  1. package/dist/src/connection/index.d.ts +152 -53
  2. package/dist/src/connection/index.d.ts.map +1 -1
  3. package/dist/src/connection/index.js.map +1 -1
  4. package/dist/src/errors.d.ts.map +1 -1
  5. package/dist/src/errors.js.map +1 -1
  6. package/dist/src/index.d.ts +8 -4
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/keys/index.d.ts.map +1 -1
  9. package/dist/src/keys/index.js.map +1 -1
  10. package/dist/src/peer-store/tags.d.ts.map +1 -1
  11. package/dist/src/peer-store/tags.js.map +1 -1
  12. package/dist/src/pubsub/index.d.ts +236 -0
  13. package/dist/src/pubsub/index.d.ts.map +1 -0
  14. package/dist/src/pubsub/index.js +36 -0
  15. package/dist/src/pubsub/index.js.map +1 -0
  16. package/dist/src/startable.d.ts.map +1 -1
  17. package/dist/src/startable.js.map +1 -1
  18. package/dist/src/stream-handler/index.d.ts +5 -0
  19. package/dist/src/stream-handler/index.d.ts.map +1 -1
  20. package/dist/src/stream-muxer/index.d.ts +6 -2
  21. package/dist/src/stream-muxer/index.d.ts.map +1 -1
  22. package/dist/src/stream-muxer/stream.d.ts +80 -21
  23. package/dist/src/stream-muxer/stream.d.ts.map +1 -1
  24. package/dist/src/stream-muxer/stream.js +224 -168
  25. package/dist/src/stream-muxer/stream.js.map +1 -1
  26. package/dist/src/transport/index.d.ts +5 -0
  27. package/dist/src/transport/index.d.ts.map +1 -1
  28. package/package.json +8 -11
  29. package/src/connection/index.ts +180 -59
  30. package/src/errors.ts +0 -1
  31. package/src/index.ts +8 -4
  32. package/src/keys/index.ts +0 -1
  33. package/src/peer-store/tags.ts +0 -1
  34. package/src/pubsub/index.ts +269 -0
  35. package/src/startable.ts +0 -1
  36. package/src/stream-handler/index.ts +6 -0
  37. package/src/stream-muxer/index.ts +7 -2
  38. package/src/stream-muxer/stream.ts +295 -186
  39. package/src/transport/index.ts +6 -0
  40. package/dist/src/connection/status.d.ts +0 -4
  41. package/dist/src/connection/status.d.ts.map +0 -1
  42. package/dist/src/connection/status.js +0 -4
  43. package/dist/src/connection/status.js.map +0 -1
  44. package/src/connection/status.ts +0 -4
@@ -37,10 +37,15 @@ export interface StreamMuxer extends Duplex<AsyncGenerator<Uint8Array>, Source<U
37
37
  /**
38
38
  * Close or abort all tracked streams and stop the muxer
39
39
  */
40
- close: (err?: Error) => void
40
+ close: (options?: AbortOptions) => Promise<void>
41
+
42
+ /**
43
+ * Close or abort all tracked streams and stop the muxer
44
+ */
45
+ abort: (err: Error) => void
41
46
  }
42
47
 
43
- export interface StreamMuxerInit extends AbortOptions {
48
+ export interface StreamMuxerInit {
44
49
  /**
45
50
  * A callback function invoked every time an incoming stream is opened
46
51
  */
@@ -1,22 +1,21 @@
1
- // import { logger } from '@libp2p/logger'
2
1
  import { abortableSource } from 'abortable-iterator'
3
- import { anySignal } from 'any-signal'
4
2
  import { type Pushable, pushable } from 'it-pushable'
3
+ import defer, { type DeferredPromise } from 'p-defer'
5
4
  import { Uint8ArrayList } from 'uint8arraylist'
6
5
  import { CodeError } from '../errors.js'
7
- import type { Direction, Stream, StreamStat } from '../connection/index.js'
6
+ import type { Direction, ReadStatus, Stream, StreamStatus, StreamTimeline, WriteStatus } from '../connection/index.js'
7
+ import type { AbortOptions } from '../index.js'
8
8
  import type { Source } from 'it-stream-types'
9
9
 
10
- // const log = logger('libp2p:stream')
11
-
12
- const log: any = () => {}
13
- log.trace = () => {}
14
- log.error = () => {}
10
+ interface Logger {
11
+ (formatter: any, ...args: any[]): void
12
+ error: (formatter: any, ...args: any[]) => void
13
+ trace: (formatter: any, ...args: any[]) => void
14
+ enabled: boolean
15
+ }
15
16
 
16
17
  const ERR_STREAM_RESET = 'ERR_STREAM_RESET'
17
- const ERR_STREAM_ABORT = 'ERR_STREAM_ABORT'
18
- const ERR_SINK_ENDED = 'ERR_SINK_ENDED'
19
- const ERR_DOUBLE_SINK = 'ERR_DOUBLE_SINK'
18
+ const ERR_SINK_INVALID_STATE = 'ERR_SINK_INVALID_STATE'
20
19
 
21
20
  export interface AbstractStreamInit {
22
21
  /**
@@ -30,10 +29,9 @@ export interface AbstractStreamInit {
30
29
  direction: Direction
31
30
 
32
31
  /**
33
- * The maximum allowable data size, any data larger than this will be
34
- * chunked and sent in multiple data messages
32
+ * A Logger implementation used to log stream-specific information
35
33
  */
36
- maxDataSize: number
34
+ log: Logger
37
35
 
38
36
  /**
39
37
  * User specific stream metadata
@@ -44,6 +42,32 @@ export interface AbstractStreamInit {
44
42
  * Invoked when the stream ends
45
43
  */
46
44
  onEnd?: (err?: Error | undefined) => void
45
+
46
+ /**
47
+ * Invoked when the readable end of the stream is closed
48
+ */
49
+ onCloseRead?: () => void
50
+
51
+ /**
52
+ * Invoked when the writable end of the stream is closed
53
+ */
54
+ onCloseWrite?: () => void
55
+
56
+ /**
57
+ * Invoked when the the stream has been reset by the remote
58
+ */
59
+ onReset?: () => void
60
+
61
+ /**
62
+ * Invoked when the the stream has errored
63
+ */
64
+ onAbort?: (err: Error) => void
65
+
66
+ /**
67
+ * How long to wait in ms for stream data to be written to the underlying
68
+ * connection when closing the writable end of the stream. (default: 500)
69
+ */
70
+ closeTimeout?: number
47
71
  }
48
72
 
49
73
  function isPromise (res?: any): res is Promise<void> {
@@ -52,54 +76,60 @@ function isPromise (res?: any): res is Promise<void> {
52
76
 
53
77
  export abstract class AbstractStream implements Stream {
54
78
  public id: string
55
- public stat: StreamStat
79
+ public direction: Direction
80
+ public timeline: StreamTimeline
81
+ public protocol?: string
56
82
  public metadata: Record<string, unknown>
57
83
  public source: AsyncGenerator<Uint8ArrayList, void, unknown>
84
+ public status: StreamStatus
85
+ public readStatus: ReadStatus
86
+ public writeStatus: WriteStatus
58
87
 
59
- private readonly abortController: AbortController
60
- private readonly resetController: AbortController
61
- private readonly closeController: AbortController
62
- private sourceEnded: boolean
63
- private sinkEnded: boolean
64
- private sinkSunk: boolean
88
+ private readonly sinkController: AbortController
89
+ private readonly sinkEnd: DeferredPromise<void>
65
90
  private endErr: Error | undefined
66
91
  private readonly streamSource: Pushable<Uint8ArrayList>
67
92
  private readonly onEnd?: (err?: Error | undefined) => void
68
- private readonly maxDataSize: number
93
+ private readonly onCloseRead?: () => void
94
+ private readonly onCloseWrite?: () => void
95
+ private readonly onReset?: () => void
96
+ private readonly onAbort?: (err: Error) => void
97
+
98
+ protected readonly log: Logger
69
99
 
70
100
  constructor (init: AbstractStreamInit) {
71
- this.abortController = new AbortController()
72
- this.resetController = new AbortController()
73
- this.closeController = new AbortController()
74
- this.sourceEnded = false
75
- this.sinkEnded = false
76
- this.sinkSunk = false
101
+ this.sinkController = new AbortController()
102
+ this.sinkEnd = defer()
103
+ this.log = init.log
104
+
105
+ // stream status
106
+ this.status = 'open'
107
+ this.readStatus = 'ready'
108
+ this.writeStatus = 'ready'
77
109
 
78
110
  this.id = init.id
79
111
  this.metadata = init.metadata ?? {}
80
- this.stat = {
81
- direction: init.direction,
82
- timeline: {
83
- open: Date.now()
84
- }
112
+ this.direction = init.direction
113
+ this.timeline = {
114
+ open: Date.now()
85
115
  }
86
- this.maxDataSize = init.maxDataSize
116
+
87
117
  this.onEnd = init.onEnd
118
+ this.onCloseRead = init?.onCloseRead
119
+ this.onCloseWrite = init?.onCloseWrite
120
+ this.onReset = init?.onReset
121
+ this.onAbort = init?.onAbort
88
122
 
89
123
  this.source = this.streamSource = pushable<Uint8ArrayList>({
90
- onEnd: () => {
91
- // already sent a reset message
92
- if (this.stat.timeline.reset !== null) {
93
- const res = this.sendCloseRead()
94
-
95
- if (isPromise(res)) {
96
- res.catch(err => {
97
- log.error('error while sending close read', err)
98
- })
99
- }
124
+ onEnd: (err) => {
125
+ if (err != null) {
126
+ this.log.trace('source ended with error', err)
127
+ } else {
128
+ this.log.trace('source ended')
100
129
  }
101
130
 
102
- this.onSourceEnd()
131
+ this.readStatus = 'closed'
132
+ this.onSourceEnd(err)
103
133
  }
104
134
  })
105
135
 
@@ -107,216 +137,295 @@ export abstract class AbstractStream implements Stream {
107
137
  this.sink = this.sink.bind(this)
108
138
  }
109
139
 
140
+ async sink (source: Source<Uint8ArrayList | Uint8Array>): Promise<void> {
141
+ if (this.writeStatus !== 'ready') {
142
+ throw new CodeError(`writable end state is "${this.writeStatus}" not "ready"`, ERR_SINK_INVALID_STATE)
143
+ }
144
+
145
+ try {
146
+ this.writeStatus = 'writing'
147
+
148
+ const options: AbortOptions = {
149
+ signal: this.sinkController.signal
150
+ }
151
+
152
+ if (this.direction === 'outbound') { // If initiator, open a new stream
153
+ const res = this.sendNewStream(options)
154
+
155
+ if (isPromise(res)) {
156
+ await res
157
+ }
158
+ }
159
+
160
+ source = abortableSource(source, this.sinkController.signal, {
161
+ returnOnAbort: true
162
+ })
163
+
164
+ this.log.trace('sink reading from source')
165
+
166
+ for await (let data of source) {
167
+ data = data instanceof Uint8Array ? new Uint8ArrayList(data) : data
168
+
169
+ const res = this.sendData(data, options)
170
+
171
+ if (isPromise(res)) { // eslint-disable-line max-depth
172
+ await res
173
+ }
174
+ }
175
+
176
+ this.log.trace('sink finished reading from source')
177
+ this.writeStatus = 'done'
178
+
179
+ this.log.trace('sink calling closeWrite')
180
+ await this.closeWrite(options)
181
+ this.onSinkEnd()
182
+ } catch (err: any) {
183
+ this.log.trace('sink ended with error, calling abort with error', err)
184
+ this.abort(err)
185
+
186
+ throw err
187
+ } finally {
188
+ this.log.trace('resolve sink end')
189
+ this.sinkEnd.resolve()
190
+ }
191
+ }
192
+
110
193
  protected onSourceEnd (err?: Error): void {
111
- if (this.sourceEnded) {
194
+ if (this.timeline.closeRead != null) {
112
195
  return
113
196
  }
114
197
 
115
- this.stat.timeline.closeRead = Date.now()
116
- this.sourceEnded = true
117
- log.trace('%s stream %s source end - err: %o', this.stat.direction, this.id, err)
198
+ this.timeline.closeRead = Date.now()
118
199
 
119
200
  if (err != null && this.endErr == null) {
120
201
  this.endErr = err
121
202
  }
122
203
 
123
- if (this.sinkEnded) {
124
- this.stat.timeline.close = Date.now()
204
+ this.onCloseRead?.()
205
+
206
+ if (this.timeline.closeWrite != null) {
207
+ this.log.trace('source and sink ended')
208
+ this.timeline.close = Date.now()
125
209
 
126
210
  if (this.onEnd != null) {
127
211
  this.onEnd(this.endErr)
128
212
  }
213
+ } else {
214
+ this.log.trace('source ended, waiting for sink to end')
129
215
  }
130
216
  }
131
217
 
132
218
  protected onSinkEnd (err?: Error): void {
133
- if (this.sinkEnded) {
219
+ if (this.timeline.closeWrite != null) {
134
220
  return
135
221
  }
136
222
 
137
- this.stat.timeline.closeWrite = Date.now()
138
- this.sinkEnded = true
139
- log.trace('%s stream %s sink end - err: %o', this.stat.direction, this.id, err)
223
+ this.timeline.closeWrite = Date.now()
140
224
 
141
225
  if (err != null && this.endErr == null) {
142
226
  this.endErr = err
143
227
  }
144
228
 
145
- if (this.sourceEnded) {
146
- this.stat.timeline.close = Date.now()
229
+ this.onCloseWrite?.()
230
+
231
+ if (this.timeline.closeRead != null) {
232
+ this.log.trace('sink and source ended')
233
+ this.timeline.close = Date.now()
147
234
 
148
235
  if (this.onEnd != null) {
149
236
  this.onEnd(this.endErr)
150
237
  }
238
+ } else {
239
+ this.log.trace('sink ended, waiting for source to end')
151
240
  }
152
241
  }
153
242
 
154
243
  // Close for both Reading and Writing
155
- close (): void {
156
- log.trace('%s stream %s close', this.stat.direction, this.id)
244
+ async close (options?: AbortOptions): Promise<void> {
245
+ this.log.trace('closing gracefully')
157
246
 
158
- this.closeRead()
159
- this.closeWrite()
160
- }
247
+ this.status = 'closing'
161
248
 
162
- // Close for reading
163
- closeRead (): void {
164
- log.trace('%s stream %s closeRead', this.stat.direction, this.id)
249
+ await Promise.all([
250
+ this.closeRead(options),
251
+ this.closeWrite(options)
252
+ ])
165
253
 
166
- if (this.sourceEnded) {
167
- return
168
- }
254
+ this.status = 'closed'
169
255
 
170
- this.streamSource.end()
256
+ this.log.trace('closed gracefully')
171
257
  }
172
258
 
173
- // Close for writing
174
- closeWrite (): void {
175
- log.trace('%s stream %s closeWrite', this.stat.direction, this.id)
176
-
177
- if (this.sinkEnded) {
259
+ async closeRead (options: AbortOptions = {}): Promise<void> {
260
+ if (this.readStatus === 'closing' || this.readStatus === 'closed') {
178
261
  return
179
262
  }
180
263
 
181
- this.closeController.abort()
264
+ this.log.trace('closing readable end of stream with starting read status "%s"', this.readStatus)
182
265
 
183
- try {
184
- // need to call this here as the sink method returns in the catch block
185
- // when the close controller is aborted
186
- const res = this.sendCloseWrite()
266
+ const readStatus = this.readStatus
267
+ this.readStatus = 'closing'
187
268
 
188
- if (isPromise(res)) {
189
- res.catch(err => {
190
- log.error('error while sending close write', err)
191
- })
192
- }
193
- } catch (err) {
194
- log.trace('%s stream %s error sending close', this.stat.direction, this.id, err)
269
+ if (readStatus === 'ready') {
270
+ this.log.trace('ending internal source queue')
271
+ this.streamSource.end()
195
272
  }
196
273
 
197
- this.onSinkEnd()
198
- }
274
+ if (this.status !== 'reset' && this.status !== 'aborted') {
275
+ this.log.trace('send close read to remote')
276
+ await this.sendCloseRead(options)
277
+ }
199
278
 
200
- // Close for reading and writing (local error)
201
- abort (err: Error): void {
202
- log.trace('%s stream %s abort', this.stat.direction, this.id, err)
203
- // End the source with the passed error
204
- this.streamSource.end(err)
205
- this.abortController.abort()
206
- this.onSinkEnd(err)
279
+ this.log.trace('closed readable end of stream')
207
280
  }
208
281
 
209
- // Close immediately for reading and writing (remote error)
210
- reset (): void {
211
- const err = new CodeError('stream reset', ERR_STREAM_RESET)
212
- this.resetController.abort()
213
- this.streamSource.end(err)
214
- this.onSinkEnd(err)
215
- }
282
+ async closeWrite (options: AbortOptions = {}): Promise<void> {
283
+ if (this.writeStatus === 'closing' || this.writeStatus === 'closed') {
284
+ return
285
+ }
216
286
 
217
- async sink (source: Source<Uint8ArrayList | Uint8Array>): Promise<void> {
218
- if (this.sinkSunk) {
219
- throw new CodeError('sink already called on stream', ERR_DOUBLE_SINK)
287
+ this.log.trace('closing writable end of stream with starting write status "%s"', this.writeStatus)
288
+
289
+ const writeStatus = this.writeStatus
290
+
291
+ if (this.writeStatus === 'ready') {
292
+ this.log.trace('sink was never sunk, sink an empty array')
293
+ await this.sink([])
220
294
  }
221
295
 
222
- this.sinkSunk = true
296
+ this.writeStatus = 'closing'
297
+
298
+ if (writeStatus === 'writing') {
299
+ // stop reading from the source passed to `.sink` in the microtask queue
300
+ // - this lets any data queued by the user in the current tick get read
301
+ // before we exit
302
+ await new Promise((resolve, reject) => {
303
+ queueMicrotask(() => {
304
+ this.log.trace('aborting source passed to .sink')
305
+ this.sinkController.abort()
306
+ this.sinkEnd.promise.then(resolve, reject)
307
+ })
308
+ })
309
+ }
223
310
 
224
- if (this.sinkEnded) {
225
- throw new CodeError('stream closed for writing', ERR_SINK_ENDED)
311
+ if (this.status !== 'reset' && this.status !== 'aborted') {
312
+ this.log.trace('send close write to remote')
313
+ await this.sendCloseWrite(options)
226
314
  }
227
315
 
228
- const signal = anySignal([
229
- this.abortController.signal,
230
- this.resetController.signal,
231
- this.closeController.signal
232
- ])
316
+ this.writeStatus = 'closed'
233
317
 
234
- try {
235
- source = abortableSource(source, signal)
318
+ this.log.trace('closed writable end of stream')
319
+ }
236
320
 
237
- if (this.stat.direction === 'outbound') { // If initiator, open a new stream
238
- const res = this.sendNewStream()
321
+ /**
322
+ * Close immediately for reading and writing and send a reset message (local
323
+ * error)
324
+ */
325
+ abort (err: Error): void {
326
+ if (this.status === 'closed' || this.status === 'aborted' || this.status === 'reset') {
327
+ return
328
+ }
239
329
 
240
- if (isPromise(res)) {
241
- await res
242
- }
243
- }
330
+ this.log('abort with error', err)
244
331
 
245
- for await (let data of source) {
246
- while (data.length > 0) {
247
- if (data.length <= this.maxDataSize) {
248
- const res = this.sendData(data instanceof Uint8Array ? new Uint8ArrayList(data) : data)
332
+ // try to send a reset message
333
+ this.log('try to send reset to remote')
334
+ const res = this.sendReset()
249
335
 
250
- if (isPromise(res)) { // eslint-disable-line max-depth
251
- await res
252
- }
336
+ if (isPromise(res)) {
337
+ res.catch((err) => {
338
+ this.log.error('error sending reset message', err)
339
+ })
340
+ }
253
341
 
254
- break
255
- }
256
- data = data instanceof Uint8Array ? new Uint8ArrayList(data) : data
257
- const res = this.sendData(data.sublist(0, this.maxDataSize))
342
+ this.status = 'aborted'
343
+ this.timeline.abort = Date.now()
344
+ this._closeSinkAndSource(err)
345
+ this.onAbort?.(err)
346
+ }
258
347
 
259
- if (isPromise(res)) {
260
- await res
261
- }
348
+ /**
349
+ * Receive a reset message - close immediately for reading and writing (remote
350
+ * error)
351
+ */
352
+ reset (): void {
353
+ if (this.status === 'closed' || this.status === 'aborted' || this.status === 'reset') {
354
+ return
355
+ }
262
356
 
263
- data.consume(this.maxDataSize)
264
- }
265
- }
266
- } catch (err: any) {
267
- if (err.type === 'aborted' && err.message === 'The operation was aborted') {
268
- if (this.closeController.signal.aborted) {
269
- return
270
- }
357
+ const err = new CodeError('stream reset', ERR_STREAM_RESET)
271
358
 
272
- if (this.resetController.signal.aborted) {
273
- err.message = 'stream reset'
274
- err.code = ERR_STREAM_RESET
275
- }
359
+ this.status = 'reset'
360
+ this._closeSinkAndSource(err)
361
+ this.onReset?.()
362
+ }
276
363
 
277
- if (this.abortController.signal.aborted) {
278
- err.message = 'stream aborted'
279
- err.code = ERR_STREAM_ABORT
280
- }
281
- }
364
+ _closeSinkAndSource (err?: Error): void {
365
+ this._closeSink(err)
366
+ this._closeSource(err)
367
+ }
282
368
 
283
- // Send no more data if this stream was remotely reset
284
- if (err.code === ERR_STREAM_RESET) {
285
- log.trace('%s stream %s reset', this.stat.direction, this.id)
286
- } else {
287
- log.trace('%s stream %s error', this.stat.direction, this.id, err)
288
- try {
289
- const res = this.sendReset()
290
-
291
- if (isPromise(res)) {
292
- await res
293
- }
294
-
295
- this.stat.timeline.reset = Date.now()
296
- } catch (err) {
297
- log.trace('%s stream %s error sending reset', this.stat.direction, this.id, err)
298
- }
299
- }
369
+ _closeSink (err?: Error): void {
370
+ // if the sink function is running, cause it to end
371
+ if (this.writeStatus === 'writing') {
372
+ this.log.trace('end sink source')
373
+ this.sinkController.abort()
374
+ }
300
375
 
376
+ this.onSinkEnd(err)
377
+ }
378
+
379
+ _closeSource (err?: Error): void {
380
+ // if the source is not ending, end it
381
+ if (this.readStatus !== 'closing' && this.readStatus !== 'closed') {
382
+ this.log.trace('ending source with %d bytes to be read by consumer', this.streamSource.readableLength)
383
+ this.readStatus = 'closing'
301
384
  this.streamSource.end(err)
302
- this.onSinkEnd(err)
385
+ }
386
+ }
303
387
 
304
- throw err
305
- } finally {
306
- signal.clear()
388
+ /**
389
+ * The remote closed for writing so we should expect to receive no more
390
+ * messages
391
+ */
392
+ remoteCloseWrite (): void {
393
+ if (this.readStatus === 'closing' || this.readStatus === 'closed') {
394
+ this.log('received remote close write but local source is already closed')
395
+ return
307
396
  }
308
397
 
309
- try {
310
- const res = this.sendCloseWrite()
398
+ this.log.trace('remote close write')
399
+ this._closeSource()
400
+ }
311
401
 
312
- if (isPromise(res)) {
313
- await res
314
- }
315
- } catch (err) {
316
- log.trace('%s stream %s error sending close', this.stat.direction, this.id, err)
402
+ /**
403
+ * The remote closed for reading so we should not send any more
404
+ * messages
405
+ */
406
+ remoteCloseRead (): void {
407
+ if (this.writeStatus === 'closing' || this.writeStatus === 'closed') {
408
+ this.log('received remote close read but local sink is already closed')
409
+ return
317
410
  }
318
411
 
319
- this.onSinkEnd()
412
+ this.log.trace('remote close read')
413
+ this._closeSink()
414
+ }
415
+
416
+ /**
417
+ * The underlying muxer has closed, no more messages can be sent or will
418
+ * be received, close immediately to free up resources
419
+ */
420
+ destroy (): void {
421
+ if (this.status === 'closed' || this.status === 'aborted' || this.status === 'reset') {
422
+ this.log('received destroy but we are already closed')
423
+ return
424
+ }
425
+
426
+ this.log.trace('muxer destroyed')
427
+
428
+ this._closeSinkAndSource()
320
429
  }
321
430
 
322
431
  /**
@@ -339,27 +448,27 @@ export abstract class AbstractStream implements Stream {
339
448
  * Send a message to the remote muxer informing them a new stream is being
340
449
  * opened
341
450
  */
342
- abstract sendNewStream (): void | Promise<void>
451
+ abstract sendNewStream (options?: AbortOptions): void | Promise<void>
343
452
 
344
453
  /**
345
454
  * Send a data message to the remote muxer
346
455
  */
347
- abstract sendData (buf: Uint8ArrayList): void | Promise<void>
456
+ abstract sendData (buf: Uint8ArrayList, options?: AbortOptions): void | Promise<void>
348
457
 
349
458
  /**
350
459
  * Send a reset message to the remote muxer
351
460
  */
352
- abstract sendReset (): void | Promise<void>
461
+ abstract sendReset (options?: AbortOptions): void | Promise<void>
353
462
 
354
463
  /**
355
464
  * Send a message to the remote muxer, informing them no more data messages
356
465
  * will be sent by this end of the stream
357
466
  */
358
- abstract sendCloseWrite (): void | Promise<void>
467
+ abstract sendCloseWrite (options?: AbortOptions): void | Promise<void>
359
468
 
360
469
  /**
361
470
  * Send a message to the remote muxer, informing them no more data messages
362
471
  * will be read by this end of the stream
363
472
  */
364
- abstract sendCloseRead (): void | Promise<void>
473
+ abstract sendCloseRead (options?: AbortOptions): void | Promise<void>
365
474
  }
@@ -96,6 +96,12 @@ export interface UpgraderOptions {
96
96
  skipEncryption?: boolean
97
97
  skipProtection?: boolean
98
98
  muxerFactory?: StreamMuxerFactory
99
+
100
+ /**
101
+ * The passed MultiaddrConnection has limits place on duration and/or data
102
+ * transfer amounts so is not expected to be open for very long.
103
+ */
104
+ transient?: boolean
99
105
  }
100
106
 
101
107
  export interface Upgrader {
@@ -1,4 +0,0 @@
1
- export declare const OPEN = "OPEN";
2
- export declare const CLOSING = "CLOSING";
3
- export declare const CLOSED = "CLOSED";
4
- //# sourceMappingURL=status.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/connection/status.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,SAAS,CAAA;AAC1B,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,MAAM,WAAW,CAAA"}
@@ -1,4 +0,0 @@
1
- export const OPEN = 'OPEN';
2
- export const CLOSING = 'CLOSING';
3
- export const CLOSED = 'CLOSED';
4
- //# sourceMappingURL=status.js.map