@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 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(fluxNetworkChannel.channelName);
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(channelName, _fluxWebSocketConnection) {
490
- this.channelName = channelName;
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.channelName,
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.channelName,
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
- resolve(new FluxNetworkChannel(channelName, fluxWebSocketConnection));
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("disconnected");
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@persistica/flux-agent",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "Persistica Flux Agent",
5
5
  "type": "module",
6
6
  "keywords": [],
@@ -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
- } | undefined);
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(packageStatus: Omit<IPackageStatus, 'txNode'>): void;
11
+ messageReport(_packageStatus: Omit<IPackageStatus, 'txNode'>): void;
12
12
  }