@persistica/flux-agent 0.0.25 → 0.0.27
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/index.js +78 -15
- package/package.json +1 -1
- package/src/lib/flux-agent.class.d.ts +4 -3
- package/src/lib/flux-interface.class.d.ts +1 -1
package/index.js
CHANGED
|
@@ -40,6 +40,7 @@ var ON_NETWORK_CHANNEL_PUBLISH = "nc-on-pub";
|
|
|
40
40
|
var SUBSCRIBE_NETWORK_CHANNEL_NAME = "subscribe-to-nc-name";
|
|
41
41
|
var SUBSCRIBED_NETWORK_CHANNEL_NAME = "subscribed-to-nc-name";
|
|
42
42
|
var UNSUBSCRIBE_NETWORK_CHANNEL_NAME = "unsubscribe-nc-name";
|
|
43
|
+
var UNSUBSCRIBED_NETWORK_CHANNEL_NAME = "unsubscribed-nc-name";
|
|
43
44
|
var AUTHORITY_CHANNEL_SUBSCRIBE = "acs";
|
|
44
45
|
var AUTHORITY_DISCONNECT_AGENT = "ada";
|
|
45
46
|
var ERROR = "e";
|
|
@@ -264,6 +265,7 @@ var FluxRemoteClient = class {
|
|
|
264
265
|
constructor(iceConnection) {
|
|
265
266
|
this.iceConnection = iceConnection;
|
|
266
267
|
}
|
|
268
|
+
iceConnection;
|
|
267
269
|
/**
|
|
268
270
|
* Calls a remote procedure on the connected client.
|
|
269
271
|
*/
|
|
@@ -319,6 +321,8 @@ var ICEConnection = class {
|
|
|
319
321
|
this._fluxWebSocketClientConnection.registerMethod("acceptAnswer", this.acceptAnswer.bind(this));
|
|
320
322
|
this._fluxWebSocketClientConnection.registerMethod("answerAcceptedByInitiator", this.answerAcceptedByInitiator.bind(this));
|
|
321
323
|
}
|
|
324
|
+
_fluxWebSocketClientConnection;
|
|
325
|
+
_stateChange;
|
|
322
326
|
//extends RPCServer<'createOffer' | 'acceptOffer' | 'acceptAnswer'> {
|
|
323
327
|
peerConnection = new RTCPeerConnection(peerConnectionConfig);
|
|
324
328
|
dataChannel;
|
|
@@ -407,6 +411,9 @@ var FluxAgentNetworkConnection = class {
|
|
|
407
411
|
console.warn("\u2757WebRTC is not available in this environment.");
|
|
408
412
|
}
|
|
409
413
|
}
|
|
414
|
+
_fluxWebSocketConnection;
|
|
415
|
+
_fluxWebSocketClientConnection;
|
|
416
|
+
_webRTCStateChange;
|
|
410
417
|
iceConnection;
|
|
411
418
|
connectedChannelSet = /* @__PURE__ */ new Set();
|
|
412
419
|
/**
|
|
@@ -420,7 +427,7 @@ var FluxAgentNetworkConnection = class {
|
|
|
420
427
|
const fluxNetworkChannel = await this._fluxWebSocketConnection.joinChannel(
|
|
421
428
|
channelName
|
|
422
429
|
);
|
|
423
|
-
this.connectedChannelSet.add(
|
|
430
|
+
this.connectedChannelSet.add(channelName);
|
|
424
431
|
return fluxNetworkChannel;
|
|
425
432
|
}
|
|
426
433
|
/**
|
|
@@ -486,16 +493,18 @@ var PicoLogger = /* @__PURE__ */ (() => {
|
|
|
486
493
|
|
|
487
494
|
// libs/flux/shared/connection/src/lib/flux-network-channel.class.ts
|
|
488
495
|
var FluxNetworkChannel = class {
|
|
489
|
-
constructor(
|
|
490
|
-
this.
|
|
496
|
+
constructor(_channelName, _fluxWebSocketConnection) {
|
|
497
|
+
this._channelName = _channelName;
|
|
491
498
|
this._fluxWebSocketConnection = _fluxWebSocketConnection;
|
|
492
499
|
}
|
|
500
|
+
_channelName;
|
|
501
|
+
_fluxWebSocketConnection;
|
|
493
502
|
/**
|
|
494
503
|
* Broadcasts a message to the channel.
|
|
495
504
|
*/
|
|
496
505
|
publish(message) {
|
|
497
506
|
this._fluxWebSocketConnection.publish(
|
|
498
|
-
this.
|
|
507
|
+
this._channelName,
|
|
499
508
|
message
|
|
500
509
|
);
|
|
501
510
|
}
|
|
@@ -504,7 +513,7 @@ var FluxNetworkChannel = class {
|
|
|
504
513
|
*/
|
|
505
514
|
onPublish(fn) {
|
|
506
515
|
this._fluxWebSocketConnection.onPublish(
|
|
507
|
-
this.
|
|
516
|
+
this._channelName,
|
|
508
517
|
fn
|
|
509
518
|
// TODO
|
|
510
519
|
);
|
|
@@ -515,11 +524,17 @@ var FluxNetworkChannel = class {
|
|
|
515
524
|
var CONNECTION_TIMEOUT_MS = 2e3;
|
|
516
525
|
var ChannelStateManager = class {
|
|
517
526
|
connectionTimeouts = /* @__PURE__ */ new Map();
|
|
527
|
+
joinedChannels = /* @__PURE__ */ new Map();
|
|
518
528
|
/**
|
|
519
529
|
* Join a channel.
|
|
520
530
|
*/
|
|
521
531
|
async joinChannel(channelName, fluxWebSocketConnection, webSocketClient) {
|
|
522
532
|
if (webSocketClient) {
|
|
533
|
+
const existingChannel = this.joinedChannels.get(channelName);
|
|
534
|
+
if (existingChannel) {
|
|
535
|
+
existingChannel.useCount++;
|
|
536
|
+
return Promise.resolve(existingChannel.channel);
|
|
537
|
+
}
|
|
523
538
|
return new Promise((resolve, reject) => {
|
|
524
539
|
const existingTimeout = this.connectionTimeouts.get(channelName);
|
|
525
540
|
if (existingTimeout) {
|
|
@@ -537,7 +552,9 @@ var ChannelStateManager = class {
|
|
|
537
552
|
this.connectionTimeouts.delete(channelName);
|
|
538
553
|
}
|
|
539
554
|
fluxWebSocketConnection.removePackageTypeInterceptor(SUBSCRIBED_NETWORK_CHANNEL_NAME, cb);
|
|
540
|
-
|
|
555
|
+
const channel = new FluxNetworkChannel(channelName, fluxWebSocketConnection);
|
|
556
|
+
this.joinedChannels.set(channelName, { channel, useCount: 1 });
|
|
557
|
+
resolve(channel);
|
|
541
558
|
};
|
|
542
559
|
fluxWebSocketConnection.interceptPackageTypeMessages(
|
|
543
560
|
SUBSCRIBED_NETWORK_CHANNEL_NAME,
|
|
@@ -559,9 +576,46 @@ var ChannelStateManager = class {
|
|
|
559
576
|
/**
|
|
560
577
|
* Leave a channel.
|
|
561
578
|
*/
|
|
562
|
-
async leaveChannel(channelName, webSocketClient) {
|
|
579
|
+
async leaveChannel(channelName, fluxWebSocketConnection, webSocketClient) {
|
|
580
|
+
const existingChannel = this.joinedChannels.get(channelName);
|
|
581
|
+
if (!existingChannel) {
|
|
582
|
+
return Promise.reject(new Error("No channel instance found"));
|
|
583
|
+
}
|
|
584
|
+
existingChannel.useCount--;
|
|
585
|
+
if (existingChannel.useCount <= 0) {
|
|
586
|
+
this.joinedChannels.delete(channelName);
|
|
587
|
+
}
|
|
588
|
+
if (webSocketClient && existingChannel.useCount <= 0) {
|
|
589
|
+
return new Promise((resolve, reject) => {
|
|
590
|
+
const cb = (message) => {
|
|
591
|
+
const receivedChannelName = message.substring(message.indexOf(":") + 1);
|
|
592
|
+
if (channelName !== receivedChannelName) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
const timeout = this.connectionTimeouts.get(channelName);
|
|
596
|
+
if (timeout) {
|
|
597
|
+
clearTimeout(timeout);
|
|
598
|
+
this.connectionTimeouts.delete(channelName);
|
|
599
|
+
}
|
|
600
|
+
fluxWebSocketConnection.removePackageTypeInterceptor(UNSUBSCRIBED_NETWORK_CHANNEL_NAME, cb);
|
|
601
|
+
resolve(void 0);
|
|
602
|
+
};
|
|
603
|
+
fluxWebSocketConnection.interceptPackageTypeMessages(
|
|
604
|
+
UNSUBSCRIBED_NETWORK_CHANNEL_NAME,
|
|
605
|
+
cb
|
|
606
|
+
);
|
|
607
|
+
this.connectionTimeouts.set(
|
|
608
|
+
channelName,
|
|
609
|
+
setTimeout(() => {
|
|
610
|
+
this.connectionTimeouts.delete(channelName);
|
|
611
|
+
fluxWebSocketConnection.removePackageTypeInterceptor(UNSUBSCRIBED_NETWORK_CHANNEL_NAME, cb);
|
|
612
|
+
reject(new Error(`Channel unsubscription timed out for channel "${channelName}"`));
|
|
613
|
+
}, CONNECTION_TIMEOUT_MS)
|
|
614
|
+
);
|
|
615
|
+
webSocketClient.send(`${UNSUBSCRIBE_NETWORK_CHANNEL_NAME}:${channelName}`);
|
|
616
|
+
});
|
|
617
|
+
}
|
|
563
618
|
if (webSocketClient) {
|
|
564
|
-
webSocketClient.send(`${UNSUBSCRIBE_NETWORK_CHANNEL_NAME}:${channelName}`);
|
|
565
619
|
return Promise.resolve(void 0);
|
|
566
620
|
}
|
|
567
621
|
return Promise.reject(new Error("Not connected"));
|
|
@@ -607,6 +661,11 @@ var FluxWebSocketConnection = class {
|
|
|
607
661
|
);
|
|
608
662
|
this.interceptPackageTypeMessages("isReady", this.readyInterceptor);
|
|
609
663
|
}
|
|
664
|
+
fluxInstanceId;
|
|
665
|
+
onReconnectCallback;
|
|
666
|
+
stateManager;
|
|
667
|
+
token;
|
|
668
|
+
options;
|
|
610
669
|
// ****************************************************************************
|
|
611
670
|
// *** State
|
|
612
671
|
// ****************************************************************************
|
|
@@ -675,7 +734,6 @@ var FluxWebSocketConnection = class {
|
|
|
675
734
|
});
|
|
676
735
|
this.socket.clearEventSubscribers();
|
|
677
736
|
this.socket.on("message", this.socketMessageHandler).on("close", this.socketCloseHandler).on("connecting", this.socketConnectingHandler).on("error", this.socketErrorHandler);
|
|
678
|
-
this.stateManager.emitNetworkState("connecting");
|
|
679
737
|
void this.socket.connect();
|
|
680
738
|
return this.connectPromise;
|
|
681
739
|
}
|
|
@@ -729,6 +787,7 @@ var FluxWebSocketConnection = class {
|
|
|
729
787
|
async leaveChannel(channelName) {
|
|
730
788
|
return this.channelStateManager.leaveChannel(
|
|
731
789
|
channelName,
|
|
790
|
+
this,
|
|
732
791
|
this.webSocketClient
|
|
733
792
|
);
|
|
734
793
|
}
|
|
@@ -815,7 +874,7 @@ var FluxWebSocketConnection = class {
|
|
|
815
874
|
this.stateManager.emitNetworkState(reason === "kicked" ? "kicked" : "disconnected");
|
|
816
875
|
}
|
|
817
876
|
handleSocketConnecting(retryAttempt) {
|
|
818
|
-
this.stateManager.emitNetworkState("
|
|
877
|
+
this.stateManager.emitNetworkState("connecting");
|
|
819
878
|
if (retryAttempt > 0) {
|
|
820
879
|
PicoLogger.log(`\u{1F504} Connecting attempt: #${retryAttempt} of ${this.options.retries ?? "none"}`, this.fluxInstanceId);
|
|
821
880
|
} else {
|
|
@@ -1148,15 +1207,19 @@ var FluxClientData = class {
|
|
|
1148
1207
|
// packages/flux/agent/src/lib/flux-agent.class.ts
|
|
1149
1208
|
var DEFAULT_FLUX_DOMAIN = "https://mesh.persistica.io";
|
|
1150
1209
|
var FluxAgent = class {
|
|
1151
|
-
constructor(networkId, options) {
|
|
1152
|
-
this.networkId = networkId;
|
|
1153
|
-
this.options = options;
|
|
1154
|
-
validateNetworkIdOrThrow(this.networkId);
|
|
1155
|
-
}
|
|
1156
1210
|
id = nanoid();
|
|
1211
|
+
networkId;
|
|
1157
1212
|
fluxWebSocketConnection;
|
|
1158
1213
|
fluxClientData = new FluxClientData();
|
|
1159
1214
|
stateManager = new StateManager();
|
|
1215
|
+
options;
|
|
1216
|
+
constructor(networkId, options) {
|
|
1217
|
+
if (!validateNetworkIdOrThrow(networkId)) {
|
|
1218
|
+
throw new Error("Will never be thrown");
|
|
1219
|
+
}
|
|
1220
|
+
this.networkId = networkId;
|
|
1221
|
+
this.options = options;
|
|
1222
|
+
}
|
|
1160
1223
|
/**
|
|
1161
1224
|
* Connect to the network using provided identification.
|
|
1162
1225
|
*
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import { type TNetworkId_S } from '@flux/shared/types';
|
|
1
2
|
import type { TMessageCallback } from '@flux/shared/ws';
|
|
2
3
|
import type { FluxAgentNetworkConnection } from '@flux/shared/connection';
|
|
3
4
|
export declare class FluxAgent {
|
|
4
|
-
private readonly networkId;
|
|
5
|
-
private readonly options?;
|
|
6
5
|
readonly id: string;
|
|
6
|
+
readonly networkId: TNetworkId_S;
|
|
7
7
|
private fluxWebSocketConnection;
|
|
8
8
|
private readonly fluxClientData;
|
|
9
9
|
private readonly stateManager;
|
|
10
|
+
private readonly options;
|
|
10
11
|
constructor(networkId: string, options?: {
|
|
11
12
|
domain?: string;
|
|
12
13
|
secretKey?: string;
|
|
13
14
|
retries?: number;
|
|
14
|
-
}
|
|
15
|
+
});
|
|
15
16
|
/**
|
|
16
17
|
* Connect to the network using provided identification.
|
|
17
18
|
*
|
|
@@ -8,5 +8,5 @@ import type { FluxWebSocketConnection } from '../../../../../libs/flux/shared/co
|
|
|
8
8
|
export declare class FluxInterface {
|
|
9
9
|
private readonly socketConnection;
|
|
10
10
|
constructor(socketConnection: FluxWebSocketConnection);
|
|
11
|
-
messageReport(
|
|
11
|
+
messageReport(_packageStatus: Omit<IPackageStatus, 'txNode'>): void;
|
|
12
12
|
}
|