lemon-model 1.1.0 → 1.2.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.
- package/dist/cores/transformer.d.ts +9 -1
- package/dist/cores/transformer.js +22 -7
- package/dist/cores/transformer.js.map +1 -1
- package/dist/genai/dump-test.d.ts +82 -0
- package/dist/genai/dump-test.js +200 -0
- package/dist/genai/dump-test.js.map +1 -0
- package/dist/genai/index.d.ts +11 -0
- package/dist/genai/index.js +31 -0
- package/dist/genai/index.js.map +1 -0
- package/dist/genai/mocks.d.ts +44 -0
- package/dist/genai/mocks.js +127 -0
- package/dist/genai/mocks.js.map +1 -0
- package/dist/genai/proxy.d.ts +65 -0
- package/dist/genai/proxy.js +165 -0
- package/dist/genai/proxy.js.map +1 -0
- package/dist/genai/testing.d.ts +11 -0
- package/dist/genai/testing.js +28 -0
- package/dist/genai/testing.js.map +1 -0
- package/dist/genai/transport.d.ts +37 -0
- package/dist/genai/transport.js +136 -0
- package/dist/genai/transport.js.map +1 -0
- package/dist/genai/types.d.ts +71 -0
- package/dist/genai/types.js +10 -0
- package/dist/genai/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/proxy/index.d.ts +12 -0
- package/dist/proxy/index.js +29 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/proxy.d.ts +75 -0
- package/dist/proxy/proxy.js +198 -0
- package/dist/proxy/proxy.js.map +1 -0
- package/dist/proxy/transport.d.ts +123 -0
- package/dist/proxy/transport.js +401 -0
- package/dist/proxy/transport.js.map +1 -0
- package/dist/proxy/types.d.ts +89 -0
- package/dist/proxy/types.js +12 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/socket/index.d.ts +9 -0
- package/dist/socket/index.js +29 -0
- package/dist/socket/index.js.map +1 -0
- package/dist/socket/socket.d.ts +191 -0
- package/dist/socket/socket.js +844 -0
- package/dist/socket/socket.js.map +1 -0
- package/dist/socket/testing.d.ts +11 -0
- package/dist/socket/testing.js +28 -0
- package/dist/socket/testing.js.map +1 -0
- package/dist/socket/transport.d.ts +200 -0
- package/dist/socket/transport.js +612 -0
- package/dist/socket/transport.js.map +1 -0
- package/dist/socket/types.d.ts +177 -0
- package/dist/socket/types.js +9 -0
- package/dist/socket/types.js.map +1 -0
- package/dist/socket/websocket.d.ts +89 -0
- package/dist/socket/websocket.js +273 -0
- package/dist/socket/websocket.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.createSocketFactory = exports.SocketFactory = exports.createPeer = exports.Peer = exports.createNetwork = exports.Network = exports.noopSocketLogger = exports.defaultPeerNetworkFactory = exports.nextMessageId = exports.defaultPeerIdentityProvider = void 0;
|
|
24
|
+
const transport_1 = require("./transport");
|
|
25
|
+
let peerNo = 0;
|
|
26
|
+
let clientNo = 0;
|
|
27
|
+
let messageNo = 0;
|
|
28
|
+
let networkNo = 0;
|
|
29
|
+
exports.defaultPeerIdentityProvider = {
|
|
30
|
+
nextPeerId: () => `peer-${++peerNo}`,
|
|
31
|
+
nextClientId: () => `client-${++clientNo}`,
|
|
32
|
+
nextMessageId: () => `message-${++messageNo}`,
|
|
33
|
+
nextNetworkId: (fromPeerId, toPeerId) => fromPeerId && toPeerId ? `${fromPeerId}->${toPeerId}` : `network-${++networkNo}`,
|
|
34
|
+
};
|
|
35
|
+
const nextMessageId = () => exports.defaultPeerIdentityProvider.nextMessageId();
|
|
36
|
+
exports.nextMessageId = nextMessageId;
|
|
37
|
+
const defaultPeerNetworkFactory = context => (0, exports.createNetwork)(Object.assign({ id: context.id, fromPeerId: context.fromPeerId, toPeerId: context.toPeerId, logger: context.logger }, context.options));
|
|
38
|
+
exports.defaultPeerNetworkFactory = defaultPeerNetworkFactory;
|
|
39
|
+
exports.noopSocketLogger = { log: () => undefined };
|
|
40
|
+
const delay = (ms) => (ms > 0 ? new Promise(resolve => setTimeout(resolve, ms)) : undefined);
|
|
41
|
+
const DEFAULT_MAX_PACKET_BYTES = 64 * 1024;
|
|
42
|
+
const DEFAULT_JITTER_MS = 1;
|
|
43
|
+
/**
|
|
44
|
+
* one-shot in-memory network transport.
|
|
45
|
+
* - public transport surface is intentionally limited to send(string) and close().
|
|
46
|
+
*/
|
|
47
|
+
class Network {
|
|
48
|
+
constructor(options) {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
this.state = 'open';
|
|
51
|
+
this.messageListeners = new Set();
|
|
52
|
+
this.used = false;
|
|
53
|
+
this.deliveryNo = 0;
|
|
54
|
+
this.errorListeners = new Set();
|
|
55
|
+
this.id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : exports.defaultPeerIdentityProvider.nextNetworkId();
|
|
56
|
+
this.fromPeerId = options === null || options === void 0 ? void 0 : options.fromPeerId;
|
|
57
|
+
this.toPeerId = options === null || options === void 0 ? void 0 : options.toPeerId;
|
|
58
|
+
this.logger = (_b = options === null || options === void 0 ? void 0 : options.logger) !== null && _b !== void 0 ? _b : exports.noopSocketLogger;
|
|
59
|
+
this.options = asNetworkOptions(options);
|
|
60
|
+
this.log('debug', 'network created', 'network.constructor', { data: { options: this.options } });
|
|
61
|
+
}
|
|
62
|
+
/** network state */
|
|
63
|
+
get readyState() {
|
|
64
|
+
return this.state;
|
|
65
|
+
}
|
|
66
|
+
/** wait until this in-memory network is ready */
|
|
67
|
+
ready() {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
this.ensureOpen('network.ready');
|
|
70
|
+
this.log('debug', 'network ready', 'network.ready');
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** attach this network to exactly one receiver */
|
|
74
|
+
attach(receiver) {
|
|
75
|
+
if (this.used)
|
|
76
|
+
throw new Error(`@network[${this.id}] is already used - network.attach(${this.id})`);
|
|
77
|
+
this.ensureOpen('network.attach');
|
|
78
|
+
this.used = true;
|
|
79
|
+
this.messageListeners.add(receiver);
|
|
80
|
+
this.log('debug', 'network receiver attached', 'network.attach');
|
|
81
|
+
}
|
|
82
|
+
/** send raw string data over the network */
|
|
83
|
+
send(data) {
|
|
84
|
+
this.ensureOpen('network.send');
|
|
85
|
+
if (this.messageListeners.size <= 0) {
|
|
86
|
+
throw new Error(`@network[${this.id}] is not connected - network.send(${this.id})`);
|
|
87
|
+
}
|
|
88
|
+
if (typeof data !== 'string')
|
|
89
|
+
throw new Error(`@data (string) is required - network.send(${this.id})`);
|
|
90
|
+
const bytes = byteLength(data);
|
|
91
|
+
if (bytes > this.options.maxPacketBytes)
|
|
92
|
+
throw new Error(`1009: message too big`);
|
|
93
|
+
const listeners = [...this.messageListeners];
|
|
94
|
+
this.log('debug', 'network packet queued', 'network.send', {
|
|
95
|
+
data: { bytes, listeners: listeners.length },
|
|
96
|
+
});
|
|
97
|
+
const _deliver = () => __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
try {
|
|
99
|
+
yield delay(this.nextDeliveryDelayMs());
|
|
100
|
+
if (this.state !== 'open')
|
|
101
|
+
return;
|
|
102
|
+
for (const listener of listeners)
|
|
103
|
+
listener(data);
|
|
104
|
+
this.log('debug', 'network packet delivered', 'network.deliver', {
|
|
105
|
+
data: { bytes, listeners: listeners.length },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
this.log('error', 'network delivery failed', 'network.deliver', { error: e });
|
|
110
|
+
this.emitError(e, { scope: 'network.deliver', network: this });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
_deliver();
|
|
114
|
+
}
|
|
115
|
+
/** subscribe to raw string data delivered from the network */
|
|
116
|
+
onMessage(handler) {
|
|
117
|
+
this.ensureOpen('network.onMessage');
|
|
118
|
+
this.messageListeners.add(handler);
|
|
119
|
+
this.log('debug', 'network message listener added', 'network.onMessage', {
|
|
120
|
+
data: { listeners: this.messageListeners.size },
|
|
121
|
+
});
|
|
122
|
+
return () => {
|
|
123
|
+
this.messageListeners.delete(handler);
|
|
124
|
+
this.log('debug', 'network message listener removed', 'network.onMessage.unsubscribe', {
|
|
125
|
+
data: { listeners: this.messageListeners.size },
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** update network conditions */
|
|
130
|
+
configure(options) {
|
|
131
|
+
this.options = Object.assign(Object.assign({}, this.options), options);
|
|
132
|
+
this.log('info', 'network configured', 'network.configure', { data: { options: this.options } });
|
|
133
|
+
}
|
|
134
|
+
/** observe asynchronous network delivery errors */
|
|
135
|
+
onError(handler) {
|
|
136
|
+
this.errorListeners.add(handler);
|
|
137
|
+
return () => {
|
|
138
|
+
this.errorListeners.delete(handler);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/** close this network forever */
|
|
142
|
+
close() {
|
|
143
|
+
if (this.state === 'closed')
|
|
144
|
+
return;
|
|
145
|
+
this.state = 'closed';
|
|
146
|
+
this.messageListeners.clear();
|
|
147
|
+
this.log('info', 'network closed', 'network.close');
|
|
148
|
+
}
|
|
149
|
+
ensureOpen(scope) {
|
|
150
|
+
if (this.state !== 'open')
|
|
151
|
+
throw new Error(`@network[${this.id}] connection error: ${this.state} - ${scope}`);
|
|
152
|
+
}
|
|
153
|
+
nextDeliveryDelayMs() {
|
|
154
|
+
const baseMs = this.options.latencyMs;
|
|
155
|
+
if (!this.options.unordered)
|
|
156
|
+
return baseMs;
|
|
157
|
+
const jitterMs = this.deliveryNo++ % 2 === 0 ? this.options.jitterMs : 0;
|
|
158
|
+
return baseMs + jitterMs;
|
|
159
|
+
}
|
|
160
|
+
emitError(error, context) {
|
|
161
|
+
for (const listener of [...this.errorListeners]) {
|
|
162
|
+
listener(error, context);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
log(level, message, location, entry) {
|
|
166
|
+
try {
|
|
167
|
+
this.logger.log(Object.assign(Object.assign({ time: Date.now(), level,
|
|
168
|
+
message,
|
|
169
|
+
location, networkId: this.id, peerId: this.fromPeerId, remotePeerId: this.toPeerId }, entry), { error: (entry === null || entry === void 0 ? void 0 : entry.error) == null ? undefined : normalizeError(entry.error) }));
|
|
170
|
+
}
|
|
171
|
+
catch (_a) {
|
|
172
|
+
// Logging must never break simulated network behavior.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.Network = Network;
|
|
177
|
+
/** create a one-shot network */
|
|
178
|
+
const createNetwork = (options) => new Network(options);
|
|
179
|
+
exports.createNetwork = createNetwork;
|
|
180
|
+
/**
|
|
181
|
+
* in-memory peer that can act as a server, a client, or both.
|
|
182
|
+
*/
|
|
183
|
+
class Peer {
|
|
184
|
+
constructor(options) {
|
|
185
|
+
var _a, _b, _c, _d;
|
|
186
|
+
this.state = 'open';
|
|
187
|
+
this.clients = new Map();
|
|
188
|
+
this.listeners = new Set();
|
|
189
|
+
this.errorListeners = new Set();
|
|
190
|
+
this.pending = new Map();
|
|
191
|
+
this.identityProvider = (_a = options === null || options === void 0 ? void 0 : options.identityProvider) !== null && _a !== void 0 ? _a : exports.defaultPeerIdentityProvider;
|
|
192
|
+
this.networkFactory = (_b = options === null || options === void 0 ? void 0 : options.networkFactory) !== null && _b !== void 0 ? _b : exports.defaultPeerNetworkFactory;
|
|
193
|
+
this.logger = (_c = options === null || options === void 0 ? void 0 : options.logger) !== null && _c !== void 0 ? _c : exports.noopSocketLogger;
|
|
194
|
+
this.id = (_d = options === null || options === void 0 ? void 0 : options.id) !== null && _d !== void 0 ? _d : this.identityProvider.nextPeerId();
|
|
195
|
+
this.networkOptions = asNetworkOptions(options);
|
|
196
|
+
this.jsonTransportOptions = asJSONTransportOptions(options === null || options === void 0 ? void 0 : options.jsonTransport, this.networkOptions.maxPacketBytes);
|
|
197
|
+
this.log('debug', 'peer created', 'peer.constructor');
|
|
198
|
+
}
|
|
199
|
+
/** assigned client id when this peer is connected to another peer */
|
|
200
|
+
get clientId() {
|
|
201
|
+
return this.assignedClientId;
|
|
202
|
+
}
|
|
203
|
+
/** endpoint state */
|
|
204
|
+
get readyState() {
|
|
205
|
+
return this.state;
|
|
206
|
+
}
|
|
207
|
+
/** upstream network when this peer is connected as a client */
|
|
208
|
+
get network() {
|
|
209
|
+
var _a;
|
|
210
|
+
return (_a = this.server) === null || _a === void 0 ? void 0 : _a.network;
|
|
211
|
+
}
|
|
212
|
+
/** wait until this peer's upstream network is ready */
|
|
213
|
+
ready() {
|
|
214
|
+
var _a;
|
|
215
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
216
|
+
this.ensureOpen('peer.ready');
|
|
217
|
+
const network = (_a = this.server) === null || _a === void 0 ? void 0 : _a.network;
|
|
218
|
+
if (!(network === null || network === void 0 ? void 0 : network.ready)) {
|
|
219
|
+
this.log('debug', 'peer ready without upstream network wait', 'peer.ready', {
|
|
220
|
+
networkId: getNetworkId(network),
|
|
221
|
+
});
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
this.log('debug', 'waiting for upstream network ready', 'peer.ready.wait', {
|
|
225
|
+
networkId: getNetworkId(network),
|
|
226
|
+
});
|
|
227
|
+
try {
|
|
228
|
+
yield network.ready();
|
|
229
|
+
this.log('debug', 'upstream network ready', 'peer.ready.ok', {
|
|
230
|
+
networkId: getNetworkId(network),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
this.log('error', 'upstream network ready failed', 'peer.ready.error', {
|
|
235
|
+
networkId: getNetworkId(network),
|
|
236
|
+
error: e,
|
|
237
|
+
});
|
|
238
|
+
throw e;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/** update network conditions for this peer and connected networks */
|
|
243
|
+
configureNetwork(options) {
|
|
244
|
+
var _a, _b, _c, _d, _e;
|
|
245
|
+
this.networkOptions = Object.assign(Object.assign({}, this.networkOptions), options);
|
|
246
|
+
(_c = (_a = this.server) === null || _a === void 0 ? void 0 : (_b = _a.network).configure) === null || _c === void 0 ? void 0 : _c.call(_b, this.networkOptions);
|
|
247
|
+
for (const link of this.clients.values()) {
|
|
248
|
+
(_e = (_d = link.network).configure) === null || _e === void 0 ? void 0 : _e.call(_d, this.networkOptions);
|
|
249
|
+
}
|
|
250
|
+
this.log('info', 'network options configured', 'peer.configureNetwork', {
|
|
251
|
+
data: { options: this.networkOptions },
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/** connect this peer as a client to a server peer */
|
|
255
|
+
connect(peer) {
|
|
256
|
+
this.ensureOpen('peer.connect');
|
|
257
|
+
const server = peer;
|
|
258
|
+
server.ensureOpen('peer.accept');
|
|
259
|
+
this.log('info', 'connecting peer', 'peer.connect', { remotePeerId: server.id });
|
|
260
|
+
const { uplink, downlink } = Peer.createNetworkPair(this, server, 'peer.connect');
|
|
261
|
+
const serverTransportOptions = server.jsonTransportOptions;
|
|
262
|
+
const clientTransportOptions = this.jsonTransportOptions;
|
|
263
|
+
const clientId = server.accept(this, downlink, serverTransportOptions);
|
|
264
|
+
server.attachClientReceiverTransport(clientId, Peer.attachReceiver(uplink, server, this, clientId, clientTransportOptions));
|
|
265
|
+
const serverReceiverTransport = Peer.attachReceiver(downlink, this, server, undefined, serverTransportOptions);
|
|
266
|
+
this.server = {
|
|
267
|
+
peer: server,
|
|
268
|
+
clientId,
|
|
269
|
+
network: uplink,
|
|
270
|
+
transportOptions: clientTransportOptions,
|
|
271
|
+
receiverTransport: serverReceiverTransport,
|
|
272
|
+
};
|
|
273
|
+
this.assignedClientId = clientId;
|
|
274
|
+
this.log('info', 'peer connected', 'peer.connect', {
|
|
275
|
+
remotePeerId: server.id,
|
|
276
|
+
clientId,
|
|
277
|
+
networkId: getNetworkId(uplink),
|
|
278
|
+
});
|
|
279
|
+
server.log('info', 'client accepted', 'peer.accept', {
|
|
280
|
+
remotePeerId: this.id,
|
|
281
|
+
clientId,
|
|
282
|
+
networkId: getNetworkId(downlink),
|
|
283
|
+
});
|
|
284
|
+
return clientId;
|
|
285
|
+
}
|
|
286
|
+
/** replace connected network instances while keeping the peer relationship */
|
|
287
|
+
reconnect(options) {
|
|
288
|
+
var _a;
|
|
289
|
+
this.ensureOpen('peer.reconnect');
|
|
290
|
+
if (options === null || options === void 0 ? void 0 : options.clientId) {
|
|
291
|
+
const link = this.clients.get(options.clientId);
|
|
292
|
+
if (!link)
|
|
293
|
+
throw new Error(`@clientId[${options.clientId}] is not connected - peer.reconnect(${this.id})`);
|
|
294
|
+
Peer.reconnectPair(link.peer, this, options.clientId);
|
|
295
|
+
this.log('info', 'peer network reconnected', 'peer.reconnect', {
|
|
296
|
+
remotePeerId: link.peer.id,
|
|
297
|
+
clientId: options.clientId,
|
|
298
|
+
});
|
|
299
|
+
return options.clientId;
|
|
300
|
+
}
|
|
301
|
+
if ((_a = this.server) === null || _a === void 0 ? void 0 : _a.clientId) {
|
|
302
|
+
Peer.reconnectPair(this, this.server.peer, this.server.clientId);
|
|
303
|
+
this.log('info', 'peer network reconnected', 'peer.reconnect', {
|
|
304
|
+
remotePeerId: this.server.peer.id,
|
|
305
|
+
clientId: this.server.clientId,
|
|
306
|
+
});
|
|
307
|
+
return this.server.clientId;
|
|
308
|
+
}
|
|
309
|
+
if (this.clients.size === 1) {
|
|
310
|
+
const [clientId, link] = [...this.clients.entries()][0];
|
|
311
|
+
Peer.reconnectPair(link.peer, this, clientId);
|
|
312
|
+
this.log('info', 'peer network reconnected', 'peer.reconnect', {
|
|
313
|
+
remotePeerId: link.peer.id,
|
|
314
|
+
clientId,
|
|
315
|
+
});
|
|
316
|
+
return clientId;
|
|
317
|
+
}
|
|
318
|
+
if (this.clients.size > 1)
|
|
319
|
+
throw new Error(`@clientId (string) is required - peer.reconnect(${this.id})`);
|
|
320
|
+
throw new Error(`@peer is not connected - peer.reconnect(${this.id})`);
|
|
321
|
+
}
|
|
322
|
+
/** find a client peer connected to this peer by client id */
|
|
323
|
+
findPeer(clientId) {
|
|
324
|
+
var _a;
|
|
325
|
+
return (_a = this.clients.get(clientId)) === null || _a === void 0 ? void 0 : _a.peer;
|
|
326
|
+
}
|
|
327
|
+
/** post a typed message without waiting for a result */
|
|
328
|
+
post(message, options) {
|
|
329
|
+
this.publish(message, options);
|
|
330
|
+
}
|
|
331
|
+
/** send a typed message and wait for a result message with the same mid */
|
|
332
|
+
send(message, options) {
|
|
333
|
+
var _a;
|
|
334
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
335
|
+
const mid = (_a = message.mid) !== null && _a !== void 0 ? _a : this.identityProvider.nextMessageId();
|
|
336
|
+
const envelope = Object.assign(Object.assign({}, message), { mid });
|
|
337
|
+
return new Promise((resolve, reject) => {
|
|
338
|
+
this.pending.set(mid, { resolve, reject });
|
|
339
|
+
try {
|
|
340
|
+
this.publish(envelope, options);
|
|
341
|
+
}
|
|
342
|
+
catch (e) {
|
|
343
|
+
this.pending.delete(mid);
|
|
344
|
+
reject(e);
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
/** subscribe to incoming messages */
|
|
350
|
+
onMessage(handler) {
|
|
351
|
+
this.ensureOpen('peer.onMessage');
|
|
352
|
+
const listener = handler;
|
|
353
|
+
this.listeners.add(listener);
|
|
354
|
+
return () => {
|
|
355
|
+
this.listeners.delete(listener);
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/** observe fire-and-forget transport errors */
|
|
359
|
+
onError(handler) {
|
|
360
|
+
this.errorListeners.add(handler);
|
|
361
|
+
return () => {
|
|
362
|
+
this.errorListeners.delete(handler);
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
/** close this peer */
|
|
366
|
+
close() {
|
|
367
|
+
var _a;
|
|
368
|
+
if (this.state === 'closed')
|
|
369
|
+
return;
|
|
370
|
+
this.log('info', 'peer closing', 'peer.close');
|
|
371
|
+
this.state = 'closed';
|
|
372
|
+
const server = this.server;
|
|
373
|
+
this.server = undefined;
|
|
374
|
+
if (server) {
|
|
375
|
+
this.closeLink(server);
|
|
376
|
+
server.peer.detachClient(server.clientId);
|
|
377
|
+
}
|
|
378
|
+
for (const [clientId, link] of this.clients) {
|
|
379
|
+
this.closeLink(link);
|
|
380
|
+
if (((_a = link.peer.server) === null || _a === void 0 ? void 0 : _a.peer) === this) {
|
|
381
|
+
link.peer.closeLink(link.peer.server);
|
|
382
|
+
link.peer.server = undefined;
|
|
383
|
+
link.peer.assignedClientId = undefined;
|
|
384
|
+
}
|
|
385
|
+
this.clients.delete(clientId);
|
|
386
|
+
}
|
|
387
|
+
this.clients.clear();
|
|
388
|
+
this.listeners.clear();
|
|
389
|
+
for (const [mid, pending] of this.pending) {
|
|
390
|
+
pending.reject(new Error(`@peer[${this.id}] is closed - peer.close(${mid})`));
|
|
391
|
+
}
|
|
392
|
+
this.pending.clear();
|
|
393
|
+
this.log('info', 'peer closed', 'peer.close');
|
|
394
|
+
}
|
|
395
|
+
accept(client, network, transportOptions) {
|
|
396
|
+
const clientId = this.identityProvider.nextClientId();
|
|
397
|
+
this.clients.set(clientId, { peer: client, network, transportOptions });
|
|
398
|
+
return clientId;
|
|
399
|
+
}
|
|
400
|
+
attachClientReceiverTransport(clientId, transport) {
|
|
401
|
+
const link = this.clients.get(clientId);
|
|
402
|
+
if (link)
|
|
403
|
+
link.receiverTransport = transport;
|
|
404
|
+
}
|
|
405
|
+
detachClient(clientId) {
|
|
406
|
+
if (!clientId)
|
|
407
|
+
return;
|
|
408
|
+
const link = this.clients.get(clientId);
|
|
409
|
+
if (!link)
|
|
410
|
+
return;
|
|
411
|
+
this.log('info', 'client detached', 'peer.detachClient', {
|
|
412
|
+
remotePeerId: link.peer.id,
|
|
413
|
+
clientId,
|
|
414
|
+
networkId: getNetworkId(link.network),
|
|
415
|
+
});
|
|
416
|
+
this.closeLink(link);
|
|
417
|
+
this.clients.delete(clientId);
|
|
418
|
+
}
|
|
419
|
+
closeLink(link) {
|
|
420
|
+
var _a, _b;
|
|
421
|
+
this.log('debug', 'closing peer link', 'peer.closeLink', {
|
|
422
|
+
remotePeerId: link.peer.id,
|
|
423
|
+
clientId: link.clientId,
|
|
424
|
+
networkId: getNetworkId(link.network),
|
|
425
|
+
});
|
|
426
|
+
(_b = (_a = link.receiverTransport) === null || _a === void 0 ? void 0 : _a.detach) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
427
|
+
link.receiverTransport = undefined;
|
|
428
|
+
link.network.close();
|
|
429
|
+
}
|
|
430
|
+
static reconnectPair(client, server, clientId) {
|
|
431
|
+
client.ensureOpen('peer.reconnect');
|
|
432
|
+
server.ensureOpen('peer.reconnect');
|
|
433
|
+
const clientLink = client.server;
|
|
434
|
+
const serverLink = server.clients.get(clientId);
|
|
435
|
+
if (!clientLink || clientLink.peer !== server || !serverLink || serverLink.peer !== client) {
|
|
436
|
+
throw new Error(`@clientId[${clientId}] link mismatch - peer.reconnect(${server.id})`);
|
|
437
|
+
}
|
|
438
|
+
const { uplink, downlink } = Peer.createNetworkPair(client, server, 'peer.reconnect');
|
|
439
|
+
client.closeLink(clientLink);
|
|
440
|
+
server.closeLink(serverLink);
|
|
441
|
+
clientLink.network = uplink;
|
|
442
|
+
clientLink.transportOptions = client.jsonTransportOptions;
|
|
443
|
+
clientLink.receiverTransport = Peer.attachReceiver(downlink, client, server, undefined, server.jsonTransportOptions);
|
|
444
|
+
serverLink.network = downlink;
|
|
445
|
+
serverLink.transportOptions = server.jsonTransportOptions;
|
|
446
|
+
serverLink.receiverTransport = Peer.attachReceiver(uplink, server, client, clientId, client.jsonTransportOptions);
|
|
447
|
+
client.assignedClientId = clientId;
|
|
448
|
+
client.log('info', 'peer link networks replaced', 'peer.reconnectPair', {
|
|
449
|
+
remotePeerId: server.id,
|
|
450
|
+
clientId,
|
|
451
|
+
networkId: getNetworkId(uplink),
|
|
452
|
+
});
|
|
453
|
+
server.log('info', 'peer link networks replaced', 'peer.reconnectPair', {
|
|
454
|
+
remotePeerId: client.id,
|
|
455
|
+
clientId,
|
|
456
|
+
networkId: getNetworkId(downlink),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
static attachReceiver(network, receiver, sender, clientId, transportOptions) {
|
|
460
|
+
var _a;
|
|
461
|
+
if (transportOptions) {
|
|
462
|
+
const transport = (0, transport_1.createJSONTransport)(network, Object.assign(Object.assign({}, transportOptions), { logger: (_a = transportOptions.logger) !== null && _a !== void 0 ? _a : receiver.logger }));
|
|
463
|
+
transport.onMessage(message => receiver.dispatch(message, sender, clientId).catch(e => receiver.rejectPending(message === null || message === void 0 ? void 0 : message.mid, e)));
|
|
464
|
+
transport.onError((error, context) => {
|
|
465
|
+
receiver.log('error', 'peer transport error', 'peer.transport', {
|
|
466
|
+
remotePeerId: sender.id,
|
|
467
|
+
clientId,
|
|
468
|
+
networkId: getNetworkId(network),
|
|
469
|
+
error,
|
|
470
|
+
data: { scope: context.scope },
|
|
471
|
+
});
|
|
472
|
+
receiver.emitError(error, Object.assign(Object.assign({}, context), { scope: `peer.transport.${context.scope}`, peer: receiver }));
|
|
473
|
+
});
|
|
474
|
+
return transport;
|
|
475
|
+
}
|
|
476
|
+
network.onMessage(data => receiver.receiveNetworkData(data, sender, clientId));
|
|
477
|
+
return undefined;
|
|
478
|
+
}
|
|
479
|
+
createPeerNetwork(toPeer) {
|
|
480
|
+
var _a;
|
|
481
|
+
const context = {
|
|
482
|
+
id: this.identityProvider.nextNetworkId(this.id, toPeer.id),
|
|
483
|
+
fromPeerId: this.id,
|
|
484
|
+
toPeerId: toPeer.id,
|
|
485
|
+
options: Object.assign({}, this.networkOptions),
|
|
486
|
+
logger: this.logger,
|
|
487
|
+
};
|
|
488
|
+
let network;
|
|
489
|
+
try {
|
|
490
|
+
network = this.networkFactory(context);
|
|
491
|
+
}
|
|
492
|
+
catch (e) {
|
|
493
|
+
const { logger: _logger } = context, logContext = __rest(context, ["logger"]);
|
|
494
|
+
this.log('error', 'peer network creation failed', 'peer.createPeerNetwork', {
|
|
495
|
+
remotePeerId: toPeer.id,
|
|
496
|
+
networkId: context.id,
|
|
497
|
+
error: e,
|
|
498
|
+
data: { context: logContext },
|
|
499
|
+
});
|
|
500
|
+
throw e;
|
|
501
|
+
}
|
|
502
|
+
const { logger: _logger } = context, logContext = __rest(context, ["logger"]);
|
|
503
|
+
this.log('debug', 'peer network created', 'peer.createPeerNetwork', {
|
|
504
|
+
remotePeerId: toPeer.id,
|
|
505
|
+
networkId: (_a = getNetworkId(network)) !== null && _a !== void 0 ? _a : context.id,
|
|
506
|
+
data: { context: logContext },
|
|
507
|
+
});
|
|
508
|
+
return network;
|
|
509
|
+
}
|
|
510
|
+
static createNetworkPair(client, server, location) {
|
|
511
|
+
let uplink;
|
|
512
|
+
try {
|
|
513
|
+
uplink = client.createPeerNetwork(server);
|
|
514
|
+
const downlink = server.createPeerNetwork(client);
|
|
515
|
+
return { uplink, downlink };
|
|
516
|
+
}
|
|
517
|
+
catch (e) {
|
|
518
|
+
uplink === null || uplink === void 0 ? void 0 : uplink.close();
|
|
519
|
+
client.log('error', 'peer network pair creation failed', location, {
|
|
520
|
+
remotePeerId: server.id,
|
|
521
|
+
error: e,
|
|
522
|
+
});
|
|
523
|
+
server.log('error', 'peer network pair creation failed', location, {
|
|
524
|
+
remotePeerId: client.id,
|
|
525
|
+
error: e,
|
|
526
|
+
});
|
|
527
|
+
throw e;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
publish(message, options) {
|
|
531
|
+
this.ensureOpen('peer.post');
|
|
532
|
+
if (!(message === null || message === void 0 ? void 0 : message.type))
|
|
533
|
+
throw new Error(`@message.type (string) is required - peer.post(${this.id})`);
|
|
534
|
+
if (!(message === null || message === void 0 ? void 0 : message.mid))
|
|
535
|
+
throw new Error(`@message.mid (string) is required - peer.post(${this.id})`);
|
|
536
|
+
const target = this.resolveTarget(options);
|
|
537
|
+
this.log('debug', 'publishing peer message', 'peer.publish', {
|
|
538
|
+
remotePeerId: target.peer.id,
|
|
539
|
+
clientId: target.clientId,
|
|
540
|
+
mid: message.mid,
|
|
541
|
+
type: message.type,
|
|
542
|
+
networkId: getNetworkId(target.network),
|
|
543
|
+
});
|
|
544
|
+
const _deliver = () => __awaiter(this, void 0, void 0, function* () {
|
|
545
|
+
try {
|
|
546
|
+
this.sendToLink(target, message);
|
|
547
|
+
}
|
|
548
|
+
catch (e) {
|
|
549
|
+
this.log('error', 'peer publish failed', 'peer.publish', {
|
|
550
|
+
remotePeerId: target.peer.id,
|
|
551
|
+
clientId: target.clientId,
|
|
552
|
+
mid: message.mid,
|
|
553
|
+
type: message.type,
|
|
554
|
+
networkId: getNetworkId(target.network),
|
|
555
|
+
error: e,
|
|
556
|
+
});
|
|
557
|
+
const pending = this.pending.get(message.mid);
|
|
558
|
+
if (pending) {
|
|
559
|
+
this.pending.delete(message.mid);
|
|
560
|
+
pending.reject(e);
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
this.emitError(e, {
|
|
564
|
+
scope: 'peer.post',
|
|
565
|
+
mid: message.mid,
|
|
566
|
+
peer: this,
|
|
567
|
+
network: target.network,
|
|
568
|
+
message,
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
_deliver();
|
|
574
|
+
}
|
|
575
|
+
resolveTarget(options) {
|
|
576
|
+
const clientId = options === null || options === void 0 ? void 0 : options.clientId;
|
|
577
|
+
if (clientId) {
|
|
578
|
+
const link = this.clients.get(clientId);
|
|
579
|
+
if (!link)
|
|
580
|
+
throw new Error(`@clientId[${clientId}] is not connected - peer.post(${this.id})`);
|
|
581
|
+
return link;
|
|
582
|
+
}
|
|
583
|
+
if (this.server)
|
|
584
|
+
return this.server;
|
|
585
|
+
if (this.clients.size === 1)
|
|
586
|
+
return [...this.clients.values()][0];
|
|
587
|
+
if (this.clients.size > 1)
|
|
588
|
+
throw new Error(`@clientId (string) is required - peer.post(${this.id})`);
|
|
589
|
+
throw new Error(`@peer is not connected - peer.post(${this.id})`);
|
|
590
|
+
}
|
|
591
|
+
receiveNetworkData(data, sender, clientId) {
|
|
592
|
+
try {
|
|
593
|
+
const message = JSON.parse(data);
|
|
594
|
+
this.dispatch(message, sender, clientId).catch(e => {
|
|
595
|
+
this.rejectPending(message === null || message === void 0 ? void 0 : message.mid, e);
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
catch (e) {
|
|
599
|
+
this.log('error', 'peer network data parse failed', 'peer.receiveNetworkData', {
|
|
600
|
+
remotePeerId: sender === null || sender === void 0 ? void 0 : sender.id,
|
|
601
|
+
clientId,
|
|
602
|
+
error: e,
|
|
603
|
+
});
|
|
604
|
+
this.rejectPending(undefined, e);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
dispatch(message, sender, clientId) {
|
|
608
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
609
|
+
this.ensureOpen('peer.dispatch');
|
|
610
|
+
this.log('debug', 'dispatching peer message', 'peer.dispatch', {
|
|
611
|
+
remotePeerId: sender === null || sender === void 0 ? void 0 : sender.id,
|
|
612
|
+
clientId,
|
|
613
|
+
mid: message === null || message === void 0 ? void 0 : message.mid,
|
|
614
|
+
type: message === null || message === void 0 ? void 0 : message.type,
|
|
615
|
+
});
|
|
616
|
+
if (message.type === 'result' || message.type === 'pong') {
|
|
617
|
+
const pending = this.pending.get(message.mid);
|
|
618
|
+
if (pending) {
|
|
619
|
+
this.pending.delete(message.mid);
|
|
620
|
+
this.log('debug', 'pending peer message resolved', 'peer.dispatch.result', {
|
|
621
|
+
remotePeerId: sender === null || sender === void 0 ? void 0 : sender.id,
|
|
622
|
+
clientId,
|
|
623
|
+
mid: message.mid,
|
|
624
|
+
type: message.type,
|
|
625
|
+
});
|
|
626
|
+
pending.resolve(message.data);
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
if (message.type === 'error') {
|
|
631
|
+
const pending = this.pending.get(message.mid);
|
|
632
|
+
if (pending) {
|
|
633
|
+
this.pending.delete(message.mid);
|
|
634
|
+
this.log('warn', 'pending peer message rejected', 'peer.dispatch.error', {
|
|
635
|
+
remotePeerId: sender === null || sender === void 0 ? void 0 : sender.id,
|
|
636
|
+
clientId,
|
|
637
|
+
mid: message.mid,
|
|
638
|
+
type: message.type,
|
|
639
|
+
data: { errorData: message.data },
|
|
640
|
+
});
|
|
641
|
+
pending.reject(message.data);
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (message.type === 'ping') {
|
|
646
|
+
this.log('debug', 'replying pong to ping', 'peer.dispatch.ping', {
|
|
647
|
+
remotePeerId: sender === null || sender === void 0 ? void 0 : sender.id,
|
|
648
|
+
clientId,
|
|
649
|
+
mid: message.mid,
|
|
650
|
+
type: message.type,
|
|
651
|
+
});
|
|
652
|
+
this.reply(sender, message.mid, 'pong', { clientId });
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
const context = {
|
|
656
|
+
mid: message.mid,
|
|
657
|
+
type: message.type,
|
|
658
|
+
peer: this,
|
|
659
|
+
sender,
|
|
660
|
+
clientId,
|
|
661
|
+
receivedAt: Date.now(),
|
|
662
|
+
reply: (data) => this.reply(sender, message.mid, 'result', data),
|
|
663
|
+
};
|
|
664
|
+
const listeners = [...this.listeners];
|
|
665
|
+
const results = [];
|
|
666
|
+
for (const listener of listeners) {
|
|
667
|
+
results.push(yield listener(message, context));
|
|
668
|
+
}
|
|
669
|
+
if (results.length > 0)
|
|
670
|
+
context.reply(results.length <= 1 ? results[0] : results);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
reply(target, mid, type, data) {
|
|
674
|
+
if (!target)
|
|
675
|
+
return;
|
|
676
|
+
const _deliver = () => __awaiter(this, void 0, void 0, function* () {
|
|
677
|
+
try {
|
|
678
|
+
const link = this.findLinkTo(target);
|
|
679
|
+
if (link) {
|
|
680
|
+
this.log('debug', 'replying peer message', 'peer.reply', {
|
|
681
|
+
remotePeerId: target.id,
|
|
682
|
+
clientId: link.clientId,
|
|
683
|
+
mid,
|
|
684
|
+
type,
|
|
685
|
+
networkId: getNetworkId(link.network),
|
|
686
|
+
});
|
|
687
|
+
this.sendToLink(link, { type, data, mid });
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
catch (e) {
|
|
691
|
+
this.log('error', 'peer reply failed', 'peer.reply', {
|
|
692
|
+
remotePeerId: target.id,
|
|
693
|
+
mid,
|
|
694
|
+
type,
|
|
695
|
+
error: e,
|
|
696
|
+
});
|
|
697
|
+
target.rejectPending(mid, e);
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
_deliver();
|
|
701
|
+
}
|
|
702
|
+
sendToLink(link, message) {
|
|
703
|
+
if (link.transportOptions) {
|
|
704
|
+
(0, transport_1.splitJSON)(message, link.transportOptions).send(link.network);
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
link.network.send(JSON.stringify(message));
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
findLinkTo(target) {
|
|
711
|
+
var _a;
|
|
712
|
+
if (((_a = this.server) === null || _a === void 0 ? void 0 : _a.peer) === target)
|
|
713
|
+
return this.server;
|
|
714
|
+
for (const link of this.clients.values()) {
|
|
715
|
+
if (link.peer === target)
|
|
716
|
+
return link;
|
|
717
|
+
}
|
|
718
|
+
return undefined;
|
|
719
|
+
}
|
|
720
|
+
rejectPending(mid, error) {
|
|
721
|
+
if (!mid)
|
|
722
|
+
return;
|
|
723
|
+
const pending = this.pending.get(mid);
|
|
724
|
+
if (!pending)
|
|
725
|
+
return;
|
|
726
|
+
this.pending.delete(mid);
|
|
727
|
+
pending.reject(error);
|
|
728
|
+
}
|
|
729
|
+
emitError(error, context) {
|
|
730
|
+
var _a;
|
|
731
|
+
this.log('error', 'peer error emitted', 'peer.emitError', {
|
|
732
|
+
mid: context.mid,
|
|
733
|
+
type: (_a = context.message) === null || _a === void 0 ? void 0 : _a.type,
|
|
734
|
+
networkId: getNetworkId(context.network),
|
|
735
|
+
error,
|
|
736
|
+
data: { scope: context.scope },
|
|
737
|
+
});
|
|
738
|
+
for (const listener of [...this.errorListeners]) {
|
|
739
|
+
listener(error, context);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
ensureOpen(scope) {
|
|
743
|
+
if (this.state !== 'open')
|
|
744
|
+
throw new Error(`@peer[${this.id}] is ${this.state} - ${scope}(${this.id})`);
|
|
745
|
+
}
|
|
746
|
+
log(level, message, location, entry) {
|
|
747
|
+
try {
|
|
748
|
+
this.logger.log(Object.assign(Object.assign({ time: Date.now(), level,
|
|
749
|
+
message,
|
|
750
|
+
location, peerId: this.id }, entry), { error: (entry === null || entry === void 0 ? void 0 : entry.error) == null ? undefined : normalizeError(entry.error) }));
|
|
751
|
+
}
|
|
752
|
+
catch (_a) {
|
|
753
|
+
// Logging must never break simulated socket behavior.
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
exports.Peer = Peer;
|
|
758
|
+
/** create a peer */
|
|
759
|
+
const createPeer = (options) => new Peer(options);
|
|
760
|
+
exports.createPeer = createPeer;
|
|
761
|
+
/**
|
|
762
|
+
* factory for creating peers and keeping a small registry for tests.
|
|
763
|
+
*/
|
|
764
|
+
class SocketFactory {
|
|
765
|
+
constructor(options) {
|
|
766
|
+
this.options = options;
|
|
767
|
+
this.no = 0;
|
|
768
|
+
this.peers = new Map();
|
|
769
|
+
}
|
|
770
|
+
/** create and register a peer */
|
|
771
|
+
peer(options) {
|
|
772
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
773
|
+
const peer = (0, exports.createPeer)({
|
|
774
|
+
latencyMs: (_a = options === null || options === void 0 ? void 0 : options.latencyMs) !== null && _a !== void 0 ? _a : (_b = this.options) === null || _b === void 0 ? void 0 : _b.latencyMs,
|
|
775
|
+
jitterMs: (_c = options === null || options === void 0 ? void 0 : options.jitterMs) !== null && _c !== void 0 ? _c : (_d = this.options) === null || _d === void 0 ? void 0 : _d.jitterMs,
|
|
776
|
+
unordered: (_e = options === null || options === void 0 ? void 0 : options.unordered) !== null && _e !== void 0 ? _e : (_f = this.options) === null || _f === void 0 ? void 0 : _f.unordered,
|
|
777
|
+
maxPacketBytes: (_g = options === null || options === void 0 ? void 0 : options.maxPacketBytes) !== null && _g !== void 0 ? _g : (_h = this.options) === null || _h === void 0 ? void 0 : _h.maxPacketBytes,
|
|
778
|
+
identityProvider: (_j = options === null || options === void 0 ? void 0 : options.identityProvider) !== null && _j !== void 0 ? _j : (_k = this.options) === null || _k === void 0 ? void 0 : _k.identityProvider,
|
|
779
|
+
networkFactory: (_l = options === null || options === void 0 ? void 0 : options.networkFactory) !== null && _l !== void 0 ? _l : (_m = this.options) === null || _m === void 0 ? void 0 : _m.networkFactory,
|
|
780
|
+
logger: (_o = options === null || options === void 0 ? void 0 : options.logger) !== null && _o !== void 0 ? _o : (_p = this.options) === null || _p === void 0 ? void 0 : _p.logger,
|
|
781
|
+
jsonTransport: (_q = options === null || options === void 0 ? void 0 : options.jsonTransport) !== null && _q !== void 0 ? _q : (_r = this.options) === null || _r === void 0 ? void 0 : _r.jsonTransport,
|
|
782
|
+
id: (_s = options === null || options === void 0 ? void 0 : options.id) !== null && _s !== void 0 ? _s : this.nextFactoryPeerId(options),
|
|
783
|
+
});
|
|
784
|
+
this.peers.set(peer.id, peer);
|
|
785
|
+
return peer;
|
|
786
|
+
}
|
|
787
|
+
/** find a registered peer by peer id */
|
|
788
|
+
find(id) {
|
|
789
|
+
return this.peers.get(id);
|
|
790
|
+
}
|
|
791
|
+
/** connect client to server and return the assigned client id */
|
|
792
|
+
connect(client, server) {
|
|
793
|
+
return client.connect(server);
|
|
794
|
+
}
|
|
795
|
+
/** find a client peer connected to a server peer by client id */
|
|
796
|
+
findPeer(server, clientId) {
|
|
797
|
+
return server.findPeer(clientId);
|
|
798
|
+
}
|
|
799
|
+
nextFactoryPeerId(options) {
|
|
800
|
+
var _a, _b, _c, _d;
|
|
801
|
+
if (((options === null || options === void 0 ? void 0 : options.identityProvider) || ((_a = this.options) === null || _a === void 0 ? void 0 : _a.identityProvider)) && !((_b = this.options) === null || _b === void 0 ? void 0 : _b.idPrefix))
|
|
802
|
+
return undefined;
|
|
803
|
+
return `${(_d = (_c = this.options) === null || _c === void 0 ? void 0 : _c.idPrefix) !== null && _d !== void 0 ? _d : 'peer'}-${++this.no}`;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
exports.SocketFactory = SocketFactory;
|
|
807
|
+
/** create a socket factory */
|
|
808
|
+
const createSocketFactory = (options) => new SocketFactory(options);
|
|
809
|
+
exports.createSocketFactory = createSocketFactory;
|
|
810
|
+
const asNetworkOptions = (options) => {
|
|
811
|
+
var _a, _b, _c, _d;
|
|
812
|
+
return ({
|
|
813
|
+
latencyMs: (_a = options === null || options === void 0 ? void 0 : options.latencyMs) !== null && _a !== void 0 ? _a : 0,
|
|
814
|
+
jitterMs: (_b = options === null || options === void 0 ? void 0 : options.jitterMs) !== null && _b !== void 0 ? _b : DEFAULT_JITTER_MS,
|
|
815
|
+
unordered: (_c = options === null || options === void 0 ? void 0 : options.unordered) !== null && _c !== void 0 ? _c : true,
|
|
816
|
+
maxPacketBytes: (_d = options === null || options === void 0 ? void 0 : options.maxPacketBytes) !== null && _d !== void 0 ? _d : DEFAULT_MAX_PACKET_BYTES,
|
|
817
|
+
});
|
|
818
|
+
};
|
|
819
|
+
const asJSONTransportOptions = (options, peerMaxPacketBytes) => {
|
|
820
|
+
if (!options)
|
|
821
|
+
return undefined;
|
|
822
|
+
const transportOptions = options === true ? {} : options;
|
|
823
|
+
if (transportOptions.chunkBytes || !peerMaxPacketBytes)
|
|
824
|
+
return transportOptions;
|
|
825
|
+
return Object.assign(Object.assign({}, transportOptions), { chunkBytes: (0, transport_1.calculateJSONTransportChunkBytes)(peerMaxPacketBytes, transportOptions.envelopeReserveBytes) });
|
|
826
|
+
};
|
|
827
|
+
const getNetworkId = (network) => {
|
|
828
|
+
const id = network === null || network === void 0 ? void 0 : network.id;
|
|
829
|
+
return typeof id === 'string' ? id : undefined;
|
|
830
|
+
};
|
|
831
|
+
const normalizeError = (error) => {
|
|
832
|
+
if (error instanceof Error)
|
|
833
|
+
return error.message;
|
|
834
|
+
if (typeof error === 'string')
|
|
835
|
+
return error;
|
|
836
|
+
try {
|
|
837
|
+
return JSON.stringify(error);
|
|
838
|
+
}
|
|
839
|
+
catch (_a) {
|
|
840
|
+
return String(error);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
const byteLength = (value) => new TextEncoder().encode(value).length;
|
|
844
|
+
//# sourceMappingURL=socket.js.map
|