/** * * Agora Real Time Engagement * Created by Wei Hu in 2022-04. * Copyright (c) 2022 Agora IO. All rights reserved. * */ import * as log from '../common/logger'; import { Extension } from '../extension/extension'; import { RTE } from '../rte/rte'; import rte_addon from '../rte_addon'; const rtes: Record = {}; export function ExportRte() { return function ( target: Extension, _key: string | symbol, descriptor: TypedPropertyDescriptor< (rte: RTE, ...args: unknown[]) => Promise >, ): TypedPropertyDescriptor<(rte: RTE, ...args: unknown[]) => Promise> { const originalFunction = descriptor.value; if (originalFunction) { descriptor.value = function ( this: Extension, rte: RTE, ...args: unknown[] ): Promise { if (!(target instanceof Extension)) { throw new Error( 'ExportRte should apply to a Extension member function.', ); } const extension_unique_name_in_graph = rte_addon.rte_nodejs_rte_extension_unique_name_in_graph(rte); log.info( `Register the RTE object of the extension[\ ${extension_unique_name_in_graph}].`, ); // Register the RTE object to the global mapping table 'rtes'. // CAUTION: The extensions in different extension groups may have the // same name, so we cannot directly use the name of the extension as // the key. rtes[extension_unique_name_in_graph] = rte; return originalFunction.apply(this, [ rte, ...args ]); }; } return descriptor; }; } export function deleteRte(rte: RTE): boolean { const key = (Object.keys(rtes) as Array).find( (key) => rtes[key] === rte, ); if (key) { return delete rtes[key]; } return false; } // Get the exported RTE object. export async function getExportedRte( extension_name: string, extension_group_name: string, timeout = 10, /* seconds */ ): Promise { const period = 300; let waiting = 0; const extension_unique_name_in_graph = `${extension_group_name}::\ ${extension_name}`; return new Promise((resolve, reject) => { if (rtes[extension_unique_name_in_graph] !== undefined) { resolve(rtes[extension_unique_name_in_graph]); } else { const timerId = setInterval((): void => { if (rtes[extension_unique_name_in_graph] !== undefined) { clearInterval(timerId); resolve(rtes[extension_unique_name_in_graph]); } waiting += period; if (waiting >= timeout * 1000) { clearInterval(timerId); log.warn( `Failed to get exported rte of extension[\ ${extension_unique_name_in_graph}], there are [${Object.keys( rtes, )}] already registered.`, ); reject( new Error( `The extension[${extension_unique_name_in_graph}] is not ready \ after ${timeout} seconds, or make sure that the extension starts with \ '@ExportRte()'.`, ), ); } }, period); } }); }