UNPKG

@simplito/privmx-webendpoint

Version:

PrivMX Web Endpoint library

283 lines (280 loc) 11.5 kB
"use strict"; /*! PrivMX Web Endpoint. Copyright © 2024 Simplito sp. z o.o. This file is part of the PrivMX Platform (https://privmx.dev). This software is Licensed under the PrivMX Free License. See the License for the specific language governing permissions and limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.EndpointFactory = void 0; const Api_1 = require("../api/Api"); const ApiStatic_1 = require("../api/ApiStatic"); const ConnectionNative_1 = require("../api/ConnectionNative"); const CryptoApiNative_1 = require("../api/CryptoApiNative"); const EventApiNative_1 = require("../api/EventApiNative"); const EventQueueNative_1 = require("../api/EventQueueNative"); const InboxApiNative_1 = require("../api/InboxApiNative"); const KvdbApiNative_1 = require("../api/KvdbApiNative"); const StoreApiNative_1 = require("../api/StoreApiNative"); const StreamApiNative_1 = require("../api/StreamApiNative"); const ThreadApiNative_1 = require("../api/ThreadApiNative"); const FinalizationHelper_1 = require("../FinalizationHelper"); const WebRtcClient_1 = require("../webStreams/WebRtcClient"); const Connection_1 = require("./Connection"); const CryptoApi_1 = require("./CryptoApi"); const EventApi_1 = require("./EventApi"); const EventQueue_1 = require("./EventQueue"); const InboxApi_1 = require("./InboxApi"); const KvdbApi_1 = require("./KvdbApi"); const StoreApi_1 = require("./StoreApi"); const StreamApi_1 = require("./StreamApi"); const ThreadApi_1 = require("./ThreadApi"); /** * Contains static factory methods - generators for Connection and APIs. */ class EndpointFactory { static api; static eventQueueInstance; static assetsBasePath; /** * Load the Endpoint's WASM assets and initialize the Endpoint library. * * @param {string} [assetsBasePath] base path/url to the Endpoint's WebAssembly assets (like: endpoint-wasm-module.js, driver-web-context.js and others) */ static async setup(assetsBasePath) { const basePath = this.resolveAssetsBasePath(assetsBasePath); this.assetsBasePath = basePath; const assets = ["driver-web-context.js", "endpoint-wasm-module.js"]; for (const asset of assets) { await this.loadScript(this.buildAssetUrl(basePath, asset)); } const lib = await endpointWasmModule(); EndpointFactory.init(lib); } static resolveAssetsBasePath(assetsBasePath) { if (assetsBasePath != null) { return this.normalizeBasePath(assetsBasePath); } return "/"; } static normalizeBasePath(path) { const trimmed = path.trim(); if (trimmed === "" || trimmed === "/") { return "/"; } if (/^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(trimmed)) { return trimmed.replace(/\/+$/, ""); } const resolved = new URL(trimmed.replace(/\/+$/, "") + "/", document.baseURI).href; return resolved.replace(/\/+$/, ""); } static buildAssetUrl(basePath, asset) { const fileName = asset.replace(/^\/+/, ""); if (basePath === "/") { return `/${fileName}`; } return new URL(fileName, basePath.endsWith("/") ? basePath : `${basePath}/`).href; } static async loadScript(url) { return new Promise((resolve) => { const head = document.getElementsByTagName("head")[0]; const script = document.createElement("script"); script.type = "text/javascript"; script.src = url; script.onload = () => { resolve(); }; head.appendChild(script); }); } /** * //doc-gen:ignore */ static init(lib) { this.api = new Api_1.Api(lib); ApiStatic_1.ApiStatic.init(this.api); FinalizationHelper_1.FinalizationHelper.init(lib); } /** * Gets the EventQueue instance. * * @returns {EventQueue} instance of EventQueue */ static async getEventQueue() { if (!this.eventQueueInstance) { const nativeApi = new EventQueueNative_1.EventQueueNative(this.api); const ptr = await nativeApi.newEventQueue(); this.eventQueueInstance = new EventQueue_1.EventQueue(nativeApi, ptr); } return this.eventQueueInstance; } static generateDefaultPKIVerificationOptions() { return { bridgeInstanceId: undefined, bridgePubKey: undefined, }; } /** * Connects to the platform backend. * * @param {string} userPrivKey user's private key * @param {string} solutionId ID of the Solution * @param {string} bridgeUrl the Bridge Server URL * @param {PKIVerificationOptions} [verificationOptions] PrivMX Bridge server instance verification options using a PKI server * @returns {Connection} instance of Connection */ static async connect(userPrivKey, solutionId, bridgeUrl, verificationOptions) { const nativeApi = new ConnectionNative_1.ConnectionNative(this.api); const ptr = await nativeApi.newConnection(); await nativeApi.connect(ptr, [ userPrivKey, solutionId, bridgeUrl, verificationOptions || this.generateDefaultPKIVerificationOptions(), ]); return new Connection_1.Connection(nativeApi, ptr); } /** * Connects to the Platform backend as a guest user. * * @param {string} solutionId ID of the Solution * @param {string} bridgeUrl the Bridge Server URL * @param {PKIVerificationOptions} [verificationOptions] PrivMX Bridge server instance verification options using a PKI server * @returns {Connection} instance of Connection */ static async connectPublic(solutionId, bridgeUrl, verificationOptions) { const nativeApi = new ConnectionNative_1.ConnectionNative(this.api); const ptr = await nativeApi.newConnection(); await nativeApi.connectPublic(ptr, [ solutionId, bridgeUrl, verificationOptions || this.generateDefaultPKIVerificationOptions(), ]); return new Connection_1.Connection(nativeApi, ptr); } /** * Creates an instance of the Thread API. * * @param {Connection} connection instance of Connection * * @returns {ThreadApi} instance of ThreadApi */ static async createThreadApi(connection) { if ("threads" in connection.apisRefs) { throw new Error("ThreadApi already registered for given connection."); } const nativeApi = new ThreadApiNative_1.ThreadApiNative(this.api); const ptr = await nativeApi.newApi(connection.servicePtr); await nativeApi.create(ptr, []); connection.apisRefs["threads"] = { _apiServicePtr: ptr }; connection.nativeApisDeps["threads"] = nativeApi; return new ThreadApi_1.ThreadApi(nativeApi, ptr); } /** * Creates an instance of the Store API. * * @param {Connection} connection instance of Connection * * @returns {StoreApi} instance of StoreApi */ static async createStoreApi(connection) { if ("stores" in connection.apisRefs) { throw new Error("StoreApi already registered for given connection."); } const nativeApi = new StoreApiNative_1.StoreApiNative(this.api); const ptr = await nativeApi.newApi(connection.servicePtr); connection.apisRefs["stores"] = { _apiServicePtr: ptr }; connection.nativeApisDeps["stores"] = nativeApi; await nativeApi.create(ptr, []); return new StoreApi_1.StoreApi(nativeApi, ptr); } /** * Creates an instance of the Inbox API. * * @param {Connection} connection instance of Connection * @param {ThreadApi} threadApi instance of ThreadApi * @param {StoreApi} storeApi instance of StoreApi * @returns {InboxApi} instance of InboxApi */ static async createInboxApi(connection, threadApi, storeApi) { if ("inboxes" in connection.apisRefs) { throw new Error("InboxApi already registered for given connection."); } const nativeApi = new InboxApiNative_1.InboxApiNative(this.api); const ptr = await nativeApi.newApi(connection.servicePtr, threadApi.servicePtr, storeApi.servicePtr); await nativeApi.create(ptr, []); connection.apisRefs["inboxes"] = { _apiServicePtr: ptr }; connection.nativeApisDeps["inboxes"] = nativeApi; return new InboxApi_1.InboxApi(nativeApi, ptr); } /** * Creates an instance of the Kvdb API. * * @param {Connection} connection instance of Connection * * @returns {KvdbApi} instance of KvdbApi */ static async createKvdbApi(connection) { if ("kvdbs" in connection.apisRefs) { throw new Error("KvdbApi already registered for given connection."); } const nativeApi = new KvdbApiNative_1.KvdbApiNative(this.api); const ptr = await nativeApi.newApi(connection.servicePtr); await nativeApi.create(ptr, []); connection.apisRefs["kvdbs"] = { _apiServicePtr: ptr }; connection.nativeApisDeps["kvdbs"] = nativeApi; return new KvdbApi_1.KvdbApi(nativeApi, ptr); } /** * Creates an instance of the Crypto API. * * @returns {CryptoApi} instance of CryptoApi */ static async createCryptoApi() { const nativeApi = new CryptoApiNative_1.CryptoApiNative(this.api); const ptr = await nativeApi.newApi(); await nativeApi.create(ptr, []); return new CryptoApi_1.CryptoApi(nativeApi, ptr); } /** * Creates an instance of 'EventApi'. * * @param connection instance of 'Connection' * * @returns {EventApi} instance of EventApi */ static async createEventApi(connection) { if ("events" in connection.apisRefs) { throw new Error("EventApi already registered for given connection."); } const nativeApi = new EventApiNative_1.EventApiNative(this.api); const ptr = await nativeApi.newApi(connection.servicePtr); await nativeApi.create(ptr, []); connection.apisRefs["events"] = { _apiServicePtr: ptr }; connection.nativeApisDeps["events"] = nativeApi; return new EventApi_1.EventApi(nativeApi, ptr); } /** * Creates an instance of the Stream API. * * @param {Connection} connection instance of Connection * @param {EventApi} eventApi instance of EventApi * @param {StoreApi} storeApi instance of StoreApi * @returns {StreamApi} instance of StreamApi */ static async createStreamApi(connection, eventApi) { if ("streams" in connection.apisRefs) { throw new Error("StreamApi already registered for given connection."); } const webRtcClient = new WebRtcClient_1.WebRtcClient(this.assetsBasePath); const nativeApi = new StreamApiNative_1.StreamApiNative(this.api, webRtcClient); const ptr = await nativeApi.newApi(connection.servicePtr, eventApi.servicePtr); await nativeApi.create(ptr, []); connection.apisRefs["streams"] = { _apiServicePtr: ptr }; connection.nativeApisDeps["streams"] = nativeApi; return new StreamApi_1.StreamApi(nativeApi, ptr, webRtcClient); } } exports.EndpointFactory = EndpointFactory;