UNPKG

react-native-webview-comlink

Version:

Add JavaScript interface for react-native-webview, based on Comlink

119 lines (118 loc) 3.52 kB
var __rest = (this && this.__rest) || function (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; }; import { generateID } from './utils'; export function toWireValue(value, channel) { // proxy function if (typeof value === 'function') { let id = channel.tryGetLocalFuntionID(value); if (!id) { id = generateID(); } const vid = generateID(); channel.registerLocalFunction(id, vid, value); return { type: "P" /* PROXY */, id, vid, }; } if (value instanceof Error) { const { message, name, stack } = value, rest = __rest(value, ["message", "name", "stack"]); return { type: "R" /* RAW */, val: Object.assign({ message }, rest), }; } // raw value return { type: "R" /* RAW */, val: value, }; } export function fromWireValue(value, channel) { switch (value.type) { case "R" /* RAW */: return value.val; case "P" /* PROXY */: const { id, vid } = value; let remoteFunction = channel.tryGetRemoteFunction(id); if (remoteFunction) { remoteFunction.addRef(vid); } else { remoteFunction = createRemoteFunction(id, vid, channel); channel.registerRemoteFunction(id, remoteFunction); } return remoteFunction; case "T" /* THROW */: const _a = value.val, { message } = _a, rest = __rest(_a, ["message"]); return Object.assign(new Error(message), rest); default: return undefined; } } export function createRemoteFunction(id, vid, channel) { let refCount = 1; let latestVid = vid; const cleanup = () => { if (refCount <= 0) { return; } refCount = 0; channel.unregisterRemoteFunction(id); channel.notifyRelease({ type: "RLS" /* RELEASE */, id, vid: latestVid, }); }; return Object.assign((...args) => { return channel .requestResponse({ type: "REQ" /* REQUEST */, id, rid: generateID(), args: args.map((arg) => toWireValue(arg, channel)), }) .then((response) => { if (!response) { return; } const value = fromWireValue(response, channel); if (value instanceof Error) { throw value; } return value; }); }, { addRef: (vid) => { if (refCount <= 0) { return 0; } latestVid = vid; refCount += 1; return refCount; }, release: () => { if (refCount <= 0) { return 0; } if (refCount === 1) { cleanup(); return refCount; } refCount -= 1; return refCount; }, cleanup, }); }