async-call-rpc
Advanced tools
Comparing version 3.3.0 to 4.0.0
@@ -5,2 +5,13 @@ # Changelog | ||
## [4.0.0](https://github.com/Jack-Works/async-call/compare/v3.3.0...v4.0.0) (2020-07-19) | ||
### ⚠ BREAKING CHANGES | ||
* remove support for deprecated messageChannel | ||
### Features | ||
* remove support for deprecated messageChannel ([e6681f7](https://github.com/Jack-Works/async-call/commit/e6681f7a13624d955b98e9e10c38db73a652a6fa)) | ||
## [3.3.0](https://github.com/Jack-Works/async-call/compare/v3.2.2...v3.3.0) (2020-07-19) | ||
@@ -7,0 +18,0 @@ |
@@ -79,2 +79,5 @@ /** | ||
* @public | ||
* @example | ||
* | ||
* [Example for EventBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/node/websocket.server.ts). | ||
*/ | ||
@@ -99,2 +102,5 @@ interface EventBasedChannel<Data = unknown> { | ||
* @public | ||
* @example | ||
* | ||
* [Example for CallbackBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/web/websocket.client.ts). | ||
*/ | ||
@@ -164,22 +170,2 @@ interface CallbackBasedChannel<Data = unknown> extends Partial<EventBasedChannel<Data>> { | ||
/** | ||
* The message channel interface that allows | ||
* @public | ||
* @deprecated Will be removed in the next major version. | ||
*/ | ||
interface MessageChannel<Context = unknown> { | ||
/** | ||
* AsyncCall will attach a listener to receive messages. | ||
* @param event - The emitting event name (if supported). | ||
* @param eventListener - The listener have two parameters. The first one is the received data. The second one is an identifier to identify who send this request. When responding, AsyncCall will call the emit with the same context. | ||
*/ | ||
on(event: string, eventListener: (data: unknown, context?: Context) => void): void; | ||
/** | ||
* AsyncCall will send message by this method. | ||
* @param event - The emitting event name (if supported). | ||
* @param data - The sending data. | ||
* @param context - The same context provided to the second parameter of on.eventListener. | ||
*/ | ||
emit(event: string, data: unknown, context?: Context): void; | ||
} | ||
/** | ||
* Options for {@link AsyncCall} | ||
@@ -190,10 +176,4 @@ * @public | ||
/** | ||
* A key to prevent collision with other AsyncCalls. | ||
* | ||
* @remarks | ||
* The value can be anything, but need to be same on both sides if you're using the deprecated MessageChannel interface. | ||
* If you're using other recommended interface for channel like EventBasedChannel or CallbackBasedChannel, | ||
* this option will only used for better logging. | ||
* | ||
* @defaultValue `default-jsonrpc` | ||
* This option will only used for better logging. | ||
* @defaultValue `jsonrpc` | ||
*/ | ||
@@ -225,22 +205,9 @@ key?: string; | ||
* @example | ||
* ```ts | ||
* const channel = { | ||
* on(event, callback) { | ||
* document.addEventListener('remote-data', x => callback(x.details)) | ||
* } | ||
* emit(event, data) { | ||
* fetch('/server', { body: data }) | ||
* } | ||
* } | ||
* ``` | ||
* [Example for CallbackBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/web/websocket.client.ts). | ||
* [Example for EventBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/node/websocket.server.ts). | ||
* @remarks | ||
* If you're using this new property, you can use "messageChannel: undefined!" to disable the type system error. | ||
* If you're using this new property, you can use "" to disable the type system error. | ||
*/ | ||
channel?: CallbackBasedChannel | EventBasedChannel; | ||
channel: CallbackBasedChannel | EventBasedChannel; | ||
/** | ||
* Leave this option "undefined!" if you're providing channel. | ||
* @deprecated renamed to "channel". In next major version, this option will be removed and the "channel" property will be required. | ||
*/ | ||
messageChannel: MessageChannel | CallbackBasedChannel | EventBasedChannel; | ||
/** | ||
* Choose log level. See {@link AsyncCallLogLevel} | ||
@@ -340,2 +307,2 @@ * @defaultValue true | ||
export { AsyncCall, AsyncCallLogLevel, AsyncCallOptions, AsyncCallStrictJSONRPC, CallbackBasedChannel, Console, ErrorMapFunction, EventBasedChannel, JSONSerialization, MessageChannel, NoSerialization, Serialization, _AsyncVersionOf, _IgnoreResponse, batch, notify }; | ||
export { AsyncCall, AsyncCallLogLevel, AsyncCallOptions, AsyncCallStrictJSONRPC, CallbackBasedChannel, Console, ErrorMapFunction, EventBasedChannel, JSONSerialization, NoSerialization, Serialization, _AsyncVersionOf, _IgnoreResponse, batch, notify }; |
/// <reference types="./base.d.ts" /> | ||
((e,r)=>{"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((e=e||self).AsyncCall={})})(this,(function(e){"use strict";class r extends Error{constructor(e,r,t,n){super(r),this.name=e,this.code=t,this.stack=n}}const t={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError};function n(e=""){return e.replace(/^.+\n.+\n/,"")}const o=(()=>{const e=Reflect.get(globalThis,"DOMException");if("function"==typeof e)return e})();function i(e,r,t,n){void 0===e&&(e=null),Number.isNaN(r=Math.floor(r))&&(r=-1);const o={jsonrpc:"2.0",id:e,error:{code:r,message:t,data:n}};return d(o.error,"data"),o}function a(e,r,t){const{id:n}=e,{code:o,message:a,data:s}=t(r,e);return i(n,o,a,s)}i.ParseError=(e,r)=>{const t=a({},e,r),n=t.error;return n.code=-32700,n.message="Parse error",t},i.InvalidRequest=e=>i(e,-32600,"Invalid Request"),i.MethodNotFound=e=>i(e,-32601,"Method not found");const s=(e="",r=-1)=>t=>{let n="";l(t)&&u(t,"message")&&"string"==typeof t.message&&(n=t.message);let i=((e,r)=>{let n="Error";try{n=null===(i=null===(o=t)||void 0===o?void 0:o.constructor)||void 0===i?void 0:i.name}catch(o){}var o,i;return"string"!=typeof n?"Error":n})();return o&&t instanceof o&&(i="DOMException:"+t.name),"string"!=typeof t&&"number"!=typeof t&&"boolean"!=typeof t&&"bigint"!=typeof t||(i="Error",n=t+""),{code:r,message:n,data:e?{stack:e,type:i}:{type:i}}};function c(e){if(!l(e))return!1;if(!u(e,"jsonrpc"))return!1;if("2.0"!==e.jsonrpc)return!1;if(u(e,"params")){const r=e.params;if(!Array.isArray(r)&&!l(r))return!1}return!0}function l(e){return"object"==typeof e&&null!==e}function u(e,r){return r in e}function d(e,r){void 0===e[r]&&delete e[r]}const f={serialization:e=>e,deserialization:e=>e},p=Symbol.for("AsyncCall/ignored"),y=Symbol.for("AsyncCall/notify"),m=Symbol.for("AsyncCall/batch");function h(e,r){return e[r][y]}async function g(e,r,t,o){return new Promise((i,a)=>{var s;let c={};try{c=document.createElement("iframe"),c.style.display="none",document.body.appendChild(c);{const s=c.contentDocument,l=c.contentWindow,u=s.createElement("button");s.body.appendChild(u),u.onclick=()=>new l.Promise(a=>{(async()=>{e(n(Error().stack)),i(await r.apply(t,o))})().then(a)}),l.onunhandledrejection=e=>a(e.reason),u.click()}}catch(e){try{console.error("Please close preservePauseOnException.",e)}catch(e){}return i(r(...o))}finally{null===(s=null==c?void 0:c.remove)||void 0===s||s.call(c)}})}const v={serializer:f,key:"default-jsonrpc",strict:!0,log:!0,parameterStructures:"by-position",preferLocalImplementation:!1,preservePauseOnException:!1,idGenerator:()=>Math.random().toString(36).slice(2)};e.AsyncCall=function(e={},f){var h;let E=void 0;e instanceof Promise||(E=e),Promise.resolve(e).then(e=>E=e);const{serializer:b,key:w,strict:k,log:P,parameterStructures:$,preferLocalImplementation:S,preservePauseOnException:C,idGenerator:A,mapError:j,logger:x,channel:O,channel:z}={...v,...f},{methodNotFound:M=!1,unknownMessage:R=!1}=(e=>"boolean"!=typeof e?e:{methodNotFound:e,unknownMessage:e})(k),{beCalled:N=!0,localError:I=!0,remoteError:T=!0,type:D="pretty",sendLocalStack:F=!1,requestReplay:W=!1}=(e=>"boolean"!=typeof e?e:{beCalled:e,localError:e,remoteError:e,type:e?"pretty":"basic"})(P),q=(e=>{const r=e||globalThis.console,t=(...e)=>r.log(...e);return Object.assign({},{debug:t,error:t,groupCollapsed:t,groupEnd:t,log:t,warn:t},r)})(x),J=z||O;if(O&&!z&&q.warn("Deprecation: messageChannel has renamed to channel"),!J)throw Error();const L=new Map;async function B(e){var r;let t;try{if(t=await b.deserialization(e),c(t))return await Q(t);if(Array.isArray(t)&&t.every(c)&&0!==t.length){const e=await Promise.all(t.map(Q));if(t.every(e=>void 0===e))return;return e.filter(e=>e)}return R?i.InvalidRequest(null!==(r=t.id)&&void 0!==r?r:null):void 0}catch(e){return I&&q.error(e,t,void 0),i.ParseError(e,j||s(null==e?void 0:e.stack))}}async function G(e){if(e){if(Array.isArray(e)){const r=e.filter(e=>u(e,"id"));if(0===r.length)return;return b.serialization(r)}if(u(e,"id"))return b.serialization(e)}}function U(e){return u(e,"send")&&"function"==typeof e.send}if(u(_=J,"emit")&&"function"==typeof _.emit)q.warn("The interface you're using in channel is deprecated. Please switch to EventBasedChannel or CallbackBasedChannel"),J.on(w,async(e,r)=>{const t=await B(e);t&&J.emit(w,t,r)});else if((e=>u(e,"setup")&&"function"==typeof e.setup)(J))J.setup(e=>B(e).then(G),e=>{const r=b.deserialization(e);return!!c(r)||Promise.resolve(r).then(c)});else if(!U(J))throw new TypeError("Invalid channel");var _;if(U(J)){const e=J;null===(h=e.on)||void 0===h||h.call(e,r=>B(r).then(G).then(r=>r&&e.send(r)))}return new Proxy({},{get(e,r){let t=n(Error().stack);const o=e=>(...n)=>{let o=void 0;if(r===m&&(o=n.shift(),r=n.shift()),"symbol"==typeof r){const e=Symbol.keyFor(r)||r.description;if(e){if(!e.startsWith("rpc."))return Promise.reject('[AsyncCall] An internal method must start with "rpc."');r=e}}else if(r.startsWith("rpc."))return Promise.reject(new TypeError("[AsyncCall] Can't call internal methods directly"));if(S&&E&&"string"==typeof r){const e=E[r];if(e&&"function"==typeof e)return new Promise(r=>r(e(...n)))}return new Promise((i,a)=>{const s=A(),[c]=n,u=F?t:"",f="by-name"===$&&1===n.length&&l(c)?c:n,p=((e,r,t,n)=>{const o={jsonrpc:"2.0",id:e,method:r,params:t,remoteStack:n};return d(o,"id"),((e,r)=>{e[r]||delete e[r]})(o,"remoteStack"),o})(e?void 0:s,r,f,u);if(o?(o.push(p),o.r||(o.r=[()=>H(o),K.bind(o)])):H(p).catch(a),e)return i();L.set(s,{f:[i,a],stack:t})})},i=o(!1);return i[y]=o(!0),i[y][y]=i[y],i}});async function H(e){const r=await b.serialization(e);return u(J,"emit")?J.emit(w,r):J.send(r)}function K(e){var r;for(const t of this)u(t,"id")&&(null===(r=L.get(t.id))||void 0===r||r.f[1](e))}async function Q(c){return u(c,"method")?async function(r){E||await e;let t="";try{const e=r.method.startsWith("rpc.")?Symbol.for(r.method):r.method,o=E[e];if("function"!=typeof o)return M?i.MethodNotFound(r.id):void(I&&q.debug("Receive remote call, but not implemented.",e,r));const{params:a}=r,s=Array.isArray(a)?a:[a];t=n(Error().stack);const c=C?g(e=>t=e,o,E,s):new Promise(e=>e(o.apply(E,s)));if(N)if("basic"===D)q.log(`${w}.${r.method}(${""+[...s]}) @${r.id}`);else{const e=[`${w}.%c${r.method}%c(${s.map(()=>"%o").join(", ")}%c)\n%o %c@${r.id}`,"color: #d2c057","",...s,"",c,"color: gray; font-style: italic;"];W&&e.push(()=>{debugger;return o.apply(E,s)}),r.remoteStack?(q.groupCollapsed(...e),q.log(r.remoteStack),q.groupEnd()):q.log(...e)}if(await c===p)return;return((e,r)=>{const t={jsonrpc:"2.0",id:e,result:r};return d(t,"id"),t})(r.id,await c)}catch(e){return"object"==typeof e&&"stack"in e&&(e.stack=t.split("\n").reduce((e,r)=>e.replace(r+"\n",""),e.stack||"")),I&&q.error(e),a(r,e,j||s(F?e.stack:void 0))}}(c):async function(e){let n="",i="",a=0,s="Error";if(u(e,"error")){const r=e.error;n=r.message,a=r.code;const t=r.data;i=l(t)&&u(t,"stack")&&"string"==typeof t.stack?t.stack:"<remote stack not available>",s=l(t)&&u(t,"type")&&"string"==typeof t.type?t.type:"Error",T&&("basic"===D?q.error(`${s}: ${n}(${a}) @${e.id}\n${i}`):q.error(`${s}: ${n}(${a}) %c@${e.id}\n%c${i}`,"color: gray",""))}if(null===e.id||void 0===e.id)return;const{f:[c,d],stack:f}=L.get(e.id)||{stack:"",f:[null,null]};c&&(L.delete(e.id),u(e,"error")?d(((e,n,i,a)=>{try{if(e.startsWith("DOMException:")&&o){const[,r]=e.split("DOMException:");return new o(n,r)}if(e in t){const r=new t[e](n);return r.stack=a,Object.assign(r,{code:i}),r}return new r(e,n,i,a)}catch(r){return Error(`E${i} ${e}: ${n}\n${a}`)}})(s,n,a,i+"\n аt AsyncCall (rpc) \n"+f)):c(e.result))}(c)}},e.JSONSerialization=(e=[void 0,void 0],r,t="null")=>({serialization(n){if(t&&l(n)&&u(n,"result")&&void 0===n.result){const e=Object.assign({},n);e.result=null,"keep"===t&&(e.undef=!0),n=e}return JSON.stringify(n,e[0],r)},deserialization(r){const t=JSON.parse(r,e[1]);return l(t)&&u(t,"result")&&null===t.result&&u(t,"undef")&&!0===t.undef&&(t.result=void 0,delete t.undef),t}}),e.NoSerialization=f,e.batch=e=>{let r=[];return[new Proxy(e,{get(e,t){const n=(...n)=>e[m](r,t,...n);return(n[y]=(...n)=>e[m][y](r,t,...n))[y]=n[y],n}}),()=>{var e;return null===(e=r.r)||void 0===e?void 0:e[0]()},(e=Error("Aborted"))=>{var t;null===(t=r.r)||void 0===t||t[1](e),r=[]}]},e.notify=e=>"function"==typeof e?e[y]:new Proxy(e,{get:h}),Object.defineProperty(e,"__esModule",{value:!0})})); | ||
((e,r)=>{"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((e=e||self).AsyncCall={})})(this,(function(e){"use strict";class r extends Error{constructor(e,r,t,n){super(r),this.name=e,this.code=t,this.stack=n}}const t={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError};function n(e=""){return e.replace(/^.+\n.+\n/,"")}const o=(()=>{const e=Reflect.get(globalThis,"DOMException");if("function"==typeof e)return e})();function i(e,r,t,n){void 0===e&&(e=null),Number.isNaN(r=Math.floor(r))&&(r=-1);const o={jsonrpc:"2.0",id:e,error:{code:r,message:t,data:n}};return d(o.error,"data"),o}function s(e,r,t){const{id:n}=e,{code:o,message:s,data:a}=t(r,e);return i(n,o,s,a)}i.ParseError=(e,r)=>{const t=s({},e,r),n=t.error;return n.code=-32700,n.message="Parse error",t},i.InvalidRequest=e=>i(e,-32600,"Invalid Request"),i.MethodNotFound=e=>i(e,-32601,"Method not found");const a=(e="",r=-1)=>t=>{let n="";l(t)&&u(t,"message")&&"string"==typeof t.message&&(n=t.message);let i=((e,r)=>{let n="Error";try{n=null===(i=null===(o=t)||void 0===o?void 0:o.constructor)||void 0===i?void 0:i.name}catch(o){}var o,i;return"string"!=typeof n?"Error":n})();return o&&t instanceof o&&(i="DOMException:"+t.name),"string"!=typeof t&&"number"!=typeof t&&"boolean"!=typeof t&&"bigint"!=typeof t||(i="Error",n=t+""),{code:r,message:n,data:e?{stack:e,type:i}:{type:i}}};function c(e){if(!l(e))return!1;if(!u(e,"jsonrpc"))return!1;if("2.0"!==e.jsonrpc)return!1;if(u(e,"params")){const r=e.params;if(!Array.isArray(r)&&!l(r))return!1}return!0}function l(e){return"object"==typeof e&&null!==e}function u(e,r){return r in e}function d(e,r){void 0===e[r]&&delete e[r]}const f={serialization:e=>e,deserialization:e=>e},p=Symbol.for("AsyncCall/ignored"),y=Symbol.for("AsyncCall/notify"),m=Symbol.for("AsyncCall/batch");function g(e,r){return e[r][y]}async function h(e,r,t,o){return new Promise((i,s)=>{var a;let c={};try{c=document.createElement("iframe"),c.style.display="none",document.body.appendChild(c);{const a=c.contentDocument,l=c.contentWindow,u=a.createElement("button");a.body.appendChild(u),u.onclick=()=>new l.Promise(s=>{(async()=>{e(n(Error().stack)),i(await r.apply(t,o))})().then(s)}),l.onunhandledrejection=e=>s(e.reason),u.click()}}catch(e){try{console.error("Please close preservePauseOnException.",e)}catch(e){}return i(r(...o))}finally{null===(a=null==c?void 0:c.remove)||void 0===a||a.call(c)}})}const v={serializer:f,key:"jsonrpc",strict:!0,log:!0,parameterStructures:"by-position",preferLocalImplementation:!1,preservePauseOnException:!1,idGenerator:()=>Math.random().toString(36).slice(2)};e.AsyncCall=function(e={},f){var g;let E=void 0;e instanceof Promise||(E=e),Promise.resolve(e).then(e=>E=e);const{serializer:b,key:k,strict:w,log:P,parameterStructures:$,preferLocalImplementation:S,preservePauseOnException:A,idGenerator:j,mapError:x,logger:C,channel:O}={...v,...f},{methodNotFound:z=!1,unknownMessage:M=!1}=(e=>"boolean"!=typeof e?e:{methodNotFound:e,unknownMessage:e})(w),{beCalled:R=!0,localError:N=!0,remoteError:I=!0,type:D="pretty",sendLocalStack:F=!1,requestReplay:T=!1}=(e=>"boolean"!=typeof e?e:{beCalled:e,localError:e,remoteError:e,type:e?"pretty":"basic"})(P),W=(e=>{const r=e||globalThis.console,t=(...e)=>r.log(...e);return Object.assign({},{debug:t,error:t,groupCollapsed:t,groupEnd:t,log:t,warn:t},r)})(C),q=new Map;async function J(e){var r;let t;try{if(t=await b.deserialization(e),c(t))return await B(t);if(Array.isArray(t)&&t.every(c)&&0!==t.length){const e=await Promise.all(t.map(B));if(t.every(e=>void 0===e))return;return e.filter(e=>e)}return M?i.InvalidRequest(null!==(r=t.id)&&void 0!==r?r:null):void 0}catch(e){return N&&W.error(e,t,void 0),i.ParseError(e,x||a(null==e?void 0:e.stack))}}async function L(e){if(e){if(Array.isArray(e)){const r=e.filter(e=>u(e,"id"));if(0===r.length)return;return b.serialization(r)}if(u(e,"id"))return b.serialization(e)}}var G;if(u(G=O,"setup")&&"function"==typeof G.setup&&O.setup(e=>J(e).then(L),e=>{const r=b.deserialization(e);return!!c(r)||Promise.resolve(r).then(c)}),(e=>u(e,"send")&&"function"==typeof e.send)(O)){const e=O;null===(g=e.on)||void 0===g||g.call(e,r=>J(r).then(L).then(r=>r&&e.send(r)))}return new Proxy({},{get(e,r){let t=n(Error().stack);const o=e=>(...n)=>{let o=void 0;if(r===m&&(o=n.shift(),r=n.shift()),"symbol"==typeof r){const e=Symbol.keyFor(r)||r.description;if(e){if(!e.startsWith("rpc."))return Promise.reject('[AsyncCall] An internal method must start with "rpc."');r=e}}else if(r.startsWith("rpc."))return Promise.reject(new TypeError("[AsyncCall] Can't call internal methods directly"));if(S&&E&&"string"==typeof r){const e=E[r];if(e&&"function"==typeof e)return new Promise(r=>r(e(...n)))}return new Promise((i,s)=>{const a=j(),[c]=n,u=F?t:"",f="by-name"===$&&1===n.length&&l(c)?c:n,p=((e,r,t,n)=>{const o={jsonrpc:"2.0",id:e,method:r,params:t,remoteStack:n};return d(o,"id"),((e,r)=>{e[r]||delete e[r]})(o,"remoteStack"),o})(e?void 0:a,r,f,u);if(o?(o.push(p),o.r||(o.r=[()=>U(o),_.bind(o)])):U(p).catch(s),e)return i();q.set(a,{f:[i,s],stack:t})})},i=o(!1);return i[y]=o(!0),i[y][y]=i[y],i}});async function U(e){const r=await b.serialization(e);return O.send(r)}function _(e){var r;for(const t of this)u(t,"id")&&(null===(r=q.get(t.id))||void 0===r||r.f[1](e))}async function B(c){return u(c,"method")?async function(r){E||await e;let t="";try{const e=r.method.startsWith("rpc.")?Symbol.for(r.method):r.method,o=E[e];if("function"!=typeof o)return z?i.MethodNotFound(r.id):void(N&&W.debug("Receive remote call, but not implemented.",e,r));const{params:s}=r,a=Array.isArray(s)?s:[s];t=n(Error().stack);const c=A?h(e=>t=e,o,E,a):new Promise(e=>e(o.apply(E,a)));if(R)if("basic"===D)W.log(`${k}.${r.method}(${""+[...a]}) @${r.id}`);else{const e=[`${k}.%c${r.method}%c(${a.map(()=>"%o").join(", ")}%c)\n%o %c@${r.id}`,"color: #d2c057","",...a,"",c,"color: gray; font-style: italic;"];T&&e.push(()=>{debugger;return o.apply(E,a)}),r.remoteStack?(W.groupCollapsed(...e),W.log(r.remoteStack),W.groupEnd()):W.log(...e)}if(await c===p)return;return((e,r)=>{const t={jsonrpc:"2.0",id:e,result:r};return d(t,"id"),t})(r.id,await c)}catch(e){return"object"==typeof e&&"stack"in e&&(e.stack=t.split("\n").reduce((e,r)=>e.replace(r+"\n",""),e.stack||"")),N&&W.error(e),s(r,e,x||a(F?e.stack:void 0))}}(c):async function(e){let n="",i="",s=0,a="Error";if(u(e,"error")){const r=e.error;n=r.message,s=r.code;const t=r.data;i=l(t)&&u(t,"stack")&&"string"==typeof t.stack?t.stack:"<remote stack not available>",a=l(t)&&u(t,"type")&&"string"==typeof t.type?t.type:"Error",I&&("basic"===D?W.error(`${a}: ${n}(${s}) @${e.id}\n${i}`):W.error(`${a}: ${n}(${s}) %c@${e.id}\n%c${i}`,"color: gray",""))}if(null===e.id||void 0===e.id)return;const{f:[c,d],stack:f}=q.get(e.id)||{stack:"",f:[null,null]};c&&(q.delete(e.id),u(e,"error")?d(((e,n,i,s)=>{try{if(e.startsWith("DOMException:")&&o){const[,r]=e.split("DOMException:");return new o(n,r)}if(e in t){const r=new t[e](n);return r.stack=s,Object.assign(r,{code:i}),r}return new r(e,n,i,s)}catch(r){return Error(`E${i} ${e}: ${n}\n${s}`)}})(a,n,s,i+"\n аt AsyncCall (rpc) \n"+f)):c(e.result))}(c)}},e.JSONSerialization=(e=[void 0,void 0],r,t="null")=>({serialization(n){if(t&&l(n)&&u(n,"result")&&void 0===n.result){const e=Object.assign({},n);e.result=null,"keep"===t&&(e.undef=!0),n=e}return JSON.stringify(n,e[0],r)},deserialization(r){const t=JSON.parse(r,e[1]);return l(t)&&u(t,"result")&&null===t.result&&u(t,"undef")&&!0===t.undef&&(t.result=void 0,delete t.undef),t}}),e.NoSerialization=f,e.batch=e=>{let r=[];return[new Proxy(e,{get(e,t){const n=(...n)=>e[m](r,t,...n);return(n[y]=(...n)=>e[m][y](r,t,...n))[y]=n[y],n}}),()=>{var e;return null===(e=r.r)||void 0===e?void 0:e[0]()},(e=Error("Aborted"))=>{var t;null===(t=r.r)||void 0===t||t[1](e),r=[]}]},e.notify=e=>"function"==typeof e?e[y]:new Proxy(e,{get:g}),Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=base.js.map |
@@ -79,2 +79,5 @@ /** | ||
* @public | ||
* @example | ||
* | ||
* [Example for EventBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/node/websocket.server.ts). | ||
*/ | ||
@@ -99,2 +102,5 @@ interface EventBasedChannel<Data = unknown> { | ||
* @public | ||
* @example | ||
* | ||
* [Example for CallbackBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/web/websocket.client.ts). | ||
*/ | ||
@@ -164,22 +170,2 @@ interface CallbackBasedChannel<Data = unknown> extends Partial<EventBasedChannel<Data>> { | ||
/** | ||
* The message channel interface that allows | ||
* @public | ||
* @deprecated Will be removed in the next major version. | ||
*/ | ||
interface MessageChannel<Context = unknown> { | ||
/** | ||
* AsyncCall will attach a listener to receive messages. | ||
* @param event - The emitting event name (if supported). | ||
* @param eventListener - The listener have two parameters. The first one is the received data. The second one is an identifier to identify who send this request. When responding, AsyncCall will call the emit with the same context. | ||
*/ | ||
on(event: string, eventListener: (data: unknown, context?: Context) => void): void; | ||
/** | ||
* AsyncCall will send message by this method. | ||
* @param event - The emitting event name (if supported). | ||
* @param data - The sending data. | ||
* @param context - The same context provided to the second parameter of on.eventListener. | ||
*/ | ||
emit(event: string, data: unknown, context?: Context): void; | ||
} | ||
/** | ||
* Options for {@link AsyncCall} | ||
@@ -190,10 +176,4 @@ * @public | ||
/** | ||
* A key to prevent collision with other AsyncCalls. | ||
* | ||
* @remarks | ||
* The value can be anything, but need to be same on both sides if you're using the deprecated MessageChannel interface. | ||
* If you're using other recommended interface for channel like EventBasedChannel or CallbackBasedChannel, | ||
* this option will only used for better logging. | ||
* | ||
* @defaultValue `default-jsonrpc` | ||
* This option will only used for better logging. | ||
* @defaultValue `jsonrpc` | ||
*/ | ||
@@ -225,22 +205,9 @@ key?: string; | ||
* @example | ||
* ```ts | ||
* const channel = { | ||
* on(event, callback) { | ||
* document.addEventListener('remote-data', x => callback(x.details)) | ||
* } | ||
* emit(event, data) { | ||
* fetch('/server', { body: data }) | ||
* } | ||
* } | ||
* ``` | ||
* [Example for CallbackBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/web/websocket.client.ts). | ||
* [Example for EventBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/node/websocket.server.ts). | ||
* @remarks | ||
* If you're using this new property, you can use "messageChannel: undefined!" to disable the type system error. | ||
* If you're using this new property, you can use "" to disable the type system error. | ||
*/ | ||
channel?: CallbackBasedChannel | EventBasedChannel; | ||
channel: CallbackBasedChannel | EventBasedChannel; | ||
/** | ||
* Leave this option "undefined!" if you're providing channel. | ||
* @deprecated renamed to "channel". In next major version, this option will be removed and the "channel" property will be required. | ||
*/ | ||
messageChannel: MessageChannel | CallbackBasedChannel | EventBasedChannel; | ||
/** | ||
* Choose log level. See {@link AsyncCallLogLevel} | ||
@@ -395,2 +362,2 @@ * @defaultValue true | ||
export { AsyncCall, AsyncCallLogLevel, AsyncCallOptions, AsyncCallStrictJSONRPC, AsyncGeneratorCall, CallbackBasedChannel, Console, ErrorMapFunction, EventBasedChannel, JSONSerialization, MessageChannel, NoSerialization, Serialization, _AsyncGeneratorVersionOf, _AsyncVersionOf, _IgnoreResponse, _UnboxPromise, batch, notify }; | ||
export { AsyncCall, AsyncCallLogLevel, AsyncCallOptions, AsyncCallStrictJSONRPC, AsyncGeneratorCall, CallbackBasedChannel, Console, ErrorMapFunction, EventBasedChannel, JSONSerialization, NoSerialization, Serialization, _AsyncGeneratorVersionOf, _AsyncVersionOf, _IgnoreResponse, _UnboxPromise, batch, notify }; |
/// <reference types="./full.d.ts" /> | ||
((e,r)=>{"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((e=e||self).AsyncCall={})})(this,(function(e){"use strict";class r extends Error{constructor(e,r,t,n){super(r),this.name=e,this.code=t,this.stack=n}}const t={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError};function n(e=""){return e.replace(/^.+\n.+\n/,"")}const o=(()=>{const e=Reflect.get(globalThis,"DOMException");if("function"==typeof e)return e})();function i(e,r,t,n){void 0===e&&(e=null),Number.isNaN(r=Math.floor(r))&&(r=-1);const o={jsonrpc:"2.0",id:e,error:{code:r,message:t,data:n}};return d(o.error,"data"),o}function a(e,r,t){const{id:n}=e,{code:o,message:a,data:s}=t(r,e);return i(n,o,a,s)}i.ParseError=(e,r)=>{const t=a({},e,r),n=t.error;return n.code=-32700,n.message="Parse error",t},i.InvalidRequest=e=>i(e,-32600,"Invalid Request"),i.MethodNotFound=e=>i(e,-32601,"Method not found");const s=(e="",r=-1)=>t=>{let n="";l(t)&&u(t,"message")&&"string"==typeof t.message&&(n=t.message);let i=((e,r)=>{let n="Error";try{n=null===(i=null===(o=t)||void 0===o?void 0:o.constructor)||void 0===i?void 0:i.name}catch(o){}var o,i;return"string"!=typeof n?"Error":n})();return o&&t instanceof o&&(i="DOMException:"+t.name),"string"!=typeof t&&"number"!=typeof t&&"boolean"!=typeof t&&"bigint"!=typeof t||(i="Error",n=t+""),{code:r,message:n,data:e?{stack:e,type:i}:{type:i}}};function c(e){if(!l(e))return!1;if(!u(e,"jsonrpc"))return!1;if("2.0"!==e.jsonrpc)return!1;if(u(e,"params")){const r=e.params;if(!Array.isArray(r)&&!l(r))return!1}return!0}function l(e){return"object"==typeof e&&null!==e}function u(e,r){return r in e}function d(e,r){void 0===e[r]&&delete e[r]}const f={serialization:e=>e,deserialization:e=>e},y=Symbol.for("AsyncCall/ignored"),p=Symbol.for("AsyncCall/notify"),h=Symbol.for("AsyncCall/batch");function m(e,r){return e[r][p]}function v(){return Math.random().toString(36).slice(2)}function g(e){return"boolean"!=typeof e?e:{methodNotFound:e,unknownMessage:e}}async function w(e,r,t,o){return new Promise((i,a)=>{var s;let c={};try{c=document.createElement("iframe"),c.style.display="none",document.body.appendChild(c);{const s=c.contentDocument,l=c.contentWindow,u=s.createElement("button");s.body.appendChild(u),u.onclick=()=>new l.Promise(a=>{(async()=>{e(n(Error().stack)),i(await r.apply(t,o))})().then(a)}),l.onunhandledrejection=e=>a(e.reason),u.click()}}catch(e){try{console.error("Please close preservePauseOnException.",e)}catch(e){}return i(r(...o))}finally{null===(s=null==c?void 0:c.remove)||void 0===s||s.call(c)}})}const E={serializer:f,key:"default-jsonrpc",strict:!0,log:!0,parameterStructures:"by-position",preferLocalImplementation:!1,preservePauseOnException:!1,idGenerator:v};function b(e={},f){var m;let v=void 0;e instanceof Promise||(v=e),Promise.resolve(e).then(e=>v=e);const{serializer:b,key:k,strict:P,log:S,parameterStructures:$,preferLocalImplementation:x,preservePauseOnException:C,idGenerator:O,mapError:j,logger:A,channel:M,channel:z}={...E,...f},{methodNotFound:N=!1,unknownMessage:R=!1}=g(P),{beCalled:I=!0,localError:T=!0,remoteError:F=!0,type:D="pretty",sendLocalStack:W=!1,requestReplay:q=!1}=(e=>"boolean"!=typeof e?e:{beCalled:e,localError:e,remoteError:e,type:e?"pretty":"basic"})(S),G=(e=>{const r=e||globalThis.console,t=(...e)=>r.log(...e);return Object.assign({},{debug:t,error:t,groupCollapsed:t,groupEnd:t,log:t,warn:t},r)})(A),J=z||M;if(M&&!z&&G.warn("Deprecation: messageChannel has renamed to channel"),!J)throw Error();const L=new Map;async function B(e){var r;let t;try{if(t=await b.deserialization(e),c(t))return await V(t);if(Array.isArray(t)&&t.every(c)&&0!==t.length){const e=await Promise.all(t.map(V));if(t.every(e=>void 0===e))return;return e.filter(e=>e)}return R?i.InvalidRequest(null!==(r=t.id)&&void 0!==r?r:null):void 0}catch(e){return T&&G.error(e,t,void 0),i.ParseError(e,j||s(null==e?void 0:e.stack))}}async function U(e){if(e){if(Array.isArray(e)){const r=e.filter(e=>u(e,"id"));if(0===r.length)return;return b.serialization(r)}if(u(e,"id"))return b.serialization(e)}}function _(e){return u(e,"send")&&"function"==typeof e.send}if(u(H=J,"emit")&&"function"==typeof H.emit)G.warn("The interface you're using in channel is deprecated. Please switch to EventBasedChannel or CallbackBasedChannel"),J.on(k,async(e,r)=>{const t=await B(e);t&&J.emit(k,t,r)});else if((e=>u(e,"setup")&&"function"==typeof e.setup)(J))J.setup(e=>B(e).then(U),e=>{const r=b.deserialization(e);return!!c(r)||Promise.resolve(r).then(c)});else if(!_(J))throw new TypeError("Invalid channel");var H;if(_(J)){const e=J;null===(m=e.on)||void 0===m||m.call(e,r=>B(r).then(U).then(r=>r&&e.send(r)))}return new Proxy({},{get(e,r){let t=n(Error().stack);const o=e=>(...n)=>{let o=void 0;if(r===h&&(o=n.shift(),r=n.shift()),"symbol"==typeof r){const e=Symbol.keyFor(r)||r.description;if(e){if(!e.startsWith("rpc."))return Promise.reject('[AsyncCall] An internal method must start with "rpc."');r=e}}else if(r.startsWith("rpc."))return Promise.reject(new TypeError("[AsyncCall] Can't call internal methods directly"));if(x&&v&&"string"==typeof r){const e=v[r];if(e&&"function"==typeof e)return new Promise(r=>r(e(...n)))}return new Promise((i,a)=>{const s=O(),[c]=n,u=W?t:"",f="by-name"===$&&1===n.length&&l(c)?c:n,y=((e,r,t,n)=>{const o={jsonrpc:"2.0",id:e,method:r,params:t,remoteStack:n};return d(o,"id"),((e,r)=>{e[r]||delete e[r]})(o,"remoteStack"),o})(e?void 0:s,r,f,u);if(o?(o.push(y),o.r||(o.r=[()=>K(o),Q.bind(o)])):K(y).catch(a),e)return i();L.set(s,{f:[i,a],stack:t})})},i=o(!1);return i[p]=o(!0),i[p][p]=i[p],i}});async function K(e){const r=await b.serialization(e);return u(J,"emit")?J.emit(k,r):J.send(r)}function Q(e){var r;for(const t of this)u(t,"id")&&(null===(r=L.get(t.id))||void 0===r||r.f[1](e))}async function V(c){return u(c,"method")?async function(r){v||await e;let t="";try{const e=r.method.startsWith("rpc.")?Symbol.for(r.method):r.method,o=v[e];if("function"!=typeof o)return N?i.MethodNotFound(r.id):void(T&&G.debug("Receive remote call, but not implemented.",e,r));const{params:a}=r,s=Array.isArray(a)?a:[a];t=n(Error().stack);const c=C?w(e=>t=e,o,v,s):new Promise(e=>e(o.apply(v,s)));if(I)if("basic"===D)G.log(`${k}.${r.method}(${""+[...s]}) @${r.id}`);else{const e=[`${k}.%c${r.method}%c(${s.map(()=>"%o").join(", ")}%c)\n%o %c@${r.id}`,"color: #d2c057","",...s,"",c,"color: gray; font-style: italic;"];q&&e.push(()=>{debugger;return o.apply(v,s)}),r.remoteStack?(G.groupCollapsed(...e),G.log(r.remoteStack),G.groupEnd()):G.log(...e)}if(await c===y)return;return((e,r)=>{const t={jsonrpc:"2.0",id:e,result:r};return d(t,"id"),t})(r.id,await c)}catch(e){return"object"==typeof e&&"stack"in e&&(e.stack=t.split("\n").reduce((e,r)=>e.replace(r+"\n",""),e.stack||"")),T&&G.error(e),a(r,e,j||s(W?e.stack:void 0))}}(c):async function(e){let n="",i="",a=0,s="Error";if(u(e,"error")){const r=e.error;n=r.message,a=r.code;const t=r.data;i=l(t)&&u(t,"stack")&&"string"==typeof t.stack?t.stack:"<remote stack not available>",s=l(t)&&u(t,"type")&&"string"==typeof t.type?t.type:"Error",F&&("basic"===D?G.error(`${s}: ${n}(${a}) @${e.id}\n${i}`):G.error(`${s}: ${n}(${a}) %c@${e.id}\n%c${i}`,"color: gray",""))}if(null===e.id||void 0===e.id)return;const{f:[c,d],stack:f}=L.get(e.id)||{stack:"",f:[null,null]};c&&(L.delete(e.id),u(e,"error")?d(((e,n,i,a)=>{try{if(e.startsWith("DOMException:")&&o){const[,r]=e.split("DOMException:");return new o(n,r)}if(e in t){const r=new t[e](n);return r.stack=a,Object.assign(r,{code:i}),r}return new r(e,n,i,a)}catch(r){return Error(`E${i} ${e}: ${n}\n${a}`)}})(s,n,a,i+"\n аt AsyncCall (rpc) \n"+f)):c(e.result))}(c)}}const k=Symbol.for("rpc.async-iterator.start"),P=Symbol.for("rpc.async-iterator.next"),S=Symbol.for("rpc.async-iterator.return"),$=Symbol.for("rpc.async-iterator.throw");class x{constructor(e,r){this.r=e,this.i=r,this.d=!1,this.c=async e=>(await j(e,()=>this.d=!0),e)}async return(e){return this.d||this.c(this.r[S](await this.i,e)).catch(()=>{}),this.d=!0,A(!0,e)}async next(e){return this.d?A(!0):await this.c(this.r[P](await this.i,e))}async throw(e){if(!this.d)return await this.c(this.r[$](await this.i,e));throw e}}const C=async function*(){}.constructor.prototype;Object.setPrototypeOf(x,C);const O=Object.getPrototypeOf(async function*(){}());async function j(e,r){try{const t=await e;(null==t?void 0:t.done)&&r()}catch(e){}}function A(e,r){return{done:e,value:r}}Object.setPrototypeOf(x.prototype,O),e.AsyncCall=b,e.AsyncGeneratorCall=(e={},r)=>{var t;const n=new Map,o=g(null===(t=r.strict)||void 0===t||t),{idGenerator:i=v}=r;function a(e,r,t){const i=n.get(e);if(!i){if(o.methodNotFound)throw Error(`Iterator ${e} not found, ${r}() failed.`);return y}const a=t(i);return j(a,()=>n.delete(e)),a}const s=b({async[k](r,t){const a=Reflect.get(await e,r);if("function"!=typeof a){if(o.methodNotFound)throw Error(r+" is not a function");return y}const s=a(...t),c=i();return n.set(c,s),Promise.resolve(c)},[P]:(e,r)=>a(e,"next",e=>e.next(r)),[S]:(e,r)=>a(e,"return",e=>{var t;return null===(t=e.return)||void 0===t?void 0:t.call(e,r)}),[$]:(e,r)=>a(e,"throw",e=>{var t;return null===(t=e.throw)||void 0===t?void 0:t.call(e,r)})},r);return new Proxy({},{get:(e,r)=>{if("string"!=typeof r)throw new TypeError("[*AsyncCall] Only string can be the method name");return(...e)=>{const t=s[k](r,e);return new x(s,t)}}})},e.JSONSerialization=(e=[void 0,void 0],r,t="null")=>({serialization(n){if(t&&l(n)&&u(n,"result")&&void 0===n.result){const e=Object.assign({},n);e.result=null,"keep"===t&&(e.undef=!0),n=e}return JSON.stringify(n,e[0],r)},deserialization(r){const t=JSON.parse(r,e[1]);return l(t)&&u(t,"result")&&null===t.result&&u(t,"undef")&&!0===t.undef&&(t.result=void 0,delete t.undef),t}}),e.NoSerialization=f,e.batch=e=>{let r=[];return[new Proxy(e,{get(e,t){const n=(...n)=>e[h](r,t,...n);return(n[p]=(...n)=>e[h][p](r,t,...n))[p]=n[p],n}}),()=>{var e;return null===(e=r.r)||void 0===e?void 0:e[0]()},(e=Error("Aborted"))=>{var t;null===(t=r.r)||void 0===t||t[1](e),r=[]}]},e.notify=e=>"function"==typeof e?e[p]:new Proxy(e,{get:m}),Object.defineProperty(e,"__esModule",{value:!0})})); | ||
((r,t)=>{"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((r=r||self).AsyncCall={})})(this,(function(r){"use strict";class t extends Error{constructor(r,t,e,n){super(t),this.name=r,this.code=e,this.stack=n}}const e={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError};function n(r=""){return r.replace(/^.+\n.+\n/,"")}const o=(()=>{const r=Reflect.get(globalThis,"DOMException");if("function"==typeof r)return r})();function i(r,t,e,n){void 0===r&&(r=null),Number.isNaN(t=Math.floor(t))&&(t=-1);const o={jsonrpc:"2.0",id:r,error:{code:t,message:e,data:n}};return d(o.error,"data"),o}function s(r,t,e){const{id:n}=r,{code:o,message:s,data:a}=e(t,r);return i(n,o,s,a)}i.ParseError=(r,t)=>{const e=s({},r,t),n=e.error;return n.code=-32700,n.message="Parse error",e},i.InvalidRequest=r=>i(r,-32600,"Invalid Request"),i.MethodNotFound=r=>i(r,-32601,"Method not found");const a=(r="",t=-1)=>e=>{let n="";l(e)&&u(e,"message")&&"string"==typeof e.message&&(n=e.message);let i=((r,t)=>{let n="Error";try{n=null===(i=null===(o=e)||void 0===o?void 0:o.constructor)||void 0===i?void 0:i.name}catch(o){}var o,i;return"string"!=typeof n?"Error":n})();return o&&e instanceof o&&(i="DOMException:"+e.name),"string"!=typeof e&&"number"!=typeof e&&"boolean"!=typeof e&&"bigint"!=typeof e||(i="Error",n=e+""),{code:t,message:n,data:r?{stack:r,type:i}:{type:i}}};function c(r){if(!l(r))return!1;if(!u(r,"jsonrpc"))return!1;if("2.0"!==r.jsonrpc)return!1;if(u(r,"params")){const t=r.params;if(!Array.isArray(t)&&!l(t))return!1}return!0}function l(r){return"object"==typeof r&&null!==r}function u(r,t){return t in r}function d(r,t){void 0===r[t]&&delete r[t]}const f={serialization:r=>r,deserialization:r=>r},y=Symbol.for("AsyncCall/ignored"),p=Symbol.for("AsyncCall/notify"),h=Symbol.for("AsyncCall/batch");function m(r,t){return r[t][p]}function v(){return Math.random().toString(36).slice(2)}function g(r){return"boolean"!=typeof r?r:{methodNotFound:r,unknownMessage:r}}async function E(r,t,e,o){return new Promise((i,s)=>{var a;let c={};try{c=document.createElement("iframe"),c.style.display="none",document.body.appendChild(c);{const a=c.contentDocument,l=c.contentWindow,u=a.createElement("button");a.body.appendChild(u),u.onclick=()=>new l.Promise(s=>{(async()=>{r(n(Error().stack)),i(await t.apply(e,o))})().then(s)}),l.onunhandledrejection=r=>s(r.reason),u.click()}}catch(r){try{console.error("Please close preservePauseOnException.",r)}catch(r){}return i(t(...o))}finally{null===(a=null==c?void 0:c.remove)||void 0===a||a.call(c)}})}const b={serializer:f,key:"jsonrpc",strict:!0,log:!0,parameterStructures:"by-position",preferLocalImplementation:!1,preservePauseOnException:!1,idGenerator:v};function w(r={},f){var m;let v=void 0;r instanceof Promise||(v=r),Promise.resolve(r).then(r=>v=r);const{serializer:w,key:k,strict:P,log:S,parameterStructures:$,preferLocalImplementation:x,preservePauseOnException:O,idGenerator:j,mapError:A,logger:C,channel:M}={...b,...f},{methodNotFound:z=!1,unknownMessage:N=!1}=g(P),{beCalled:R=!0,localError:I=!0,remoteError:F=!0,type:T="pretty",sendLocalStack:D=!1,requestReplay:W=!1}=(r=>"boolean"!=typeof r?r:{beCalled:r,localError:r,remoteError:r,type:r?"pretty":"basic"})(S),q=(r=>{const t=r||globalThis.console,e=(...r)=>t.log(...r);return Object.assign({},{debug:e,error:e,groupCollapsed:e,groupEnd:e,log:e,warn:e},t)})(C),G=new Map;async function J(r){var t;let e;try{if(e=await w.deserialization(r),c(e))return await H(e);if(Array.isArray(e)&&e.every(c)&&0!==e.length){const r=await Promise.all(e.map(H));if(e.every(r=>void 0===r))return;return r.filter(r=>r)}return N?i.InvalidRequest(null!==(t=e.id)&&void 0!==t?t:null):void 0}catch(r){return I&&q.error(r,e,void 0),i.ParseError(r,A||a(null==r?void 0:r.stack))}}async function L(r){if(r){if(Array.isArray(r)){const t=r.filter(r=>u(r,"id"));if(0===t.length)return;return w.serialization(t)}if(u(r,"id"))return w.serialization(r)}}var U;if(u(U=M,"setup")&&"function"==typeof U.setup&&M.setup(r=>J(r).then(L),r=>{const t=w.deserialization(r);return!!c(t)||Promise.resolve(t).then(c)}),(r=>u(r,"send")&&"function"==typeof r.send)(M)){const r=M;null===(m=r.on)||void 0===m||m.call(r,t=>J(t).then(L).then(t=>t&&r.send(t)))}return new Proxy({},{get(r,t){let e=n(Error().stack);const o=r=>(...n)=>{let o=void 0;if(t===h&&(o=n.shift(),t=n.shift()),"symbol"==typeof t){const r=Symbol.keyFor(t)||t.description;if(r){if(!r.startsWith("rpc."))return Promise.reject('[AsyncCall] An internal method must start with "rpc."');t=r}}else if(t.startsWith("rpc."))return Promise.reject(new TypeError("[AsyncCall] Can't call internal methods directly"));if(x&&v&&"string"==typeof t){const r=v[t];if(r&&"function"==typeof r)return new Promise(t=>t(r(...n)))}return new Promise((i,s)=>{const a=j(),[c]=n,u=D?e:"",f="by-name"===$&&1===n.length&&l(c)?c:n,y=((r,t,e,n)=>{const o={jsonrpc:"2.0",id:r,method:t,params:e,remoteStack:n};return d(o,"id"),((r,t)=>{r[t]||delete r[t]})(o,"remoteStack"),o})(r?void 0:a,t,f,u);if(o?(o.push(y),o.r||(o.r=[()=>_(o),B.bind(o)])):_(y).catch(s),r)return i();G.set(a,{f:[i,s],stack:e})})},i=o(!1);return i[p]=o(!0),i[p][p]=i[p],i}});async function _(r){const t=await w.serialization(r);return M.send(t)}function B(r){var t;for(const e of this)u(e,"id")&&(null===(t=G.get(e.id))||void 0===t||t.f[1](r))}async function H(c){return u(c,"method")?async function(t){v||await r;let e="";try{const r=t.method.startsWith("rpc.")?Symbol.for(t.method):t.method,o=v[r];if("function"!=typeof o)return z?i.MethodNotFound(t.id):void(I&&q.debug("Receive remote call, but not implemented.",r,t));const{params:s}=t,a=Array.isArray(s)?s:[s];e=n(Error().stack);const c=O?E(r=>e=r,o,v,a):new Promise(r=>r(o.apply(v,a)));if(R)if("basic"===T)q.log(`${k}.${t.method}(${""+[...a]}) @${t.id}`);else{const r=[`${k}.%c${t.method}%c(${a.map(()=>"%o").join(", ")}%c)\n%o %c@${t.id}`,"color: #d2c057","",...a,"",c,"color: gray; font-style: italic;"];W&&r.push(()=>{debugger;return o.apply(v,a)}),t.remoteStack?(q.groupCollapsed(...r),q.log(t.remoteStack),q.groupEnd()):q.log(...r)}if(await c===y)return;return((r,t)=>{const e={jsonrpc:"2.0",id:r,result:t};return d(e,"id"),e})(t.id,await c)}catch(r){return"object"==typeof r&&"stack"in r&&(r.stack=e.split("\n").reduce((r,t)=>r.replace(t+"\n",""),r.stack||"")),I&&q.error(r),s(t,r,A||a(D?r.stack:void 0))}}(c):async function(r){let n="",i="",s=0,a="Error";if(u(r,"error")){const t=r.error;n=t.message,s=t.code;const e=t.data;i=l(e)&&u(e,"stack")&&"string"==typeof e.stack?e.stack:"<remote stack not available>",a=l(e)&&u(e,"type")&&"string"==typeof e.type?e.type:"Error",F&&("basic"===T?q.error(`${a}: ${n}(${s}) @${r.id}\n${i}`):q.error(`${a}: ${n}(${s}) %c@${r.id}\n%c${i}`,"color: gray",""))}if(null===r.id||void 0===r.id)return;const{f:[c,d],stack:f}=G.get(r.id)||{stack:"",f:[null,null]};c&&(G.delete(r.id),u(r,"error")?d(((r,n,i,s)=>{try{if(r.startsWith("DOMException:")&&o){const[,t]=r.split("DOMException:");return new o(n,t)}if(r in e){const t=new e[r](n);return t.stack=s,Object.assign(t,{code:i}),t}return new t(r,n,i,s)}catch(t){return Error(`E${i} ${r}: ${n}\n${s}`)}})(a,n,s,i+"\n аt AsyncCall (rpc) \n"+f)):c(r.result))}(c)}}const k=Symbol.for("rpc.async-iterator.start"),P=Symbol.for("rpc.async-iterator.next"),S=Symbol.for("rpc.async-iterator.return"),$=Symbol.for("rpc.async-iterator.throw");class x{constructor(r,t){this.r=r,this.i=t,this.d=!1,this.c=async r=>(await A(r,()=>this.d=!0),r)}async return(r){return this.d||this.c(this.r[S](await this.i,r)).catch(()=>{}),this.d=!0,C(!0,r)}async next(r){return this.d?C(!0):await this.c(this.r[P](await this.i,r))}async throw(r){if(!this.d)return await this.c(this.r[$](await this.i,r));throw r}}const O=async function*(){}.constructor.prototype;Object.setPrototypeOf(x,O);const j=Object.getPrototypeOf(async function*(){}());async function A(r,t){try{const e=await r;(null==e?void 0:e.done)&&t()}catch(r){}}function C(r,t){return{done:r,value:t}}Object.setPrototypeOf(x.prototype,j),r.AsyncCall=w,r.AsyncGeneratorCall=(r={},t)=>{var e;const n=new Map,o=g(null===(e=t.strict)||void 0===e||e),{idGenerator:i=v}=t;function s(r,t,e){const i=n.get(r);if(!i){if(o.methodNotFound)throw Error(`Iterator ${r} not found, ${t}() failed.`);return y}const s=e(i);return A(s,()=>n.delete(r)),s}const a=w({async[k](t,e){const s=Reflect.get(await r,t);if("function"!=typeof s){if(o.methodNotFound)throw Error(t+" is not a function");return y}const a=s(...e),c=i();return n.set(c,a),Promise.resolve(c)},[P]:(r,t)=>s(r,"next",r=>r.next(t)),[S]:(r,t)=>s(r,"return",r=>{var e;return null===(e=r.return)||void 0===e?void 0:e.call(r,t)}),[$]:(r,t)=>s(r,"throw",r=>{var e;return null===(e=r.throw)||void 0===e?void 0:e.call(r,t)})},t);return new Proxy({},{get:(r,t)=>{if("string"!=typeof t)throw new TypeError("[*AsyncCall] Only string can be the method name");return(...r)=>{const e=a[k](t,r);return new x(a,e)}}})},r.JSONSerialization=(r=[void 0,void 0],t,e="null")=>({serialization(n){if(e&&l(n)&&u(n,"result")&&void 0===n.result){const r=Object.assign({},n);r.result=null,"keep"===e&&(r.undef=!0),n=r}return JSON.stringify(n,r[0],t)},deserialization(t){const e=JSON.parse(t,r[1]);return l(e)&&u(e,"result")&&null===e.result&&u(e,"undef")&&!0===e.undef&&(e.result=void 0,delete e.undef),e}}),r.NoSerialization=f,r.batch=r=>{let t=[];return[new Proxy(r,{get(r,e){const n=(...n)=>r[h](t,e,...n);return(n[p]=(...n)=>r[h][p](t,e,...n))[p]=n[p],n}}),()=>{var r;return null===(r=t.r)||void 0===r?void 0:r[0]()},(r=Error("Aborted"))=>{var e;null===(e=t.r)||void 0===e||e[1](r),t=[]}]},r.notify=r=>"function"==typeof r?r[p]:new Proxy(r,{get:m}),Object.defineProperty(r,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=full.js.map |
{ | ||
"name": "async-call-rpc", | ||
"version": "3.3.0", | ||
"version": "4.0.0", | ||
"description": "A lightweight JSON RPC server & client", | ||
@@ -5,0 +5,0 @@ "main": "out/base.js", |
@@ -75,3 +75,3 @@ # Async Call | ||
// create a server | ||
AsyncCall(server, { channel, messageChannel: undefined! }) | ||
AsyncCall(server, { channel }) | ||
``` | ||
@@ -83,3 +83,3 @@ | ||
import { AsyncCall } from 'async-call-rpc' | ||
const server = AsyncCall<typeof server>({}, { channel, messageChannel: undefined! }) | ||
const server = AsyncCall<typeof server>({}, { channel }) | ||
server.add(2, 40).then(console.log) // 42 | ||
@@ -103,3 +103,3 @@ ``` | ||
import { AsyncCall, notify } from 'async-call-rpc' | ||
const server = notify(AsyncCall<typeof server>({}, { channel, messageChannel: undefined! })) | ||
const server = notify(AsyncCall<typeof server>({}, { channel })) | ||
server.online().then(console.log) // undefined | ||
@@ -112,3 +112,3 @@ ``` | ||
import { AsyncCall, batch } from 'async-call-rpc' | ||
const [server, emit, drop] = batch(AsyncCall<typeof server>({}, { channel, messageChannel: undefined! })) | ||
const [server, emit, drop] = batch(AsyncCall<typeof server>({}, { channel })) | ||
const a = server.req1() // pending | ||
@@ -115,0 +115,0 @@ const b = server.req2() // pending |
@@ -84,22 +84,2 @@ /** | ||
/** | ||
* The message channel interface that allows | ||
* @public | ||
* @deprecated Will be removed in the next major version. | ||
*/ | ||
export interface MessageChannel<Context = unknown> { | ||
/** | ||
* AsyncCall will attach a listener to receive messages. | ||
* @param event - The emitting event name (if supported). | ||
* @param eventListener - The listener have two parameters. The first one is the received data. The second one is an identifier to identify who send this request. When responding, AsyncCall will call the emit with the same context. | ||
*/ | ||
on(event: string, eventListener: (data: unknown, context?: Context) => void): void | ||
/** | ||
* AsyncCall will send message by this method. | ||
* @param event - The emitting event name (if supported). | ||
* @param data - The sending data. | ||
* @param context - The same context provided to the second parameter of on.eventListener. | ||
*/ | ||
emit(event: string, data: unknown, context?: Context): void | ||
} | ||
export type { CallbackBasedChannel, EventBasedChannel } from './types' | ||
@@ -112,10 +92,4 @@ /** | ||
/** | ||
* A key to prevent collision with other AsyncCalls. | ||
* | ||
* @remarks | ||
* The value can be anything, but need to be same on both sides if you're using the deprecated MessageChannel interface. | ||
* If you're using other recommended interface for channel like EventBasedChannel or CallbackBasedChannel, | ||
* this option will only used for better logging. | ||
* | ||
* @defaultValue `default-jsonrpc` | ||
* This option will only used for better logging. | ||
* @defaultValue `jsonrpc` | ||
*/ | ||
@@ -147,22 +121,9 @@ key?: string | ||
* @example | ||
* ```ts | ||
* const channel = { | ||
* on(event, callback) { | ||
* document.addEventListener('remote-data', x => callback(x.details)) | ||
* } | ||
* emit(event, data) { | ||
* fetch('/server', { body: data }) | ||
* } | ||
* } | ||
* ``` | ||
* [Example for CallbackBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/web/websocket.client.ts). | ||
* [Example for EventBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/node/websocket.server.ts). | ||
* @remarks | ||
* If you're using this new property, you can use "messageChannel: undefined!" to disable the type system error. | ||
* If you're using this new property, you can use "" to disable the type system error. | ||
*/ | ||
channel?: CallbackBasedChannel | EventBasedChannel | ||
channel: CallbackBasedChannel | EventBasedChannel | ||
/** | ||
* Leave this option "undefined!" if you're providing channel. | ||
* @deprecated renamed to "channel". In next major version, this option will be removed and the "channel" property will be required. | ||
*/ | ||
messageChannel: MessageChannel | CallbackBasedChannel | EventBasedChannel | ||
/** | ||
* Choose log level. See {@link AsyncCallLogLevel} | ||
@@ -253,9 +214,7 @@ * @defaultValue true | ||
const AsyncCallDefaultOptions = (< | ||
T extends Omit<Required<AsyncCallOptions>, 'messageChannel' | 'channel' | 'logger' | 'mapError'> | ||
>( | ||
const AsyncCallDefaultOptions = (<T extends Omit<Required<AsyncCallOptions>, 'channel' | 'logger' | 'mapError'>>( | ||
a: T, | ||
) => a)({ | ||
serializer: NoSerialization, | ||
key: 'default-jsonrpc', | ||
key: 'jsonrpc', | ||
strict: true, | ||
@@ -305,3 +264,2 @@ log: true, | ||
logger, | ||
channel: oldChannel, | ||
channel, | ||
@@ -325,5 +283,2 @@ } = { | ||
const console = getConsole(logger) | ||
const message: EventBasedChannel | CallbackBasedChannel | MessageChannel = (channel || oldChannel)! | ||
if (oldChannel && !channel) console.warn('Deprecation: messageChannel has renamed to channel') | ||
if (!message) throw new Error() | ||
type PromiseParam = Parameters<ConstructorParameters<typeof Promise>[0]> | ||
@@ -477,21 +432,10 @@ const requestContext = new Map<string | number, { f: PromiseParam; stack: string }>() | ||
} | ||
function isMessageChannel(x: typeof message): x is MessageChannel { | ||
return hasKey(x, 'emit') && typeof x.emit === 'function' | ||
} | ||
function isEventBasedChannel(x: typeof message): x is EventBasedChannel { | ||
function isEventBasedChannel(x: typeof channel): x is EventBasedChannel { | ||
return hasKey(x, 'send') && typeof x.send === 'function' | ||
} | ||
function isCallbackBasedChannel(x: typeof message): x is CallbackBasedChannel { | ||
function isCallbackBasedChannel(x: typeof channel): x is CallbackBasedChannel { | ||
return hasKey(x, 'setup') && typeof x.setup === 'function' | ||
} | ||
if (isMessageChannel(message)) { | ||
console.warn( | ||
"The interface you're using in channel is deprecated. Please switch to EventBasedChannel or CallbackBasedChannel", | ||
) | ||
message.on(logKey, async (_, context) => { | ||
const r = await rawMessageReceiver(_) | ||
if (r) message.emit(logKey, r, context) | ||
}) | ||
} else if (isCallbackBasedChannel(message)) { | ||
message.setup( | ||
if (isCallbackBasedChannel(channel)) { | ||
channel.setup( | ||
(data) => rawMessageReceiver(data).then(rawMessageSender), | ||
@@ -504,7 +448,5 @@ (data) => { | ||
) | ||
} else if (!isEventBasedChannel(message)) { | ||
throw new TypeError('Invalid channel') | ||
} | ||
if (isEventBasedChannel(message)) { | ||
const m = message as EventBasedChannel | CallbackBasedChannel | ||
if (isEventBasedChannel(channel)) { | ||
const m = channel as EventBasedChannel | CallbackBasedChannel | ||
m.on?.((_) => | ||
@@ -572,5 +514,3 @@ rawMessageReceiver(_) | ||
const data = await serializer.serialization(payload) | ||
if (hasKey(message, 'emit')) return message.emit(logKey, data) | ||
// CallbackBasedChannel might have no send method. let it throw | ||
return message.send!(data) | ||
return channel.send!(data) | ||
} | ||
@@ -577,0 +517,0 @@ function rejectsQueue(this: BatchQueue, error: unknown) { |
@@ -6,2 +6,5 @@ /** | ||
* @public | ||
* @example | ||
* | ||
* [Example for EventBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/node/websocket.server.ts). | ||
*/ | ||
@@ -27,2 +30,5 @@ export interface EventBasedChannel<Data = unknown> { | ||
* @public | ||
* @example | ||
* | ||
* [Example for CallbackBasedChannel](https://github.com/Jack-Works/async-call-rpc/blob/master/utils-src/web/websocket.client.ts). | ||
*/ | ||
@@ -29,0 +35,0 @@ export interface CallbackBasedChannel<Data = unknown> extends Partial<EventBasedChannel<Data>> { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
343884
2080