UNPKG

@open-condo/bridge

Version:

A library that allows the client of your mini-application to communicate with the main user's client on different devices, using a common bridge API

224 lines (213 loc) 7.1 kB
/****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } const NO_RESPONSE_TIMEOUT_MS = 1000; // 1 sec const NO_RESPONSE_ERROR = { errorType: 'client', errorCode: 5, errorReason: 'TIMEOUT_REACHED', errorMessage: `Request was failed. Response was not received in ${NO_RESPONSE_TIMEOUT_MS} ms timeout.`, }; function* createCounter() { let counter = 0; while (true) { yield counter++; } } function createRequestResolver() { const requestIdCounter = createCounter(); const controllers = {}; return { add(controller, customId) { const requestId = customId || requestIdCounter.next().value; controllers[requestId] = controller; return requestId; }, resolve(requestId, data, isSuccess) { const controller = controllers[requestId]; if (controller) { if (isSuccess(data)) { controller.resolve(data); } else { controller.reject(data); } delete controllers[requestId]; } }, }; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types function promisifySend(send, subscribe) { const requestResolver = createRequestResolver(); subscribe((event) => { if (!event || !event.data || typeof event.data !== 'object') { return; } if ('requestId' in event.data) { const _a = event.data, { requestId } = _a, data = __rest(_a, ["requestId"]); if (typeof requestId !== 'undefined') { requestResolver.resolve(requestId, data, (data) => !('errorType' in data)); } } }); return function promisifiedSend(method, params = {}) { return Promise.race([ new Promise((resolve, reject) => { const requestId = requestResolver.add({ resolve, reject }, params.requestId); send(method, Object.assign(Object.assign({}, params), { requestId })); }), new Promise((resolve, reject) => { setTimeout(() => reject(NO_RESPONSE_ERROR), NO_RESPONSE_TIMEOUT_MS); }), ]); }; } var name = "@open-condo/bridge"; var description = "A library that allows the client of your mini-application to communicate with the main user's client on different devices, using a common bridge API "; var keywords = [ "condo", "open-condo-software", "client", "bridge" ]; var version = "2.0.0"; var repository = { type: "git", url: "git+https://github.com/open-condo-software/condo.git", directory: "packages/bridge" }; var author = { name: "Matthew Savelev", email: "matthew@doma.ai", url: "https://github.com/SavelevMatthew" }; var license = "MIT"; var files = [ "dist" ]; var main = "dist/index.js"; var module = "dist/index.es.js"; var browser = "dist/index.umd.js"; var types = "dist/types/src/index.d.ts"; var scripts = { build: "rm -rf dist && NODE_ENV=production rollup -c", watch: "rollup -c -w" }; var publishConfig = { access: "public" }; var devDependencies = { "@open-condo/tsconfig": "^1.0.4", "@rollup/plugin-typescript": "^11.0.0", rollup: "^4.28.0", "rollup-plugin-babel": "^4.3.3", "rollup-plugin-bundle-size": "^1.0.3", "rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-json": "^4.0.0", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-uglify": "^6.0.4", tslib: "^2.4.1", typescript: "^5.8.3" }; var pkg = { name: name, description: description, keywords: keywords, version: version, repository: repository, author: author, license: license, files: files, main: main, module: module, browser: browser, types: types, scripts: scripts, publishConfig: publishConfig, devDependencies: devDependencies }; const IS_CLIENT_SIDE = typeof window !== 'undefined'; // TODO(DOMA-5084): add mobile clients env checks const IS_BROWSER_CLIENT = IS_CLIENT_SIDE; const WEB_SPECIFIC_METHODS = [ 'CondoWebAppCloseModalWindow', 'CondoWebAppGetActiveProgressBars', 'CondoWebAppGetLaunchParams', 'CondoWebAppRedirect', 'CondoWebAppRequestAuth', 'CondoWebAppResizeWindow', 'CondoWebAppShowModalWindow', 'CondoWebAppShowNotification', 'CondoWebAppShowProgressBar', 'CondoWebAppUpdateModalWindow', 'CondoWebAppUpdateProgressBar', ]; const ALL_METHODS = [ ...(IS_BROWSER_CLIENT ? WEB_SPECIFIC_METHODS : []), ]; const webBridge = IS_BROWSER_CLIENT ? parent : undefined; function createCondoBridge() { const subscribers = []; function send(method, params) { if (webBridge && typeof webBridge.postMessage === 'function') { // nosemgrep: javascript.browser.security.wildcard-postmessage-configuration.wildcard-postmessage-configuration webBridge.postMessage({ handler: method, params, type: 'condo-bridge', version: pkg.version, }, '*'); } } function supports(method) { return ALL_METHODS.includes(method); } function subscribe(listener) { subscribers.push(listener); } function unsubscribe(listener) { const idx = subscribers.indexOf(listener); if (idx >= 0) { subscribers.splice(idx, 1); } } function handleResponseEvent(event) { const response = event.data; if (typeof response !== 'object') { return; } subscribers.forEach(listener => listener(response)); } if (IS_BROWSER_CLIENT && 'addEventListener' in window) { window.addEventListener('message', handleResponseEvent); } return { send: promisifySend(send, subscribe), supports, subscribe, unsubscribe, }; } const bridge = createCondoBridge(); export { bridge as default }; //# sourceMappingURL=index.es.js.map