@casual-simulation/aux-vm-client
Version:
A set of utilities required to securely run an AUX as a client.
133 lines • 5.5 kB
JavaScript
import { AuthenticatedConnectionClient, InstRecordsClient, InstRecordsClientTimeSyncConnection, } from '@casual-simulation/aux-common';
import { ApiGatewayWebsocketConnectionClient } from '@casual-simulation/aux-websocket-aws';
import { WebsocketConnectionClient } from '@casual-simulation/aux-websocket';
import { OtherPlayersPartitionImpl, RemoteYjsPartitionImpl, } from '@casual-simulation/aux-common';
import { SocketManager as WebSocketManager } from '@casual-simulation/websocket';
import { TimeSyncController } from '@casual-simulation/timesync';
import { RemoteYjsSharedDocument } from '@casual-simulation/aux-common/documents/RemoteYjsSharedDocument';
const DEFAULT_RESEND_UPDATES_INTERVAL_MS = 1000;
const DEFAULT_RETRY_UPDATES_AFTER_MS = 5000;
/**
* A map of hostnames to CausalRepoClients.
* Helps prevent duplicating websocket connections to the same host.
*/
let awsApiaryClientCache = new Map();
/**
* A map of hostnames to CausalRepoClients.
* Helps prevent duplicating websocket connections to the same host.
*/
let websocketClientCache = new Map();
/**
* Gets the causal repo client that should be used for the given host.
* @param host The host.
*/
export function getClientForHostAndProtocol(host, authSource, protocol) {
if (protocol === 'apiary-aws') {
return getAWSApiaryClientForHostAndProtocol(host, authSource);
}
else {
return getWebSocketClientForHost(host, authSource);
}
}
function constructInstRecordsClientWithRetry(connection) {
const client = new InstRecordsClient(connection);
client.resendUpdatesAfterMs = DEFAULT_RETRY_UPDATES_AFTER_MS;
client.resendUpdatesIntervalMs = DEFAULT_RESEND_UPDATES_INTERVAL_MS;
return client;
}
/**
* Gets the casual repo client that should be used for the given host when connecting over the AWS Apiary protocol.
* @param host The URl that should be connected to.
* @param user The user that the connection should be made with.
*/
export function getAWSApiaryClientForHostAndProtocol(host, authSource) {
let client = awsApiaryClientCache.get(host);
if (!client) {
const url = new URL(host);
if (url.protocol === 'http:') {
url.protocol = 'ws:';
}
else if (url.protocol === 'https:') {
url.protocol = 'wss:';
}
const manager = new WebSocketManager(url);
manager.init();
const awsConnection = new ApiGatewayWebsocketConnectionClient(manager.socket);
const connection = new AuthenticatedConnectionClient(awsConnection, authSource);
client = constructInstRecordsClientWithRetry(connection);
awsApiaryClientCache.set(host, client);
connection.connect();
}
return client;
}
/**
* Gets the causal repo client that should be used for the given host when connecting over the websocket protocol.
* @param host The host.
*/
export function getWebSocketClientForHost(host, authSource) {
let client = websocketClientCache.get(host);
if (!client) {
const url = new URL('/websocket', host);
if (url.protocol === 'http:') {
url.protocol = 'ws:';
}
else if (url.protocol === 'https:') {
url.protocol = 'wss:';
}
const manager = new WebSocketManager(url);
manager.init();
const inner = new WebsocketConnectionClient(manager.socket);
const connection = new AuthenticatedConnectionClient(inner, authSource);
client = constructInstRecordsClientWithRetry(connection);
websocketClientCache.set(host, client);
connection.connect();
}
return client;
}
/**
* Attempts to create a CausalTree2Partition from the given config.
* @param config The config.
*/
export async function createRemoteYjsPartition(config, authSource, useCache = true) {
if (config.type === 'remote_yjs') {
const client = getClientForHostAndProtocol(config.host, authSource, config.connectionProtocol);
const partition = new RemoteYjsPartitionImpl(client, authSource, config);
await partition.init();
return partition;
}
return undefined;
}
/**
* Attempts to create a RemoteYjsSharedDocument from the given config.
* @param config The config.
* @param authSource The auth source.
*/
export async function createRemoteYjsSharedDocument(config, authSource) {
if (config.inst) {
const client = getClientForHostAndProtocol(config.host, authSource, config.connectionProtocol);
const partition = new RemoteYjsSharedDocument(client, authSource, config);
await partition.init();
return partition;
}
return undefined;
}
/**
* Attempts to create a CausalTree2Partition from the given config.
* @param config The config.
*/
export async function createOtherPlayersRepoPartition(config, authSource, useCache = true) {
if (config.type === 'other_players_repo') {
const client = getClientForHostAndProtocol(config.host, authSource, config.connectionProtocol);
const partition = new OtherPlayersPartitionImpl(client, authSource, config);
return partition;
}
return undefined;
}
export function createTimeSyncController(config, authSource) {
if (config.host) {
const client = getClientForHostAndProtocol(config.host, authSource, config.connectionProtocol);
return new TimeSyncController(new InstRecordsClientTimeSyncConnection(client));
}
return undefined;
}
//# sourceMappingURL=PartitionFactories.js.map