48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
// Module-level singleton holding the active relay tunnel client, if the runtime
|
|||
|
|
// is in relay mode. Kept in its own module so runtime-switch, runtime-fetch,
|
||
|
|
// runtime-url, and the event pipeline can all read it without an import cycle
|
||
|
|
// (runtime-switch <-> runtime-url).
|
||
|
|
|
||
|
|
import { createRelayTunnelClient, type RelayTunnelClient } from './tunnel-client';
|
||
|
|
|
||
|
|
export interface RelayRuntimeDescriptor {
|
||
|
|
relayUrl: string;
|
||
|
|
serverId: string;
|
||
|
|
hostEncPubJwk: JsonWebKey;
|
||
|
|
grant?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
let activeTunnel: RelayTunnelClient | null = null;
|
||
|
|
let activeDescriptor: RelayRuntimeDescriptor | null = null;
|
||
|
|
|
||
|
|
const descriptorsEqual = (a: RelayRuntimeDescriptor, b: RelayRuntimeDescriptor): boolean =>
|
||
|
|
a.relayUrl === b.relayUrl &&
|
||
|
|
a.serverId === b.serverId &&
|
||
|
|
a.grant === b.grant &&
|
||
|
|
JSON.stringify(a.hostEncPubJwk) === JSON.stringify(b.hostEncPubJwk);
|
||
|
|
|
||
|
|
export const getActiveRelayTunnel = (): RelayTunnelClient | null => activeTunnel;
|
||
|
|
|
||
|
|
export const isRelayModeActive = (): boolean => activeTunnel !== null;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Activates relay mode with the given descriptor, replacing any previous tunnel.
|
||
|
|
* Reuses the existing client when the descriptor is unchanged so a redundant
|
||
|
|
* runtime switch does not tear down a live tunnel.
|
||
|
|
*/
|
||
|
|
export const activateRelayTunnel = (descriptor: RelayRuntimeDescriptor): RelayTunnelClient => {
|
||
|
|
if (activeTunnel && activeDescriptor && descriptorsEqual(activeDescriptor, descriptor)) {
|
||
|
|
return activeTunnel;
|
||
|
|
}
|
||
|
|
activeTunnel?.close();
|
||
|
|
activeDescriptor = descriptor;
|
||
|
|
activeTunnel = createRelayTunnelClient(descriptor);
|
||
|
|
return activeTunnel;
|
||
|
|
};
|
||
|
|
|
||
|
|
export const deactivateRelayTunnel = (): void => {
|
||
|
|
activeTunnel?.close();
|
||
|
|
activeTunnel = null;
|
||
|
|
activeDescriptor = null;
|
||
|
|
};
|