UNPKG

message-port-api

Version:

A simple package that allows you to simplify the use of `MessagePort API` more easily (Worker, IFrame...)

123 lines (118 loc) 3.82 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/index.ts function isRequest(data) { return data && "id" in data && "arguments" in data; } function isResponseResult(data) { return data && "id" in data && "result" in data; } function isResponseError(data) { return data && "id" in data && "error" in data; } function useValue(value) { return typeof value === "function" ? value() : value; } function useReceive(sender, receiver) { if (!receiver && "postMessage" in sender) receiver = sender; const handlers = /* @__PURE__ */ new Set(); function receive(controllers, targetOrigin) { function handler(_0) { return __async(this, arguments, function* ({ data }) { if (isRequest(data)) { if (data.name in controllers) { const controller = controllers[data.name]; try { const responseResult = { id: data.id, name: data.name, result: yield controller(...data.arguments) }; useValue(receiver).postMessage(responseResult, targetOrigin); } catch (err) { const responseError = { id: data.id, name: data.name, error: err + "" }; useValue(receiver).postMessage(responseError, targetOrigin); } } else { const responseError = { id: data.id, name: data.name, error: "NOT_FOUND_ERR" }; useValue(receiver).postMessage(responseError, targetOrigin); } } }); } useValue(sender).addEventListener("message", handler); handlers.add(handler); return controllers; } receive.cancel = () => { const senderVal = useValue(sender); handlers.forEach((handler) => { senderVal.removeEventListener("message", handler); }); }; return receive; } function useSend(sender, receiver, timeout = 3e4) { if (!receiver && "postMessage" in sender) receiver = sender; function send(name, args, targetOrigin) { const id = Math.random().toString(34).slice(2); return new Promise( (resolve, reject) => { const request = { id, name, arguments: args }; useValue(sender).addEventListener("message", handler); const timer = !timeout ? void 0 : setTimeout(() => { reject("TIME_OUT"); useValue(sender).removeEventListener("message", handler); }, timeout); function handler({ data }) { if (isResponseResult(data) && data.id === id && data.name === name) { timer && clearTimeout(timer); resolve(data.result); useValue(sender).removeEventListener("message", handler); return; } if (isResponseError(data) && data.id === id && data.name === name) { timer && clearTimeout(timer); reject(data.error); useValue(sender).removeEventListener("message", handler); } } useValue(receiver).postMessage(request, targetOrigin); } ); } return send; } exports.useReceive = useReceive; exports.useSend = useSend;