@persistica/flux-mesh 0.0.11 → 0.0.16

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.
Files changed (36) hide show
  1. package/index.js +271 -4
  2. package/package.json +11 -5
  3. package/src/_classes/web-rtc-client-interface.class.d.ts +52 -0
  4. package/src/_managers/agent.manager.d.ts +15 -0
  5. package/src/_managers/authority.manager.d.ts +15 -0
  6. package/src/_managers/global/global-client.manager.d.ts +22 -0
  7. package/src/_managers/local/local-agent.manager.d.ts +12 -0
  8. package/src/_managers/local/local-authority.manager.d.ts +12 -0
  9. package/src/_routes/auth/network-authority.post.route.d.ts +10 -2
  10. package/src/_routes/auth/network-client.post.route.d.ts +7 -6
  11. package/src/_routes/npc-interact.get.route.d.ts +6 -0
  12. package/src/_routes/options.route.d.ts +1 -1
  13. package/src/auth/auth.d.ts +10 -3
  14. package/src/business-logic/channels/channel-manager.class.d.ts +11 -36
  15. package/src/business-logic/npc/npc-dialogue-manager.class.d.ts +7 -0
  16. package/src/business-logic/npc/npc-dialogue-script.class.d.ts +7 -0
  17. package/src/business-logic/npc/npc-dialogue-script.class.spec.d.ts +1 -0
  18. package/src/business-logic/npc/npc-dialogue.types.d.ts +6 -0
  19. package/src/business-logic/npc/npc-interaction-tracker.class.d.ts +5 -0
  20. package/src/business-logic/npc/npc-interaction-tracker.class.spec.d.ts +1 -0
  21. package/src/index.d.ts +2 -0
  22. package/src/main.d.ts +3 -3
  23. package/src/orchestrators/facilitate-webrtc-connection.class.d.ts +3 -0
  24. package/src/register/{network-client-manager.class.d.ts → network-agent-redis-cache.class.d.ts} +20 -10
  25. package/src/register/network-authority-redis-cache.class.d.ts +49 -0
  26. package/src/routing/addressing.utils.d.ts +11 -1
  27. package/src/routing/global-channel/global-channel-pubsub.class.d.ts +6 -6
  28. package/src/routing/outgoing-message-router.class.d.ts +3 -4
  29. package/src/routing/process-message-router.class.d.ts +4 -8
  30. package/src/routing/redis/_utils/split-message.utils.d.ts +11 -0
  31. package/src/routing/redis/_utils/split-message.utils.spec.d.ts +1 -0
  32. package/src/routing/redis/hash/network-agent.redis.sorted-set.d.ts +5 -5
  33. package/src/routing/redis/network-agent.redis.d.ts +37 -13
  34. package/src/routing/redis/redis-connection.class.d.ts +69 -20
  35. package/src/routing/rpc/core/global-rpc-client.class.d.ts +9 -12
  36. package/src/register/register-network-authority.class.d.ts +0 -34
package/package.json CHANGED
@@ -1,23 +1,29 @@
1
1
  {
2
2
  "name": "@persistica/flux-mesh",
3
- "version": "0.0.11",
3
+ "version": "0.0.16",
4
4
  "description": "Persistica Flux Mesh",
5
5
  "type": "module",
6
6
  "keywords": [],
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
10
- "exports": "./index.js",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./src/index.d.ts",
13
+ "import": "./index.js",
14
+ "default": "./index.js"
15
+ }
16
+ },
11
17
  "main": "./index.js",
12
18
  "types": "./src/index.d.ts",
13
19
  "repository": {
14
20
  "type": "git",
15
- "url": "git+https://github.com/rujorgensen/persistica.git"
21
+ "url": "git+https://github.com/rujorgensen/flux.git"
16
22
  },
17
23
  "author": "pixl.prophet",
18
24
  "license": "ISC",
19
25
  "bugs": {
20
- "url": "https://github.com/rujorgensen/persistica/issues"
26
+ "url": "https://github.com/rujorgensen/flux/issues"
21
27
  },
22
- "homepage": "https://github.com/rujorgensen/persistica#readme"
28
+ "homepage": "https://github.com/rujorgensen/flux#readme"
23
29
  }
@@ -7,14 +7,66 @@ export declare class WebRTCClient extends RPCClient<'createOffer' | 'acceptOffer
7
7
  private readonly _handleResponseMessage;
8
8
  constructor(_originProcessAddress: TProcessAddress, _sendToRPCServer: (data: any, // ! Use 'unknown' or Bun.BufferSource (does not work)
9
9
  compress?: boolean | undefined) => number, _handleResponseMessage: (fn: TRPCResponseCallbackFunction) => void);
10
+ /**
11
+ * Creates a WebRTC offer.
12
+ *
13
+ * @returns { Promise<unknown> } The WebRTC offer
14
+ */
10
15
  createOffer(): Promise<unknown>;
16
+ /**
17
+ * Accepts a WebRTC offer and creates an answer.
18
+ *
19
+ * @param { unknown } offer - The WebRTC offer from remote
20
+ *
21
+ * @returns { Promise<unknown> } The answer
22
+ */
11
23
  acceptOfferAndCreateAnswer(offer: unknown): Promise<unknown>;
24
+ /**
25
+ * Accepts a WebRTC answer from the remote client.
26
+ *
27
+ * @param { unknown } answer - The WebRTC answer
28
+ *
29
+ * @returns { Promise<boolean> } True if accepted
30
+ */
12
31
  acceptAnswer(answer: unknown): Promise<boolean>;
32
+ /**
33
+ * Notifies the remote client that the answer was accepted.
34
+ *
35
+ * @param { boolean } answerAccepted - Whether the answer was accepted
36
+ *
37
+ * @returns { Promise<boolean> }
38
+ */
13
39
  answerWasAccepted(answerAccepted: boolean): Promise<boolean>;
14
40
  }
15
41
  export declare class GlobalWebRTCClient extends GlobalRPCClient2<'createOffer' | 'acceptOffer' | 'acceptAnswer' | 'answerAcceptedByInitiator'> {
42
+ /**
43
+ * Creates a WebRTC offer.
44
+ *
45
+ * @returns { Promise<unknown> } The WebRTC offer
46
+ */
16
47
  createOffer(): Promise<unknown>;
48
+ /**
49
+ * Accepts a WebRTC offer and creates an answer.
50
+ *
51
+ * @param { unknown } offer - The WebRTC offer from remote
52
+ *
53
+ * @returns { Promise<unknown> } The answer
54
+ */
17
55
  acceptOfferAndCreateAnswer(offer: unknown): Promise<unknown>;
56
+ /**
57
+ * Accepts a WebRTC answer from the remote client.
58
+ *
59
+ * @param { unknown } answer - The WebRTC answer
60
+ *
61
+ * @returns { Promise<boolean> } True if accepted
62
+ */
18
63
  acceptAnswer(answer: unknown): Promise<boolean>;
64
+ /**
65
+ * Notifies the remote client that the answer was accepted.
66
+ *
67
+ * @param { boolean } answerAccepted - Whether the answer was accepted
68
+ *
69
+ * @returns { Promise<boolean> }
70
+ */
19
71
  answerWasAccepted(answerAccepted: boolean): Promise<boolean>;
20
72
  }
@@ -0,0 +1,15 @@
1
+ import { type TAddress, type TClientId } from '@flux/shared/types';
2
+ import { RedisConnection } from '../routing/redis/redis-connection.class';
3
+ import { TConnectedClientSocket } from '../connected-client-socket.types';
4
+ import { NetworkAgentRedisCache } from '../register/network-agent-redis-cache.class';
5
+ export declare class AgentManager {
6
+ private readonly _redisConnection;
7
+ private readonly _clientMap;
8
+ private readonly _networkAgentRedisCache;
9
+ private readonly machineAddress;
10
+ private readonly processAddress;
11
+ private readonly _globalClientManager;
12
+ private readonly _localAgentManager;
13
+ constructor(_redisConnection: RedisConnection, _clientMap: Map<TClientId, TConnectedClientSocket>, _networkAgentRedisCache: NetworkAgentRedisCache);
14
+ kick(agentAddress: TAddress): void;
15
+ }
@@ -0,0 +1,15 @@
1
+ import { type TAddress, TClientId } from '@flux/shared/types';
2
+ import { RedisConnection } from '../routing/redis/redis-connection.class';
3
+ import { TConnectedClientSocket } from '../connected-client-socket.types';
4
+ import { NetworkAuthorityRedisCache } from '../register/network-authority-redis-cache.class';
5
+ export declare class AuthorityManager {
6
+ private readonly _redisConnection;
7
+ private readonly _clientMap;
8
+ private readonly _networkAuthorityRedisCache;
9
+ private readonly machineAddress;
10
+ private readonly processAddress;
11
+ private readonly _globalClientManager;
12
+ private readonly _localAuthorityManager;
13
+ constructor(_redisConnection: RedisConnection, _clientMap: Map<TClientId, TConnectedClientSocket>, _networkAuthorityRedisCache: NetworkAuthorityRedisCache);
14
+ kick(agentAddress: TAddress): void;
15
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Global client manager.
3
+ */
4
+ import { type TAddress, type TClientId } from '@flux/shared/types';
5
+ import { RedisConnection } from '../../routing/redis/redis-connection.class';
6
+ export declare class GlobalClientManager {
7
+ private readonly _redisConnection;
8
+ private readonly processAddress;
9
+ constructor(_redisConnection: RedisConnection);
10
+ /**
11
+ * Sends a global message to kick a client.
12
+ *
13
+ * @param { TAddress } fullClientAddress - The full client address
14
+ *
15
+ * @returns { Promise<void> }
16
+ */
17
+ kickClient(agentAddress: TAddress): Promise<void>;
18
+ /**
19
+ * On event on this process
20
+ */
21
+ onKickClient(onKickCallback: (clientAddress: TClientId) => void): void;
22
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Disconnects a local agent client, and cleans up all related state in redis and locally.
3
+ */
4
+ import type { TClientId } from '@flux/shared/types';
5
+ import { TConnectedClientSocket } from '../../connected-client-socket.types';
6
+ import { NetworkAgentRedisCache } from '../../register/network-agent-redis-cache.class';
7
+ export declare class LocalAgentManager {
8
+ private readonly _clientMap;
9
+ private readonly _networkAgentRedisCache;
10
+ constructor(_clientMap: Map<TClientId, TConnectedClientSocket>, _networkAgentRedisCache: NetworkAgentRedisCache);
11
+ kickAgent(clientAddress: TClientId): void;
12
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Disconnects a local authority client, and cleans up all related state in redis and locally.
3
+ */
4
+ import type { TClientId } from '@flux/shared/types';
5
+ import type { TConnectedClientSocket } from '../../connected-client-socket.types';
6
+ import { NetworkAuthorityRedisCache } from '../../register/network-authority-redis-cache.class';
7
+ export declare class LocalAuthorityManager {
8
+ private readonly _clientMap;
9
+ private readonly _networkAuthorityRedisCache;
10
+ constructor(_clientMap: Map<TClientId, TConnectedClientSocket>, _networkAuthorityRedisCache: NetworkAuthorityRedisCache);
11
+ kickAuthority(clientAddress: TClientId): void;
12
+ }
@@ -1,7 +1,15 @@
1
1
  import type * as Bun from 'bun';
2
+ import { type TNetworkId_S } from '@flux/shared/types';
2
3
  /**
3
4
  * This route is used to authorize a network authority.
4
5
  *
5
- * @returns { Promise<Response> }
6
+ * The plain-text token value sent in the request body is validated against
7
+ * the local {@link NetworkTokenCache}. The cache is kept in sync via Redis
8
+ * pub/sub events emitted by the portal on token creation, rotation, or
9
+ * deletion — so no database round-trip is unless it doesn't exist locally.
10
+ *
11
+ * @param { Bun.BunRequest } request - The incoming HTTP request
12
+ *
13
+ * @returns { Promise<Response> } The HTTP response with auth token or error
6
14
  */
7
- export declare const authorizeNetworkAuthority: (request: Bun.BunRequest) => Promise<Response>;
15
+ export declare const authorizeNetworkAuthority: (request: Bun.BunRequest, hardcodedNetworkCredentials?: Map<TNetworkId_S, string>) => Promise<Response>;
@@ -1,12 +1,13 @@
1
1
  import type { BunRequest } from 'bun';
2
2
  import type { GlobalRPCClient } from '../../routing/rpc/core/global-rpc-client.class';
3
- import type { NetworkAuthorityManager } from '../../register/register-network-authority.class';
3
+ import type { NetworkAuthorityRedisCache } from '../../register/network-authority-redis-cache.class';
4
4
  /**
5
+ * This route is used to authorize a network agent.
5
6
  *
6
- * @param { BunRequest } request
7
- * @param { NetworkAuthorityManager } networkAuthorityManager
8
- * @param { GlobalRPCClient<'authorize'> } globalRPCClient
7
+ * @param { BunRequest } request - The incoming HTTP request
8
+ * @param { NetworkAuthorityRedisCache } networkAuthorityManager - The network authority manager
9
+ * @param { GlobalRPCClient<'authorize'> } globalRPCClient - The global RPC client
9
10
  *
10
- * @returns { void }
11
+ * @returns { Promise<Response> } The HTTP response with auth token or error
11
12
  */
12
- export declare const authorizeNetworkAgent: (request: BunRequest, networkAuthorityManager: NetworkAuthorityManager, globalRPCClient: GlobalRPCClient<"authorize">) => Promise<Response>;
13
+ export declare const authorizeNetworkAgent: (request: BunRequest, networkAuthorityManager: NetworkAuthorityRedisCache, globalRPCClient: GlobalRPCClient<"authorize">) => Promise<Response>;
@@ -0,0 +1,6 @@
1
+ import type * as Bun from 'bun';
2
+ /**
3
+ * Returns mesh NPC dialogue with random flavor text for the first few
4
+ * interactions from the same player, then a fixed final line afterwards.
5
+ */
6
+ export declare const interactWithNpc: (request: Bun.BunRequest) => Response;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Standard CORS response.
3
3
  *
4
- * @returns { Response }
4
+ * @returns { Response } A 204 No Content response with CORS headers
5
5
  */
6
6
  export declare const OPTIONS_RESPONSE: () => Response;
@@ -13,10 +13,17 @@ export type TTokenPayloadJWT = string & {
13
13
  /**
14
14
  * Generates JWT string from a token payload.
15
15
  *
16
- * @param { TTokenPayload } payload
17
- * @param { number } expiresIn
16
+ * @param { TTokenPayload } payload - The token payload to sign
17
+ * @param { number } [expiresIn] - Token expiry time in seconds
18
18
  *
19
- * @returns { TTokenPayloadJWT }
19
+ * @returns { string } The signed JWT string
20
20
  */
21
21
  export declare const generateToken: (payload: TTokenPayload, expiresIn?: number) => string;
22
+ /**
23
+ * Verifies a JWT token and returns the payload or throws if invalid.
24
+ *
25
+ * @param { unknown } token - The JWT token string to verify
26
+ *
27
+ * @returns { TTokenPayload } The decoded token payload
28
+ */
22
29
  export declare const verifyTokenOrThrow: (token: unknown) => TTokenPayload;
@@ -1,5 +1,14 @@
1
- import { type TAddress, type TChannelName, type TNetworkId_S } from '@flux/shared/types';
1
+ import { type TAddress, type TChannelName, type TNetworkId_S, type TSubscription_S } from '@flux/shared/types';
2
2
  import type { GlobalChannelPubsub } from '../../routing/global-channel/global-channel-pubsub.class';
3
+ export declare const MAX_CHANNEL_MEMBERS_BY_SUBSCRIPTION_TYPE: {
4
+ [key in TSubscription_S]: number;
5
+ };
6
+ export declare const MAX_CHANNEL_MEMBERS: number;
7
+ export declare const normalizeSubscriptionType: (subscriptionType?: string) => TSubscription_S | undefined;
8
+ export declare const resolveSubscriptionTypeOrDefault: (subscriptionType?: string) => TSubscription_S;
9
+ export declare const readMaxChannelMembers: (subscriptionType?: string) => number;
10
+ export declare const readSubscriptionTypeFromClaim: (claim?: string) => TSubscription_S | undefined;
11
+ export declare const canChannelHaveMoreMembers: (memberCount: number, subscriptionType?: TSubscription_S) => boolean;
3
12
  export declare class NetworkChannelManager {
4
13
  private readonly _globalChannelPubsub;
5
14
  private readonly channelUsageCount;
@@ -10,60 +19,26 @@ export declare class NetworkChannelManager {
10
19
  * Checks if a channel can have more members.
11
20
  *
12
21
  * ! TODO Don't query the database repeatedly, implement local synced cache.
13
- *
14
- * @param { TNetworkId_S } networkId
15
- * @param { TChannelName } channelName
16
- *
17
- * @returns { Promise<boolean> }
18
22
  */
19
- canHaveMembers(networkId: TNetworkId_S, channelName: TChannelName): Promise<boolean>;
23
+ canHaveMembers(networkId: TNetworkId_S, channelName: TChannelName, subscriptionType?: TSubscription_S): Promise<boolean>;
20
24
  /**
21
25
  * Joins a network channel.
22
- *
23
- * @param { TNetworkId_S } networkId
24
- * @param { TChannelName } channelName
25
- * @param { TAddress } clientAddress
26
- *
27
- * @returns { void }
28
26
  */
29
27
  joinNetworkChannel(networkId: TNetworkId_S, channelName: TChannelName, clientAddress: TAddress): void;
30
28
  /**
31
29
  * Leaves a network channel.
32
- *
33
- * @param { TNetworkId_S } networkId
34
- * @param { TChannelName } channelName
35
- * @param { TAddress } clientAddress
36
- *
37
- * @returns { Promise<void> }
38
30
  */
39
31
  leaveNetworkChannel(networkId: TNetworkId_S, channelName: TChannelName, clientAddress: TAddress): Promise<void>;
40
32
  /**
41
33
  * Leaves all network channels.
42
- *
43
- * @param { TNetworkId_S } networkId
44
- * @param { TAddress } clientAddress
45
- * @param { Set<TChannelName> } channelNames
46
- *
47
- * @returns { void }
48
34
  */
49
35
  leaveAllNetworkChannels(networkId: TNetworkId_S, clientAddress: TAddress, channelNames: Set<TChannelName>): void;
50
36
  /**
51
37
  * Creates a network channel if it does not exist.
52
- *
53
- * @param { TNetworkId_S } networkId
54
- * @param { TChannelName } channelName
55
- *
56
- * @returns { void }
57
38
  */
58
39
  private createNetworkChannelIfNotExist;
59
40
  /**
60
41
  * Increases the usage count of a channel.
61
- *
62
- * @param { TNetworkId_S } networkId
63
- * @param { TChannelName } channelName
64
- * @param { number } usage
65
- *
66
- * @returns { void }
67
42
  */
68
43
  increaseUsageCount(networkId: TNetworkId_S, channelName: TChannelName, usage: number): void;
69
44
  }
@@ -0,0 +1,7 @@
1
+ import type { INpcInteractionResult } from './npc-dialogue.types';
2
+ export declare class NPCDialogueManager {
3
+ private readonly interactionTracker;
4
+ private readonly dialogueScript;
5
+ constructor(randomNumberGenerator?: () => number);
6
+ interact(userId: string, npcId: string): INpcInteractionResult;
7
+ }
@@ -0,0 +1,7 @@
1
+ import type { INpcInteractionResult } from './npc-dialogue.types';
2
+ export declare class NPCDialogueScript {
3
+ private readonly randomNumberGenerator;
4
+ constructor(randomNumberGenerator?: () => number);
5
+ resolveInteraction(interactionCount: number): INpcInteractionResult;
6
+ private resolveMessage;
7
+ }
@@ -0,0 +1,6 @@
1
+ export interface INpcInteractionResult {
2
+ interactionCount: number;
3
+ isFinalResponse: boolean;
4
+ message: string;
5
+ remainingRandomResponses: number;
6
+ }
@@ -0,0 +1,5 @@
1
+ export declare class NPCInteractionTracker {
2
+ private readonly interactionCountByUserAndNpc;
3
+ incrementInteractionCount(userId: string, npcId: string): number;
4
+ private buildInteractionKey;
5
+ }
package/src/index.d.ts CHANGED
@@ -1 +1,3 @@
1
1
  export { FluxMeshServer, } from './main';
2
+ export { type RedisConnection, getMeshRedisConnection, } from './routing/redis/redis-connection.class';
3
+ export { GlobalClientManager, } from './_managers/global/global-client.manager';
package/src/main.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  declare global {
2
2
  var meshLoadCount: number | null;
3
3
  }
4
+ import { TNetworkId_S } from '@flux/shared/types';
4
5
  type TOptions = {
5
6
  port?: number;
6
7
  redisConnectionString?: string;
8
+ hardcodedNetworkCredentials?: Map<TNetworkId_S, string>;
7
9
  };
8
10
  export declare class FluxMeshServer {
9
11
  private readonly optionsOrPort?;
@@ -12,13 +14,11 @@ export declare class FluxMeshServer {
12
14
  private readonly bunServer;
13
15
  private readonly globalChannelPubsub;
14
16
  private readonly channelManager;
15
- private readonly options;
17
+ private readonly agentManager;
16
18
  constructor(optionsOrPort?: (TOptions | number) | undefined);
17
19
  onReady(fn: () => void): void;
18
20
  /**
19
21
  * Gracefully shuts down the server.
20
- *
21
- * @returns { Promise<void> }
22
22
  */
23
23
  stop(): Promise<void>;
24
24
  }
@@ -1,2 +1,5 @@
1
1
  import { GlobalWebRTCClient, WebRTCClient } from '../_classes/web-rtc-client-interface.class';
2
+ /**
3
+ * Orchestrates the WebRTC connection handshake between two clients.
4
+ */
2
5
  export declare const facilitateWebRTCConnection: (initiator: WebRTCClient | GlobalWebRTCClient, remoteClient: GlobalWebRTCClient) => Promise<void>;
@@ -2,7 +2,7 @@ import type { NetworkAgentRedisService } from '@flux/mesh/store/redis/network-ag
2
2
  import { NetworkUsageRedisCacheService } from '@flux/mesh/store/redis/network-usage';
3
3
  import type { TAddress, TClientId, TAgentOwnUId, TNetworkId_S } from '@flux/shared/types';
4
4
  import type { TFluxClientUID } from '@flux/shared/utils';
5
- export declare class NetworkAgentManager {
5
+ export declare class NetworkAgentRedisCache {
6
6
  readonly networkAgentRedisService: NetworkAgentRedisService;
7
7
  readonly networkUsageRedisCacheService: NetworkUsageRedisCacheService;
8
8
  private readonly redisConnection;
@@ -12,13 +12,15 @@ export declare class NetworkAgentManager {
12
12
  /**
13
13
  * Register an agent.
14
14
  *
15
- * @param { TNetworkId_S } networkId
16
- * @param { TClientId } id
17
- * @param { Bun.SocketAddress | null } ip
18
- * @param { TAddress } address
19
- * @param { TAgentOwnUId } [uid]
15
+ * @param { TNetworkId_S } networkId - The network ID
16
+ * @param { TClientId } id - The client socket ID
17
+ * @param { Bun.SocketAddress | null } ip - The client IP address
18
+ * @param { TAddress } address - The client address
19
+ * @param { object } throughput - The throughput tracking object
20
+ * @param { TAgentOwnUId } [uid] - Optional agent UID
21
+ * @param { TFluxClientUID } [machineUID] - Optional machine UID
20
22
  *
21
- * @returns { void }
23
+ * @returns { Promise<void> }
22
24
  */
23
25
  registerAgent(networkId: TNetworkId_S, id: TClientId, ip: Bun.SocketAddress | null, address: TAddress, throughput: {
24
26
  bytes: number;
@@ -27,12 +29,20 @@ export declare class NetworkAgentManager {
27
29
  /**
28
30
  * Unregisters a network agent UID and associated data from the Redis hash.
29
31
  *
30
- * @param { TNetworkId_S } networkId
31
- * @param { TClientId } clientId
32
- * @param { TAgentOwnUId } clientOwnUId
32
+ * @param { TNetworkId_S } networkId - The network ID
33
+ * @param { TClientId } clientId - The client socket ID
34
+ * @param { TAgentOwnUId } [clientOwnUId] - Optional agent UID
33
35
  *
34
36
  * @returns { void }
35
37
  */
36
38
  unregisterNetworkAgent(networkId: TNetworkId_S, clientId: TClientId, clientOwnUId?: TAgentOwnUId): void;
39
+ /**
40
+ * Resolves the network client address by an agent's UID, using a local cache to avoid unnecessary Redis calls.
41
+ *
42
+ * @param { TNetworkId_S } networkId - The network ID
43
+ * @param { TAgentOwnUId } clientOwnUId - The agent UID to look up
44
+ *
45
+ * @returns { Promise<TAddress> } The resolved address
46
+ */
37
47
  resolveNetworkClientAddressByUid(networkId: TNetworkId_S, clientOwnUId: TAgentOwnUId): Promise<TAddress>;
38
48
  }
@@ -0,0 +1,49 @@
1
+ import { type TAddress, type TClientId, type TNetworkId_S } from '@flux/shared/types';
2
+ import type { TFluxClientUID } from '@flux/shared/utils';
3
+ export declare class NetworkAuthorityRedisCache {
4
+ private readonly redisConnection;
5
+ private readonly cache;
6
+ /**
7
+ * Registers a network authority.
8
+ *
9
+ * @param { TNetworkId_S } networkId - The network ID to register on
10
+ * @param { TClientId } socketId - The socket ID of the authority
11
+ * @param { TFluxClientUID } [machineUID] - Optional machine UID
12
+ *
13
+ * @returns { Promise<void> }
14
+ */
15
+ register(networkId: TNetworkId_S, socketId: TClientId, machineUID?: TFluxClientUID): Promise<void>;
16
+ /**
17
+ * Unregisters a network authority from the local network.
18
+ *
19
+ * @param { TNetworkId_S } networkId - The network ID
20
+ * @param { TAddress } networkAuthorityAddress - The address of the authority to unregister
21
+ *
22
+ * @returns { void }
23
+ */
24
+ unregister(networkId: TNetworkId_S, networkAuthorityAddress: TAddress): void;
25
+ /**
26
+ * Used for cleanup, in case of discovering an idle authority.
27
+ *
28
+ * @param { TNetworkId_S } networkId - The network ID
29
+ * @param { TAddress } networkAuthorityAddress - The address of the authority to unregister globally
30
+ *
31
+ * @returns { void }
32
+ */
33
+ unregisterGlobal(networkId: TNetworkId_S, networkAuthorityAddress: TAddress): void;
34
+ /**
35
+ * Resolves a random network authority address for a given network ID.
36
+ *
37
+ * @param { TNetworkId_S } networkId - The network ID to resolve an authority for
38
+ *
39
+ * @returns { Promise<TAddress> } The resolved authority address
40
+ */
41
+ resolveNetworkAuthorityAddressOrThrow(networkId: TNetworkId_S): Promise<TAddress>;
42
+ /**
43
+ * Removes a client from the cache and unregisters it globally.
44
+ *
45
+ * @param { TNetworkId_S } networkId - The network ID
46
+ * @param { TAddress } networkAuthorityAddress - The address of the unresponsive client
47
+ */
48
+ removeUnresponsiveClient(networkId: TNetworkId_S, networkAuthorityAddress: TAddress): void;
49
+ }
@@ -1,9 +1,19 @@
1
1
  import type { TMachineAddress, TProcessId, TProcessAddress } from '@flux/shared/types';
2
+ /**
3
+ * Returns the current process ID.
4
+ *
5
+ * @returns { TProcessId } The current process ID
6
+ */
2
7
  export declare const readProcessId: () => TProcessId;
8
+ /**
9
+ * Returns the current machine's network address.
10
+ *
11
+ * @returns { TMachineAddress } The current machine's network address
12
+ */
3
13
  export declare const readMachineAddress: () => TMachineAddress;
4
14
  /**
5
15
  * Returns the process address.
6
16
  *
7
- * @returns { TProcessAddress }
17
+ * @returns { TProcessAddress } The current process address
8
18
  */
9
19
  export declare const readProcessAddress: () => TProcessAddress;
@@ -10,25 +10,25 @@ import type { RedisConnection } from '../redis/redis-connection.class';
10
10
  export type TGlobalChannel = string & {
11
11
  __brand: 'global-channel';
12
12
  };
13
+ type TWebsocketData = {};
13
14
  export declare class GlobalChannelPubsub {
14
15
  private readonly redisConnection;
15
16
  private readonly bunServer;
16
17
  private readonly processAddress;
17
- constructor(redisConnection: RedisConnection, bunServer: Bun.Server, processAddress: TProcessAddress);
18
+ constructor(redisConnection: RedisConnection, bunServer: Bun.Server<TWebsocketData>, processAddress: TProcessAddress);
18
19
  /**
19
20
  * Subscribes to the websocket channel event and publishes it on the local process.
20
- *
21
- * @returns { void }
22
21
  */
23
22
  private subscribeWebsocketChannelEvent;
24
23
  /**
25
24
  * Publishes a message to the given channel.
26
25
  *
27
- * @param { string } channel
28
- * @param { string } message
29
- * @param { TConnectedClientSocket } [ws]
26
+ * @param { string } channel - The channel name to publish to
27
+ * @param { string } message - The message to publish
28
+ * @param { TConnectedClientSocket } [ws] - Optional websocket to skip when publishing locally
30
29
  *
31
30
  * @returns { Promise<void> }
32
31
  */
33
32
  publish(channel: string, message: string, ws?: TConnectedClientSocket): Promise<void>;
34
33
  }
34
+ export {};
@@ -9,11 +9,10 @@ export declare class OutgoingMessageRouter {
9
9
  private readonly redisConnection;
10
10
  constructor(passToLocalClientOrThrowUnknownClient: (clientId: TClientId, message: string) => void);
11
11
  /**
12
+ * Routes a message to the correct destination.
12
13
  *
13
- * @param address
14
- * @param message
15
- *
16
- * @returns
14
+ * @param { TAddress } address - The destination address
15
+ * @param { string } message - The message to route
17
16
  */
18
17
  message(address: TAddress, message: string): void;
19
18
  }
@@ -11,18 +11,14 @@ export declare class ProcessMessageRouter {
11
11
  /**
12
12
  * Sends a message to a process.
13
13
  *
14
- * @param { TProcessAddress } address
15
- * @param { string } message
16
- *
17
- * @returns
14
+ * @param { TProcessAddress } address - The destination process address
15
+ * @param { string } message - The message to route
18
16
  */
19
17
  message(address: TProcessAddress, message: string): void;
20
18
  /**
21
- * Subscribe to mesaages for local process.
22
- *
23
- * @param message
19
+ * Subscribes to messages for the local process.
24
20
  *
25
- * @returns { void }
21
+ * @param { TCallbackFunction } onMessage - Callback to invoke when a message is received
26
22
  */
27
23
  subscribe(onMessage: TCallbackFunction): void;
28
24
  }
@@ -0,0 +1,11 @@
1
+ import type { TClientId, TChannelName, TProcessAddress } from '@flux/shared/types';
2
+ export type TMessageConstruct = `${TProcessAddress}:nc-on-pub:${TClientId}:${TChannelName}:${string}`;
3
+ export interface ISplitMessageResult {
4
+ clientId: TClientId;
5
+ channelName: TChannelName;
6
+ data: string;
7
+ }
8
+ /**
9
+ * Splits a raw message string into its components: clientId, channelName, and data.
10
+ */
11
+ export declare const splitOrThrowMessage: (rawMessage: TMessageConstruct) => ISplitMessageResult;