async-call-rpc
Advanced tools
Comparing version 6.1.0 to 6.1.1
@@ -244,2 +244,3 @@ /** | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -246,0 +247,0 @@ declare type AsyncVersionOf<T> = T extends Record<keyof T, (...args: any) => PromiseLike<any>> ? 'then' extends keyof T ? Omit<Readonly<T>, 'then'> : T : _AsyncVersionOf<T>; |
183
out/base.js
@@ -80,3 +80,2 @@ /// <reference types="./base.d.ts" /> | ||
const undefined$1 = void 0; | ||
const Promise_reject = (x) => Promise.reject(x); | ||
const Promise_resolve = (x) => Promise.resolve(x); | ||
@@ -167,14 +166,16 @@ const isArray = Array.isArray; | ||
const defaultErrorMapper = (stack = '', code = -1) => (e) => { | ||
let message = toString('', () => (e ).message); | ||
let type = toString(ERROR, (ctor = (e ).constructor) => isFunction(ctor) && ctor.name); | ||
const E = globalDOMException(); | ||
if (E && e instanceof E) type = DOMExceptionHeader + e.name; | ||
if (isString(e) || typeof e === 'number' || isBoolean(e) || typeof e === 'bigint') { | ||
type = ERROR; | ||
message = String(e); | ||
} | ||
const data = stack ? { stack, type } : { type }; | ||
return { code, message, data } | ||
}; | ||
const defaultErrorMapper = | ||
(stack = '', code = -1) => | ||
(e) => { | ||
let message = toString('', () => (e ).message); | ||
let type = toString(ERROR, (ctor = (e ).constructor) => isFunction(ctor) && ctor.name); | ||
const E = globalDOMException(); | ||
if (E && e instanceof E) type = DOMExceptionHeader + e.name; | ||
if (isString(e) || typeof e === 'number' || isBoolean(e) || typeof e === 'bigint') { | ||
type = ERROR; | ||
message = String(e); | ||
} | ||
const data = stack ? { stack, type } : { type }; | ||
return { code, message, data } | ||
}; | ||
@@ -197,10 +198,12 @@ /** | ||
const hasKey = ( | ||
obj, | ||
key, | ||
) => key in obj; | ||
const hasKey = (obj, key) => key in obj; | ||
const toString = (_default, val) => { | ||
@@ -470,10 +473,4 @@ try { | ||
const [banMethodNotFound, banUnknownMessage] = normalizeStrictOptions(strict); | ||
const [ | ||
log_beCalled, | ||
log_localError, | ||
log_remoteError, | ||
log_pretty, | ||
log_requestReplay, | ||
log_sendLocalStack, | ||
] = normalizeLogOptions(log); | ||
const [log_beCalled, log_localError, log_remoteError, log_pretty, log_requestReplay, log_sendLocalStack] = | ||
normalizeLogOptions(log); | ||
const { | ||
@@ -549,3 +546,3 @@ log: console_log, | ||
if (hasKey(data, 'error')) { | ||
const e = data.error; | ||
const e = data.error; | ||
errorMessage = e.message; | ||
@@ -684,64 +681,80 @@ errorCode = e.code; | ||
}; | ||
return new Proxy({ __proto__: null } , { | ||
get(cache, method) { | ||
if (method === 'then') { | ||
if (thenable === undefined$1) { | ||
console_warn( | ||
makeHostedMessage( | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
new TypeError('RPC used as Promise: '), | ||
), | ||
); | ||
const call = (method, args, stack, notify = false) => { | ||
return new Promise((resolve, reject) => { | ||
let queue = undefined$1; | ||
if (method === AsyncCallBatch) { | ||
queue = args.shift(); | ||
method = args.shift(); | ||
} | ||
if (typeof method === 'symbol') { | ||
const RPCInternalMethod = Symbol.keyFor(method) || (method ).description; | ||
if (RPCInternalMethod) { | ||
if (RPCInternalMethod.startsWith('rpc.')) method = RPCInternalMethod; | ||
else throw new TypeError('Not start with rpc.') | ||
} | ||
if (thenable !== true) return undefined$1 | ||
} else if (method.startsWith('rpc.')) { | ||
throw makeHostedMessage(Err_Cannot_call_method_starts_with_rpc_dot_directly, new TypeError()) | ||
} | ||
if (isString(method) && cache[method]) return cache[method] | ||
const factory = (notify) => (...params) => { | ||
let stack = removeStackHeader(new Error().stack); | ||
let queue = undefined$1; | ||
if (method === AsyncCallBatch) { | ||
queue = params.shift(); | ||
method = params.shift(); | ||
} | ||
if (typeof method === 'symbol') { | ||
const RPCInternalMethod = Symbol.keyFor(method) || (method ).description; | ||
if (RPCInternalMethod) { | ||
if (RPCInternalMethod.startsWith('rpc.')) method = RPCInternalMethod; | ||
else return Promise_reject(new TypeError('Not start with rpc.')) | ||
} | ||
} else if (method.startsWith('rpc.')) | ||
return Promise_reject( | ||
makeHostedMessage(Err_Cannot_call_method_starts_with_rpc_dot_directly, new TypeError()), | ||
) | ||
return new Promise((resolve, reject) => { | ||
if (preferLocalImplementation && !isThisSideImplementationPending && isString(method)) { | ||
const localImpl = | ||
resolvedThisSideImplementationValue && (resolvedThisSideImplementationValue )[method]; | ||
if (isFunction(localImpl)) return resolve(localImpl(...params)) | ||
} | ||
const id = idGenerator(); | ||
const [param0] = params; | ||
const sendingStack = log_sendLocalStack ? stack : ''; | ||
const param = | ||
parameterStructures === 'by-name' && params.length === 1 && isObject(param0) ? param0 : params; | ||
const request = Request(notify ? undefined$1 : id, method , param, sendingStack); | ||
if (queue) { | ||
queue.push(request); | ||
if (!queue.r) queue.r = [() => sendPayload(queue, true), (e) => rejectsQueue(queue, e)]; | ||
} else sendPayload(request).catch(reject); | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}); | ||
}) | ||
}; | ||
const f = factory(false); | ||
// @ts-ignore | ||
f[AsyncCallNotify] = factory(true); | ||
// @ts-ignore | ||
f[AsyncCallNotify][AsyncCallNotify] = f[AsyncCallNotify]; | ||
isString(method) && Object.defineProperty(cache, method, { value: f, configurable: true }); | ||
return f | ||
if (preferLocalImplementation && !isThisSideImplementationPending && isString(method)) { | ||
const localImpl = | ||
resolvedThisSideImplementationValue && (resolvedThisSideImplementationValue )[method]; | ||
if (isFunction(localImpl)) return resolve(localImpl(...args)) | ||
} | ||
const id = idGenerator(); | ||
stack = removeStackHeader(stack); | ||
const param = parameterStructures === 'by-name' && args.length === 1 && isObject(args[0]) ? args[0] : args; | ||
const request = Request( | ||
notify ? undefined$1 : id, | ||
method , | ||
param, | ||
log_sendLocalStack ? stack : undefined$1, | ||
); | ||
if (queue) { | ||
queue.push(request); | ||
if (!queue.r) queue.r = [() => sendPayload(queue, true), (e) => rejectsQueue(queue, e)]; | ||
} else sendPayload(request).catch(reject); | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}); | ||
}) | ||
}; | ||
const getTrap = new Proxy( | ||
{}, | ||
{ | ||
get(_, method) { | ||
const f = { | ||
// This function will be logged to the console so it must be 1 line | ||
[method]: (..._) => call(method, _, new Error().stack), | ||
}[method ]; | ||
const f2 = { | ||
[method]: (..._) => call(method, _, new Error().stack, true), | ||
}[method ]; | ||
// @ts-expect-error | ||
f[AsyncCallNotify] = f2[AsyncCallNotify] = f2; | ||
isString(method) && Object.defineProperty(methodContainer, method, { value: f, configurable: true }); | ||
return f | ||
}, | ||
}, | ||
); | ||
const methodContainer = { __proto__: getTrap }; | ||
if (thenable === false) methodContainer.then = undefined$1; | ||
else if (thenable === undefined$1) { | ||
Object.defineProperty(methodContainer, 'then', { | ||
configurable: true, | ||
get() { | ||
console_warn( | ||
makeHostedMessage( | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
new TypeError('RPC used as Promise: '), | ||
), | ||
); | ||
}, | ||
}); | ||
} | ||
return new Proxy(methodContainer, { | ||
getPrototypeOf: () => null, | ||
setPrototypeOf: (_, value) => value === null, | ||
}) | ||
@@ -748,0 +761,0 @@ } |
@@ -244,2 +244,3 @@ /** | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -246,0 +247,0 @@ declare type AsyncVersionOf<T> = T extends Record<keyof T, (...args: any) => PromiseLike<any>> ? 'then' extends keyof T ? Omit<Readonly<T>, 'then'> : T : _AsyncVersionOf<T>; |
/// <reference types="./base.min.d.ts" /> | ||
((r,e)=>{"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((r="undefined"!=typeof globalThis?globalThis:r||self).AsyncCall={})})(this,(function(r){"use strict";class e extends Error{constructor(r,e,t,n){super(e),this.name=r,this.code=t,this.stack=n}}const t={},n={},o=[{},{},t,n];function s(r,e){const t=o.indexOf(r);return e.message+=`Error ${t}: https://github.com/Jack-Works/async-call-rpc/wiki/Errors#`+t,e}const a={__proto__:null,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},i="DOMException:",c=r=>(r+"").replace(/^.+\n.+\n/,""),l=()=>{try{return DOMException}catch(r){}},u=r=>"string"==typeof r,f=r=>"boolean"==typeof r,d=r=>"function"==typeof r,p=r=>"object"==typeof r&&null!==r,y="Error",m=void 0,h=r=>Promise.reject(r),g=Array.isArray,E=()=>"() => replay()",b="2.0",k=(r,e,t,n)=>{r===m&&(r=null),Number.isNaN(e=Math.floor(e))&&(e=-1);const o={jsonrpc:b,id:r,error:{code:e,message:t,data:n}};return _(o.error,"data"),o},w=(r,e,t)=>{const{id:n}=r,{code:o,message:s,data:a}=t(e,r);return k(n,o,s,a)},$=(r="",e=-1)=>t=>{let n=v("",(()=>t.message)),o=v(y,((r=t.constructor)=>d(r)&&r.name));const s=l();return s&&t instanceof s&&(o=i+t.name),(u(t)||"number"==typeof t||f(t)||"bigint"==typeof t)&&(o=y,n=t+""),{code:e,message:n,data:r?{stack:r,type:o}:{type:o}}},S=r=>{if(!p(r))return!1;if(!P(r,"jsonrpc"))return!1;if(r.jsonrpc!==b)return!1;if(P(r,"params")){const e=r.params;if(!g(e)&&!p(e))return!1}return!0},P=(r,e)=>e in r,v=(r,e)=>{try{const t=e();return t===m?r:t+""}catch(e){return r}},_=(r,e)=>{r[e]===m&&delete r[e]},j={serialization:r=>r,deserialization:r=>r},x="AsyncCall/",z=Symbol.for(x+"ignored"),M=Symbol.for(x+"notify"),N=Symbol.for(x+"batch"),O=(r,e)=>r[e][M],R=()=>Math.random().toString(36).slice(2),A=r=>void 0===r||r;r.AsyncCall=(r,o)=>{let v=!0,x=m,O=m;const C=async()=>{try{x=await r}catch(r){O=r,tr("AsyncCall failed to start",r)}finally{v=!1}},{serializer:T=j,key:W="rpc",strict:I=!0,log:J=!0,parameterStructures:q="by-position",preferLocalImplementation:D=!1,idGenerator:F=R,mapError:L,logger:U,channel:G,thenable:B}=o;r instanceof Promise?C():(x=r,v=!1);const[H,K]=(r=>{if(!f(r)){const{methodNotFound:e,unknownMessage:t}=r;return[e,t]}return[r,r]})(I),[Q,V,X,Y,Z,rr]=(r=>{if("all"===r)return[!0,!0,!0,!0,!0,!0];if(!f(r)){const{beCalled:e,localError:t,remoteError:n,type:o,requestReplay:s,sendLocalStack:a}=r;return[A(e),A(t),A(n),"basic"!==o,s,a]}return r?[!0,!0,!0,!0]:[]})(J),{log:er,error:tr=er,debug:nr=er,groupCollapsed:or=er,groupEnd:sr=er,warn:ar=er}=U||console,ir=new Map,cr=async r=>{let e;try{if(e=await fr(r),S(e))return await mr(e);if(g(e)&&e.every(S)&&0!==e.length)return Promise.all(e.map(mr));if(K){let r=e.id;return r===m&&(r=null),(r=>k(r,-32600,"Invalid Request"))(r)}return m}catch(r){return V&&tr(r,e,void 0),((r,e)=>{const t=w({},r,e),n=t.error;return n.code=-32700,n.message="Parse error",t})(r,L||$(r&&r.stack))}},lr=async r=>{if(r){if(g(r)){const e=r.filter((r=>r&&P(r,"id")));if(0===e.length)return;return ur(e)}return ur(r)}},ur=r=>T.serialization(r),fr=r=>T.deserialization(r);var dr;if(P(dr=G,"setup")&&d(dr.setup)&&G.setup((r=>cr(r).then(lr)),(r=>{const e=fr(r);return!!S(e)||(r=>Promise.resolve(r))(e).then(S)})),(r=>P(r,"send")&&d(r.send))(G)){const r=G;r.on&&r.on((e=>cr(e).then(lr).then((e=>e&&r.send(e)))))}function pr(r,e,t){return p(r)&&P(r,"stack")&&(r.stack=e.split("\n").reduce(((r,e)=>r.replace(e+"\n","")),""+r.stack)),V&&tr(r),w(t,r,L||$(rr?r.stack:m))}async function yr(r,e=!1){e&&(r=[...r]);const t=await ur(r);return G.send(t)}const mr=async r=>{if(P(r,"method")){const e=(async r=>{if(v)await C();else if(O)return pr(O,"",r);let e="";try{const{params:t,method:n,id:o,remoteStack:s}=r,a=n.startsWith("rpc.")?Symbol.for(n):n,i=x&&x[a];if(!d(i))return H?k(o,-32601,"Method not found"):void(V&&nr("Missing method",a,r));const l=g(t)?t:[t];e=c(Error().stack);const u=new Promise((r=>r(i.apply(x,l))));if(Q)if(Y){const r=[`${W}.%c${n}%c(${l.map((()=>"%o")).join(", ")}%c)\n%o %c@${o}`,"color: #d2c057","",...l,"",u,"color: gray; font-style: italic;"];if(Z){const e=()=>{debugger;return i.apply(x,l)};e.toString=E,r.push(e)}s?(or(...r),er(s),sr()):er(...r)}else er(`${W}.${n}(${""+[...l]}) @${o}`);if(await u===z)return;return((r,e)=>{const t={jsonrpc:b,id:r,result:e};return _(t,"id"),t})(o,await u)}catch(t){return pr(t,e,r)}})(r);if(P(r,"id"))return e;try{await e}catch(r){}return m}return(async r=>{let t="",n="",o=0,s=y;if(P(r,"error")){const e=r.error;t=e.message,o=e.code;const a=e.data;n=p(a)&&P(a,"stack")&&u(a.stack)?a.stack:"<remote stack not available>",s=p(a)&&P(a,"type")&&u(a.type)?a.type:y,X&&(Y?tr(`${s}: ${t}(${o}) %c@${r.id}\n%c${n}`,"color: gray",""):tr(`${s}: ${t}(${o}) @${r.id}\n${n}`))}if(null===r.id||r.id===m)return;const{f:[c,f]=[null,null],stack:d=""}=ir.get(r.id)||{};c&&f&&(ir.delete(r.id),P(r,"error")?f(((r,t,n,o)=>{try{const s=l();if(r.startsWith(i)&&s)return new s(t,r.slice(13));if(r in a){const e=new a[r](t);return e.stack=o,e.code=n,e}return new e(r,t,n,o)}catch(e){return Error(`E${n} ${r}: ${t}\n${o}`)}})(s,t,o,n+"\n аt AsyncCall (rpc) \n"+d)):c(r.result))})(r)};return new Proxy({__proto__:null},{get(r,e){if("then"===e&&(B===m&&ar(s(n,new TypeError("RPC used as Promise: "))),!0!==B))return m;if(u(e)&&r[e])return r[e];const o=r=>(...n)=>{let o=c(Error().stack),a=m;if(e===N&&(a=n.shift(),e=n.shift()),"symbol"==typeof e){const r=Symbol.keyFor(e)||e.description;if(r){if(!r.startsWith("rpc."))return h(new TypeError("Not start with rpc."));e=r}}else if(e.startsWith("rpc."))return h(s(t,new TypeError));return new Promise(((t,s)=>{if(D&&!v&&u(e)){const r=x&&x[e];if(d(r))return t(r(...n))}const i=F(),[c]=n,l=rr?o:"",f="by-name"===q&&1===n.length&&p(c)?c:n,y=((r,e,t,n)=>{const o={jsonrpc:b,id:r,method:e,params:t,remoteStack:n};return _(o,"id"),((r,e)=>{r[e]||delete r[e]})(o,"remoteStack"),o})(r?m:i,e,f,l);if(a?(a.push(y),a.r||(a.r=[()=>yr(a,!0),r=>((r,e)=>{for(const t of r)if(P(t,"id")){const r=ir.get(t.id);r&&r.f[1](e)}})(a,r)])):yr(y).catch(s),r)return t();ir.set(i,{f:[t,s],stack:o})}))},a=o(!1);return a[M]=o(!0),a[M][M]=a[M],u(e)&&Object.defineProperty(r,e,{value:a,configurable:!0}),a}})},r.JSONSerialization=(r=[m,m],e,t="null")=>({serialization(n){if(t&&p(n)&&P(n,"result")&&n.result===m){const r={...n};r.result=null,"keep"===t&&(r.undef=!0),n=r}return JSON.stringify(n,r[0],e)},deserialization(e){const t=JSON.parse(e,r[1]);return p(t)&&P(t,"result")&&null===t.result&&P(t,"undef")&&!0===t.undef&&(t.result=m,delete t.undef),t}}),r.NoSerialization=j,r.batch=r=>{let e=[];return[new Proxy({__proto__:null},{get(t,n){if(u(n)&&t[n])return t[n];const o=(...t)=>r[N](e,n,...t);return(o[M]=(...t)=>r[N][M](e,n,...t))[M]=o[M],u(n)&&Object.defineProperty(t,n,{value:o,configurable:!0}),o}}),(r=e.r)=>r&&r[0](),(r=Error("Aborted"),t=e.r)=>{t&&t[1](r),e=[]}]},r.notify=r=>d(r)?r[M]:new Proxy(r,{get:O}),Object.defineProperty(r,"__esModule",{value:!0})})); | ||
((r,e)=>{"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((r="undefined"!=typeof globalThis?globalThis:r||self).AsyncCall={})})(this,(function(r){"use strict";class e extends Error{constructor(r,e,t,n){super(e),this.name=r,this.code=t,this.stack=n}}const t={},n={},o=[{},{},t,n];function s(r,e){const t=o.indexOf(r);return e.message+=`Error ${t}: https://github.com/Jack-Works/async-call-rpc/wiki/Errors#`+t,e}const a={__proto__:null,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},i="DOMException:",c=r=>(r+"").replace(/^.+\n.+\n/,""),l=()=>{try{return DOMException}catch(r){}},u=r=>"string"==typeof r,f=r=>"boolean"==typeof r,d=r=>"function"==typeof r,p=r=>"object"==typeof r&&null!==r,y="Error",m=void 0,h=Array.isArray,g=()=>"() => replay()",E="2.0",b=(r,e,t,n)=>{r===m&&(r=null),Number.isNaN(e=Math.floor(e))&&(e=-1);const o={jsonrpc:E,id:r,error:{code:e,message:t,data:n}};return v(o.error,"data"),o},k=(r,e,t)=>{const{id:n}=r,{code:o,message:s,data:a}=t(e,r);return b(n,o,s,a)},w=(r="",e=-1)=>t=>{let n=P("",(()=>t.message)),o=P(y,((r=t.constructor)=>d(r)&&r.name));const s=l();return s&&t instanceof s&&(o=i+t.name),(u(t)||"number"==typeof t||f(t)||"bigint"==typeof t)&&(o=y,n=t+""),{code:e,message:n,data:r?{stack:r,type:o}:{type:o}}},$=r=>{if(!p(r))return!1;if(!S(r,"jsonrpc"))return!1;if(r.jsonrpc!==E)return!1;if(S(r,"params")){const e=r.params;if(!h(e)&&!p(e))return!1}return!0},S=(r,e)=>e in r,P=(r,e)=>{try{const t=e();return t===m?r:t+""}catch(e){return r}},v=(r,e)=>{r[e]===m&&delete r[e]},_={serialization:r=>r,deserialization:r=>r},x="AsyncCall/",j=Symbol.for(x+"ignored"),O=Symbol.for(x+"notify"),z=Symbol.for(x+"batch"),M=(r,e)=>r[e][O],N=()=>Math.random().toString(36).slice(2),R=r=>void 0===r||r;r.AsyncCall=(r,o)=>{let P=!0,x=m,M=m;const A=async()=>{try{x=await r}catch(r){M=r,er("AsyncCall failed to start",r)}finally{P=!1}},{serializer:C=_,key:T="rpc",strict:W=!0,log:I=!0,parameterStructures:J="by-position",preferLocalImplementation:q=!1,idGenerator:D=N,mapError:F,logger:L,channel:U,thenable:G}=o;r instanceof Promise?A():(x=r,P=!1);const[B,H]=(r=>{if(!f(r)){const{methodNotFound:e,unknownMessage:t}=r;return[e,t]}return[r,r]})(W),[K,Q,V,X,Y,Z]=(r=>{if("all"===r)return[!0,!0,!0,!0,!0,!0];if(!f(r)){const{beCalled:e,localError:t,remoteError:n,type:o,requestReplay:s,sendLocalStack:a}=r;return[R(e),R(t),R(n),"basic"!==o,s,a]}return r?[!0,!0,!0,!0]:[]})(I),{log:rr,error:er=rr,debug:tr=rr,groupCollapsed:nr=rr,groupEnd:or=rr,warn:sr=rr}=L||console,ar=new Map,ir=async r=>{let e;try{if(e=await ur(r),$(e))return await yr(e);if(h(e)&&e.every($)&&0!==e.length)return Promise.all(e.map(yr));if(H){let r=e.id;return r===m&&(r=null),(r=>b(r,-32600,"Invalid Request"))(r)}return m}catch(r){return Q&&er(r,e,void 0),((r,e)=>{const t=k({},r,e),n=t.error;return n.code=-32700,n.message="Parse error",t})(r,F||w(r&&r.stack))}},cr=async r=>{if(r){if(h(r)){const e=r.filter((r=>r&&S(r,"id")));if(0===e.length)return;return lr(e)}return lr(r)}},lr=r=>C.serialization(r),ur=r=>C.deserialization(r);var fr;if(S(fr=U,"setup")&&d(fr.setup)&&U.setup((r=>ir(r).then(cr)),(r=>{const e=ur(r);return!!$(e)||(r=>Promise.resolve(r))(e).then($)})),(r=>S(r,"send")&&d(r.send))(U)){const r=U;r.on&&r.on((e=>ir(e).then(cr).then((e=>e&&r.send(e)))))}function dr(r,e,t){return p(r)&&S(r,"stack")&&(r.stack=e.split("\n").reduce(((r,e)=>r.replace(e+"\n","")),""+r.stack)),Q&&er(r),k(t,r,F||w(Z?r.stack:m))}async function pr(r,e=!1){e&&(r=[...r]);const t=await lr(r);return U.send(t)}const yr=async r=>{if(S(r,"method")){const e=(async r=>{if(P)await A();else if(M)return dr(M,"",r);let e="";try{const{params:t,method:n,id:o,remoteStack:s}=r,a=n.startsWith("rpc.")?Symbol.for(n):n,i=x&&x[a];if(!d(i))return B?b(o,-32601,"Method not found"):void(Q&&tr("Missing method",a,r));const l=h(t)?t:[t];e=c(Error().stack);const u=new Promise((r=>r(i.apply(x,l))));if(K)if(X){const r=[`${T}.%c${n}%c(${l.map((()=>"%o")).join(", ")}%c)\n%o %c@${o}`,"color: #d2c057","",...l,"",u,"color: gray; font-style: italic;"];if(Y){const e=()=>{debugger;return i.apply(x,l)};e.toString=g,r.push(e)}s?(nr(...r),rr(s),or()):rr(...r)}else rr(`${T}.${n}(${""+[...l]}) @${o}`);if(await u===j)return;return((r,e)=>{const t={jsonrpc:E,id:r,result:e};return v(t,"id"),t})(o,await u)}catch(t){return dr(t,e,r)}})(r);if(S(r,"id"))return e;try{await e}catch(r){}return m}return(async r=>{let t="",n="",o=0,s=y;if(S(r,"error")){const e=r.error;t=e.message,o=e.code;const a=e.data;n=p(a)&&S(a,"stack")&&u(a.stack)?a.stack:"<remote stack not available>",s=p(a)&&S(a,"type")&&u(a.type)?a.type:y,V&&(X?er(`${s}: ${t}(${o}) %c@${r.id}\n%c${n}`,"color: gray",""):er(`${s}: ${t}(${o}) @${r.id}\n${n}`))}if(null===r.id||r.id===m)return;const{f:[c,f]=[null,null],stack:d=""}=ar.get(r.id)||{};c&&f&&(ar.delete(r.id),S(r,"error")?f(((r,t,n,o)=>{try{const s=l();if(r.startsWith(i)&&s)return new s(t,r.slice(13));if(r in a){const e=new a[r](t);return e.stack=o,e.code=n,e}return new e(r,t,n,o)}catch(e){return Error(`E${n} ${r}: ${t}\n${o}`)}})(s,t,o,n+"\n аt AsyncCall (rpc) \n"+d)):c(r.result))})(r)},mr=(r,e,n,o=!1)=>new Promise(((a,i)=>{let l=m;if(r===z&&(l=e.shift(),r=e.shift()),"symbol"==typeof r){const e=Symbol.keyFor(r)||r.description;if(e){if(!e.startsWith("rpc."))throw new TypeError("Not start with rpc.");r=e}}else if(r.startsWith("rpc."))throw s(t,new TypeError);if(q&&!P&&u(r)){const t=x&&x[r];if(d(t))return a(t(...e))}const f=D();n=c(n);const y="by-name"===J&&1===e.length&&p(e[0])?e[0]:e,h=((r,e,t,n)=>{const o={jsonrpc:E,id:r,method:e,params:t,remoteStack:n};return v(o,"id"),((r,e)=>{r[e]||delete r[e]})(o,"remoteStack"),o})(o?m:f,r,y,Z?n:m);if(l?(l.push(h),l.r||(l.r=[()=>pr(l,!0),r=>((r,e)=>{for(const t of r)if(S(t,"id")){const r=ar.get(t.id);r&&r.f[1](e)}})(l,r)])):pr(h).catch(i),o)return a();ar.set(f,{f:[a,i],stack:n})})),hr={__proto__:new Proxy({},{get(r,e){const t={[e]:(...r)=>mr(e,r,Error().stack)}[e],n={[e]:(...r)=>mr(e,r,Error().stack,!0)}[e];return t[O]=n[O]=n,u(e)&&Object.defineProperty(hr,e,{value:t,configurable:!0}),t}})};return!1===G?hr.then=m:G===m&&Object.defineProperty(hr,"then",{configurable:!0,get(){sr(s(n,new TypeError("RPC used as Promise: ")))}}),new Proxy(hr,{getPrototypeOf:()=>null,setPrototypeOf:(r,e)=>null===e})},r.JSONSerialization=(r=[m,m],e,t="null")=>({serialization(n){if(t&&p(n)&&S(n,"result")&&n.result===m){const r={...n};r.result=null,"keep"===t&&(r.undef=!0),n=r}return JSON.stringify(n,r[0],e)},deserialization(e){const t=JSON.parse(e,r[1]);return p(t)&&S(t,"result")&&null===t.result&&S(t,"undef")&&!0===t.undef&&(t.result=m,delete t.undef),t}}),r.NoSerialization=_,r.batch=r=>{let e=[];return[new Proxy({__proto__:null},{get(t,n){if(u(n)&&t[n])return t[n];const o=(...t)=>r[z](e,n,...t);return(o[O]=(...t)=>r[z][O](e,n,...t))[O]=o[O],u(n)&&Object.defineProperty(t,n,{value:o,configurable:!0}),o}}),(r=e.r)=>r&&r[0](),(r=Error("Aborted"),t=e.r)=>{t&&t[1](r),e=[]}]},r.notify=r=>d(r)?r[O]:new Proxy(r,{get:M}),Object.defineProperty(r,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=base.min.js.map |
@@ -244,2 +244,3 @@ /** | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -382,2 +383,3 @@ declare type AsyncVersionOf<T> = T extends Record<keyof T, (...args: any) => PromiseLike<any>> ? 'then' extends keyof T ? Omit<Readonly<T>, 'then'> : T : _AsyncVersionOf<T>; | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -384,0 +386,0 @@ declare type AsyncGeneratorVersionOf<T> = T extends Record<keyof T, _IteratorOrIterableFunction> ? 'then' extends keyof T ? Omit<Readonly<T>, 'then'> : T : _AsyncGeneratorVersionOf<T>; |
220
out/full.js
@@ -81,3 +81,2 @@ /// <reference types="./full.d.ts" /> | ||
const Object_setPrototypeOf = Object.setPrototypeOf; | ||
const Promise_reject = (x) => Promise.reject(x); | ||
const Promise_resolve = (x) => Promise.resolve(x); | ||
@@ -168,14 +167,16 @@ const isArray = Array.isArray; | ||
const defaultErrorMapper = (stack = '', code = -1) => (e) => { | ||
let message = toString('', () => (e ).message); | ||
let type = toString(ERROR, (ctor = (e ).constructor) => isFunction(ctor) && ctor.name); | ||
const E = globalDOMException(); | ||
if (E && e instanceof E) type = DOMExceptionHeader + e.name; | ||
if (isString(e) || typeof e === 'number' || isBoolean(e) || typeof e === 'bigint') { | ||
type = ERROR; | ||
message = String(e); | ||
} | ||
const data = stack ? { stack, type } : { type }; | ||
return { code, message, data } | ||
}; | ||
const defaultErrorMapper = | ||
(stack = '', code = -1) => | ||
(e) => { | ||
let message = toString('', () => (e ).message); | ||
let type = toString(ERROR, (ctor = (e ).constructor) => isFunction(ctor) && ctor.name); | ||
const E = globalDOMException(); | ||
if (E && e instanceof E) type = DOMExceptionHeader + e.name; | ||
if (isString(e) || typeof e === 'number' || isBoolean(e) || typeof e === 'bigint') { | ||
type = ERROR; | ||
message = String(e); | ||
} | ||
const data = stack ? { stack, type } : { type }; | ||
return { code, message, data } | ||
}; | ||
@@ -198,10 +199,12 @@ /** | ||
const hasKey = ( | ||
obj, | ||
key, | ||
) => key in obj; | ||
const hasKey = (obj, key) => key in obj; | ||
const toString = (_default, val) => { | ||
@@ -471,10 +474,4 @@ try { | ||
const [banMethodNotFound, banUnknownMessage] = normalizeStrictOptions(strict); | ||
const [ | ||
log_beCalled, | ||
log_localError, | ||
log_remoteError, | ||
log_pretty, | ||
log_requestReplay, | ||
log_sendLocalStack, | ||
] = normalizeLogOptions(log); | ||
const [log_beCalled, log_localError, log_remoteError, log_pretty, log_requestReplay, log_sendLocalStack] = | ||
normalizeLogOptions(log); | ||
const { | ||
@@ -550,3 +547,3 @@ log: console_log, | ||
if (hasKey(data, 'error')) { | ||
const e = data.error; | ||
const e = data.error; | ||
errorMessage = e.message; | ||
@@ -685,64 +682,80 @@ errorCode = e.code; | ||
}; | ||
return new Proxy({ __proto__: null } , { | ||
get(cache, method) { | ||
if (method === 'then') { | ||
if (thenable === undefined$1) { | ||
console_warn( | ||
makeHostedMessage( | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
new TypeError('RPC used as Promise: '), | ||
), | ||
); | ||
const call = (method, args, stack, notify = false) => { | ||
return new Promise((resolve, reject) => { | ||
let queue = undefined$1; | ||
if (method === AsyncCallBatch) { | ||
queue = args.shift(); | ||
method = args.shift(); | ||
} | ||
if (typeof method === 'symbol') { | ||
const RPCInternalMethod = Symbol.keyFor(method) || (method ).description; | ||
if (RPCInternalMethod) { | ||
if (RPCInternalMethod.startsWith('rpc.')) method = RPCInternalMethod; | ||
else throw new TypeError('Not start with rpc.') | ||
} | ||
if (thenable !== true) return undefined$1 | ||
} else if (method.startsWith('rpc.')) { | ||
throw makeHostedMessage(Err_Cannot_call_method_starts_with_rpc_dot_directly, new TypeError()) | ||
} | ||
if (isString(method) && cache[method]) return cache[method] | ||
const factory = (notify) => (...params) => { | ||
let stack = removeStackHeader(new Error().stack); | ||
let queue = undefined$1; | ||
if (method === AsyncCallBatch) { | ||
queue = params.shift(); | ||
method = params.shift(); | ||
} | ||
if (typeof method === 'symbol') { | ||
const RPCInternalMethod = Symbol.keyFor(method) || (method ).description; | ||
if (RPCInternalMethod) { | ||
if (RPCInternalMethod.startsWith('rpc.')) method = RPCInternalMethod; | ||
else return Promise_reject(new TypeError('Not start with rpc.')) | ||
} | ||
} else if (method.startsWith('rpc.')) | ||
return Promise_reject( | ||
makeHostedMessage(Err_Cannot_call_method_starts_with_rpc_dot_directly, new TypeError()), | ||
) | ||
return new Promise((resolve, reject) => { | ||
if (preferLocalImplementation && !isThisSideImplementationPending && isString(method)) { | ||
const localImpl = | ||
resolvedThisSideImplementationValue && (resolvedThisSideImplementationValue )[method]; | ||
if (isFunction(localImpl)) return resolve(localImpl(...params)) | ||
} | ||
const id = idGenerator(); | ||
const [param0] = params; | ||
const sendingStack = log_sendLocalStack ? stack : ''; | ||
const param = | ||
parameterStructures === 'by-name' && params.length === 1 && isObject(param0) ? param0 : params; | ||
const request = Request(notify ? undefined$1 : id, method , param, sendingStack); | ||
if (queue) { | ||
queue.push(request); | ||
if (!queue.r) queue.r = [() => sendPayload(queue, true), (e) => rejectsQueue(queue, e)]; | ||
} else sendPayload(request).catch(reject); | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}); | ||
}) | ||
}; | ||
const f = factory(false); | ||
// @ts-ignore | ||
f[AsyncCallNotify] = factory(true); | ||
// @ts-ignore | ||
f[AsyncCallNotify][AsyncCallNotify] = f[AsyncCallNotify]; | ||
isString(method) && Object.defineProperty(cache, method, { value: f, configurable: true }); | ||
return f | ||
if (preferLocalImplementation && !isThisSideImplementationPending && isString(method)) { | ||
const localImpl = | ||
resolvedThisSideImplementationValue && (resolvedThisSideImplementationValue )[method]; | ||
if (isFunction(localImpl)) return resolve(localImpl(...args)) | ||
} | ||
const id = idGenerator(); | ||
stack = removeStackHeader(stack); | ||
const param = parameterStructures === 'by-name' && args.length === 1 && isObject(args[0]) ? args[0] : args; | ||
const request = Request( | ||
notify ? undefined$1 : id, | ||
method , | ||
param, | ||
log_sendLocalStack ? stack : undefined$1, | ||
); | ||
if (queue) { | ||
queue.push(request); | ||
if (!queue.r) queue.r = [() => sendPayload(queue, true), (e) => rejectsQueue(queue, e)]; | ||
} else sendPayload(request).catch(reject); | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}); | ||
}) | ||
}; | ||
const getTrap = new Proxy( | ||
{}, | ||
{ | ||
get(_, method) { | ||
const f = { | ||
// This function will be logged to the console so it must be 1 line | ||
[method]: (..._) => call(method, _, new Error().stack), | ||
}[method ]; | ||
const f2 = { | ||
[method]: (..._) => call(method, _, new Error().stack, true), | ||
}[method ]; | ||
// @ts-expect-error | ||
f[AsyncCallNotify] = f2[AsyncCallNotify] = f2; | ||
isString(method) && Object.defineProperty(methodContainer, method, { value: f, configurable: true }); | ||
return f | ||
}, | ||
}, | ||
); | ||
const methodContainer = { __proto__: getTrap }; | ||
if (thenable === false) methodContainer.then = undefined$1; | ||
else if (thenable === undefined$1) { | ||
Object.defineProperty(methodContainer, 'then', { | ||
configurable: true, | ||
get() { | ||
console_warn( | ||
makeHostedMessage( | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
new TypeError('RPC used as Promise: '), | ||
), | ||
); | ||
}, | ||
}); | ||
} | ||
return new Proxy(methodContainer, { | ||
getPrototypeOf: () => null, | ||
setPrototypeOf: (_, value) => value === null, | ||
}) | ||
@@ -816,2 +829,3 @@ } | ||
/** | ||
@@ -884,3 +898,3 @@ * The async generator version of the AsyncCall | ||
iterators.set(id, iterator); | ||
return Promise_resolve(id) | ||
return id | ||
}, | ||
@@ -898,13 +912,25 @@ [AsyncIteratorNext](id, val) { | ||
const remote = AsyncCall(server, options); | ||
const proxyTrap = (cache, key) => { | ||
if (!isString(key)) throw makeHostedMessage(Err_Only_string_can_be_the_RPC_method_name, new TypeError('')) | ||
if (cache[key]) return cache[key] | ||
const f = (...args) => { | ||
const id = remote[AsyncIteratorStart](key, args); | ||
return new _AsyncGenerator(remote, id) | ||
}; | ||
Object.defineProperty(cache, key, { value: f, configurable: true }); | ||
return f | ||
}; | ||
return new Proxy({ __proto__: null }, { get: proxyTrap }) | ||
const getTrap = new Proxy( | ||
{}, | ||
{ | ||
get(_, method) { | ||
if (!isString(method)) | ||
throw makeHostedMessage(Err_Only_string_can_be_the_RPC_method_name, new TypeError('')) | ||
const f = { | ||
[method]: (..._) => { | ||
const id = remote[AsyncIteratorStart](method, _); | ||
return new _AsyncGenerator(remote, id) | ||
}, | ||
}[method]; | ||
Object.defineProperty(methodContainer, method, { value: f, configurable: true }); | ||
return f | ||
}, | ||
}, | ||
); | ||
const methodContainer = { __proto__: getTrap }; | ||
return new Proxy(methodContainer, { | ||
getPrototypeOf: () => null, | ||
setPrototypeOf: (_, val) => val === null, | ||
}) | ||
} | ||
@@ -911,0 +937,0 @@ class _AsyncGenerator { |
@@ -244,2 +244,3 @@ /** | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -382,2 +383,3 @@ declare type AsyncVersionOf<T> = T extends Record<keyof T, (...args: any) => PromiseLike<any>> ? 'then' extends keyof T ? Omit<Readonly<T>, 'then'> : T : _AsyncVersionOf<T>; | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -384,0 +386,0 @@ declare type AsyncGeneratorVersionOf<T> = T extends Record<keyof T, _IteratorOrIterableFunction> ? 'then' extends keyof T ? Omit<Readonly<T>, 'then'> : T : _AsyncGeneratorVersionOf<T>; |
/// <reference types="./full.min.d.ts" /> | ||
((r,t)=>{"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((r="undefined"!=typeof globalThis?globalThis: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={},n={},o={},s={},i=[e,n,o,s];function a(r,t){const e=i.indexOf(r);return t.message+=`Error ${e}: https://github.com/Jack-Works/async-call-rpc/wiki/Errors#`+e,t}const c={__proto__:null,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},l="DOMException:",u=r=>(r+"").replace(/^.+\n.+\n/,""),f=()=>{try{return DOMException}catch(r){}},d=r=>"string"==typeof r,y=r=>"boolean"==typeof r,p=r=>"function"==typeof r,h=r=>"object"==typeof r&&null!==r,m="Error",g=void 0,w=Object.setPrototypeOf,b=r=>Promise.reject(r),E=r=>Promise.resolve(r),k=Array.isArray,_=()=>"() => replay()",$="2.0",S=(r,t,e,n)=>{r===g&&(r=null),Number.isNaN(t=Math.floor(t))&&(t=-1);const o={jsonrpc:$,id:r,error:{code:t,message:e,data:n}};return M(o.error,"data"),o},P=(r,t,e)=>{const{id:n}=r,{code:o,message:s,data:i}=e(t,r);return S(n,o,s,i)},v=(r="",t=-1)=>e=>{let n=O("",(()=>e.message)),o=O(m,((r=e.constructor)=>p(r)&&r.name));const s=f();return s&&e instanceof s&&(o=l+e.name),(d(e)||"number"==typeof e||y(e)||"bigint"==typeof e)&&(o=m,n=e+""),{code:t,message:n,data:r?{stack:r,type:o}:{type:o}}},x=r=>{if(!h(r))return!1;if(!j(r,"jsonrpc"))return!1;if(r.jsonrpc!==$)return!1;if(j(r,"params")){const t=r.params;if(!k(t)&&!h(t))return!1}return!0},j=(r,t)=>t in r,O=(r,t)=>{try{const e=t();return e===g?r:e+""}catch(t){return r}},M=(r,t)=>{r[t]===g&&delete r[t]},z={serialization:r=>r,deserialization:r=>r},A="AsyncCall/",C=Symbol.for(A+"ignored"),N=Symbol.for(A+"notify"),R=Symbol.for(A+"batch"),T=(r,t)=>r[t][N],I=()=>Math.random().toString(36).slice(2),W=r=>void 0===r||r,J=r=>{if(!y(r)){const{methodNotFound:t,unknownMessage:e}=r;return[t,e]}return[r,r]};function G(r,e){let n=!0,i=g,w=g;const O=async()=>{try{i=await r}catch(r){w=r,or("AsyncCall failed to start",r)}finally{n=!1}},{serializer:A=z,key:T="rpc",strict:G=!0,log:q=!0,parameterStructures:D="by-position",preferLocalImplementation:F=!1,idGenerator:L=I,mapError:U,logger:B,channel:H,thenable:K}=e;r instanceof Promise?O():(i=r,n=!1);const[Q,V]=J(G),[X,Y,Z,rr,tr,er]=(r=>{if("all"===r)return[!0,!0,!0,!0,!0,!0];if(!y(r)){const{beCalled:t,localError:e,remoteError:n,type:o,requestReplay:s,sendLocalStack:i}=r;return[W(t),W(e),W(n),"basic"!==o,s,i]}return r?[!0,!0,!0,!0]:[]})(q),{log:nr,error:or=nr,debug:sr=nr,groupCollapsed:ir=nr,groupEnd:ar=nr,warn:cr=nr}=B||console,lr=new Map,ur=async r=>{let t;try{if(t=await yr(r),x(t))return await gr(t);if(k(t)&&t.every(x)&&0!==t.length)return Promise.all(t.map(gr));if(V){let r=t.id;return r===g&&(r=null),(r=>S(r,-32600,"Invalid Request"))(r)}return g}catch(r){return Y&&or(r,t,void 0),((r,t)=>{const e=P({},r,t),n=e.error;return n.code=-32700,n.message="Parse error",e})(r,U||v(r&&r.stack))}},fr=async r=>{if(r){if(k(r)){const t=r.filter((r=>r&&j(r,"id")));if(0===t.length)return;return dr(t)}return dr(r)}},dr=r=>A.serialization(r),yr=r=>A.deserialization(r);var pr;if(j(pr=H,"setup")&&p(pr.setup)&&H.setup((r=>ur(r).then(fr)),(r=>{const t=yr(r);return!!x(t)||E(t).then(x)})),(r=>j(r,"send")&&p(r.send))(H)){const r=H;r.on&&r.on((t=>ur(t).then(fr).then((t=>t&&r.send(t)))))}function hr(r,t,e){return h(r)&&j(r,"stack")&&(r.stack=t.split("\n").reduce(((r,t)=>r.replace(t+"\n","")),""+r.stack)),Y&&or(r),P(e,r,U||v(er?r.stack:g))}async function mr(r,t=!1){t&&(r=[...r]);const e=await dr(r);return H.send(e)}const gr=async r=>{if(j(r,"method")){const t=(async r=>{if(n)await O();else if(w)return hr(w,"",r);let t="";try{const{params:e,method:n,id:o,remoteStack:s}=r,a=n.startsWith("rpc.")?Symbol.for(n):n,c=i&&i[a];if(!p(c))return Q?S(o,-32601,"Method not found"):void(Y&&sr("Missing method",a,r));const l=k(e)?e:[e];t=u(Error().stack);const f=new Promise((r=>r(c.apply(i,l))));if(X)if(rr){const r=[`${T}.%c${n}%c(${l.map((()=>"%o")).join(", ")}%c)\n%o %c@${o}`,"color: #d2c057","",...l,"",f,"color: gray; font-style: italic;"];if(tr){const t=()=>{debugger;return c.apply(i,l)};t.toString=_,r.push(t)}s?(ir(...r),nr(s),ar()):nr(...r)}else nr(`${T}.${n}(${""+[...l]}) @${o}`);if(await f===C)return;return((r,t)=>{const e={jsonrpc:$,id:r,result:t};return M(e,"id"),e})(o,await f)}catch(e){return hr(e,t,r)}})(r);if(j(r,"id"))return t;try{await t}catch(r){}return g}return(async r=>{let e="",n="",o=0,s=m;if(j(r,"error")){const t=r.error;e=t.message,o=t.code;const i=t.data;n=h(i)&&j(i,"stack")&&d(i.stack)?i.stack:"<remote stack not available>",s=h(i)&&j(i,"type")&&d(i.type)?i.type:m,Z&&(rr?or(`${s}: ${e}(${o}) %c@${r.id}\n%c${n}`,"color: gray",""):or(`${s}: ${e}(${o}) @${r.id}\n${n}`))}if(null===r.id||r.id===g)return;const{f:[i,a]=[null,null],stack:u=""}=lr.get(r.id)||{};i&&a&&(lr.delete(r.id),j(r,"error")?a(((r,e,n,o)=>{try{const s=f();if(r.startsWith(l)&&s)return new s(e,r.slice(13));if(r in c){const t=new c[r](e);return t.stack=o,t.code=n,t}return new t(r,e,n,o)}catch(t){return Error(`E${n} ${r}: ${e}\n${o}`)}})(s,e,o,n+"\n аt AsyncCall (rpc) \n"+u)):i(r.result))})(r)};return new Proxy({__proto__:null},{get(r,t){if("then"===t&&(K===g&&cr(a(s,new TypeError("RPC used as Promise: "))),!0!==K))return g;if(d(t)&&r[t])return r[t];const e=r=>(...e)=>{let s=u(Error().stack),c=g;if(t===R&&(c=e.shift(),t=e.shift()),"symbol"==typeof t){const r=Symbol.keyFor(t)||t.description;if(r){if(!r.startsWith("rpc."))return b(new TypeError("Not start with rpc."));t=r}}else if(t.startsWith("rpc."))return b(a(o,new TypeError));return new Promise(((o,a)=>{if(F&&!n&&d(t)){const r=i&&i[t];if(p(r))return o(r(...e))}const l=L(),[u]=e,f=er?s:"",y="by-name"===D&&1===e.length&&h(u)?u:e,m=((r,t,e,n)=>{const o={jsonrpc:$,id:r,method:t,params:e,remoteStack:n};return M(o,"id"),((r,t)=>{r[t]||delete r[t]})(o,"remoteStack"),o})(r?g:l,t,y,f);if(c?(c.push(m),c.r||(c.r=[()=>mr(c,!0),r=>((r,t)=>{for(const e of r)if(j(e,"id")){const r=lr.get(e.id);r&&r.f[1](t)}})(c,r)])):mr(m).catch(a),r)return o();lr.set(l,{f:[o,a],stack:s})}))},c=e(!1);return c[N]=e(!0),c[N][N]=c[N],d(t)&&Object.defineProperty(r,t,{value:c,configurable:!0}),c}})}const q="rpc.async-iterator.",D=Symbol.for(q+"start"),F=Symbol.for(q+"next"),L=Symbol.for(q+"return"),U=Symbol.for(q+"throw");class B{__init(){this.d=!1}__init2(){this.c=async r=>(await Q(r,(()=>this.d=!0)),r)}constructor(r,t){this.r=r,this.i=t,B.prototype.__init.call(this),B.prototype.__init2.call(this)}async return(r){return this.d?V(!0,r):this.c(this.r[L](await this.i,r))}async next(r){return this.d?V(!0):this.c(this.r[F](await this.i,r))}async throw(r){if(!this.d)return this.c(this.r[U](await this.i,r));throw r}}const H=async function*(){};w(B,H.constructor.prototype);const K=Object.getPrototypeOf(H());w(B.prototype,K);const Q=async(r,t)=>{try{const e=await r;e&&e.done&&t()}catch(r){}},V=(r,t)=>({done:r,value:t});r.AsyncCall=G,r.AsyncGeneratorCall=(r,t)=>{const o=new Map,[s]=J(null==(i=t.strict)||i);var i;const{idGenerator:c=I}=t,l=(r,t)=>{const n=o.get(r);if(!n){if(s)throw a(e,Error(`Iterator ${r}, `));return C}const i=t(n);return Q(i,(()=>o.delete(r))),i},u=G({async[D](t,e){const n=(await r)[t];if(!p(n)){if(s)throw new TypeError(t+" is not a function");return C}const i=n(...e),a=c();return o.set(a,i),E(a)},[F]:(r,t)=>l(r,(r=>r.next(t))),[L]:(r,t)=>l(r,(r=>p(r.return)&&r.return(t))),[U]:(r,t)=>l(r,(r=>p(r.throw)&&r.throw(t)))},t);return new Proxy({__proto__:null},{get:(r,t)=>{if(!d(t))throw a(n,new TypeError(""));if(r[t])return r[t];const e=(...r)=>{const e=u[D](t,r);return new B(u,e)};return Object.defineProperty(r,t,{value:e,configurable:!0}),e}})},r.JSONSerialization=(r=[g,g],t,e="null")=>({serialization(n){if(e&&h(n)&&j(n,"result")&&n.result===g){const r={...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 h(e)&&j(e,"result")&&null===e.result&&j(e,"undef")&&!0===e.undef&&(e.result=g,delete e.undef),e}}),r.NoSerialization=z,r.batch=r=>{let t=[];return[new Proxy({__proto__:null},{get(e,n){if(d(n)&&e[n])return e[n];const o=(...e)=>r[R](t,n,...e);return(o[N]=(...e)=>r[R][N](t,n,...e))[N]=o[N],d(n)&&Object.defineProperty(e,n,{value:o,configurable:!0}),o}}),(r=t.r)=>r&&r[0](),(r=Error("Aborted"),e=t.r)=>{e&&e[1](r),t=[]}]},r.notify=r=>p(r)?r[N]:new Proxy(r,{get:T}),Object.defineProperty(r,"__esModule",{value:!0})})); | ||
((r,t)=>{"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((r="undefined"!=typeof globalThis?globalThis: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={},n={},o={},s={},i=[e,n,o,s];function a(r,t){const e=i.indexOf(r);return t.message+=`Error ${e}: https://github.com/Jack-Works/async-call-rpc/wiki/Errors#`+e,t}const c={__proto__:null,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},l="DOMException:",u=r=>(r+"").replace(/^.+\n.+\n/,""),f=()=>{try{return DOMException}catch(r){}},y=r=>"string"==typeof r,p=r=>"boolean"==typeof r,d=r=>"function"==typeof r,h=r=>"object"==typeof r&&null!==r,m="Error",g=void 0,w=Object.setPrototypeOf,b=Array.isArray,E=()=>"() => replay()",k="2.0",_=(r,t,e,n)=>{r===g&&(r=null),Number.isNaN(t=Math.floor(t))&&(t=-1);const o={jsonrpc:k,id:r,error:{code:t,message:e,data:n}};return v(o.error,"data"),o},P=(r,t,e)=>{const{id:n}=r,{code:o,message:s,data:i}=e(t,r);return _(n,o,s,i)},$=(r="",t=-1)=>e=>{let n=x("",(()=>e.message)),o=x(m,((r=e.constructor)=>d(r)&&r.name));const s=f();return s&&e instanceof s&&(o=l+e.name),(y(e)||"number"==typeof e||p(e)||"bigint"==typeof e)&&(o=m,n=e+""),{code:t,message:n,data:r?{stack:r,type:o}:{type:o}}},S=r=>{if(!h(r))return!1;if(!O(r,"jsonrpc"))return!1;if(r.jsonrpc!==k)return!1;if(O(r,"params")){const t=r.params;if(!b(t)&&!h(t))return!1}return!0},O=(r,t)=>t in r,x=(r,t)=>{try{const e=t();return e===g?r:e+""}catch(t){return r}},v=(r,t)=>{r[t]===g&&delete r[t]},j={serialization:r=>r,deserialization:r=>r},M="AsyncCall/",z=Symbol.for(M+"ignored"),A=Symbol.for(M+"notify"),C=Symbol.for(M+"batch"),N=(r,t)=>r[t][A],R=()=>Math.random().toString(36).slice(2),T=r=>void 0===r||r,I=r=>{if(!p(r)){const{methodNotFound:t,unknownMessage:e}=r;return[t,e]}return[r,r]};function W(r,e){let n=!0,i=g,w=g;const x=async()=>{try{i=await r}catch(r){w=r,er("AsyncCall failed to start",r)}finally{n=!1}},{serializer:M=j,key:N="rpc",strict:W=!0,log:J=!0,parameterStructures:G="by-position",preferLocalImplementation:q=!1,idGenerator:D=R,mapError:F,logger:L,channel:U,thenable:B}=e;r instanceof Promise?x():(i=r,n=!1);const[H,K]=I(W),[Q,V,X,Y,Z,rr]=(r=>{if("all"===r)return[!0,!0,!0,!0,!0,!0];if(!p(r)){const{beCalled:t,localError:e,remoteError:n,type:o,requestReplay:s,sendLocalStack:i}=r;return[T(t),T(e),T(n),"basic"!==o,s,i]}return r?[!0,!0,!0,!0]:[]})(J),{log:tr,error:er=tr,debug:nr=tr,groupCollapsed:or=tr,groupEnd:sr=tr,warn:ir=tr}=L||console,ar=new Map,cr=async r=>{let t;try{if(t=await fr(r),S(t))return await hr(t);if(b(t)&&t.every(S)&&0!==t.length)return Promise.all(t.map(hr));if(K){let r=t.id;return r===g&&(r=null),(r=>_(r,-32600,"Invalid Request"))(r)}return g}catch(r){return V&&er(r,t,void 0),((r,t)=>{const e=P({},r,t),n=e.error;return n.code=-32700,n.message="Parse error",e})(r,F||$(r&&r.stack))}},lr=async r=>{if(r){if(b(r)){const t=r.filter((r=>r&&O(r,"id")));if(0===t.length)return;return ur(t)}return ur(r)}},ur=r=>M.serialization(r),fr=r=>M.deserialization(r);var yr;if(O(yr=U,"setup")&&d(yr.setup)&&U.setup((r=>cr(r).then(lr)),(r=>{const t=fr(r);return!!S(t)||(r=>Promise.resolve(r))(t).then(S)})),(r=>O(r,"send")&&d(r.send))(U)){const r=U;r.on&&r.on((t=>cr(t).then(lr).then((t=>t&&r.send(t)))))}function pr(r,t,e){return h(r)&&O(r,"stack")&&(r.stack=t.split("\n").reduce(((r,t)=>r.replace(t+"\n","")),""+r.stack)),V&&er(r),P(e,r,F||$(rr?r.stack:g))}async function dr(r,t=!1){t&&(r=[...r]);const e=await ur(r);return U.send(e)}const hr=async r=>{if(O(r,"method")){const t=(async r=>{if(n)await x();else if(w)return pr(w,"",r);let t="";try{const{params:e,method:n,id:o,remoteStack:s}=r,a=n.startsWith("rpc.")?Symbol.for(n):n,c=i&&i[a];if(!d(c))return H?_(o,-32601,"Method not found"):void(V&&nr("Missing method",a,r));const l=b(e)?e:[e];t=u(Error().stack);const f=new Promise((r=>r(c.apply(i,l))));if(Q)if(Y){const r=[`${N}.%c${n}%c(${l.map((()=>"%o")).join(", ")}%c)\n%o %c@${o}`,"color: #d2c057","",...l,"",f,"color: gray; font-style: italic;"];if(Z){const t=()=>{debugger;return c.apply(i,l)};t.toString=E,r.push(t)}s?(or(...r),tr(s),sr()):tr(...r)}else tr(`${N}.${n}(${""+[...l]}) @${o}`);if(await f===z)return;return((r,t)=>{const e={jsonrpc:k,id:r,result:t};return v(e,"id"),e})(o,await f)}catch(e){return pr(e,t,r)}})(r);if(O(r,"id"))return t;try{await t}catch(r){}return g}return(async r=>{let e="",n="",o=0,s=m;if(O(r,"error")){const t=r.error;e=t.message,o=t.code;const i=t.data;n=h(i)&&O(i,"stack")&&y(i.stack)?i.stack:"<remote stack not available>",s=h(i)&&O(i,"type")&&y(i.type)?i.type:m,X&&(Y?er(`${s}: ${e}(${o}) %c@${r.id}\n%c${n}`,"color: gray",""):er(`${s}: ${e}(${o}) @${r.id}\n${n}`))}if(null===r.id||r.id===g)return;const{f:[i,a]=[null,null],stack:u=""}=ar.get(r.id)||{};i&&a&&(ar.delete(r.id),O(r,"error")?a(((r,e,n,o)=>{try{const s=f();if(r.startsWith(l)&&s)return new s(e,r.slice(13));if(r in c){const t=new c[r](e);return t.stack=o,t.code=n,t}return new t(r,e,n,o)}catch(t){return Error(`E${n} ${r}: ${e}\n${o}`)}})(s,e,o,n+"\n аt AsyncCall (rpc) \n"+u)):i(r.result))})(r)},mr=(r,t,e,s=!1)=>new Promise(((c,l)=>{let f=g;if(r===C&&(f=t.shift(),r=t.shift()),"symbol"==typeof r){const t=Symbol.keyFor(r)||r.description;if(t){if(!t.startsWith("rpc."))throw new TypeError("Not start with rpc.");r=t}}else if(r.startsWith("rpc."))throw a(o,new TypeError);if(q&&!n&&y(r)){const e=i&&i[r];if(d(e))return c(e(...t))}const p=D();e=u(e);const m="by-name"===G&&1===t.length&&h(t[0])?t[0]:t,w=((r,t,e,n)=>{const o={jsonrpc:k,id:r,method:t,params:e,remoteStack:n};return v(o,"id"),((r,t)=>{r[t]||delete r[t]})(o,"remoteStack"),o})(s?g:p,r,m,rr?e:g);if(f?(f.push(w),f.r||(f.r=[()=>dr(f,!0),r=>((r,t)=>{for(const e of r)if(O(e,"id")){const r=ar.get(e.id);r&&r.f[1](t)}})(f,r)])):dr(w).catch(l),s)return c();ar.set(p,{f:[c,l],stack:e})})),gr={__proto__:new Proxy({},{get(r,t){const e={[t]:(...r)=>mr(t,r,Error().stack)}[t],n={[t]:(...r)=>mr(t,r,Error().stack,!0)}[t];return e[A]=n[A]=n,y(t)&&Object.defineProperty(gr,t,{value:e,configurable:!0}),e}})};return!1===B?gr.then=g:B===g&&Object.defineProperty(gr,"then",{configurable:!0,get(){ir(a(s,new TypeError("RPC used as Promise: ")))}}),new Proxy(gr,{getPrototypeOf:()=>null,setPrototypeOf:(r,t)=>null===t})}const J="rpc.async-iterator.",G=Symbol.for(J+"start"),q=Symbol.for(J+"next"),D=Symbol.for(J+"return"),F=Symbol.for(J+"throw");class L{__init(){this.d=!1}__init2(){this.c=async r=>(await H(r,(()=>this.d=!0)),r)}constructor(r,t){this.r=r,this.i=t,L.prototype.__init.call(this),L.prototype.__init2.call(this)}async return(r){return this.d?K(!0,r):this.c(this.r[D](await this.i,r))}async next(r){return this.d?K(!0):this.c(this.r[q](await this.i,r))}async throw(r){if(!this.d)return this.c(this.r[F](await this.i,r));throw r}}const U=async function*(){};w(L,U.constructor.prototype);const B=Object.getPrototypeOf(U());w(L.prototype,B);const H=async(r,t)=>{try{const e=await r;e&&e.done&&t()}catch(r){}},K=(r,t)=>({done:r,value:t});r.AsyncCall=W,r.AsyncGeneratorCall=(r,t)=>{const o=new Map,[s]=I(null==(i=t.strict)||i);var i;const{idGenerator:c=R}=t,l=(r,t)=>{const n=o.get(r);if(!n){if(s)throw a(e,Error(`Iterator ${r}, `));return z}const i=t(n);return H(i,(()=>o.delete(r))),i},u=W({async[G](t,e){const n=(await r)[t];if(!d(n)){if(s)throw new TypeError(t+" is not a function");return z}const i=n(...e),a=c();return o.set(a,i),a},[q]:(r,t)=>l(r,(r=>r.next(t))),[D]:(r,t)=>l(r,(r=>d(r.return)&&r.return(t))),[F]:(r,t)=>l(r,(r=>d(r.throw)&&r.throw(t)))},t),f={__proto__:new Proxy({},{get(r,t){if(!y(t))throw a(n,new TypeError(""));const e={[t]:(...r)=>{const e=u[G](t,r);return new L(u,e)}}[t];return Object.defineProperty(f,t,{value:e,configurable:!0}),e}})};return new Proxy(f,{getPrototypeOf:()=>null,setPrototypeOf:(r,t)=>null===t})},r.JSONSerialization=(r=[g,g],t,e="null")=>({serialization(n){if(e&&h(n)&&O(n,"result")&&n.result===g){const r={...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 h(e)&&O(e,"result")&&null===e.result&&O(e,"undef")&&!0===e.undef&&(e.result=g,delete e.undef),e}}),r.NoSerialization=j,r.batch=r=>{let t=[];return[new Proxy({__proto__:null},{get(e,n){if(y(n)&&e[n])return e[n];const o=(...e)=>r[C](t,n,...e);return(o[A]=(...e)=>r[C][A](t,n,...e))[A]=o[A],y(n)&&Object.defineProperty(e,n,{value:o,configurable:!0}),o}}),(r=t.r)=>r&&r[0](),(r=Error("Aborted"),e=t.r)=>{e&&e[1](r),t=[]}]},r.notify=r=>d(r)?r[A]:new Proxy(r,{get:N}),Object.defineProperty(r,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=full.min.js.map |
{ | ||
"name": "async-call-rpc", | ||
"packageManager": "pnpm@7.2.1", | ||
"version": "6.1.0", | ||
"packageManager": "pnpm@7.6.0", | ||
"version": "6.1.1", | ||
"description": "A lightweight JSON RPC server & client", | ||
@@ -53,18 +53,2 @@ "main": "out/base.js", | ||
}, | ||
"scripts": { | ||
"prepublishOnly": "npm run clean && npm run test && npm run build", | ||
"clean": "rimraf ./out ./utils/web ./utils/node ./es ./coverage ./temp", | ||
"release": "npm run clean && npm run test && npm run build && standard-version", | ||
"watch:tsc": "tsc -b -w", | ||
"build:tsc": "tsc -b", | ||
"watch:rollup": "rollup -c -w", | ||
"build:rollup": "rollup -c", | ||
"build": "npm run build:tsc && npm run build:rollup && npm run doc", | ||
"doc:api": "api-extractor run --local --verbose", | ||
"doc:md": "api-documenter markdown -o docs -i temp", | ||
"doc": "run-s doc:api doc:md", | ||
"start": "run-p watch:rollup watch:tsc watch:test", | ||
"test": "jest --coverage", | ||
"watch:test": "jest --watch" | ||
}, | ||
"repository": { | ||
@@ -84,25 +68,25 @@ "type": "git", | ||
"devDependencies": { | ||
"@microsoft/api-documenter": "^7.17.17", | ||
"@microsoft/api-extractor": "^7.25.0", | ||
"@microsoft/api-documenter": "^7.19.0", | ||
"@microsoft/api-extractor": "^7.28.6", | ||
"@msgpack/msgpack": "^2.7.2", | ||
"@rollup/plugin-sucrase": "^4.0.4", | ||
"@types/jest": "^28.1.1", | ||
"@types/node": "^17.0.42", | ||
"@types/jest": "^28.1.6", | ||
"@types/node": "^18.6.1", | ||
"@types/ws": "^8.5.3", | ||
"async-call-rpc": "link:", | ||
"bson": "^4.6.4", | ||
"jest": "^28.1.1", | ||
"bson": "^4.6.5", | ||
"jest": "^28.1.3", | ||
"jest-file-snapshot": "^0.5.0", | ||
"npm-run-all": "^4.1.5", | ||
"prettier": "^2.6.2", | ||
"pretty-format": "^28.1.1", | ||
"prettier": "^2.7.1", | ||
"pretty-format": "^28.1.3", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.75.6", | ||
"rollup": "^2.77.1", | ||
"rollup-plugin-dts": "^4.2.2", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"standard-version": "^9.5.0", | ||
"ts-jest": "^28.0.5", | ||
"ts-jest": "^28.0.7", | ||
"tslib": "^2.4.0", | ||
"typescript": "^4.7.3", | ||
"ws": "^8.8.0" | ||
"typescript": "^4.7.4", | ||
"ws": "^8.8.1" | ||
}, | ||
@@ -115,3 +99,18 @@ "files": [ | ||
"utils-src" | ||
] | ||
} | ||
], | ||
"scripts": { | ||
"clean": "rimraf ./out ./utils/web ./utils/node ./es ./coverage ./temp", | ||
"release": "pnpm run clean && pnpm run test && pnpm run build && standard-version", | ||
"watch:tsc": "tsc -b -w", | ||
"build:tsc": "tsc -b", | ||
"watch:rollup": "rollup -c -w", | ||
"build:rollup": "rollup -c", | ||
"build": "pnpm run build:tsc && pnpm run build:rollup && pnpm run doc", | ||
"doc:api": "api-extractor run --local --verbose", | ||
"doc:md": "api-documenter markdown -o docs -i temp", | ||
"doc": "run-s doc:api doc:md", | ||
"start": "run-p watch:rollup watch:tsc watch:test", | ||
"test": "jest --coverage", | ||
"watch:test": "jest --watch" | ||
} | ||
} |
@@ -8,3 +8,3 @@ /** | ||
import { generateRandomID } from './utils/generateRandomID' | ||
import { isFunction, isString, Object_setPrototypeOf, Promise_resolve } from './utils/constants' | ||
import { isFunction, isString, Object_setPrototypeOf } from './utils/constants' | ||
import { | ||
@@ -56,2 +56,3 @@ Err_Cannot_find_a_running_iterator_with_given_ID, | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -144,3 +145,3 @@ export type AsyncGeneratorVersionOf<T> = T extends Record<keyof T, _IteratorOrIterableFunction> | ||
iterators.set(id, iterator) | ||
return Promise_resolve(id) | ||
return id | ||
}, | ||
@@ -158,13 +159,25 @@ [AsyncIteratorNext](id, val) { | ||
const remote = AsyncCall<AsyncGeneratorInternalMethods>(server, options) | ||
const proxyTrap = (cache: any, key: string): ((...args: unknown[]) => AsyncIterableIterator<unknown>) => { | ||
if (!isString(key)) throw makeHostedMessage(Err_Only_string_can_be_the_RPC_method_name, new TypeError('')) | ||
if (cache[key]) return cache[key] | ||
const f = (...args: unknown[]) => { | ||
const id = remote[AsyncIteratorStart](key, args) | ||
return new _AsyncGenerator(remote, id) | ||
} | ||
Object.defineProperty(cache, key, { value: f, configurable: true }) | ||
return f | ||
} | ||
return new Proxy({ __proto__: null }, { get: proxyTrap }) as AsyncGeneratorVersionOf<OtherSideImplementedFunctions> | ||
const getTrap = new Proxy( | ||
{}, | ||
{ | ||
get(_, method) { | ||
if (!isString(method)) | ||
throw makeHostedMessage(Err_Only_string_can_be_the_RPC_method_name, new TypeError('')) | ||
const f = { | ||
[method]: (..._: unknown[]) => { | ||
const id = remote[AsyncIteratorStart](method, _) | ||
return new _AsyncGenerator(remote, id) | ||
}, | ||
}[method]! | ||
Object.defineProperty(methodContainer, method, { value: f, configurable: true }) | ||
return f | ||
}, | ||
}, | ||
) | ||
const methodContainer = { __proto__: getTrap } as any | ||
return new Proxy(methodContainer, { | ||
getPrototypeOf: () => null, | ||
setPrototypeOf: (_, val) => val === null, | ||
}) as AsyncGeneratorVersionOf<OtherSideImplementedFunctions> | ||
} | ||
@@ -171,0 +184,0 @@ class _AsyncGenerator implements AsyncIterableIterator<unknown>, AsyncIterator<unknown, unknown, unknown> { |
@@ -33,13 +33,10 @@ export * from './types' | ||
import type { BatchQueue } from './core/batch' | ||
import type { CallbackBasedChannel, EventBasedChannel, AsyncCallOptions, ConsoleInterface, AsyncVersionOf } from './types' | ||
import { | ||
ERROR, | ||
isArray, | ||
isFunction, | ||
isString, | ||
Promise_reject, | ||
Promise_resolve, | ||
replayFunction, | ||
undefined, | ||
} from './utils/constants' | ||
import type { | ||
CallbackBasedChannel, | ||
EventBasedChannel, | ||
AsyncCallOptions, | ||
ConsoleInterface, | ||
AsyncVersionOf, | ||
} from './types' | ||
import { ERROR, isArray, isFunction, isString, Promise_resolve, replayFunction, undefined } from './utils/constants' | ||
@@ -104,10 +101,4 @@ /** | ||
const [banMethodNotFound, banUnknownMessage] = normalizeStrictOptions(strict) | ||
const [ | ||
log_beCalled, | ||
log_localError, | ||
log_remoteError, | ||
log_pretty, | ||
log_requestReplay, | ||
log_sendLocalStack, | ||
] = normalizeLogOptions(log) | ||
const [log_beCalled, log_localError, log_remoteError, log_pretty, log_requestReplay, log_sendLocalStack] = | ||
normalizeLogOptions(log) | ||
const { | ||
@@ -183,3 +174,3 @@ log: console_log, | ||
if (hasKey(data, 'error')) { | ||
const e = data.error | ||
const e = data.error as any | ||
errorMessage = e.message | ||
@@ -318,64 +309,80 @@ errorCode = e.code | ||
} | ||
return new Proxy({ __proto__: null } as any, { | ||
get(cache, method: string | symbol) { | ||
if (method === 'then') { | ||
if (thenable === undefined) { | ||
console_warn( | ||
makeHostedMessage( | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
new TypeError('RPC used as Promise: '), | ||
), | ||
) | ||
} | ||
if (thenable !== true) return undefined | ||
const call = (method: string | symbol, args: unknown[], stack: string | undefined, notify = false) => { | ||
return new Promise<void>((resolve, reject) => { | ||
let queue: BatchQueue | undefined = undefined | ||
if (method === AsyncCallBatch) { | ||
queue = args.shift() as any | ||
method = args.shift() as any | ||
} | ||
if (isString(method) && cache[method]) return cache[method] | ||
const factory = (notify: boolean) => (...params: unknown[]) => { | ||
let stack = removeStackHeader(new Error().stack) | ||
let queue: BatchQueue | undefined = undefined | ||
if (method === AsyncCallBatch) { | ||
queue = params.shift() as any | ||
method = params.shift() as any | ||
if (typeof method === 'symbol') { | ||
const RPCInternalMethod: string = Symbol.keyFor(method) || (method as any).description | ||
if (RPCInternalMethod) { | ||
if (RPCInternalMethod.startsWith('rpc.')) method = RPCInternalMethod | ||
else throw new TypeError('Not start with rpc.') | ||
} | ||
if (typeof method === 'symbol') { | ||
const RPCInternalMethod = Symbol.keyFor(method) || (method as any).description | ||
if (RPCInternalMethod) { | ||
if (RPCInternalMethod.startsWith('rpc.')) method = RPCInternalMethod | ||
else return Promise_reject(new TypeError('Not start with rpc.')) | ||
} | ||
} else if (method.startsWith('rpc.')) | ||
return Promise_reject( | ||
makeHostedMessage(Err_Cannot_call_method_starts_with_rpc_dot_directly, new TypeError()), | ||
) | ||
return new Promise<void>((resolve, reject) => { | ||
if (preferLocalImplementation && !isThisSideImplementationPending && isString(method)) { | ||
const localImpl: unknown = | ||
resolvedThisSideImplementationValue && (resolvedThisSideImplementationValue as any)[method] | ||
if (isFunction(localImpl)) return resolve(localImpl(...params)) | ||
} | ||
const id = idGenerator() | ||
const [param0] = params | ||
const sendingStack = log_sendLocalStack ? stack : '' | ||
const param = | ||
parameterStructures === 'by-name' && params.length === 1 && isObject(param0) ? param0 : params | ||
const request = Request(notify ? undefined : id, method as string, param, sendingStack) | ||
if (queue) { | ||
queue.push(request) | ||
if (!queue.r) queue.r = [() => sendPayload(queue, true), (e) => rejectsQueue(queue!, e)] | ||
} else sendPayload(request).catch(reject) | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}) | ||
}) | ||
} else if (method.startsWith('rpc.')) { | ||
throw makeHostedMessage(Err_Cannot_call_method_starts_with_rpc_dot_directly, new TypeError()) | ||
} | ||
const f = factory(false) | ||
// @ts-ignore | ||
f[AsyncCallNotify] = factory(true) | ||
// @ts-ignore | ||
f[AsyncCallNotify][AsyncCallNotify] = f[AsyncCallNotify] | ||
isString(method) && Object.defineProperty(cache, method, { value: f, configurable: true }) | ||
return f | ||
if (preferLocalImplementation && !isThisSideImplementationPending && isString(method)) { | ||
const localImpl: unknown = | ||
resolvedThisSideImplementationValue && (resolvedThisSideImplementationValue as any)[method] | ||
if (isFunction(localImpl)) return resolve(localImpl(...args)) | ||
} | ||
const id = idGenerator() | ||
stack = removeStackHeader(stack) | ||
const param = parameterStructures === 'by-name' && args.length === 1 && isObject(args[0]) ? args[0] : args | ||
const request = Request( | ||
notify ? undefined : id, | ||
method as string, | ||
param, | ||
log_sendLocalStack ? stack : undefined, | ||
) | ||
if (queue) { | ||
queue.push(request) | ||
if (!queue.r) queue.r = [() => sendPayload(queue, true), (e) => rejectsQueue(queue!, e)] | ||
} else sendPayload(request).catch(reject) | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}) | ||
}) | ||
} | ||
const getTrap = new Proxy( | ||
{}, | ||
{ | ||
get(_, method) { | ||
const f = { | ||
// This function will be logged to the console so it must be 1 line | ||
[method]: (..._: unknown[]) => call(method, _, new Error().stack), | ||
}[method as any]! | ||
const f2 = { | ||
[method]: (..._: unknown[]) => call(method, _, new Error().stack, true), | ||
}[method as any]! | ||
// @ts-expect-error | ||
f[AsyncCallNotify] = f2[AsyncCallNotify] = f2 | ||
isString(method) && Object.defineProperty(methodContainer, method, { value: f, configurable: true }) | ||
return f | ||
}, | ||
}, | ||
) | ||
const methodContainer = { __proto__: getTrap } as any | ||
if (thenable === false) methodContainer.then = undefined | ||
else if (thenable === undefined) { | ||
Object.defineProperty(methodContainer, 'then', { | ||
configurable: true, | ||
get() { | ||
console_warn( | ||
makeHostedMessage( | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
new TypeError('RPC used as Promise: '), | ||
), | ||
) | ||
}, | ||
}) | ||
} | ||
return new Proxy(methodContainer, { | ||
getPrototypeOf: () => null, | ||
setPrototypeOf: (_, value) => value === null, | ||
}) as AsyncVersionOf<OtherSideImplementedFunctions> | ||
@@ -382,0 +389,0 @@ } |
@@ -256,2 +256,3 @@ /** | ||
* Method called `then` are intentionally removed because it is very likely to be a foot gun in promise auto-unwrap. | ||
* @public | ||
*/ | ||
@@ -258,0 +259,0 @@ export type AsyncVersionOf<T> = T extends Record<keyof T, (...args: any) => PromiseLike<any>> |
@@ -8,5 +8,4 @@ export const isString = (x: unknown): x is string => typeof x === 'string' | ||
export const Object_setPrototypeOf = Object.setPrototypeOf | ||
export const Promise_reject = (x: any) => Promise.reject(x) | ||
export const Promise_resolve = <T>(x: T) => Promise.resolve(x) | ||
export const isArray = Array.isArray | ||
export const replayFunction = () => '() => replay()' |
@@ -86,14 +86,16 @@ import { globalDOMException as DOMException, DOMExceptionHeader } from './error' | ||
export const defaultErrorMapper = (stack = '', code = -1): ErrorMapFunction<AsyncCallErrorDetail> => (e) => { | ||
let message = toString('', () => (e as any).message) | ||
let type = toString(ERROR, (ctor = (e as any).constructor) => isFunction(ctor) && ctor.name) | ||
const E = DOMException() | ||
if (E && e instanceof E) type = DOMExceptionHeader + e.name | ||
if (isString(e) || typeof e === 'number' || isBoolean(e) || typeof e === 'bigint') { | ||
type = ERROR | ||
message = String(e) | ||
export const defaultErrorMapper = | ||
(stack = '', code = -1): ErrorMapFunction<AsyncCallErrorDetail> => | ||
(e) => { | ||
let message = toString('', () => (e as any).message) | ||
let type = toString(ERROR, (ctor = (e as any).constructor) => isFunction(ctor) && ctor.name) | ||
const E = DOMException() | ||
if (E && e instanceof E) type = DOMExceptionHeader + e.name | ||
if (isString(e) || typeof e === 'number' || isBoolean(e) || typeof e === 'bigint') { | ||
type = ERROR | ||
message = String(e) | ||
} | ||
const data: AsyncCallErrorDetail = stack ? { stack, type } : { type } | ||
return { code, message, data } | ||
} | ||
const data: AsyncCallErrorDetail = stack ? { stack, type } : { type } | ||
return { code, message, data } | ||
} | ||
@@ -118,9 +120,11 @@ /** | ||
export const hasKey = <T, Q extends string>( | ||
obj: T, | ||
key: Q, | ||
): obj is T & | ||
{ | ||
export type hasKey = { | ||
(obj: SuccessResponse | ErrorResponse | Request, key: 'result'): obj is SuccessResponse | ||
(obj: SuccessResponse | ErrorResponse | Request, key: 'error'): obj is ErrorResponse | ||
(obj: SuccessResponse | ErrorResponse | Request, key: 'method'): obj is Request | ||
<T, Q extends string>(obj: T, key: Q): obj is T & { | ||
[key in Q]: unknown | ||
} => key in obj | ||
} | ||
} | ||
export const hasKey: hasKey = (obj: any, key: any): obj is any => key in obj | ||
@@ -127,0 +131,0 @@ const toString = (_default: string, val: () => any) => { |
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
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
768734
6404