UNPKG

@web5/agent

Version:
90 lines 4.82 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { CryptoUtils } from '@web5/crypto'; import { createJsonRpcRequest, createJsonRpcSubscriptionRequest } from './json-rpc.js'; import { JsonRpcSocket } from './json-rpc-socket.js'; export class WebSocketDwnRpcClient { get transportProtocols() { return ['ws:', 'wss:']; } sendDwnRequest(request, jsonRpcSocketOptions) { return __awaiter(this, void 0, void 0, function* () { // validate that the dwn URL provided is a valid WebSocket URL const url = new URL(request.dwnUrl); if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { throw new Error(`Invalid websocket protocol ${url.protocol}`); } // check if there is already a connection to this host, if it does not exist, initiate a new connection const hasConnection = WebSocketDwnRpcClient.connections.has(url.host); if (!hasConnection) { try { const socket = yield JsonRpcSocket.connect(url.toString(), jsonRpcSocketOptions); const subscriptions = new Map(); WebSocketDwnRpcClient.connections.set(url.host, { socket, subscriptions }); } catch (error) { throw new Error(`Error connecting to ${url.host}: ${error.message}`); } } const connection = WebSocketDwnRpcClient.connections.get(url.host); const { targetDid, message, subscriptionHandler } = request; if (subscriptionHandler) { return WebSocketDwnRpcClient.subscriptionRequest(connection, targetDid, message, subscriptionHandler); } return WebSocketDwnRpcClient.processMessage(connection, targetDid, message); }); } static processMessage(connection, target, message) { return __awaiter(this, void 0, void 0, function* () { const requestId = CryptoUtils.randomUuid(); const request = createJsonRpcRequest(requestId, 'dwn.processMessage', { target, message }); const { socket } = connection; const response = yield socket.request(request); const { error, result } = response; if (error !== undefined) { throw new Error(`error sending DWN request: ${error.message}`); } return result.reply; }); } static subscriptionRequest(connection, target, message, messageHandler) { return __awaiter(this, void 0, void 0, function* () { const requestId = CryptoUtils.randomUuid(); const subscriptionId = CryptoUtils.randomUuid(); const request = createJsonRpcSubscriptionRequest(requestId, 'dwn.processMessage', subscriptionId, { target, message }); const { socket, subscriptions } = connection; const { response, close } = yield socket.subscribe(request, (response) => { const { result, error } = response; if (error) { // if there is an error, close the subscription and delete it from the connection const subscription = subscriptions.get(subscriptionId); if (subscription) { subscription.close(); } subscriptions.delete(subscriptionId); return; } const { event } = result; messageHandler(event); }); const { error, result } = response; if (error) { throw new Error(`could not subscribe via jsonrpc socket: ${error.message}`); } const { reply } = result; if (reply.subscription && close) { subscriptions.set(subscriptionId, Object.assign(Object.assign({}, reply.subscription), { close })); reply.subscription.close = close; } return reply; }); } } // a map of dwn host to WebSocket connection WebSocketDwnRpcClient.connections = new Map(); //# sourceMappingURL=web-socket-clients.js.map