@agoric/network 0.1.1-dev-2f092c3.0

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.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @template T
3
+ * @typedef {object} Router A delimited string router implementation
4
+ * @property {(addr: string) => [string, T][]} getRoutes Return the match and
5
+ * route in order of preference
6
+ * @property {(prefix: string, route: T) => void} register Add a prefix->route
7
+ * to the database
8
+ * @property {(prefix: string, route: T) => void} unregister Remove a
9
+ * prefix->route from the database
10
+ */
11
+ /**
12
+ * Create a slash-delimited router.
13
+ *
14
+ * @template T
15
+ * @returns {Router<T>} a new Router
16
+ */
17
+ export default function makeRouter<T>(): Router<T>;
18
+ /**
19
+ * @typedef {object} RouterProtocol
20
+ * @property {(prefix: string) => Promise<Port>} bind
21
+ * @property {(paths: string[], protocolHandler: ProtocolHandler) => void} registerProtocolHandler
22
+ * @property {(prefix: string, protocolHandler: ProtocolHandler) => void} unregisterProtocolHandler
23
+ */
24
+ /**
25
+ * Create a router that behaves like a Protocol.
26
+ *
27
+ * @param {typeof defaultE} [E] Eventual sender
28
+ * @returns {RouterProtocol} The new delegated protocol
29
+ */
30
+ export function makeRouterProtocol(E?: ((<T>(x: T) => import("@endo/eventual-send/src/E.js").ECallableOrMethods<import("@endo/eventual-send").RemoteFunctions<T>>) & {
31
+ readonly get: <T_1>(x: T_1) => import("@endo/eventual-send/src/E.js").EGetters<import("@endo/eventual-send").LocalRecord<T_1>>;
32
+ readonly resolve: {
33
+ (): Promise<void>;
34
+ <T_2>(value: T_2): Promise<Awaited<T_2>>;
35
+ <T_3>(value: T_3 | PromiseLike<T_3>): Promise<Awaited<T_3>>;
36
+ };
37
+ readonly sendOnly: <T_4>(x: T_4) => import("@endo/eventual-send/src/E.js").ESendOnlyCallableOrMethods<import("@endo/eventual-send").RemoteFunctions<T_4>>;
38
+ readonly when: <T_5, U = T_5>(x: T_5 | PromiseLike<T_5>, onfulfilled?: ((value: T_5) => import("@endo/eventual-send").ERef<U>) | undefined, onrejected?: ((reason: any) => import("@endo/eventual-send").ERef<U>) | undefined) => Promise<U>;
39
+ }) | undefined): RouterProtocol;
40
+ /**
41
+ * A delimited string router implementation
42
+ */
43
+ export type Router<T> = {
44
+ /**
45
+ * Return the match and
46
+ * route in order of preference
47
+ */
48
+ getRoutes: (addr: string) => [string, T][];
49
+ /**
50
+ * Add a prefix->route
51
+ * to the database
52
+ */
53
+ register: (prefix: string, route: T) => void;
54
+ /**
55
+ * Remove a
56
+ * prefix->route from the database
57
+ */
58
+ unregister: (prefix: string, route: T) => void;
59
+ };
60
+ export type RouterProtocol = {
61
+ bind: (prefix: string) => Promise<Port>;
62
+ registerProtocolHandler: (paths: string[], protocolHandler: ProtocolHandler) => void;
63
+ unregisterProtocolHandler: (prefix: string, protocolHandler: ProtocolHandler) => void;
64
+ };
65
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["router.js"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,mDAkCC;AAED;;;;;GAKG;AAEH;;;;;GAKG;AACH;;;;;;;;;iBAFa,cAAc,CAyC1B;;;;;;;;;sBAtGoB,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;;;;;uBAEtB,MAAM,SAAS,CAAC,KAAK,IAAI;;;;;yBAEzB,MAAM,SAAS,CAAC,KAAK,IAAI;;;mBAgDzB,MAAM,KAAK,QAAQ,IAAI,CAAC;qCACzB,MAAM,EAAE,mBAAmB,eAAe,KAAK,IAAI;wCAClD,MAAM,mBAAmB,eAAe,KAAK,IAAI"}
package/src/router.js ADDED
@@ -0,0 +1,114 @@
1
+ import { Far, E as defaultE } from '@endo/far';
2
+ import { makeScalarMapStore } from '@agoric/store';
3
+ import { Fail } from '@agoric/assert';
4
+ import { makeNetworkProtocol, ENDPOINT_SEPARATOR } from './network.js';
5
+
6
+ import '@agoric/store/exported.js';
7
+ import './types.js';
8
+
9
+ /**
10
+ * @template T
11
+ * @typedef {object} Router A delimited string router implementation
12
+ * @property {(addr: string) => [string, T][]} getRoutes Return the match and
13
+ * route in order of preference
14
+ * @property {(prefix: string, route: T) => void} register Add a prefix->route
15
+ * to the database
16
+ * @property {(prefix: string, route: T) => void} unregister Remove a
17
+ * prefix->route from the database
18
+ */
19
+
20
+ /**
21
+ * Create a slash-delimited router.
22
+ *
23
+ * @template T
24
+ * @returns {Router<T>} a new Router
25
+ */
26
+ export default function makeRouter() {
27
+ /** @type {MapStore<string, T>} */
28
+ const prefixToRoute = makeScalarMapStore('prefix');
29
+ return Far('Router', {
30
+ getRoutes(addr) {
31
+ const parts = addr.split(ENDPOINT_SEPARATOR);
32
+ /** @type {[string, T][]} */
33
+ const ret = [];
34
+ for (let i = parts.length; i > 0; i -= 1) {
35
+ // Try most specific match.
36
+ const prefix = parts.slice(0, i).join(ENDPOINT_SEPARATOR);
37
+ if (prefixToRoute.has(prefix)) {
38
+ ret.push([prefix, prefixToRoute.get(prefix)]);
39
+ }
40
+ // Trim off the last value (after the slash).
41
+ const defaultPrefix = prefix.substr(
42
+ 0,
43
+ prefix.lastIndexOf(ENDPOINT_SEPARATOR) + 1,
44
+ );
45
+ if (prefixToRoute.has(defaultPrefix)) {
46
+ ret.push([defaultPrefix, prefixToRoute.get(defaultPrefix)]);
47
+ }
48
+ }
49
+ return harden(ret);
50
+ },
51
+ register(prefix, route) {
52
+ prefixToRoute.init(prefix, route);
53
+ },
54
+ unregister(prefix, route) {
55
+ prefixToRoute.get(prefix) === route ||
56
+ Fail`Router is not registered at prefix ${prefix}`;
57
+ prefixToRoute.delete(prefix);
58
+ },
59
+ });
60
+ }
61
+
62
+ /**
63
+ * @typedef {object} RouterProtocol
64
+ * @property {(prefix: string) => Promise<Port>} bind
65
+ * @property {(paths: string[], protocolHandler: ProtocolHandler) => void} registerProtocolHandler
66
+ * @property {(prefix: string, protocolHandler: ProtocolHandler) => void} unregisterProtocolHandler
67
+ */
68
+
69
+ /**
70
+ * Create a router that behaves like a Protocol.
71
+ *
72
+ * @param {typeof defaultE} [E] Eventual sender
73
+ * @returns {RouterProtocol} The new delegated protocol
74
+ */
75
+ export function makeRouterProtocol(E = defaultE) {
76
+ const router = makeRouter();
77
+ /** @type {MapStore<string, Protocol>} */
78
+ const protocols = makeScalarMapStore('prefix');
79
+ /** @type {MapStore<string, ProtocolHandler>} */
80
+ const protocolHandlers = makeScalarMapStore('prefix');
81
+
82
+ function registerProtocolHandler(paths, protocolHandler) {
83
+ const protocol = makeNetworkProtocol(protocolHandler);
84
+ for (const prefix of paths) {
85
+ router.register(prefix, protocol);
86
+ protocols.init(prefix, protocol);
87
+ protocolHandlers.init(prefix, protocolHandler);
88
+ }
89
+ }
90
+
91
+ // FIXME: Buggy.
92
+ // Needs to account for multiple paths.
93
+ function unregisterProtocolHandler(prefix, protocolHandler) {
94
+ const ph = protocolHandlers.get(prefix);
95
+ ph === protocolHandler ||
96
+ Fail`Protocol handler is not registered at prefix ${prefix}`;
97
+ router.unregister(prefix, ph);
98
+ protocols.delete(prefix);
99
+ protocolHandlers.delete(prefix);
100
+ }
101
+
102
+ /** @type {Protocol['bind']} */
103
+ async function bind(localAddr) {
104
+ const [route] = router.getRoutes(localAddr);
105
+ route !== undefined || Fail`No registered router for ${localAddr}`;
106
+ return E(route[1]).bind(localAddr);
107
+ }
108
+
109
+ return Far('RouterProtocol', {
110
+ bind,
111
+ registerProtocolHandler,
112
+ unregisterProtocolHandler,
113
+ });
114
+ }
package/src/types.d.ts ADDED
@@ -0,0 +1,205 @@
1
+ type Data = string | Buffer | ArrayBuffer;
2
+ type Bytes = string;
3
+ /**
4
+ * A local or remote address See multiaddr.js for an
5
+ * opinionated router implementation
6
+ */
7
+ type Endpoint = string;
8
+ /**
9
+ * A closable object
10
+ */
11
+ type Closable = {
12
+ /**
13
+ * Terminate the object
14
+ */
15
+ close: () => Promise<void>;
16
+ };
17
+ /**
18
+ * The network Protocol
19
+ */
20
+ type Protocol = {
21
+ /**
22
+ * Claim a port, or if
23
+ * ending in ENDPOINT_SEPARATOR, a fresh name
24
+ */
25
+ bind: (prefix: Endpoint) => Promise<Port>;
26
+ };
27
+ /**
28
+ * A port that has been bound to a protocol
29
+ */
30
+ type Port = {
31
+ /**
32
+ * Get the locally bound name of this
33
+ * port
34
+ */
35
+ getLocalAddress: () => Endpoint;
36
+ /**
37
+ * Begin accepting incoming connections
38
+ */
39
+ addListener: (acceptHandler: ListenHandler) => Promise<void>;
40
+ /**
41
+ * Make an outbound connection
42
+ */
43
+ connect: (remote: Endpoint, connectionHandler?: ConnectionHandler) => Promise<Connection>;
44
+ /**
45
+ * Remove the currently-bound listener
46
+ */
47
+ removeListener: (acceptHandler: ListenHandler) => Promise<void>;
48
+ /**
49
+ * Deallocate the port entirely, removing all
50
+ * listeners and closing all active connections
51
+ */
52
+ revoke: () => void;
53
+ };
54
+ /**
55
+ * A handler for incoming connections
56
+ */
57
+ type ListenHandler = {
58
+ /**
59
+ * The
60
+ * listener has been registered
61
+ */
62
+ onListen?: ((port: Port, l: ListenHandler) => Promise<void>) | undefined;
63
+ /**
64
+ * A new connection is incoming
65
+ */
66
+ onAccept: (port: Port, localAddr: Endpoint, remoteAddr: Endpoint, l: ListenHandler) => Promise<ConnectionHandler>;
67
+ /**
68
+ * The connection was rejected
69
+ */
70
+ onReject?: ((port: Port, localAddr: Endpoint, remoteAddr: Endpoint, l: ListenHandler) => Promise<void>) | undefined;
71
+ /**
72
+ * There was an error while listening
73
+ */
74
+ onError?: ((port: Port, rej: any, l: ListenHandler) => Promise<void>) | undefined;
75
+ /**
76
+ * The
77
+ * listener has been removed
78
+ */
79
+ onRemove?: ((port: Port, l: ListenHandler) => Promise<void>) | undefined;
80
+ };
81
+ type Connection = {
82
+ /**
83
+ * Send a packet on the connection
84
+ */
85
+ send: (packetBytes: Data, opts?: Record<string, any>) => Promise<Bytes>;
86
+ /**
87
+ * Close both ends of the connection
88
+ */
89
+ close: () => Promise<void>;
90
+ /**
91
+ * Get the locally bound name of this
92
+ * connection
93
+ */
94
+ getLocalAddress: () => Endpoint;
95
+ /**
96
+ * Get the name of the counterparty
97
+ */
98
+ getRemoteAddress: () => Endpoint;
99
+ };
100
+ /**
101
+ * A handler for a given Connection
102
+ */
103
+ type ConnectionHandler = {
104
+ /**
105
+ * The connection has been opened
106
+ */
107
+ onOpen?: ((connection: Connection, localAddr: Endpoint, remoteAddr: Endpoint, c: ConnectionHandler) => void) | undefined;
108
+ /**
109
+ * The connection received a packet
110
+ */
111
+ onReceive?: ((connection: Connection, packetBytes: Bytes, c: ConnectionHandler, opts?: Record<string, any>) => Promise<Data>) | undefined;
112
+ /**
113
+ * The connection has been closed
114
+ */
115
+ onClose?: ((connection: Connection, reason?: CloseReason, c?: ConnectionHandler) => Promise<void>) | undefined;
116
+ };
117
+ /**
118
+ * The reason a connection was closed
119
+ */
120
+ type CloseReason = any | null;
121
+ type AttemptDescription = {
122
+ handler: ConnectionHandler;
123
+ remoteAddress?: string | undefined;
124
+ localAddress?: string | undefined;
125
+ };
126
+ /**
127
+ * A handler for things the protocol
128
+ * implementation will invoke
129
+ */
130
+ type ProtocolHandler = {
131
+ /**
132
+ * This protocol is created
133
+ */
134
+ onCreate: (protocol: ProtocolImpl, p: ProtocolHandler) => Promise<void>;
135
+ /**
136
+ * Create a fresh port identifier for this protocol
137
+ */
138
+ generatePortID: (localAddr: Endpoint, p: ProtocolHandler) => Promise<string>;
139
+ /**
140
+ * A port will be bound
141
+ */
142
+ onBind: (port: Port, localAddr: Endpoint, p: ProtocolHandler) => Promise<void>;
143
+ /**
144
+ * A port was listening
145
+ */
146
+ onListen: (port: Port, localAddr: Endpoint, listenHandler: ListenHandler, p: ProtocolHandler) => Promise<void>;
147
+ /**
148
+ * A port listener has been reset
149
+ */
150
+ onListenRemove: (port: Port, localAddr: Endpoint, listenHandler: ListenHandler, p: ProtocolHandler) => Promise<void>;
151
+ /**
152
+ * Return unique suffix for local address
153
+ */
154
+ onInstantiate?: ((port: Port, localAddr: Endpoint, remote: Endpoint, p: ProtocolHandler) => Promise<Endpoint>) | undefined;
155
+ /**
156
+ * A port initiates an outbound connection
157
+ */
158
+ onConnect: (port: Port, localAddr: Endpoint, remote: Endpoint, c: ConnectionHandler, p: ProtocolHandler) => Promise<AttemptDescription>;
159
+ /**
160
+ * The port is being completely destroyed
161
+ */
162
+ onRevoke: (port: Port, localAddr: Endpoint, p: ProtocolHandler) => Promise<void>;
163
+ };
164
+ /**
165
+ * An inbound connection attempt
166
+ */
167
+ type InboundAttempt = {
168
+ /**
169
+ * Establish the connection
170
+ */
171
+ accept: (desc: AttemptDescription) => Promise<Connection>;
172
+ /**
173
+ * Return the local address for this
174
+ * attempt
175
+ */
176
+ getLocalAddress: () => Endpoint;
177
+ /**
178
+ * Return the remote address for
179
+ * this attempt
180
+ */
181
+ getRemoteAddress: () => Endpoint;
182
+ /**
183
+ * Abort the attempt
184
+ */
185
+ close: () => Promise<void>;
186
+ };
187
+ /**
188
+ * Things the protocol can do for us
189
+ */
190
+ type ProtocolImpl = {
191
+ /**
192
+ * Claim a port, or if
193
+ * ending in ENDPOINT_SEPARATOR, a fresh name
194
+ */
195
+ bind: (prefix: Endpoint) => Promise<Port>;
196
+ /**
197
+ * Make an attempt to connect into this protocol
198
+ */
199
+ inbound: (listenAddr: Endpoint, remoteAddr: Endpoint) => Promise<InboundAttempt>;
200
+ /**
201
+ * Create an outbound connection
202
+ */
203
+ outbound: (port: Port, remoteAddr: Endpoint, connectionHandler: ConnectionHandler) => Promise<Connection>;
204
+ };
205
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"YACa,MAAM,GAAG,MAAM,GAAG,WAAW;aAE7B,MAAM;;;;;gBAIN,MAAM;;;;;;;;WAML,MAAM,QAAQ,IAAI,CAAC;;;;;;;;;;mBAKV,QAAQ,KAAK,QAAQ,IAAI,CAAC;;;;;;;;;;qBAMnC,MAAM,QAAQ;;;;iCAEE,aAAa,KAAK,QAAQ,IAAI,CAAC;;;;sBAGhD,QAAQ,sBACI,iBAAiB,KAClC,QAAQ,UAAU,CAAC;;;;oCAEG,aAAa,KAAK,QAAQ,IAAI,CAAC;;;;;YAE/C,MAAM,IAAI;;;;;;;;;;uBAMH,IAAI,KAAK,aAAa,KAAK,QAAQ,IAAI,CAAC;;;;qBAGlD,IAAI,aACC,QAAQ,cACP,QAAQ,KACjB,aAAa,KACb,QAAQ,iBAAiB,CAAC;;;;uBAGvB,IAAI,aACC,QAAQ,cACP,QAAQ,KACjB,aAAa,KACb,QAAQ,IAAI,CAAC;;;;sBAEA,IAAI,OAAO,GAAG,KAAK,aAAa,KAAK,QAAQ,IAAI,CAAC;;;;;uBAElD,IAAI,KAAK,aAAa,KAAK,QAAQ,IAAI,CAAC;;;;;;wBAO3C,IAAI,SACV,OAAO,MAAM,EAAE,GAAG,CAAC,KACvB,QAAQ,KAAK,CAAC;;;;WAER,MAAM,QAAQ,IAAI,CAAC;;;;;qBACnB,MAAM,QAAQ;;;;sBAEd,MAAM,QAAQ;;;;;;;;;2BAMX,UAAU,aACX,QAAQ,cACP,QAAQ,KACjB,iBAAiB,KACjB,IAAI;;;;8BAGK,UAAU,eACT,KAAK,KACf,iBAAiB,SACb,OAAO,MAAM,EAAE,GAAG,CAAC,KACvB,QAAQ,IAAI,CAAC;;;;4BAGJ,UAAU,WACb,WAAW,MAChB,iBAAiB,KAClB,QAAQ,IAAI,CAAC;;;;;mBAGR,GAAG,GAAG,IAAI;;aAKT,iBAAiB;;;;;;;;;;;;yBAQN,YAAY,KAAK,eAAe,KAAK,QAAQ,IAAI,CAAC;;;;gCAEjD,QAAQ,KAAK,eAAe,KAAK,QAAQ,MAAM,CAAC;;;;mBAG/D,IAAI,aACC,QAAQ,KAChB,eAAe,KACf,QAAQ,IAAI,CAAC;;;;qBAGV,IAAI,aACC,QAAQ,iBACJ,aAAa,KACzB,eAAe,KACf,QAAQ,IAAI,CAAC;;;;2BAGV,IAAI,aACC,QAAQ,iBACJ,aAAa,KACzB,eAAe,KACf,QAAQ,IAAI,CAAC;;;;4BAGV,IAAI,aACC,QAAQ,UACX,QAAQ,KACb,eAAe,KACf,QAAQ,QAAQ,CAAC;;;;sBAGd,IAAI,aACC,QAAQ,UACX,QAAQ,KACb,iBAAiB,KACjB,eAAe,KACf,QAAQ,kBAAkB,CAAC;;;;qBAGxB,IAAI,aACC,QAAQ,KAChB,eAAe,KACf,QAAQ,IAAI,CAAC;;;;;;;;;mBAIA,kBAAkB,KAAK,QAAQ,UAAU,CAAC;;;;;qBAEjD,MAAM,QAAQ;;;;;sBAEd,MAAM,QAAQ;;;;WAEd,MAAM,QAAQ,IAAI,CAAC;;;;;;;;;;mBAGV,QAAQ,KAAK,QAAQ,IAAI,CAAC;;;;0BAGhC,QAAQ,cACR,QAAQ,KACjB,QAAQ,cAAc,CAAC;;;;qBAGpB,IAAI,cACE,QAAQ,qBACD,iBAAiB,KACjC,QAAQ,UAAU,CAAC"}
package/src/types.js ADDED
@@ -0,0 +1,182 @@
1
+ /**
2
+ * @typedef {string | Buffer | ArrayBuffer} Data
3
+ *
4
+ * @typedef {string} Bytes
5
+ */
6
+
7
+ /**
8
+ * @typedef {string} Endpoint A local or remote address See multiaddr.js for an
9
+ * opinionated router implementation
10
+ */
11
+
12
+ /**
13
+ * @typedef {object} Closable A closable object
14
+ * @property {() => Promise<void>} close Terminate the object
15
+ */
16
+
17
+ /**
18
+ * @typedef {object} Protocol The network Protocol
19
+ * @property {(prefix: Endpoint) => Promise<Port>} bind Claim a port, or if
20
+ * ending in ENDPOINT_SEPARATOR, a fresh name
21
+ */
22
+
23
+ /**
24
+ * @typedef {object} Port A port that has been bound to a protocol
25
+ * @property {() => Endpoint} getLocalAddress Get the locally bound name of this
26
+ * port
27
+ * @property {(acceptHandler: ListenHandler) => Promise<void>} addListener
28
+ * Begin accepting incoming connections
29
+ * @property {(
30
+ * remote: Endpoint,
31
+ * connectionHandler?: ConnectionHandler,
32
+ * ) => Promise<Connection>} connect
33
+ * Make an outbound connection
34
+ * @property {(acceptHandler: ListenHandler) => Promise<void>} removeListener
35
+ * Remove the currently-bound listener
36
+ * @property {() => void} revoke Deallocate the port entirely, removing all
37
+ * listeners and closing all active connections
38
+ */
39
+
40
+ /**
41
+ * @typedef {object} ListenHandler A handler for incoming connections
42
+ * @property {(port: Port, l: ListenHandler) => Promise<void>} [onListen] The
43
+ * listener has been registered
44
+ * @property {(
45
+ * port: Port,
46
+ * localAddr: Endpoint,
47
+ * remoteAddr: Endpoint,
48
+ * l: ListenHandler,
49
+ * ) => Promise<ConnectionHandler>} onAccept
50
+ * A new connection is incoming
51
+ * @property {(
52
+ * port: Port,
53
+ * localAddr: Endpoint,
54
+ * remoteAddr: Endpoint,
55
+ * l: ListenHandler,
56
+ * ) => Promise<void>} [onReject]
57
+ * The connection was rejected
58
+ * @property {(port: Port, rej: any, l: ListenHandler) => Promise<void>} [onError]
59
+ * There was an error while listening
60
+ * @property {(port: Port, l: ListenHandler) => Promise<void>} [onRemove] The
61
+ * listener has been removed
62
+ */
63
+
64
+ /**
65
+ * @typedef {object} Connection
66
+ * @property {(
67
+ * packetBytes: Data,
68
+ * opts?: Record<string, any>,
69
+ * ) => Promise<Bytes>} send
70
+ * Send a packet on the connection
71
+ * @property {() => Promise<void>} close Close both ends of the connection
72
+ * @property {() => Endpoint} getLocalAddress Get the locally bound name of this
73
+ * connection
74
+ * @property {() => Endpoint} getRemoteAddress Get the name of the counterparty
75
+ */
76
+
77
+ /**
78
+ * @typedef {object} ConnectionHandler A handler for a given Connection
79
+ * @property {(
80
+ * connection: Connection,
81
+ * localAddr: Endpoint,
82
+ * remoteAddr: Endpoint,
83
+ * c: ConnectionHandler,
84
+ * ) => void} [onOpen]
85
+ * The connection has been opened
86
+ * @property {(
87
+ * connection: Connection,
88
+ * packetBytes: Bytes,
89
+ * c: ConnectionHandler,
90
+ * opts?: Record<string, any>,
91
+ * ) => Promise<Data>} [onReceive]
92
+ * The connection received a packet
93
+ * @property {(
94
+ * connection: Connection,
95
+ * reason?: CloseReason,
96
+ * c?: ConnectionHandler,
97
+ * ) => Promise<void>} [onClose]
98
+ * The connection has been closed
99
+ *
100
+ * @typedef {any | null} CloseReason The reason a connection was closed
101
+ */
102
+
103
+ /**
104
+ * @typedef {object} AttemptDescription
105
+ * @property {ConnectionHandler} handler
106
+ * @property {Endpoint} [remoteAddress]
107
+ * @property {Endpoint} [localAddress]
108
+ */
109
+
110
+ /**
111
+ * @typedef {object} ProtocolHandler A handler for things the protocol
112
+ * implementation will invoke
113
+ * @property {(protocol: ProtocolImpl, p: ProtocolHandler) => Promise<void>} onCreate
114
+ * This protocol is created
115
+ * @property {(localAddr: Endpoint, p: ProtocolHandler) => Promise<string>} generatePortID
116
+ * Create a fresh port identifier for this protocol
117
+ * @property {(
118
+ * port: Port,
119
+ * localAddr: Endpoint,
120
+ * p: ProtocolHandler,
121
+ * ) => Promise<void>} onBind
122
+ * A port will be bound
123
+ * @property {(
124
+ * port: Port,
125
+ * localAddr: Endpoint,
126
+ * listenHandler: ListenHandler,
127
+ * p: ProtocolHandler,
128
+ * ) => Promise<void>} onListen
129
+ * A port was listening
130
+ * @property {(
131
+ * port: Port,
132
+ * localAddr: Endpoint,
133
+ * listenHandler: ListenHandler,
134
+ * p: ProtocolHandler,
135
+ * ) => Promise<void>} onListenRemove
136
+ * A port listener has been reset
137
+ * @property {(
138
+ * port: Port,
139
+ * localAddr: Endpoint,
140
+ * remote: Endpoint,
141
+ * p: ProtocolHandler,
142
+ * ) => Promise<Endpoint>} [onInstantiate]
143
+ * Return unique suffix for local address
144
+ * @property {(
145
+ * port: Port,
146
+ * localAddr: Endpoint,
147
+ * remote: Endpoint,
148
+ * c: ConnectionHandler,
149
+ * p: ProtocolHandler,
150
+ * ) => Promise<AttemptDescription>} onConnect
151
+ * A port initiates an outbound connection
152
+ * @property {(
153
+ * port: Port,
154
+ * localAddr: Endpoint,
155
+ * p: ProtocolHandler,
156
+ * ) => Promise<void>} onRevoke
157
+ * The port is being completely destroyed
158
+ *
159
+ * @typedef {object} InboundAttempt An inbound connection attempt
160
+ * @property {(desc: AttemptDescription) => Promise<Connection>} accept
161
+ * Establish the connection
162
+ * @property {() => Endpoint} getLocalAddress Return the local address for this
163
+ * attempt
164
+ * @property {() => Endpoint} getRemoteAddress Return the remote address for
165
+ * this attempt
166
+ * @property {() => Promise<void>} close Abort the attempt
167
+ *
168
+ * @typedef {object} ProtocolImpl Things the protocol can do for us
169
+ * @property {(prefix: Endpoint) => Promise<Port>} bind Claim a port, or if
170
+ * ending in ENDPOINT_SEPARATOR, a fresh name
171
+ * @property {(
172
+ * listenAddr: Endpoint,
173
+ * remoteAddr: Endpoint,
174
+ * ) => Promise<InboundAttempt>} inbound
175
+ * Make an attempt to connect into this protocol
176
+ * @property {(
177
+ * port: Port,
178
+ * remoteAddr: Endpoint,
179
+ * connectionHandler: ConnectionHandler,
180
+ * ) => Promise<Connection>} outbound
181
+ * Create an outbound connection
182
+ */