@libp2p/memory 1.1.14 → 2.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.
@@ -1,55 +1,12 @@
1
- /**
2
- * @packageDocumentation
3
- *
4
- * A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/)
5
- * that operates in-memory only.
6
- *
7
- * This is intended for testing and can only be used to connect two libp2p nodes
8
- * that are running in the same process.
9
- *
10
- * @example
11
- *
12
- * ```TypeScript
13
- * import { createLibp2p } from 'libp2p'
14
- * import { memory } from '@libp2p/memory'
15
- * import { multiaddr } from '@multiformats/multiaddr'
16
- *
17
- * const listener = await createLibp2p({
18
- * addresses: {
19
- * listen: [
20
- * '/memory/node-a'
21
- * ]
22
- * },
23
- * transports: [
24
- * memory()
25
- * ]
26
- * })
27
- *
28
- * const dialer = await createLibp2p({
29
- * transports: [
30
- * memory()
31
- * ]
32
- * })
33
- *
34
- * const ma = multiaddr('/memory/node-a')
35
- *
36
- * // dial the listener, timing out after 10s
37
- * const connection = await dialer.dial(ma, {
38
- * signal: AbortSignal.timeout(10_000)
39
- * })
40
- *
41
- * // use connection...
42
- * ```
43
- */
44
-
45
1
  import { ConnectionFailedError } from '@libp2p/interface'
46
2
  import { multiaddr } from '@multiformats/multiaddr'
47
3
  import delay from 'delay'
48
- import map from 'it-map'
49
4
  import { pushable } from 'it-pushable'
50
5
  import { raceSignal } from 'race-signal'
6
+ import { DEFAULT_MAX_MESSAGE_SIZE } from './constants.ts'
7
+ import { pushableToMaConn } from './pushable-to-conn.ts'
51
8
  import type { MemoryTransportComponents, MemoryTransportInit } from './index.js'
52
- import type { MultiaddrConnection, PeerId } from '@libp2p/interface'
9
+ import type { Logger, MultiaddrConnection, PeerId } from '@libp2p/interface'
53
10
  import type { Uint8ArrayList } from 'uint8arraylist'
54
11
 
55
12
  export const connections = new Map<string, MemoryConnection>()
@@ -63,106 +20,74 @@ interface MemoryConnectionInit extends MemoryTransportInit {
63
20
  address: string
64
21
  }
65
22
 
23
+ let connectionId = 0
24
+
66
25
  export class MemoryConnection {
26
+ public readonly latency: number
27
+
67
28
  private readonly components: MemoryTransportComponents
68
29
  private readonly init: MemoryConnectionInit
69
30
  private readonly connections: Set<MultiaddrConnection>
70
- private readonly latency: number
31
+ private readonly log: Logger
71
32
 
72
33
  constructor (components: MemoryTransportComponents, init: MemoryConnectionInit) {
73
34
  this.components = components
74
35
  this.init = init
75
36
  this.connections = new Set()
76
37
  this.latency = init.latency ?? 0
38
+ this.log = components.logger.forComponent('libp2p:memory')
77
39
  }
78
40
 
79
- async dial (dialingPeerId: PeerId, signal: AbortSignal): Promise<MultiaddrConnection> {
80
- const dialerPushable = pushable<Uint8Array | Uint8ArrayList>()
81
- const listenerPushable = pushable<Uint8Array | Uint8ArrayList>()
41
+ async dial (dialingPeerId: PeerId, dialingPeerLog: Logger, signal: AbortSignal): Promise<MultiaddrConnection> {
82
42
  const self = this
83
43
 
84
- const dialer: MultiaddrConnection = {
85
- source: (async function * () {
86
- yield * map(listenerPushable, async buf => {
87
- if (self.latency > 0) {
88
- await delay(self.latency)
89
- }
90
-
91
- return buf
92
- })
93
- })(),
94
- sink: async (source) => {
95
- for await (const buf of source) {
96
- dialerPushable.push(buf)
44
+ let dialerEnded = false
45
+ let listenerEnded = false
46
+
47
+ const dialerPushable = pushable<Uint8Array | Uint8ArrayList>({
48
+ onEnd (err) {
49
+ dialerEnded = true
50
+ self.connections.delete(dialer)
51
+
52
+ if (!listenerEnded) {
53
+ listenerPushable.end(err)
97
54
  }
98
- },
99
- close: async () => {
100
- dialerPushable.end()
101
- this.connections.delete(dialer)
102
- dialer.timeline.close = Date.now()
103
-
104
- listenerPushable.end()
105
- this.connections.delete(listener)
106
- listener.timeline.close = Date.now()
107
- },
108
- abort: (err) => {
109
- dialerPushable.end(err)
110
- this.connections.delete(dialer)
111
- dialer.timeline.close = Date.now()
112
-
113
- listenerPushable.end(err)
114
- this.connections.delete(listener)
115
- listener.timeline.close = Date.now()
116
- },
117
- timeline: {
118
- open: Date.now()
119
- },
120
- remoteAddr: multiaddr(`${this.init.address}/p2p/${this.components.peerId}`),
121
- log: this.components.logger.forComponent('libp2p:memory')
122
- }
123
-
124
- const listener: MultiaddrConnection = {
125
- source: (async function * () {
126
- yield * map(dialerPushable, async buf => {
127
- if (self.latency > 0) {
128
- await delay(self.latency)
129
- }
130
-
131
- return buf
132
- })
133
- })(),
134
- sink: async (source) => {
135
- for await (const buf of source) {
136
- listenerPushable.push(buf)
55
+ }
56
+ })
57
+ const listenerPushable = pushable<Uint8Array | Uint8ArrayList>({
58
+ onEnd (err) {
59
+ listenerEnded = true
60
+ self.connections.delete(listener)
61
+
62
+ if (!dialerEnded) {
63
+ dialerPushable.end(err)
137
64
  }
138
- },
139
- close: async () => {
140
- listenerPushable.end()
141
- this.connections.delete(listener)
142
- listener.timeline.close = Date.now()
143
-
144
- dialerPushable.end()
145
- this.connections.delete(dialer)
146
- dialer.timeline.close = Date.now()
147
- },
148
- abort: (err) => {
149
- listenerPushable.end(err)
150
- this.connections.delete(listener)
151
- listener.timeline.close = Date.now()
152
-
153
- dialerPushable.end(err)
154
- this.connections.delete(dialer)
155
- dialer.timeline.close = Date.now()
156
- },
157
- timeline: {
158
- open: Date.now()
159
- },
65
+ }
66
+ })
67
+
68
+ const dialer = pushableToMaConn({
69
+ connection: this,
70
+ remoteAddr: multiaddr(`${this.init.address}/p2p/${this.components.peerId}`),
71
+ direction: 'outbound',
72
+ localPushable: dialerPushable,
73
+ remotePushable: listenerPushable,
74
+ log: dialingPeerLog.newScope(`connection:${connectionId}`),
75
+ maxMessageSize: this.init.maxMessageSize ?? DEFAULT_MAX_MESSAGE_SIZE
76
+ })
77
+
78
+ const listener = pushableToMaConn({
79
+ connection: this,
160
80
  remoteAddr: multiaddr(`${this.init.address}-outgoing/p2p/${dialingPeerId}`),
161
- log: this.components.logger.forComponent('libp2p:memory')
162
- }
81
+ direction: 'inbound',
82
+ localPushable: listenerPushable,
83
+ remotePushable: dialerPushable,
84
+ log: this.log.newScope(`connection:${connectionId}`),
85
+ maxMessageSize: this.init.maxMessageSize ?? DEFAULT_MAX_MESSAGE_SIZE
86
+ })
163
87
 
164
88
  this.connections.add(dialer)
165
89
  this.connections.add(listener)
90
+ connectionId++
166
91
 
167
92
  await raceSignal(delay(this.latency), signal)
168
93
 
@@ -0,0 +1 @@
1
+ export const DEFAULT_MAX_MESSAGE_SIZE = 65_536
package/src/index.ts CHANGED
@@ -59,6 +59,13 @@ export interface MemoryTransportInit {
59
59
  * @default 0
60
60
  */
61
61
  latency?: number
62
+
63
+ /**
64
+ * Data messages larger than this will be chunked before sending
65
+ *
66
+ * @default 65_536
67
+ */
68
+ maxMessageSize?: number
62
69
  }
63
70
 
64
71
  export function memory (init?: MemoryTransportInit): (components: MemoryTransportComponents) => Transport {
package/src/listener.ts CHANGED
@@ -28,7 +28,8 @@ export class MemoryTransportListener extends TypedEventEmitter<ListenerEvents> i
28
28
  }
29
29
 
30
30
  async listen (ma: Multiaddr): Promise<void> {
31
- const [[, value]] = ma.stringTuples()
31
+ const components = ma.getComponents()
32
+ const value = components[0]?.value
32
33
 
33
34
  const address = `/memory/${value ?? nanoid()}`
34
35
 
package/src/memory.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ConnectionFailedError, serviceCapabilities, transportSymbol } from '@libp2p/interface'
2
+ import { CODE_P2P } from '@multiformats/multiaddr'
2
3
  import { Memory } from '@multiformats/multiaddr-matcher'
3
4
  import { connections } from './connections.js'
4
5
  import { MemoryTransportListener } from './listener.js'
@@ -26,13 +27,14 @@ export class MemoryTransport implements Transport {
26
27
  async dial (ma: Multiaddr, options: DialTransportOptions): Promise<Connection> {
27
28
  options.signal.throwIfAborted()
28
29
 
29
- const memoryConnection = connections.get(`${ma.getPeerId() == null ? ma : ma.decapsulate('/p2p')}`)
30
+ const peerId = ma.getComponents().find(c => c.code === CODE_P2P)?.value
31
+ const memoryConnection = connections.get(`${peerId == null ? ma : ma.decapsulate('/p2p')}`)
30
32
 
31
33
  if (memoryConnection == null) {
32
34
  throw new ConnectionFailedError(`No memory listener found at ${ma}`)
33
35
  }
34
36
 
35
- const maConn = await memoryConnection.dial(this.components.peerId, options.signal)
37
+ const maConn = await memoryConnection.dial(this.components.peerId, this.components.logger.forComponent('libp2p:memory'), options.signal)
36
38
 
37
39
  try {
38
40
  options.signal.throwIfAborted()
@@ -0,0 +1,78 @@
1
+ import { StreamResetError } from '@libp2p/interface'
2
+ import { AbstractMultiaddrConnection } from '@libp2p/utils'
3
+ import delay from 'delay'
4
+ import map from 'it-map'
5
+ import { Uint8ArrayList } from 'uint8arraylist'
6
+ import type { MemoryConnection } from './connections.ts'
7
+ import type { MessageStreamDirection, MultiaddrConnection, AbortOptions } from '@libp2p/interface'
8
+ import type { AbstractMultiaddrConnectionInit, SendResult } from '@libp2p/utils'
9
+ import type { Multiaddr } from '@multiformats/multiaddr'
10
+ import type { Pushable } from 'it-pushable'
11
+
12
+ export interface MemoryMultiaddrConnectionInit extends Omit<AbstractMultiaddrConnectionInit, 'name' | 'stream'> {
13
+ localPushable: Pushable<Uint8Array | Uint8ArrayList>
14
+ remotePushable: Pushable<Uint8Array | Uint8ArrayList>
15
+ inactivityTimeout?: number
16
+ closeTimeout?: number
17
+ listeningAddr?: Multiaddr
18
+ connection: MemoryConnection
19
+ direction: MessageStreamDirection
20
+ }
21
+
22
+ class MemoryMultiaddrConnection extends AbstractMultiaddrConnection {
23
+ private localPushable: Pushable<Uint8Array | Uint8ArrayList>
24
+
25
+ constructor (init: MemoryMultiaddrConnectionInit) {
26
+ super(init)
27
+
28
+ this.localPushable = init.localPushable
29
+
30
+ Promise.resolve()
31
+ .then(async () => {
32
+ for await (const buf of map(init.remotePushable, async buf => {
33
+ if (init.connection.latency > 0) {
34
+ await delay(init.connection.latency)
35
+ }
36
+
37
+ return buf
38
+ })) {
39
+ this.onData(buf)
40
+ }
41
+
42
+ this.onTransportClosed()
43
+ })
44
+ .catch(err => {
45
+ this.abort(err)
46
+ })
47
+ }
48
+
49
+ sendReset (): void {
50
+ this.localPushable.end(new StreamResetError())
51
+ }
52
+
53
+ sendData (data: Uint8ArrayList): SendResult {
54
+ this.localPushable.push(data)
55
+
56
+ return {
57
+ sentBytes: data.byteLength,
58
+ canSendMore: true
59
+ }
60
+ }
61
+
62
+ async sendClose (options?: AbortOptions): Promise<void> {
63
+ this.localPushable.end()
64
+ options?.signal?.throwIfAborted()
65
+ }
66
+
67
+ sendPause (): void {
68
+ // read backpressure is not supported
69
+ }
70
+
71
+ sendResume (): void {
72
+ // read backpressure is not supported
73
+ }
74
+ }
75
+
76
+ export function pushableToMaConn (init: MemoryMultiaddrConnectionInit): MultiaddrConnection {
77
+ return new MemoryMultiaddrConnection(init)
78
+ }
@@ -1,8 +0,0 @@
1
- {
2
- "MemoryTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_memory.MemoryTransportComponents.html",
3
- ".:MemoryTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_memory.MemoryTransportComponents.html",
4
- "MemoryTransportInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_memory.MemoryTransportInit.html",
5
- ".:MemoryTransportInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_memory.MemoryTransportInit.html",
6
- "memory": "https://libp2p.github.io/js-libp2p/functions/_libp2p_memory.memory.html",
7
- ".:memory": "https://libp2p.github.io/js-libp2p/functions/_libp2p_memory.memory.html"
8
- }