From 69728c4092c1884573065613f8358983f1ccd75d Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 13 Apr 2020 12:02:19 +0800 Subject: [PATCH 1/6] put the new inject state prop keys method in the helper for the final step setup --- packages/ws-client-core/package.json | 2 +- .../src/callers/setup-final-step.js | 9 ++++---- packages/ws-client-core/src/utils/helpers.js | 21 +++++++++++++++++-- packages/ws-client-core/src/utils/index.js | 6 ++++-- packages/ws-client-core/tests/options.test.js | 13 ++++++++++++ 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/packages/ws-client-core/package.json b/packages/ws-client-core/package.json index d3297f58..96e90c00 100644 --- a/packages/ws-client-core/package.json +++ b/packages/ws-client-core/package.json @@ -58,7 +58,7 @@ "dependencies": { "@jsonql/security": "^1.0.1", "@to1source/event": "^1.3.0", - "jsonql-constants": "^2.1.2", + "jsonql-constants": "^2.1.3", "jsonql-errors": "^1.2.1", "jsonql-params-validator": "^1.6.3", "jsonql-utils": "^1.2.7" diff --git a/packages/ws-client-core/src/callers/setup-final-step.js b/packages/ws-client-core/src/callers/setup-final-step.js index fa1ccc25..3b637d32 100644 --- a/packages/ws-client-core/src/callers/setup-final-step.js +++ b/packages/ws-client-core/src/callers/setup-final-step.js @@ -1,13 +1,12 @@ // The final step of the setup before it returns the client import { CONNECT_EVENT_NAME, - SUSPEND_EVENT_PROP_KEY, - IS_LOGIN_PROP_KEY + SUSPEND_EVENT_PROP_KEY } from 'jsonql-constants' import { setupInterCom } from './setup-intercom' +import { setupStatePropKeys } from '../utils' -import { injectToFn } from 'jsonql-utils' /** * The final step to return the client @@ -35,8 +34,8 @@ function setupFinalStep(obj, opts, ee) { opts.$releaseNamespace() } - // just inject one more property to the client - return injectToFn(client, IS_LOGIN_PROP_KEY, false, true) + // finally inject some prop keys to the client + return setupStatePropKeys(obj) } diff --git a/packages/ws-client-core/src/utils/helpers.js b/packages/ws-client-core/src/utils/helpers.js index 29e5b6d9..11376b43 100644 --- a/packages/ws-client-core/src/utils/helpers.js +++ b/packages/ws-client-core/src/utils/helpers.js @@ -1,9 +1,13 @@ // group all the small functions here -import { EMIT_REPLY_TYPE } from 'jsonql-constants' +import { + EMIT_REPLY_TYPE, + IS_LOGIN_PROP_KEY, + IS_READY_PROP_KEY +} from 'jsonql-constants' import { toArray, createEvt } from 'jsonql-utils/src/generic' +import { injectToFn } from 'jsonql-utils/src/obj-define-props' import JsonqlValidationError from 'jsonql-errors/src/validation-error' - /** * WebSocket is strict about the path, therefore we need to make sure before it goes in * @param {string} url input url @@ -47,4 +51,17 @@ export const clearMainEmitEvt = (ee, namespace) => { }) } +/** + * Setup the IS_LOGIN_PROP_KEY IS_READY_PROP_KEY + * @param {*} client + * @return {*} client + */ +export function setupStatePropKeys(client) { + return [IS_READY_PROP_KEY, IS_LOGIN_PROP_KEY] + // .map(key => injectToFn(client, key, false, true)) + .reduce((c, key) => { + return injectToFn(c, key, false, true) + }, client) +} + diff --git a/packages/ws-client-core/src/utils/index.js b/packages/ws-client-core/src/utils/index.js index e782324d..538d36f4 100644 --- a/packages/ws-client-core/src/utils/index.js +++ b/packages/ws-client-core/src/utils/index.js @@ -22,7 +22,8 @@ import { import { fixWss, getHostName, - clearMainEmitEvt + clearMainEmitEvt, + setupStatePropKeys } from './helpers' // export @@ -50,5 +51,6 @@ export { fixWss, getHostName, - clearMainEmitEvt + clearMainEmitEvt, + setupStatePropKeys } diff --git a/packages/ws-client-core/tests/options.test.js b/packages/ws-client-core/tests/options.test.js index 69a9802d..1332c7de 100644 --- a/packages/ws-client-core/tests/options.test.js +++ b/packages/ws-client-core/tests/options.test.js @@ -5,6 +5,8 @@ const { injectToFn, chainFns } = require('jsonql-utils') const constants = require('../src/options/constants') const { triggerNamespacesOnError } = require('../src/listener/trigger-namespaces-on-error') const { checkConfiguration } = require('../src/options') +const { setupStatePropKeys } = require('../src/utils') +const { IS_LOGIN_PROP_KEY, IS_READY_PROP_KEY } = require('jsonql-constants') test(`Should have a debug logger pass from here`, async t => { const opts = { hostname:'http://localhost:3456' } @@ -42,3 +44,14 @@ test(`test the objDefineProps if it return a new prop`, t => { t.is(obj.prop1, prop1) }) + + +test(`test the inject prop_keys method`, t => { + const client = setupStatePropKeys({}) + + debug(client) + + t.is(client[IS_LOGIN_PROP_KEY], false) + t.is(client[IS_READY_PROP_KEY], false) + +}) \ No newline at end of file -- Gitee From dab4cf6f3b63444532d3e4db09eda85a1879fd02 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 13 Apr 2020 12:25:15 +0800 Subject: [PATCH 2/6] finalize the setupAuthMethod --- packages/@jsonql/ws/package.json | 14 ++--- .../src/auth/setup-auth-methods.js | 58 ++++++++++--------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/packages/@jsonql/ws/package.json b/packages/@jsonql/ws/package.json index f7c5349d..54ffc50d 100644 --- a/packages/@jsonql/ws/package.json +++ b/packages/@jsonql/ws/package.json @@ -51,7 +51,7 @@ "homepage": "jsonql.org", "dependencies": { "js-cookie": "^2.2.1", - "jsonql-constants": "^2.1.2", + "jsonql-constants": "^2.1.3", "jsonql-errors": "^1.2.1", "jsonql-params-validator": "^1.6.3", "jsonql-utils": "^1.2.7", @@ -59,13 +59,13 @@ "ws": "^7.2.3" }, "devDependencies": { - "@rollup/plugin-alias": "^3.0.1", - "@rollup/plugin-buble": "^0.21.1", - "@rollup/plugin-commonjs": "^11.0.2", + "@rollup/plugin-alias": "^3.1.0", + "@rollup/plugin-buble": "^0.21.3", + "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-json": "^4.0.2", - "@rollup/plugin-node-resolve": "^7.1.1", + "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.1", - "@rollup/pluginutils": "^3.0.8", + "@rollup/pluginutils": "^3.0.9", "ava": "^3.6.0", "colors": "^1.4.0", "esm": "^3.2.25", @@ -77,7 +77,7 @@ "kefir": "^3.8.6", "koa": "^2.11.0", "koa-bodyparser": "^4.3.0", - "rollup": "^2.6.0", + "rollup": "^2.6.1", "rollup-plugin-async": "^1.2.0", "rollup-plugin-bundle-size": "^1.0.3", "rollup-plugin-copy": "^3.3.0", diff --git a/packages/ws-client-core/src/auth/setup-auth-methods.js b/packages/ws-client-core/src/auth/setup-auth-methods.js index e88e3bdc..fcaaff39 100644 --- a/packages/ws-client-core/src/auth/setup-auth-methods.js +++ b/packages/ws-client-core/src/auth/setup-auth-methods.js @@ -3,11 +3,13 @@ import { LOGIN_EVENT_NAME, LOGOUT_EVENT_NAME, ON_LOGIN_FN_NAME, - SOCKET_AUTH_NAME + IS_LOGIN_PROP_KEY, + STANDALONE_PROP_KEY + // SOCKET_AUTH_NAME } from 'jsonql-constants' -import { JsonqlValidationError, finalCatch } from 'jsonql-errors' +import { JsonqlValidationError } from 'jsonql-errors' import { injectToFn, chainFns, isString, objDefineProps, isFunc } from '../utils' -import { validateAsync } from 'jsonql-params-validator' +// import { validateAsync } from 'jsonql-params-validator' /** * @UPDATE it might be better if we decoup the two http-client only emit a login event @@ -40,30 +42,29 @@ const setupLoginHandler = (obj, opts, ee) => [ /** * Switch to this one when standalone mode is enable + * @NOTE we don't actually have this because the public contract not included it + * so we need to figure out a different way to include the auth method + * that get expose to the public before we can continue with this standalone mode + * const { contract, loginHandlerName } = opts + * const params = contract[SOCKET_AUTH_NAME][loginHandlerName] * @param {*} obj * @param {*} opts * @param {*} ee */ -const setupStandaloneLoginHandler = (obj, opts, ee) => { - /* - we don't actually have this because the public contract not included it - so we need to figure out a different way to include the auth method - that get expose to the public before we can continue with this standalone mode - const { contract, loginHandlerName } = opts - const params = contract[SOCKET_AUTH_NAME][loginHandlerName] - */ - return [ - injectToFn( - obj, - loginHandlerName, - function standaloneLoginHandler(...args) { +const setupStandaloneLoginHandler = (obj, opts, ee) => [ + injectToFn( + obj, + loginHandlerName, + function standaloneLoginHandler(...args) { + // we only need to pass the argument + // let the listener to handle the rest + ee.$trigger(LOGIN_EVENT_NAME, args) + } + ), + opts, + ee +] - } - ), - opts, - ee - ] -} /** * break out from createAuthMethods to allow chaining call - final in chain * @param {object} obj the main client object @@ -76,6 +77,7 @@ const setupLogoutHandler = (obj, opts, ee) => [ obj, opts.logoutHandlerName, function logoutHandler(...args) { + opts[IS_LOGIN_PROP_KEY] = true ee.$trigger(LOGOUT_EVENT_NAME, args) } ), @@ -83,7 +85,6 @@ const setupLogoutHandler = (obj, opts, ee) => [ ee ] - /** * This event will fire when the socket.io.on('connection') and ws.onopen * Plus this will check if it's the private namespace that fired the event @@ -97,6 +98,10 @@ const setupOnLoginListener = (obj, opts, ee) => [ ON_LOGIN_FN_NAME, function onLoginCallbackHandler(onLoginCallback) { if (isFunc(onLoginCallback)) { + // @NOTE just put this here for the time being + // if the obj (client) is not mutated then we need to put this elsewhere + opts[IS_LOGIN_PROP_KEY] = true + // only one callback can registered with it, TBC // Should this be a $onlyOnce listener after the logout // we add it back? @@ -108,11 +113,8 @@ const setupOnLoginListener = (obj, opts, ee) => [ ee ] -// @TODO future feature setup switch user - - /** - * Create auth related methods + * Main Create auth related methods * @param {object} obj the client itself * @param {object} opts configuration * @param {object} ee Event Emitter @@ -120,7 +122,7 @@ const setupOnLoginListener = (obj, opts, ee) => [ */ export function setupAuthMethods(obj, opts, ee) { return chainFns( - setupLoginHandler, // @TODO need a switch here + opts[STANDALONE_PROP_KEY] === true ? setupStandaloneLoginHandler : setupLoginHandler, setupLogoutHandler, setupOnLoginListener )(obj, opts, ee) -- Gitee From 2b6754a6570bdb3b23664012d47a7f2d7789afeb Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 13 Apr 2020 14:57:42 +0800 Subject: [PATCH 3/6] rollup fucks up again --- .../@jsonql/ws/dist/jsonql-ws-client.umd.js | 1820 ++++++++++++++++- .../ws/dist/jsonql-ws-client.umd.js.map | 2 +- packages/@jsonql/ws/package.json | 7 + packages/@jsonql/ws/rollup.config.js | 33 +- .../connect-event-listener.js | 2 - .../src/auth/setup-auth-methods.js | 4 - 6 files changed, 1845 insertions(+), 23 deletions(-) diff --git a/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js b/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js index 7d0b4670..8aac9bdb 100644 --- a/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js +++ b/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js @@ -1,2 +1,1820 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("fs"),require("path")):"function"==typeof define&&define.amd?define(["fs","path"],e):(t=t||self).jsonqlWsClient=e(t.fs,t.path)}(this,(function(t,e){"use strict";t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var r=Array.isArray,n="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},o="object"==typeof n&&n&&n.Object===Object&&n,i="object"==typeof self&&self&&self.Object===Object&&self,u=o||i||Function("return this")(),a=u.Symbol,c=Object.prototype,s=c.hasOwnProperty,f=c.toString,l=a?a.toStringTag:void 0;var p=Object.prototype.toString;var h=a?a.toStringTag:void 0;function g(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":h&&h in Object(t)?function(t){var e=s.call(t,l),r=t[l];try{t[l]=void 0;var n=!0}catch(t){}var o=f.call(t);return n&&(e?t[l]=r:delete t[l]),o}(t):function(t){return p.call(t)}(t)}function v(t,e){return function(r){return t(e(r))}}var d=v(Object.getPrototypeOf,Object);function y(t){return null!=t&&"object"==typeof t}var _=Function.prototype,b=Object.prototype,m=_.toString,w=b.hasOwnProperty,j=m.call(Object);function E(t){if(!y(t)||"[object Object]"!=g(t))return!1;var e=d(t);if(null===e)return!0;var r=w.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&m.call(r)==j}function S(t,e){for(var r=-1,n=null==t?0:t.length,o=Array(n);++r=n?t:function(t,e,r){var n=-1,o=t.length;e<0&&(e=-e>o?0:o+e),(r=r>o?o:r)<0&&(r+=o),o=e>r?0:r-e>>>0,e>>>=0;for(var i=Array(o);++n-1;);return r}(n,o),function(t,e){for(var r=t.length;r--&&k(e,t[r],0)>-1;);return r}(n,o)+1).join("")}var V=function(t){return r(t)?t:[t]},G=function(t,e){void 0===e&&(e=!0);try{return JSON.parse(t)}catch(r){if(e)return t;throw new Error(r)}},H=function(t,e){try{var r=Object.keys(t);return n=e,!!r.filter((function(t){return t===n})).length}catch(t){return!1}var n},Q=function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];return t.join("_")},K=function(t){return G("string"==typeof t?t:JSON.stringify(t))},X=function(t){if("function"==typeof t)return!0;console.error("Expect to be Function type! Got "+typeof t)},Z=function(){return!1},tt=function(t){for(var e=[],r=arguments.length-1;r-- >0;)e[r]=arguments[r+1];return function(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];return e.reduce((function(t,e){return Reflect.apply(e,null,V(t))}),Reflect.apply(t,null,r))}};function et(t,e){return t===e||t!=t&&e!=e}function rt(t,e){for(var r=t.length;r--;)if(et(t[r][0],e))return r;return-1}var nt=Array.prototype.splice;function ot(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e-1},ot.prototype.set=function(t,e){var r=this.__data__,n=rt(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this};function ut(t){if(!it(t))return!1;var e=g(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}var at,ct=u["__core-js_shared__"],st=(at=/[^.]+$/.exec(ct&&ct.keys&&ct.keys.IE_PROTO||""))?"Symbol(src)_1."+at:"";var ft=Function.prototype.toString;function lt(t){if(null!=t){try{return ft.call(t)}catch(t){}try{return t+""}catch(t){}}return""}var pt=/^\[object .+?Constructor\]$/,ht=Function.prototype,gt=Object.prototype,vt=ht.toString,dt=gt.hasOwnProperty,yt=RegExp("^"+vt.call(dt).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function _t(t){return!(!it(t)||(e=t,st&&st in e))&&(ut(t)?yt:pt).test(lt(t));var e}function bt(t,e){var r=function(t,e){return null==t?void 0:t[e]}(t,e);return _t(r)?r:void 0}var mt=bt(u,"Map"),wt=bt(Object,"create");var jt=Object.prototype.hasOwnProperty;var Et=Object.prototype.hasOwnProperty;function St(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}function Ht(t){return null!=t&&Gt(t.length)&&!ut(t)}var Qt="object"==typeof exports&&exports&&!exports.nodeType&&exports,Kt=Qt&&"object"==typeof module&&module&&!module.nodeType&&module,Xt=Kt&&Kt.exports===Qt?u.Buffer:void 0,Zt=(Xt?Xt.isBuffer:void 0)||function(){return!1},te={};te["[object Float32Array]"]=te["[object Float64Array]"]=te["[object Int8Array]"]=te["[object Int16Array]"]=te["[object Int32Array]"]=te["[object Uint8Array]"]=te["[object Uint8ClampedArray]"]=te["[object Uint16Array]"]=te["[object Uint32Array]"]=!0,te["[object Arguments]"]=te["[object Array]"]=te["[object ArrayBuffer]"]=te["[object Boolean]"]=te["[object DataView]"]=te["[object Date]"]=te["[object Error]"]=te["[object Function]"]=te["[object Map]"]=te["[object Number]"]=te["[object Object]"]=te["[object RegExp]"]=te["[object Set]"]=te["[object String]"]=te["[object WeakMap]"]=!1;var ee,re="object"==typeof exports&&exports&&!exports.nodeType&&exports,ne=re&&"object"==typeof module&&module&&!module.nodeType&&module,oe=ne&&ne.exports===re&&o.process,ie=function(){try{var t=ne&&ne.require&&ne.require("util").types;return t||oe&&oe.binding&&oe.binding("util")}catch(t){}}(),ue=ie&&ie.isTypedArray,ae=ue?(ee=ue,function(t){return ee(t)}):function(t){return y(t)&&Gt(t.length)&&!!te[g(t)]};function ce(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]}var se=Object.prototype.hasOwnProperty;function fe(t,e,r){var n=t[e];se.call(t,e)&&et(n,r)&&(void 0!==r||e in t)||Pt(t,e,r)}var le=/^(?:0|[1-9]\d*)$/;function pe(t,e){var r=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==r||"symbol"!=r&&le.test(t))&&t>-1&&t%1==0&&t0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(Se);function Te(t,e){return Ae(function(t,e,r){return e=Ee(void 0===e?t.length-1:e,0),function(){for(var n=arguments,o=-1,i=Ee(n.length-e,0),u=Array(i);++o1?e[n-1]:void 0,i=n>2?e[2]:void 0;for(o=Re.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,e,r){if(!it(r))return!1;var n=typeof e;return!!("number"==n?Ht(r)&&pe(e,r.length):"string"==n&&e in r)&&et(r[e],t)}(e[0],e[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++r0))},cr=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var e=t.replace("array.<","").replace(">","");return e.indexOf("|")?e.split("|"):[e]}return!1},sr=function(t,e){var r=t.arg;return e.length>1?!r.filter((function(t){return!(e.length>e.filter((function(e){return!ur(e)(t)})).length)})).length:e.length>e.filter((function(t){return!ar(r,t)})).length},fr=function(t,e){if(void 0===e&&(e=null),E(t)){if(!e)return!0;if(ar(e))return!e.filter((function(e){var r=t[e.name];return!(e.type.length>e.type.filter((function(t){var e;return void 0===r||(!1!==(e=cr(t))?!sr({arg:r},e):!ur(t)(r))})).length)})).length}return!1},lr=function(t,e){var r,n,o,i,u;switch(!0){case"object"===t:return o=(n=e).arg,i=n.param,u=[o],Array.isArray(i.keys)&&i.keys.length&&u.push(i.keys),!Reflect.apply(fr,null,u);case"array"===t:return!ar(e.arg);case!1!==(r=cr(t)):return!sr(e,r);default:return!ur(t)(e.arg)}},pr=function(t,e){return void 0!==t?t:!0===e.optional&&void 0!==e.defaultvalue?e.defaultvalue:null},hr=function(t,e,r){var n;void 0===r&&(r=!1);var o=function(t,e){if(!ar(e))throw new qe("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===e.length)return[];if(!ar(t))throw console.info(t),new qe("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==e.length:return t.map((function(t,r){return{arg:t,index:r,param:e[r]}}));case!0===e[0].variable:var r=e[0].type;return t.map((function(t,n){return{arg:t,index:n,param:e[n]||{type:r,name:"_"}}}));case t.lengthe.length:var n=e.length,o=["any"];return t.map((function(t,r){var i=r>=n||!!e[r].optional,u=e[r]||{type:o,name:"_"+r};return{arg:i?pr(t,u):t,index:r,param:u,optional:i}}));default:throw new Fe("Could not understand your arguments and parameter structure!",{args:t,params:e})}}(t,e),i=o.filter((function(t){return!0===t.optional||!0===t.param.optional?function(t){var e=t.arg,r=t.param;return!!tr(e)&&!(r.type.length>r.type.filter((function(e){return lr(e,t)})).length)}(t):!(t.param.type.length>t.param.type.filter((function(e){return lr(e,t)})).length)}));return r?((n={}).error=i,n.data=o.map((function(t){return t.arg})),n):i},gr=v(Object.keys,Object),vr=Object.prototype.hasOwnProperty;function dr(t){return Ht(t)?ge(t):function(t){if(!qt(t))return gr(t);var e=[];for(var r in Object(t))vr.call(t,r)&&"constructor"!=r&&e.push(r);return e}(t)}function yr(t,e){return t&&$t(t,e,dr)}function _r(t){var e=-1,r=null==t?0:t.length;for(this.__data__=new At;++ea))return!1;var s=i.get(t);if(s&&i.get(e))return s==e;var f=-1,l=!0,p=2&r?new _r:void 0;for(i.set(t,e),i.set(e,t);++f0){if(!1!==this.$get(t,!0)){var n=this.searchMapEvt(t);if(n.length){var o=n[0][3],i=(this.checkMaxStore(t,e),this);return function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var u=i.getMaxStore(t),a=-1;if(u>0){var c=i.$call(t,o,r);if(Reflect.apply(c,i,e),-1===(a=i.checkMaxStore(t)))return i.$off(t),-1}return a}}}return this.logger("The "+t+" is not registered, can not execute non-existing event at the moment"),-1}throw new Error("Expect max to be an integer and greater than zero! But we got ["+typeof e+"]"+e+" instead")},e.prototype.$replace=function(t,e,r,n){if(void 0===r&&(r=null),void 0===n&&(n="on"),this.validateType(n)){this.$off(t);var o=this["$"+n];return this.logger("($replace)",t,e),Reflect.apply(o,this,[t,e,r])}throw new Error(n+" is not supported!")},e.prototype.$trigger=function(t,e,r,n){void 0===e&&(e=[]),void 0===r&&(r=null),void 0===n&&(n=!1),this.validateEvt(t);var o=0,i=this.normalStore;if(this.logger("($trigger) normalStore",i),i.has(t)){if(this.logger('($trigger) "'+t+'" found'),this.$queue(t,e,r,n))return this.logger('($trigger) Currently suspended "'+t+'" added to queue, nothing executed. Exit now.'),!1;for(var u=Array.from(i.get(t)),a=u.length,c=!1,s=0;s0&&--r,!(r>0))return this.maxCountStore.delete(t),this.logger("remove "+t+" from maxStore"),-1;this.maxCountStore.set(t,r)}return r}throw new Error("Expect max to be an integer, but we got "+typeof e+" "+e)},e.prototype.searchMapEvt=function(t){var e=this.$get(t,!0).filter((function(t){var e,r=t[3];return e=r,!!$n.filter((function(t){return e===t})).length}));return e.length?e:[]},e.prototype.takeFromStore=function(t,e){void 0===e&&(e="lazyStore");var r=this[e];if(r){if(this.logger("(takeFromStore)",e,r),r.has(t)){var n=r.get(t);return this.logger('(takeFromStore) has "'+t+'"',n),r.delete(t),n}return!1}throw new Error('"'+e+'" is not supported!')},e.prototype.findFromStore=function(t,e,r){return void 0===r&&(r=!1),!!e.has(t)&&Array.from(e.get(t)).map((function(t){return r?t:t[1]}))},e.prototype.removeFromStore=function(t,e){return!!e.has(t)&&(this.logger("($off)",t),e.delete(t),!0)},e.prototype.getStoreSet=function(t,e){var r;return t.has(e)?(this.logger('(addToStore) "'+e+'" existed'),r=t.get(e)):(this.logger('(addToStore) create new Set for "'+e+'"'),r=new Set),r},e.prototype.addToStore=function(t,e){for(var r=[],n=arguments.length-2;n-- >0;)r[n]=arguments[n+2];var o=this.getStoreSet(t,e);if(r.length>2)if(Array.isArray(r[0])){var i=r[2];this.checkTypeInLazyStore(e,i)||o.add(r)}else this.checkContentExist(r,o)||(this.logger("(addToStore) insert new",r),o.add(r));else o.add(r);return t.set(e,o),[t,o.size]},e.prototype.checkContentExist=function(t,e){return!!Array.from(e).filter((function(e){return e[0]===t[0]})).length},e.prototype.checkTypeInStore=function(t,e){this.validateEvt(t,e);var r=this.$get(t,!0);return!1===r||!r.filter((function(t){var r=t[3];return e!==r})).length},e.prototype.checkTypeInLazyStore=function(t,e){this.validateEvt(t,e);var r=this.lazyStore.get(t);return this.logger("(checkTypeInLazyStore)",r),!!r&&!!Array.from(r).filter((function(t){return t[2]!==e})).length},e.prototype.addToNormalStore=function(t,e,r,n){if(void 0===n&&(n=null),this.logger('(addToNormalStore) try to add "'+e+'" --\x3e "'+t+'" to normal store'),this.checkTypeInStore(t,e)){this.logger("(addToNormalStore)",'"'+e+'" --\x3e "'+t+'" can add to normal store');var o=this.hashFnToKey(r),i=[this.normalStore,t,o,r,n,e],u=Reflect.apply(this.addToStore,this,i),a=u[0],c=u[1];return this.normalStore=a,c}return!1},e.prototype.addToLazyStore=function(t,e,r,n){void 0===e&&(e=[]),void 0===r&&(r=null),void 0===n&&(n=!1);var o=[this.lazyStore,t,this.toArray(e),r];n&&o.push(n);var i=Reflect.apply(this.addToStore,this,o),u=i[0],a=i[1];return this.lazyStore=u,this.logger("(addToLazyStore) size: "+a),a},e.prototype.toArray=function(t){return Array.isArray(t)?t:[t]},r.normalStore.set=function(t){Mn.set(this,t)},r.normalStore.get=function(){return Mn.get(this)},r.lazyStore.set=function(t){Ln.set(this,t)},r.lazyStore.get=function(){return Ln.get(this)},Object.defineProperties(e.prototype,r),e}(function(t){function e(){t.call(this),this.__suspend_state__=null,this.__pattern__=[],this.queueStore=new Set}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={$queues:{configurable:!0}};return e.prototype.$suspend=function(){this.logger("---\x3e SUSPEND ALL OPS <---"),this.__suspend__(!0)},e.prototype.$release=function(){this.logger("---\x3e RELEASE ALL SUSPENDED QUEUE <---"),this.__suspend__(!1)},e.prototype.$suspendEvent=function(){for(var t=this,e=[],r=arguments.length;r--;)e[r]=arguments[r];return e.map((function(e){var r=Un(e);if(Nn(r))return!1===t.__isPatternRegisterd(r)&&(t.__pattern__.push(r),t.__pattern__.length);throw new Error('We expect a pattern variable to be string or RegExp, but we got "'+typeof r+'" instead')}))},e.prototype.$releaseEvent=function(){for(var t=this,e=[],r=arguments.length;r--;)e[r]=arguments[r];return e.map((function(e){t.logger("($releaseEvent)",e);var r=Un(e);if(Nn(r)&&t.__isPatternRegisterd(r)){var n=t;return t.__getToReleaseQueue(r).map((function(t,e){return Reflect.apply(n.$trigger,n,t),e})).reduce((function(t,e){return++e}),0)}throw t.logger("$releaseEvent throw error ==========================>",t.__pattern__,r),new Error('We expect a pattern variable to be string or RegExp, but we got "'+typeof r+'" instead')})).reduce((function(t,e){return t+e}),0)},e.prototype.$queue=function(t){for(var e=[],r=arguments.length-1;r-- >0;)e[r]=arguments[r+1];switch(!0){case!0===this.__suspend_state__:return this.__addToQueueStore(t,e);case!0==!!this.__pattern__.length:return this.__pattern__.filter((function(e){return e.test(t)})).length?this.__addToQueueStore(t,e):(this.logger("($queue) "+t+" NOT added to $queueStore",this.__pattern__),!1);default:return this.logger("($queue) get called NOTHING added"),!1}},r.$queues.get=function(){var t=this.queueStore.size;return this.logger("($queues)","size: "+t),t>0?Array.from(this.queueStore):[]},e.prototype.__getToReleaseQueue=function(t){var e=this,r=this.$queues.filter((function(e){return t.test(e[0])})).map((function(r){return e.logger("[release] execute "+r[0]+" matches "+t,r),e.queueStore.delete(r),r}));return r.length>0&&(this.__pattern__=this.__pattern__.filter((function(e){return e.toString()!==t.toString()}))),r},e.prototype.__addToQueueStore=function(t,e){return this.logger("($queue) "+t+" added to $queueStore",e),this.queueStore.add([t].concat(e)),!0},e.prototype.__isPatternRegisterd=function(t){return!!this.__pattern__.filter((function(e){return e.toString()===t.toString()})).length},e.prototype.__suspend__=function(t){if("boolean"!=typeof t)throw new Error("$suspend only accept Boolean value! we got "+typeof t);var e=this.__suspend_state__;this.__suspend_state__=t,this.logger('($suspend) Change from "'+e+'" --\x3e "'+t+'"'),!0===e&&!1===t&&this.__release__()},e.prototype.__release__=function(){var t=this,e=this.queueStore.size,r=this.__pattern__;if(this.__pattern__=[],this.logger("(release) was called with "+e+(r.length?' for "'+r.join(",")+'"':"")+" item"+(e>1?"s":"")),e>0){var n=Array.from(this.queueStore);this.logger("(release queue)",n),n.forEach((function(e){t.logger("[release] execute "+e[0],e),Reflect.apply(t.$trigger,t,e)})),this.queueStore.clear(),this.logger("Release size "+this.queueStore.size)}return e},Object.defineProperties(e.prototype,r),e}(Bn)))),qn=function(t){var e=new RegExp("^(http|https)://","i"),r=t.match(e);if(r&&r.length){var n="https"===r[1].toLowerCase()?"wss":"ws";return t.replace(e,n+"://")}return t},Fn=function(t,e){V(e).forEach((function(e){t.$off(Q(e,"emit_reply"))}))};function Yn(t,e,r){H(t,"error")?r(t.error):H(t,"data")?Reflect.apply(e,null,[].concat(t.data)):r({message:"UKNNOWN RESULT!",error:t})}function Jn(t,e,r,n,o){void 0===n&&(n=[]);var i=Q(e,"emit_reply");return o("actionCall: "+i+" --\x3e "+r,n),t.$trigger(i,[r,V(n)]),new Promise((function(n,i){var u=Q(e,r,"onResult");t.$on(u,(function(t){o("got the first result",t),Yn(t,n,i)}))}))}var Wn=function(t,e,r,n,o,i){return xe(t,"send",Z,(function(){return i("running call getter method"),function(){for(var t=[],u=arguments.length;u--;)t[u]=arguments[u];return On(t,o.params,!0).then((function(t){return i("execute send",r,n,t),Jn(e,r,n,t,i)})).catch((function(t){i("send error",t),e.$call(Q(r,n,"onError"),[new qe(n,t)])}))}}))};function Vn(t,e,r,n,o){return function(){for(var i=[],u=arguments.length;u--;)i[u]=arguments[u];return On(i,n.params,!0).then((function(n){return Jn(t,e,r,n,o)})).catch(Je)}}var Gn=function(t,e,r,n,o,i){return[ke(t,"myNamespace",r),e,r,n,o,i]},Hn=function(t,e,r,n,o,i){return[xe(t,"onResult",(function(t){X(t)&&e.$on(Q(r,n,"onResult"),(function(o){Yn(o,t,(function(t){i('Catch error: "'+n+'"',t),e.$trigger(Q(r,n,"onError"),t)}))}))})),e,r,n,o,i]},Qn=function(t,e,r,n,o,i){return[xe(t,"onMessage",(function(t){if(X(t)){e.$only(Q(r,n,"onMessage"),(function(o){i("onMessageCallback",o),Yn(o,t,(function(t){i('Catch error: "'+n+'"',t),e.$trigger(Q(r,n,"onError"),t)}))}))}})),e,r,n,o,i]},Kn=function(t,e,r,n,o,i){return[xe(t,"onError",(function(t){X(t)&&e.$only(Q(r,n,"onError"),t)})),e,r,n,o,i]};function Xn(t,e,r,n,o,i){var u=[Gn,Hn,Qn,Kn,Wn];return Reflect.apply(tt,null,u)(n,o,t,e,r,i)}function Zn(t,e,r){var n=t.log,o={};for(var i in r){var u=r[i];for(var a in u){var c=u[a];o=ke(o,a,Xn(i,a,c,Vn(e,i,a,c,n),e,n))}}return[o,t,e,r]}function to(t,e,r){return[xe(t,"onReady",(function(t){X(t)&&r.$only("onReady",t)})),e,r]}function eo(t,e,r,n){return[xe(t,"onError",(function(t){if(X(t))for(var e in n)r.$on(Q(e,"onError"),t)})),e,r]}var ro=function(t,e,r){return[ke(t,e.loginHandlerName,(function(t){if(t&&Sn(t))return e.log("Received __login__ with "+t),r.$trigger("__login__",[t]);throw new qe(e.loginHandlerName,"Unexpected token "+t)})),e,r]},no=function(t,e,r){return[ke(t,e.logoutHandlerName,(function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];r.$trigger("__logout__",t)})),e,r]},oo=function(t,e,r){return[xe(t,"onLogin",(function(t){X(t)&&r.$only("onLogin",t)})),e,r]};function io(t,e,r){return tt(ro,no,oo)(t,e,r)}function uo(t,e,r){return(0,e.log)("[1] setupConnectPropKey"),[t=ke(t,"connected",!1,!0),e,r]}function ao(t,e,r){var n=e.log;return n("[2] setupConnectEvtListener"),r.$on("__connect__",(function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];n("setupConnectEvtListener pass and do nothing at the moment",t)})),[t,e,r]}function co(t,e,r){var n=e.log;return n("[3] setupConnectedEvtListener"),r.$on("__connected__",(function(){var e;t.connected=!0;var o=r.$release();return n("CONNECTED_EVENT_NAME",!0,"queue count",o),(e={}).connected=!0,e})),[t,e,r]}function so(t,e,r){var n=e.log;return n("[4] setupDisconnectListener"),r.$on("__disconnect__",(function(){var e;return t.connected=!1,n("CONNECTED_EVENT_NAME",!1),(e={}).connected=!1,e})),[t,e,r]}function fo(t,e,r){var n=e.disconnectHandlerName;return(0,e.log)("[5] setupDisconectAction"),ke(t,n,(function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];r.$trigger("__disconnect__",t)}))}var lo=[],po=[],ho="undefined"!=typeof Uint8Array?Uint8Array:Array,go=!1;function vo(){go=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e=0,r=t.length;e>18&63]+lo[o>>12&63]+lo[o>>6&63]+lo[63&o]);return i.join("")}function _o(t){var e;go||vo();for(var r=t.length,n=r%3,o="",i=[],u=0,a=r-n;ua?a:u+16383));return 1===n?(e=t[r-1],o+=lo[e>>2],o+=lo[e<<4&63],o+="=="):2===n&&(e=(t[r-2]<<8)+t[r-1],o+=lo[e>>10],o+=lo[e>>4&63],o+=lo[e<<2&63],o+="="),i.push(o),i.join("")}function bo(t,e,r,n,o){var i,u,a=8*o-n-1,c=(1<>1,f=-7,l=r?o-1:0,p=r?-1:1,h=t[e+l];for(l+=p,i=h&(1<<-f)-1,h>>=-f,f+=a;f>0;i=256*i+t[e+l],l+=p,f-=8);for(u=i&(1<<-f)-1,i>>=-f,f+=n;f>0;u=256*u+t[e+l],l+=p,f-=8);if(0===i)i=1-s;else{if(i===c)return u?NaN:1/0*(h?-1:1);u+=Math.pow(2,n),i-=s}return(h?-1:1)*u*Math.pow(2,i-n)}function mo(t,e,r,n,o,i){var u,a,c,s=8*i-o-1,f=(1<>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=n?0:i-1,g=n?1:-1,v=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(a=isNaN(e)?1:0,u=f):(u=Math.floor(Math.log(e)/Math.LN2),e*(c=Math.pow(2,-u))<1&&(u--,c*=2),(e+=u+l>=1?p/c:p*Math.pow(2,1-l))*c>=2&&(u++,c/=2),u+l>=f?(a=0,u=f):u+l>=1?(a=(e*c-1)*Math.pow(2,o),u+=l):(a=e*Math.pow(2,l-1)*Math.pow(2,o),u=0));o>=8;t[r+h]=255&a,h+=g,a/=256,o-=8);for(u=u<0;t[r+h]=255&u,h+=g,u/=256,s-=8);t[r+h-g]|=128*v}var wo={}.toString,jo=Array.isArray||function(t){return"[object Array]"==wo.call(t)};function Eo(){return Oo.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function So(t,e){if(Eo()=Eo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+Eo().toString(16)+" bytes");return 0|t}function ko(t){return!(null==t||!t._isBuffer)}function $o(t,e){if(ko(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var n=!1;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return ui(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return ai(t).length;default:if(n)return ui(t).length;e=(""+e).toLowerCase(),n=!0}}function No(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return Vo(this,e,r);case"utf8":case"utf-8":return Yo(this,e,r);case"ascii":return Jo(this,e,r);case"latin1":case"binary":return Wo(this,e,r);case"base64":return Fo(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Go(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function Co(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function zo(t,e,r,n,o){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=o?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(o)return-1;r=t.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof e&&(e=Oo.from(e,n)),ko(e))return 0===e.length?-1:Uo(t,e,r,n,o);if("number"==typeof e)return e&=255,Oo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):Uo(t,[e],r,n,o);throw new TypeError("val must be string, number or Buffer")}function Uo(t,e,r,n,o){var i,u=1,a=t.length,c=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;u=2,a/=2,c/=2,r/=2}function s(t,e){return 1===u?t[e]:t.readUInt16BE(e*u)}if(o){var f=-1;for(i=r;ia&&(r=a-c),i=r;i>=0;i--){for(var l=!0,p=0;po&&(n=o):n=o;var i=e.length;if(i%2!=0)throw new TypeError("Invalid hex string");n>i/2&&(n=i/2);for(var u=0;u>8,o=r%256,i.push(o),i.push(n);return i}(e,t.length-r),t,r,n)}function Fo(t,e,r){return 0===e&&r===t.length?_o(t):_o(t.slice(e,r))}function Yo(t,e,r){r=Math.min(t.length,r);for(var n=[],o=e;o239?4:s>223?3:s>191?2:1;if(o+l<=r)switch(l){case 1:s<128&&(f=s);break;case 2:128==(192&(i=t[o+1]))&&(c=(31&s)<<6|63&i)>127&&(f=c);break;case 3:i=t[o+1],u=t[o+2],128==(192&i)&&128==(192&u)&&(c=(15&s)<<12|(63&i)<<6|63&u)>2047&&(c<55296||c>57343)&&(f=c);break;case 4:i=t[o+1],u=t[o+2],a=t[o+3],128==(192&i)&&128==(192&u)&&128==(192&a)&&(c=(15&s)<<18|(63&i)<<12|(63&u)<<6|63&a)>65535&&c<1114112&&(f=c)}null===f?(f=65533,l=1):f>65535&&(f-=65536,n.push(f>>>10&1023|55296),f=56320|1023&f),n.push(f),o+=l}return function(t){var e=t.length;if(e<=4096)return String.fromCharCode.apply(String,t);var r="",n=0;for(;n0&&(t=this.toString("hex",0,50).match(/.{2}/g).join(" "),this.length>50&&(t+=" ... ")),""},Oo.prototype.compare=function(t,e,r,n,o){if(!ko(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),e<0||r>t.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&e>=r)return 0;if(n>=o)return-1;if(e>=r)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(n>>>=0),u=(r>>>=0)-(e>>>=0),a=Math.min(i,u),c=this.slice(n,o),s=t.slice(e,r),f=0;fo)&&(r=o),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return Mo(this,t,e,r);case"utf8":case"utf-8":return Lo(this,t,e,r);case"ascii":return Bo(this,t,e,r);case"latin1":case"binary":return Io(this,t,e,r);case"base64":return Do(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return qo(this,t,e,r);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},Oo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function Jo(t,e,r){var n="";r=Math.min(t.length,r);for(var o=e;on)&&(r=n);for(var o="",i=e;ir)throw new RangeError("Trying to access beyond buffer length")}function Qo(t,e,r,n,o,i){if(!ko(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>o||et.length)throw new RangeError("Index out of range")}function Ko(t,e,r,n){e<0&&(e=65535+e+1);for(var o=0,i=Math.min(t.length-r,2);o>>8*(n?o:1-o)}function Xo(t,e,r,n){e<0&&(e=4294967295+e+1);for(var o=0,i=Math.min(t.length-r,4);o>>8*(n?o:3-o)&255}function Zo(t,e,r,n,o,i){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function ti(t,e,r,n,o){return o||Zo(t,0,r,4),mo(t,e,r,n,23,4),r+4}function ei(t,e,r,n,o){return o||Zo(t,0,r,8),mo(t,e,r,n,52,8),r+8}Oo.prototype.slice=function(t,e){var r,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(e=void 0===e?n:~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),e0&&(o*=256);)n+=this[t+--e]*o;return n},Oo.prototype.readUInt8=function(t,e){return e||Ho(t,1,this.length),this[t]},Oo.prototype.readUInt16LE=function(t,e){return e||Ho(t,2,this.length),this[t]|this[t+1]<<8},Oo.prototype.readUInt16BE=function(t,e){return e||Ho(t,2,this.length),this[t]<<8|this[t+1]},Oo.prototype.readUInt32LE=function(t,e){return e||Ho(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},Oo.prototype.readUInt32BE=function(t,e){return e||Ho(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},Oo.prototype.readIntLE=function(t,e,r){t|=0,e|=0,r||Ho(t,e,this.length);for(var n=this[t],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*e)),n},Oo.prototype.readIntBE=function(t,e,r){t|=0,e|=0,r||Ho(t,e,this.length);for(var n=e,o=1,i=this[t+--n];n>0&&(o*=256);)i+=this[t+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*e)),i},Oo.prototype.readInt8=function(t,e){return e||Ho(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},Oo.prototype.readInt16LE=function(t,e){e||Ho(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},Oo.prototype.readInt16BE=function(t,e){e||Ho(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},Oo.prototype.readInt32LE=function(t,e){return e||Ho(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},Oo.prototype.readInt32BE=function(t,e){return e||Ho(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},Oo.prototype.readFloatLE=function(t,e){return e||Ho(t,4,this.length),bo(this,t,!0,23,4)},Oo.prototype.readFloatBE=function(t,e){return e||Ho(t,4,this.length),bo(this,t,!1,23,4)},Oo.prototype.readDoubleLE=function(t,e){return e||Ho(t,8,this.length),bo(this,t,!0,52,8)},Oo.prototype.readDoubleBE=function(t,e){return e||Ho(t,8,this.length),bo(this,t,!1,52,8)},Oo.prototype.writeUIntLE=function(t,e,r,n){(t=+t,e|=0,r|=0,n)||Qo(this,t,e,r,Math.pow(2,8*r)-1,0);var o=1,i=0;for(this[e]=255&t;++i=0&&(i*=256);)this[e+o]=t/i&255;return e+r},Oo.prototype.writeUInt8=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,1,255,0),Oo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},Oo.prototype.writeUInt16LE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,2,65535,0),Oo.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):Ko(this,t,e,!0),e+2},Oo.prototype.writeUInt16BE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,2,65535,0),Oo.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):Ko(this,t,e,!1),e+2},Oo.prototype.writeUInt32LE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,4,4294967295,0),Oo.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):Xo(this,t,e,!0),e+4},Oo.prototype.writeUInt32BE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,4,4294967295,0),Oo.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):Xo(this,t,e,!1),e+4},Oo.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e|=0,!n){var o=Math.pow(2,8*r-1);Qo(this,t,e,r,o-1,-o)}var i=0,u=1,a=0;for(this[e]=255&t;++i>0)-a&255;return e+r},Oo.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e|=0,!n){var o=Math.pow(2,8*r-1);Qo(this,t,e,r,o-1,-o)}var i=r-1,u=1,a=0;for(this[e+i]=255&t;--i>=0&&(u*=256);)t<0&&0===a&&0!==this[e+i+1]&&(a=1),this[e+i]=(t/u>>0)-a&255;return e+r},Oo.prototype.writeInt8=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,1,127,-128),Oo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},Oo.prototype.writeInt16LE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,2,32767,-32768),Oo.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):Ko(this,t,e,!0),e+2},Oo.prototype.writeInt16BE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,2,32767,-32768),Oo.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):Ko(this,t,e,!1),e+2},Oo.prototype.writeInt32LE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,4,2147483647,-2147483648),Oo.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):Xo(this,t,e,!0),e+4},Oo.prototype.writeInt32BE=function(t,e,r){return t=+t,e|=0,r||Qo(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),Oo.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):Xo(this,t,e,!1),e+4},Oo.prototype.writeFloatLE=function(t,e,r){return ti(this,t,e,!0,r)},Oo.prototype.writeFloatBE=function(t,e,r){return ti(this,t,e,!1,r)},Oo.prototype.writeDoubleLE=function(t,e,r){return ei(this,t,e,!0,r)},Oo.prototype.writeDoubleBE=function(t,e,r){return ei(this,t,e,!1,r)},Oo.prototype.copy=function(t,e,r,n){if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e=0;--o)t[o+e]=this[o+r];else if(i<1e3||!Oo.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(i=e;i55295&&r<57344){if(!o){if(r>56319){(e-=3)>-1&&i.push(239,191,189);continue}if(u+1===n){(e-=3)>-1&&i.push(239,191,189);continue}o=r;continue}if(r<56320){(e-=3)>-1&&i.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(e-=3)>-1&&i.push(239,191,189);if(o=null,r<128){if((e-=1)<0)break;i.push(r)}else if(r<2048){if((e-=2)<0)break;i.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;i.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;i.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return i}function ai(t){return function(t){var e,r,n,o,i,u;go||vo();var a=t.length;if(a%4>0)throw new Error("Invalid string. Length must be a multiple of 4");i="="===t[a-2]?2:"="===t[a-1]?1:0,u=new ho(3*a/4-i),n=i>0?a-4:a;var c=0;for(e=0,r=0;e>16&255,u[c++]=o>>8&255,u[c++]=255&o;return 2===i?(o=po[t.charCodeAt(e)]<<2|po[t.charCodeAt(e+1)]>>4,u[c++]=255&o):1===i&&(o=po[t.charCodeAt(e)]<<10|po[t.charCodeAt(e+1)]<<4|po[t.charCodeAt(e+2)]>>2,u[c++]=o>>8&255,u[c++]=255&o),u}(function(t){if((t=function(t){if(t.trim)return t.trim();return t.replace(/^\s+|\s+$/g,"")}(t).replace(oi,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function ci(t,e,r,n){for(var o=0;o=e.length||o>=t.length);++o)e[o+r]=t[o];return o}function si(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}function fi(t,e,r){var n=function(t,e,r){var n=[uo,ao,co,so,fo];return Reflect.apply(tt,null,n)(t,e,r)}(t,e,r);return n.verifyEventEmitter=function(){return r.is},n.eventEmitter=e.eventEmitter,n.log=e.log,r.$trigger("__connect__",[e,r]),!0===e.suspendOnStart&&e.$releaseNamespace(),ke(n,"isLogin",!1,!0)}var li={};li.standalone=An(!1,["boolean"]),li.debugOn=An(!1,["boolean"]),li.loginHandlerName=An("login",["string"]),li.logoutHandlerName=An("logout",["string"]),li.disconnectHandlerName=An("disconnect",["string"]),li.switchUserHandlerName=An("switch-user",["string"]),li.hostname=An(!1,["string"]),li.namespace=An("jsonql",["string"]),li.wsOptions=An({},["object"]),li.contract=An({},["object"],((ri={}).checker=function(t){return!!function(t){return E(t)&&(H(t,"query")||H(t,"mutation")||H(t,"socket"))}(t)&&t},ri)),li.enableAuth=An(!1,["boolean"]),li.token=An(!1,["string"]),li.csrf=An("X-CSRF-Token",["string"]),li.suspendOnStart=An(!1,["boolean"]);var pi={};pi.serverType=An(null,["string"],((ni={}).alias="socketClientType",ni));var hi=Object.assign(li,pi),gi={};function vi(t){return Promise.resolve(t).then((function(t){return t.hostname||(t.hostname=function(){try{return[window.location.protocol,window.location.host].join("//")}catch(t){throw new qe(t)}}()),t.wssPath=qn([t.hostname,t.namespace].join("/"),t.serverType),t.log=Pn(t),t.eventEmitter=function(t){var e=t.log,r=t.eventEmitter;return r?(e("eventEmitter is:",r.name),r):new Dn(t.log)}(t),t}))}function di(t){var e=function(t){var e=t.contract,r=t.enableAuth,n=function(t){var e="jsonql";return t.enableAuth?[[e,t.privateNamespace].join("/"),[e,t.publicNamespace].join("/")]:[e]}(t),o=r?Qe(e):function(t,e){var r,n={};for(var o in t){var i=t[o];n[o]=i}return{size:1,nspGroup:(r={},r[e]=n,r),publicNamespace:e}}(e.socket,n[0]);return Object.assign(o,{namespaces:n})}(t),r=t.eventEmitter,n=t.log,o=e.namespaces;return n("namespaces",o),!0===t.suspendOnStart&&(t.$suspendNamepsace=function(){return o.forEach((function(t){return r.$suspendEvent(t)}))},t.$releaseNamespace=function(){return r.$release()},t.$suspendNamepsace()),{opts:t,nspMap:e,ee:r}}function yi(t){return function(e){return void 0===e&&(e={}),vi(e).then(di).then((function(e){var r=e.opts,n=e.nspMap,o=e.ee;return t(r,n,o)})).then((function(t){return function(t,e,r){var n=[Zn,to,eo];return t.enableAuth&&n.push(io),n.push(fi),Reflect.apply(tt,null,n)(t,r,e.nspGroup)}(t.opts,t.nspMap,t.ee)})).catch((function(t){console.error("[jsonql-ws-core-client init error]",t)}))}}function _i(t,e,r){return void 0===e&&(e={}),void 0===r&&(r={}),function(n){return void 0===n&&(n={}),function(t,e,r){var n=Object.assign(hi,e),o=Object.assign(gi,r);return Tn(t,n,o)}(n,e,r).then(yi(t))}}gi.useJwt=!0,gi.log=null,gi.eventEmitter=null,gi.nspClient=null,gi.nspAuthClient=null,gi.wssPath="",gi.publicNamespace="public",gi.privateNamespace="private";var bi=function(t,e,r,n){var o=n.log;r.$on("__logout__",(function(){var i=getPrivateNamespace(e);o("__logout__ event triggered"),function(t,e,r){e.forEach((function(e){t.$trigger(Q(e,"onError"),[{message:r,namespace:e}])}))}(r,[i],"__logout__"),o("logout from "+i),Fn(r,i),t[i]=null,notLoginWsListerner(i,r,n)}))};function mi(t,e){return function(r,n,o){var i=r.log,u=n.namespaces,a=function(t){return t.length>1&&t[0]}(u),c=u.length-1;return u.map((function(n){var s=a===n;if(i(n," --\x3e "+(s?"private":"public")+" nsp --\x3e ",!1!==e[n]),e[n]){i("[call bindWsHandler]",s,n);var f=[n,e[n],o,s,r,--c];Reflect.apply(t,null,f)}else i("binding notLoginWsHandler to "+n),function(t,e,r){var n=r.log;e.$only(Q(t,"emit_reply"),(function(r,o){n("[notLoginListerner] hijack the ws call",t,r,o);var i={message:"NOT LOGIN"};e.$call(Q(t,r,"onError"),[i]),e.$call(Q(t,r,"onResult"),[{error:i}])}))}(n,o,r);return s&&(i("Has private and add logoutEvtHandler"),bi(e,u,o,r)),s}))}}function wi(t,e){var r=e.hostname,n=e.wssPath,o=e.nspClient,i=e.log,u=t?[r,t].join("/"):n;return i("createNspClient with URL --\x3e ",u),o(u,e)}var ji,Ei,Si,Oi,Ai,Ti,Ri,Pi,xi;Error;try{"undefined"!=typeof window&&window.atob&&window.atob.bind(window)}catch(t){}An("HS256",["string"]),An(!1,["boolean","number","string"],((ji={}).alias="exp",ji.optional=!0,ji)),An(!1,["boolean","number","string"],((Ei={}).alias="nbf",Ei.optional=!0,Ei)),An(!1,["boolean","string"],((Si={}).alias="iss",Si.optional=!0,Si)),An(!1,["boolean","string"],((Oi={}).alias="sub",Oi.optional=!0,Oi)),An(!1,["boolean","string"],((Ai={}).alias="iss",Ai.optional=!0,Ai)),An(!1,["boolean"],((Ti={}).optional=!0,Ti)),An(!1,["boolean","string"],((Ri={}).optional=!0,Ri)),An(!1,["boolean","string"],((Pi={}).optional=!0,Pi)),An(!1,["boolean"],((xi={}).optional=!0,xi));function ki(t,e){var r,n;void 0===e&&(e=!1);var o=t.wsOptions||{},i=t.headers||{};return e&&(i=Object.assign(i,((r={}).Authorization="Bearer "+e,r))),Object.assign({},o,((n={}).headers=i,n))}function $i(t,e,r){switch(void 0===e&&(e={}),void 0===r&&(r=!1),e.tokenDeliverLocation||"url"){case"url":return{url:r?t+"?token="+r:t,opts:ki(e,!1)};case"header":default:return{url:t,opts:ki(e,r)}}}var Ni="object"==typeof n&&n&&n.Object===Object&&n,Ci="object"==typeof self&&self&&self.Object===Object&&self,zi=Ni||Ci||Function("return this")(),Ui=zi.Symbol;var Mi=Array.isArray,Li=Object.prototype,Bi=Li.hasOwnProperty,Ii=Li.toString,Di=Ui?Ui.toStringTag:void 0;var qi=Object.prototype.toString;var Fi=Ui?Ui.toStringTag:void 0;function Yi(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":Fi&&Fi in Object(t)?function(t){var e=Bi.call(t,Di),r=t[Di];try{t[Di]=void 0;var n=!0}catch(t){}var o=Ii.call(t);return n&&(e?t[Di]=r:delete t[Di]),o}(t):function(t){return qi.call(t)}(t)}function Ji(t){return null!=t&&"object"==typeof t}var Wi=Ui?Ui.prototype:void 0,Vi=Wi?Wi.toString:void 0;function Gi(t){if("string"==typeof t)return t;if(Mi(t))return function(t,e){for(var r=-1,n=null==t?0:t.length,o=Array(n);++r=n?t:function(t,e,r){var n=-1,o=t.length;e<0&&(e=-e>o?0:o+e),(r=r>o?o:r)<0&&(r+=o),o=e>r?0:r-e>>>0,e>>>=0;for(var i=Array(o);++n-1;);return r}(o,i),function(t,e){for(var r=t.length;r--&&Ki(e,t[r],0)>-1;);return r}(o,i)+1).join("")}function pu(t){return function(t){return"number"==typeof t||Ji(t)&&"[object Number]"==Yi(t)}(t)&&t!=+t}function hu(t){return"string"==typeof t||!Mi(t)&&Ji(t)&&"[object String]"==Yi(t)}var gu=function(t){return!hu(t)&&!pu(parseFloat(t))},vu=function(t){return""!==lu(t)&&hu(t)},du=function(t){return null!=t&&"boolean"==typeof t},yu=function(t,e){return void 0===e&&(e=!0),void 0!==t&&""!==t&&""!==lu(t)&&(!1===e||!0===e&&null!==t)},_u=function(t,e){return void 0===e&&(e=""),!!Mi(t)&&(""===e||""===lu(e)||!(t.filter((function(t){return!function(t){switch(t){case"number":return gu;case"string":return vu;case"boolean":return du;default:return yu}}(e)(t)})).length>0))};var bu=function(t,e){return function(r){return t(e(r))}}(Object.getPrototypeOf,Object),mu=Function.prototype,wu=Object.prototype,ju=mu.toString,Eu=wu.hasOwnProperty,Su=ju.call(Object);function Ou(t){if(!Ji(t)||"[object Object]"!=Yi(t))return!1;var e=bu(t);if(null===e)return!0;var r=Eu.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&ju.call(r)==Su}var Au=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(e,r),e}(Error),Tu=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0},statusCode:{configurable:!0}};return r.name.get=function(){return"JsonqlError"},r.statusCode.get=function(){return-1},Object.defineProperties(e,r),e}(Error);function Ru(t,e){return t===e||t!=t&&e!=e}function Pu(t,e){for(var r=t.length;r--;)if(Ru(t[r][0],e))return r;return-1}var xu=Array.prototype.splice;function ku(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e-1},ku.prototype.set=function(t,e){var r=this.__data__,n=Pu(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this};function Nu(t){if(!$u(t))return!1;var e=Yi(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}var Cu=zi["__core-js_shared__"],zu=function(){var t=/[^.]+$/.exec(Cu&&Cu.keys&&Cu.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();var Uu=Function.prototype.toString;var Mu=/^\[object .+?Constructor\]$/,Lu=Function.prototype,Bu=Object.prototype,Iu=Lu.toString,Du=Bu.hasOwnProperty,qu=RegExp("^"+Iu.call(Du).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Fu(t){return!(!$u(t)||function(t){return!!zu&&zu in t}(t))&&(Nu(t)?qu:Mu).test(function(t){if(null!=t){try{return Uu.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function Yu(t,e){var r=function(t,e){return null==t?void 0:t[e]}(t,e);return Fu(r)?r:void 0}var Ju=Yu(zi,"Map"),Wu=Yu(Object,"create");var Vu=Object.prototype.hasOwnProperty;var Gu=Object.prototype.hasOwnProperty;function Hu(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}function ba(t){return null!=t&&_a(t.length)&&!Nu(t)}var ma="object"==typeof exports&&exports&&!exports.nodeType&&exports,wa=ma&&"object"==typeof module&&module&&!module.nodeType&&module,ja=wa&&wa.exports===ma?zi.Buffer:void 0,Ea=(ja?ja.isBuffer:void 0)||function(){return!1},Sa={};Sa["[object Float32Array]"]=Sa["[object Float64Array]"]=Sa["[object Int8Array]"]=Sa["[object Int16Array]"]=Sa["[object Int32Array]"]=Sa["[object Uint8Array]"]=Sa["[object Uint8ClampedArray]"]=Sa["[object Uint16Array]"]=Sa["[object Uint32Array]"]=!0,Sa["[object Arguments]"]=Sa["[object Array]"]=Sa["[object ArrayBuffer]"]=Sa["[object Boolean]"]=Sa["[object DataView]"]=Sa["[object Date]"]=Sa["[object Error]"]=Sa["[object Function]"]=Sa["[object Map]"]=Sa["[object Number]"]=Sa["[object Object]"]=Sa["[object RegExp]"]=Sa["[object Set]"]=Sa["[object String]"]=Sa["[object WeakMap]"]=!1;var Oa="object"==typeof exports&&exports&&!exports.nodeType&&exports,Aa=Oa&&"object"==typeof module&&module&&!module.nodeType&&module,Ta=Aa&&Aa.exports===Oa&&Ni.process,Ra=function(){try{var t=Aa&&Aa.require&&Aa.require("util").types;return t||Ta&&Ta.binding&&Ta.binding("util")}catch(t){}}(),Pa=Ra&&Ra.isTypedArray,xa=Pa?function(t){return function(e){return t(e)}}(Pa):function(t){return Ji(t)&&_a(t.length)&&!!Sa[Yi(t)]};function ka(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]}var $a=Object.prototype.hasOwnProperty;function Na(t,e,r){var n=t[e];$a.call(t,e)&&Ru(n,r)&&(void 0!==r||e in t)||ta(t,e,r)}var Ca=/^(?:0|[1-9]\d*)$/;function za(t,e){var r=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==r||"symbol"!=r&&Ca.test(t))&&t>-1&&t%1==0&&t0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(Va);function Qa(t,e){return Ha(function(t,e,r){return e=Wa(void 0===e?t.length-1:e,0),function(){for(var n=arguments,o=-1,i=Wa(n.length-e,0),u=Array(i);++o1?r[o-1]:void 0,u=o>2?r[2]:void 0;for(i=t.length>3&&"function"==typeof i?(o--,i):void 0,u&&function(t,e,r){if(!$u(r))return!1;var n=typeof e;return!!("number"==n?ba(r)&&za(e,r.length):"string"==n&&e in r)&&Ru(r[e],t)}(r[0],r[1],u)&&(i=o<3?void 0:i,o=1),e=Object(e);++n0;)e[r]=arguments[r+1];var n=We(),o=[t].concat(e);return o.push(n),He("__intercom__",o)}(LOGOUT_EVENT_NAME)),log("terminate ws connection"),e.terminate()}catch(t){console.error("ws.terminate error",t)}}))}var jc=function(t,e,r,n){var o=[e];r&&o.push(r),o.push("onError");var i=Reflect.apply(cc,null,o),u=n.data||n;t.$trigger(i,[u])};function Ec(t,e,r,n,o,i){var u=o.log;return n&&(u("Private namespace",t," binding to the DISCONNECT ws.terminate"),wc(r,e)),e.onopen=function(){u("client.ws.onopen listened --\x3e",t),n?(u("isPrivate and fire the onLogin"),r.$call("onLogin")(t)):(r.$call("onReady")(t,i),u("isPublic onReady hook executed",i),0===i&&r.$off("onReady")),r.$only(cc(t,"emit_reply"),(function(t,r){var n=function(t,e,r){return void 0===e&&(e=[]),void 0===r&&(r=!1),JSON.stringify(hc(t,e,r))}(t,r);u("ws.onopen.send",t,r,n),e.send(n)}))},e.onmessage=function(e){u("client.ws.onmessage raw payload",e.data);try{var n=function(t,e){void 0===e&&(e=lc);try{var r,n=sc(t);if(!1!==(r=vc(n)))return e("_data",r),{data:sc(r.__data__),resolverName:r.__event__,type:r.__reply__};throw new Tu("payload can not decoded",t)}catch(t){return e("error",t)}}(e.data),o=n.resolverName,i=n.type;switch(u("Respond from server",i,n),i){case"emit_reply":var a=cc(t,o,"onMessage"),c=r.$call(a)(n);u("EMIT_REPLY_TYPE",a,c);break;case"emit_acknowledge":var s=cc(t,o,"onResult"),f=r.$call(s)(n);u("ACKNOWLEDGE_REPLY_TYPE",s,f);break;case"error":u("ERROR_KEY"),jc(r,t,o,n);break;default:u("Unhandled event!",n),jc(r,t,o,n)}}catch(e){u("client.ws.onmessage error",e),jc(r,t,!1,e)}},e.onclose=function(){u("client.ws.onclose callback")},e.onerror=function(e){u("client.ws.onerror",e),function(t,e,r){t.$trigger(Q(e,"onError"),[r])}(r,t,e)},e}var Sc,Oc,Ac=(Sc=ic,void 0===Oc&&(Oc="browser"),function(t,e,r){var n=t.log;return n("There is problem here with passing the opts",t),t.nspClient=bc(Sc,Oc),!0===t.enableAuth&&(t.nspAuthClient=bc(Sc,Oc,!0)),n("[1] bindWebsocketToJsonql",r.$name,e),function(t,e,r){r("[2] setup the CONNECT_EVENT_NAME"),e.$only("__connect__",(function(e,n){return r("[3] CONNECT_EVENT_NAME",n),mc(e,t).then((function(t){return mi(Ec,t)})).then((function(r){return r(e,t,n)}))}))}(e,r,n),function(t,e,r){var n=t.log,o=e.namespaces;n("[4] loginEventHandler"),r.$only("__login__",(function(e){n("createClient LOGIN_EVENT_NAME $only handler"),Fn(r,o),t.token=e,r.$trigger("__connect__",[t,r])}))}(t,e,r),n("just before returing the values for the next operation from createClientBindingAction"),{opts:t,nspMap:e,ee:r}});return function(t,e){return void 0===t&&(t={}),void 0===e&&(e={}),_i(Ac,nc,Object.assign({},rc,e))(t)}})); +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jsonql-constants'), require('jsonql-utils/module'), require('jsonql-errors'), require('jsonql-params-validator'), require('@to1source/event'), require('jsonql-utils/src/generic'), require('jsonql-utils/src/obj-define-props'), require('jsonql-errors/src/validation-error'), require('jsonql-utils/src/namespace'), require('@jsonql/security'), require('js-cookie'), require('jsonql-utils/src/chain-promises')) : + typeof define === 'function' && define.amd ? define(['jsonql-constants', 'jsonql-utils/module', 'jsonql-errors', 'jsonql-params-validator', '@to1source/event', 'jsonql-utils/src/generic', 'jsonql-utils/src/obj-define-props', 'jsonql-errors/src/validation-error', 'jsonql-utils/src/namespace', '@jsonql/security', 'js-cookie', 'jsonql-utils/src/chain-promises'], factory) : + (global = global || self, global.jsonqlWsClient = factory(global.jsonqlConstants, global.module, global.jsonqlErrors, global.jsonqlParamsValidator, global.EventEmitterClass, global.generic, global.objDefineProps, global.JsonqlValidationError, global.namespace, global.security, global.cookies, global.chainPromises)); +}(this, (function (jsonqlConstants, module, jsonqlErrors, jsonqlParamsValidator, EventEmitterClass, generic, objDefineProps, JsonqlValidationError, namespace, security, cookies, chainPromises) { 'use strict'; + + EventEmitterClass = EventEmitterClass && Object.prototype.hasOwnProperty.call(EventEmitterClass, 'default') ? EventEmitterClass['default'] : EventEmitterClass; + JsonqlValidationError = JsonqlValidationError && Object.prototype.hasOwnProperty.call(JsonqlValidationError, 'default') ? JsonqlValidationError['default'] : JsonqlValidationError; + cookies = cookies && Object.prototype.hasOwnProperty.call(cookies, 'default') ? cookies['default'] : cookies; + + // this will be part of the init client sequence + var CSRF_HEADER_NOT_EXIST_ERR = 'CSRF header is not in the received payload'; + + /** + * Util method + * @param {string} payload return from server + * @return {object} the useful bit + */ + function extractSrvPayload(payload) { + var json = module.toJson(payload); + + if (json && typeof json === 'object') { + // note this method expect the json.data inside + return module.extractWsPayload(json) + } + + throw new jsonqlErrors.JsonqlError('extractSrvPayload', json) + } + + /** + * call the server to get a csrf token + * @return {string} formatted payload to send to the server + */ + function createInitPing() { + var ts = module.timestamp(); + + return module.createQueryStr(jsonqlConstants.INTERCOM_RESOLVER_NAME, [jsonqlConstants.SOCKET_PING_EVENT_NAME, ts]) + } + + /** + * Take the raw on.message result back then decoded it + * @param {*} payload the raw result from server + * @return {object} the csrf payload + */ + function extractPingResult(payload) { + var obj; + + var result = extractSrvPayload(payload); + + if (result && result[jsonqlConstants.DATA_KEY] && result[jsonqlConstants.DATA_KEY][jsonqlConstants.CSRF_HEADER_KEY]) { + return ( obj = {}, obj[jsonqlConstants.HEADERS_KEY] = result[jsonqlConstants.DATA_KEY], obj ) + } + + throw new jsonqlErrors.JsonqlError('extractPingResult', CSRF_HEADER_NOT_EXIST_ERR) + } + + + /** + * Create a generic intercom method + * @param {string} type the event type + * @param {array} args if any + * @return {string} formatted payload to send + */ + function createIntercomPayload(type) { + var args = [], len = arguments.length - 1; + while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; + + var ts = module.timestamp(); + var payload = [type].concat(args); + payload.push(ts); + return module.createQueryStr(jsonqlConstants.INTERCOM_RESOLVER_NAME, payload) + } + + // move the get logger stuff here + + // it does nothing + var dummyLogger = function () {}; + + /** + * re-use the debugOn prop to control this log method + * @param {object} opts configuration + * @return {function} the log function + */ + var getLogger = function (opts) { + var debugOn = opts.debugOn; + if (debugOn) { + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Reflect.apply(console.info, console, ['[jsonql-ws-client-core]' ].concat( args)); + } + } + return dummyLogger + }; + + /** + * Make sure there is a log method + * @param {object} opts configuration + * @return {object} opts + */ + var getLogFn = function (opts) { + var log = opts.log; // 1.3.9 if we pass a log method here then we use this + if (!log || typeof log !== 'function') { + return getLogger(opts) + } + opts.log('---> getLogFn user supplied log function <---', opts); + return log + }; + + // this will generate a event emitter and will be use everywhere + // create a clone version so we know which one we actually is using + var JsonqlWsEvt = /*@__PURE__*/(function (EventEmitterClass) { + function JsonqlWsEvt(logger) { + if (typeof logger !== 'function') { + throw new Error("Just die here the logger is not a function!") + } + logger("---> Create a new EventEmitter <---"); + // this ee will always come with the logger + // because we should take the ee from the configuration + EventEmitterClass.call(this, { logger: logger }); + } + + if ( EventEmitterClass ) JsonqlWsEvt.__proto__ = EventEmitterClass; + JsonqlWsEvt.prototype = Object.create( EventEmitterClass && EventEmitterClass.prototype ); + JsonqlWsEvt.prototype.constructor = JsonqlWsEvt; + + var prototypeAccessors = { name: { configurable: true } }; + + prototypeAccessors.name.get = function () { + return 'jsonql-ws-client-core' + }; + + Object.defineProperties( JsonqlWsEvt.prototype, prototypeAccessors ); + + return JsonqlWsEvt; + }(EventEmitterClass)); + + /** + * getting the event emitter + * @param {object} opts configuration + * @return {object} the event emitter instance + */ + var getEventEmitter = function (opts) { + var log = opts.log; + var eventEmitter = opts.eventEmitter; + + if (eventEmitter) { + log("eventEmitter is:", eventEmitter.name); + return eventEmitter + } + + return new JsonqlWsEvt( opts.log ) + }; + + // group all the small functions here + + /** + * WebSocket is strict about the path, therefore we need to make sure before it goes in + * @param {string} url input url + * @return {string} url with correct path name + */ + var fixWss = function (url) { + var pattern = new RegExp('^(http|https)\:\/\/', 'i'); + var result = url.match(pattern); + if (result && result.length) { + var target = result[1].toLowerCase(); + var replacement = target === 'https' ? 'wss' : 'ws'; + + return url.replace(pattern, replacement + '://') + } + + return url + }; + + + /** + * get a stock host name from browser + */ + var getHostName = function () { + try { + return [window.location.protocol, window.location.host].join('//') + } catch(e) { + throw new JsonqlValidationError(e) + } + }; + + /** + * Unbind the event, this should only get call when it's disconnected + * @param {object} ee EventEmitter + * @param {string} namespace + * @return {void} + */ + var clearMainEmitEvt = function (ee, namespace) { + var nsps = generic.toArray(namespace); + nsps.forEach(function (n) { + ee.$off(generic.createEvt(n, jsonqlConstants.EMIT_REPLY_TYPE)); + }); + }; + + /** + * Setup the IS_LOGIN_PROP_KEY IS_READY_PROP_KEY + * @param {*} client + * @return {*} client + */ + function setupStatePropKeys(client) { + return [jsonqlConstants.IS_READY_PROP_KEY, jsonqlConstants.IS_LOGIN_PROP_KEY] + // .map(key => injectToFn(client, key, false, true)) + .reduce(function (c, key) { + return objDefineProps.injectToFn(c, key, false, true) + }, client) + } + + // constants + + var EMIT_EVT = jsonqlConstants.EMIT_REPLY_TYPE; + + var UNKNOWN_RESULT = 'UKNNOWN RESULT!'; + + var MY_NAMESPACE = 'myNamespace'; + + // breaking it up further to share between methods + + /** + * break out to use in different places to handle the return from server + * @param {object} data from server + * @param {function} resolver NOT from promise + * @param {function} rejecter NOT from promise + * @return {void} nothing + */ + function respondHandler(data, resolver, rejecter) { + if (module.isObjectHasKey(data, jsonqlConstants.ERROR_KEY)) { + // debugFn('-- rejecter called --', data[ERROR_KEY]) + rejecter(data[jsonqlConstants.ERROR_KEY]); + } else if (module.isObjectHasKey(data, jsonqlConstants.DATA_KEY)) { + // debugFn('-- resolver called --', data[DATA_KEY]) + // @NOTE we change from calling it directly to use reflect + // this could have another problem later when the return data is no in an array structure + Reflect.apply(resolver, null, [].concat( data[jsonqlConstants.DATA_KEY] )); + } else { + // debugFn('-- UNKNOWN_RESULT --', data) + rejecter({message: UNKNOWN_RESULT, error: data}); + } + } + + // the actual trigger call method + + /** + * just wrapper + * @param {object} ee EventEmitter + * @param {string} namespace where this belongs + * @param {string} resolverName resolver + * @param {array} args arguments + * @param {function} log function + * @return {void} nothing + */ + function actionCall(ee, namespace, resolverName, args, log) { + if ( args === void 0 ) args = []; + + // reply event + var outEventName = module.createEvt(namespace, jsonqlConstants.EMIT_REPLY_TYPE); + + log(("actionCall: " + outEventName + " --> " + resolverName), args); + // This is the out going call + ee.$trigger(outEventName, [resolverName, module.toArray(args)]); + + // then we need to listen to the event callback here as well + return new Promise(function (resolver, rejecter) { + var inEventName = module.createEvt(namespace, resolverName, jsonqlConstants.ON_RESULT_FN_NAME); + // this cause the onResult got the result back first + // and it should be the promise resolve first + // @TODO we need to rewrote the respondHandler to change the problem stated above + ee.$on( + inEventName, + function actionCallResultHandler(result) { + log("got the first result", result); + respondHandler(result, resolver, rejecter); + } + ); + }) + } + + // setting up the send method + + /** + * pairing with the server vesrion SEND_MSG_FN_NAME + * last of the chain so only return the resolver (fn) + * This is now change to a getter / setter method + * and call like this: resolver.send(...args) + * @param {function} fn the resolver function + * @param {object} ee event emitter instance + * @param {string} namespace the namespace it belongs to + * @param {string} resolverName name of the resolver + * @param {object} params from contract + * @param {function} log a logger function + * @return {function} return the resolver itself + */ + var setupSendMethod = function (fn, ee, namespace, resolverName, params, log) { return ( + module.objDefineProps( + fn, + jsonqlConstants.SEND_MSG_FN_NAME, + module.nil, + function sendHandler() { + log("running call getter method"); + // let _log = (...args) => Reflect.apply(console.info, console, ['[SEND]'].concat(args)) + /** + * This will follow the same pattern like the resolver + * @param {array} args list of unknown argument follow the resolver + * @return {promise} resolve the result + */ + return function sendCallback() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return jsonqlParamsValidator.validateAsync(args, params.params, true) + .then(function (_args) { + // @TODO check the result + // because the validation could failed with the list of fail properties + log('execute send', namespace, resolverName, _args); + return actionCall(ee, namespace, resolverName, _args, log) + }) + .catch(function (err) { + // @TODO it shouldn't be just a validation error + // it could be server return error, so we need to check + // what error we got back here first + log('send error', err); + // @TODO it might not an validation error need the finalCatch here + ee.$call( + module.createEvt(namespace, resolverName, jsonqlConstants.ON_ERROR_FN_NAME), + [new jsonqlErrors.JsonqlValidationError(resolverName, err)] + ); + }) + } + }) + ); }; + + // break up the original setup resolver method here + + + /** + * moved back from generator-methods + * create the actual function to send message to server + * @param {object} ee EventEmitter instance + * @param {string} namespace this resolver end point + * @param {string} resolverName name of resolver as event name + * @param {object} params from contract + * @param {function} log pass the log function + * @return {function} resolver + */ + function createResolver(ee, namespace, resolverName, params, log) { + // note we pass the new withResult=true option + return function resolver() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return jsonqlParamsValidator.validateAsync(args, params.params, true) + .then(function (_args) { return actionCall(ee, namespace, resolverName, _args, log); }) + .catch(jsonqlErrors.finalCatch) + } + } + + /** + * The first one in the chain, just setup a namespace prop + * the rest are passing through + * @param {function} fn the resolver function + * @param {object} ee the event emitter + * @param {string} resolverName what it said + * @param {object} params for resolver from contract + * @param {function} log the logger function + * @return {array} + */ + var setupNamespace = function (fn, ee, namespace, resolverName, params, log) { return [ + module.injectToFn(fn, MY_NAMESPACE, namespace), + ee, + namespace, + resolverName, + params, + log + ]; }; + + /** + * onResult handler + */ + var setupOnResult = function (fn, ee, namespace, resolverName, params, log) { return [ + module.objDefineProps(fn, jsonqlConstants.ON_RESULT_FN_NAME, function(resultCallback) { + if (module.isFunc(resultCallback)) { + ee.$on( + module.createEvt(namespace, resolverName, jsonqlConstants.ON_RESULT_FN_NAME), + function resultHandler(result) { + respondHandler(result, resultCallback, function (error) { + log(("Catch error: \"" + resolverName + "\""), error); + ee.$trigger( + module.createEvt(namespace, resolverName, jsonqlConstants.ON_ERROR_FN_NAME), + error + ); + }); + } + ); + } + }), + ee, + namespace, + resolverName, + params, + log + ]; }; + + /** + * we do need to add the send prop back because it's the only way to deal with + * bi-directional data stream + */ + var setupOnMessage = function (fn, ee, namespace, resolverName, params, log) { return [ + module.objDefineProps(fn, jsonqlConstants.ON_MESSAGE_FN_NAME, function(messageCallback) { + // we expect this to be a function + if (module.isFunc(messageCallback)) { + // did that add to the callback + var onMessageCallback = function (args) { + log("onMessageCallback", args); + respondHandler( + args, + messageCallback, + function (error) { + log(("Catch error: \"" + resolverName + "\""), error); + ee.$trigger( + module.createEvt(namespace, resolverName, jsonqlConstants.ON_ERROR_FN_NAME), + error + ); + }); + }; + // register the handler for this message event + ee.$only( + module.createEvt(namespace, resolverName, jsonqlConstants.ON_MESSAGE_FN_NAME), + onMessageCallback + ); + } + }), + ee, + namespace, + resolverName, + params, + log + ]; }; + + /** + * ON_ERROR_FN_NAME handler + */ + var setupOnError = function (fn, ee, namespace, resolverName, params, log) { return [ + module.objDefineProps(fn, jsonqlConstants.ON_ERROR_FN_NAME, function(resolverErrorHandler) { + if (module.isFunc(resolverErrorHandler)) { + // please note ON_ERROR_FN_NAME can add multiple listners + ee.$only( + module.createEvt(namespace, resolverName, jsonqlConstants.ON_ERROR_FN_NAME), + resolverErrorHandler + ); + } + }), + ee, + namespace, + resolverName, + params, + log + ]; }; + + /** + * Add extra property / listeners to the resolver + * @param {string} namespace where this belongs + * @param {string} resolverName name as event name + * @param {object} params from contract + * @param {function} fn resolver function + * @param {object} ee EventEmitter + * @param {function} log function + * @return {function} resolver + */ + function setupResolver(namespace, resolverName, params, fn, ee, log) { + var fns = [ + setupNamespace, + setupOnResult, + setupOnMessage, + setupOnError, + setupSendMethod + ]; + var executor = Reflect.apply(module.chainFns, null, fns); + // get the executor + return executor(fn, ee, namespace, resolverName, params, log) + } + + // put all the resolver related methods here to make it more clear + + /** + * step one get the clientmap with the namespace + * @param {object} opts configuration + * @param {object} ee EventEmitter + * @param {object} nspGroup resolvers index by their namespace + * @return {promise} resolve the clientmapped, and start the chain + */ + function generateResolvers(opts, ee, nspGroup) { + var log = opts.log; + var client= {}; + + for (var namespace in nspGroup) { + var list = nspGroup[namespace]; + for (var resolverName in list) { + // resolverNames.push(resolverName) + var params = list[resolverName]; + var fn = createResolver(ee, namespace, resolverName, params, log); + // this should set as a getter therefore can not be overwrite by accident + client = module.injectToFn( + client, + resolverName, + setupResolver(namespace, resolverName, params, fn, ee, log) + ); + } + } + // resolve the clientto start the chain + // chain the result to allow the chain processing + return [ client, opts, ee, nspGroup ] + } + + // move from generator-methods + + /** + * This event will fire when the socket.io.on('connection') and ws.onopen + * @param {object} client client itself + * @param {object} opts configuration + * @param {object} ee Event Emitter + * @return {array} [ obj, opts, ee ] + */ + function setupOnReadyListener(client, opts, ee) { + return [ + module.objDefineProps( + client, + jsonqlConstants.ON_READY_FN_NAME, + function onReadyCallbackHandler(onReadyCallback) { + if (module.isFunc(onReadyCallback)) { + // reduce it down to just one flat level + // @2020-03-19 only allow ONE onReady callback otherwise + // it will get fire multiple times which is not what we want + ee.$only(jsonqlConstants.ON_READY_FN_NAME, onReadyCallback); + } + } + ), + opts, + ee + ] + } + + /** + * The problem is the namespace can have more than one + * and we only have on onError message + * @param {object} clientthe client itself + * @param {object} opts configuration + * @param {object} ee Event Emitter + * @param {object} nspGroup namespace keys + * @return {array} [obj, opts, ee] + */ + function setupNamespaceErrorListener(client, opts, ee, nspGroup) { + return [ + module.objDefineProps( + client, + jsonqlConstants.ON_ERROR_FN_NAME, + function namespaceErrorCallbackHandler(namespaceErrorHandler) { + if (module.isFunc(namespaceErrorHandler)) { + // please note ON_ERROR_FN_NAME can add multiple listners + for (var namespace in nspGroup) { + // this one is very tricky, we need to make sure the trigger is calling + // with the namespace as well as the error + ee.$on(module.createEvt(namespace, jsonqlConstants.ON_ERROR_FN_NAME), namespaceErrorHandler); + } + } + } + ), + opts, + ee + ] + } + + // take out from the resolver-methods + // import { validateAsync } from 'jsonql-params-validator' + + /** + * @UPDATE it might be better if we decoup the two http-client only emit a login event + * Here should catch it and reload the ws client @TBC + * break out from createAuthMethods to allow chaining call + * @TODO when this is using the standalone mode then this will have to be disable + * or delegated to the login method from the contract + * @param {object} obj the main client object + * @param {object} opts configuration + * @param {object} ee event emitter + * @return {array} [ obj, opts, ee ] what comes in what goes out + */ + var setupLoginHandler = function (obj, opts, ee) { return [ + module.injectToFn( + obj, + opts.loginHandlerName, + function loginHandler(token) { + if (token && jsonqlParamsValidator.isString(token)) { + opts.log(("Received " + jsonqlConstants.LOGIN_EVENT_NAME + " with " + token)); + // @TODO add the interceptor hook + return ee.$trigger(jsonqlConstants.LOGIN_EVENT_NAME, [token]) + } + // should trigger a global error instead @TODO + throw new jsonqlErrors.JsonqlValidationError(opts.loginHandlerName, ("Unexpected token " + token)) + } + ), + opts, + ee + ]; }; + + /** + * Switch to this one when standalone mode is enable + * @NOTE we don't actually have this because the public contract not included it + * so we need to figure out a different way to include the auth method + * that get expose to the public before we can continue with this standalone mode + * const { contract, loginHandlerName } = opts + * const params = contract[SOCKET_AUTH_NAME][loginHandlerName] + * @param {*} obj + * @param {*} opts + * @param {*} ee + */ + var setupStandaloneLoginHandler = function (obj, opts, ee) { return [ + module.injectToFn( + obj, + loginHandlerName, + function standaloneLoginHandler() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + // we only need to pass the argument + // let the listener to handle the rest + ee.$trigger(jsonqlConstants.LOGIN_EVENT_NAME, args); + } + ), + opts, + ee + ]; }; + + /** + * break out from createAuthMethods to allow chaining call - final in chain + * @param {object} obj the main client object + * @param {object} opts configuration + * @param {object} ee event emitter + * @return {array} [ obj, opts, ee ] what comes in what goes out + */ + var setupLogoutHandler = function (obj, opts, ee) { return [ + module.injectToFn( + obj, + opts.logoutHandlerName, + function logoutHandler() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + opts[jsonqlConstants.IS_LOGIN_PROP_KEY] = true; + ee.$trigger(jsonqlConstants.LOGOUT_EVENT_NAME, args); + } + ), + opts, + ee + ]; }; + + /** + * This event will fire when the socket.io.on('connection') and ws.onopen + * Plus this will check if it's the private namespace that fired the event + * @param {object} obj the client itself + * @param {object} ee Event Emitter + * @return {array} [ obj, opts, ee] what comes in what goes out + */ + var setupOnLoginListener = function (obj, opts, ee) { return [ + module.objDefineProps( + obj, + jsonqlConstants.ON_LOGIN_FN_NAME, + function onLoginCallbackHandler(onLoginCallback) { + if (module.isFunc(onLoginCallback)) { + // only one callback can registered with it, TBC + // Should this be a $onlyOnce listener after the logout + // we add it back? + ee.$only(jsonqlConstants.ON_LOGIN_FN_NAME, onLoginCallback); + } + } + ), + opts, + ee + ]; }; + + /** + * Main Create auth related methods + * @param {object} obj the client itself + * @param {object} opts configuration + * @param {object} ee Event Emitter + * @return {array} [ obj, opts, ee ] what comes in what goes out + */ + function setupAuthMethods(obj, opts, ee) { + return module.chainFns( + opts[jsonqlConstants.STANDALONE_PROP_KEY] === true ? setupStandaloneLoginHandler : setupLoginHandler, + setupLogoutHandler, + setupOnLoginListener + )(obj, opts, ee) + } + + // this is a new method that will create several + + /** + * Set up the CONNECTED_PROP_KEY to the client + * @param {*} client + * @param {*} opts + * @param {*} ee + */ + function setupConnectPropKey(client, opts, ee) { + var log = opts.log; + log('[1] setupConnectPropKey'); + // we just inject a helloWorld method here + // set up the init state of the connect + client = module.injectToFn(client, jsonqlConstants.CONNECTED_PROP_KEY , false, true); + return [ client, opts, ee ] + } + + + /** + * setup listener to the connect event + * @param {*} client + * @param {*} opts + * @param {*} ee + */ + function setupConnectEvtListener(client, opts, ee) { + // @TODO do what at this point? + var log = opts.log; + + log("[2] setupConnectEvtListener"); + + ee.$on(jsonqlConstants.CONNECT_EVENT_NAME, function() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + log("setupConnectEvtListener pass and do nothing at the moment", args); + }); + + return [client, opts, ee] + } + + /** + * setup listener to the connected event + * @param {*} client + * @param {*} opts + * @param {*} ee + */ + function setupConnectedEvtListener(client, opts, ee) { + var log = opts.log; + + log("[3] setupConnectedEvtListener"); + + ee.$on(jsonqlConstants.CONNECTED_EVENT_NAME, function() { + var obj; + + client[jsonqlConstants.CONNECTED_PROP_KEY] = true; + // new action to take release the holded event queue + var ctn = ee.$release(); + + log("CONNECTED_EVENT_NAME", true, 'queue count', ctn); + + return ( obj = {}, obj[jsonqlConstants.CONNECTED_PROP_KEY] = true, obj ) + }); + + return [client, opts, ee] + } + + /** + * Listen to the disconnect event and set the property to the client + * @param {*} client + * @param {*} opts + * @param {*} ee + */ + function setupDisconnectListener(client, opts, ee) { + var log = opts.log; + + log("[4] setupDisconnectListener"); + + ee.$on(jsonqlConstants.DISCONNECT_EVENT_NAME, function() { + var obj; + + client[jsonqlConstants.CONNECTED_PROP_KEY] = false; + log("CONNECTED_EVENT_NAME", false); + + return ( obj = {}, obj[jsonqlConstants.CONNECTED_PROP_KEY] = false, obj ) + }); + + return [client, opts, ee] + } + + /** + * disconnect action + * @param {*} client + * @param {*} opts + * @param {*} ee + * @return {object} this is the final step to return the client + */ + function setupDisconectAction(client, opts, ee) { + var disconnectHandlerName = opts.disconnectHandlerName; + var log = opts.log; + log("[5] setupDisconectAction"); + + return module.injectToFn( + client, + disconnectHandlerName, + function disconnectHandler() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + ee.$trigger(jsonqlConstants.DISCONNECT_EVENT_NAME, args); + } + ) + } + + /** + * this is the new method that setup the intercom handler + * also this serve as the final call in the then chain to + * output the client + * @param {object} client the client + * @param {object} opts configuration + * @param {object} ee the event emitter + * @return {object} client + */ + function setupInterCom(client, opts, ee) { + var fns = [ + setupConnectPropKey, + setupConnectEvtListener, + setupConnectedEvtListener, + setupDisconnectListener, + setupDisconectAction + ]; + + var executor = Reflect.apply(module.chainFns, null, fns); + return executor(client, opts, ee) + } + + // The final step of the setup before it returns the client + + + /** + * The final step to return the client + * @param {object} obj the client + * @param {object} opts configuration + * @param {object} ee the event emitter + * @return {object} client + */ + function setupFinalStep(obj, opts, ee) { + + var client = setupInterCom(obj, opts, ee); + // opts.log(`---> The final step to return the ws-client <---`) + // add some debug functions + client.verifyEventEmitter = function () { return ee.is; }; + // we add back the two things into the client + // then when we do integration, we run it in reverse, + // create the ws client first then the host client + client.eventEmitter = opts.eventEmitter; + client.log = opts.log; + + // now at this point, we are going to call the connect event + ee.$trigger(jsonqlConstants.CONNECT_EVENT_NAME, [opts, ee]); // just passing back the entire opts object + // also we can release the queue here + if (opts[jsonqlConstants.SUSPEND_EVENT_PROP_KEY] === true) { + opts.$releaseNamespace(); + } + + // finally inject some prop keys to the client + return setupStatePropKeys(obj) + } + + // resolvers generator + + /** + * This is the starting point of binding callable method to the + * ws, and we have to determine which is actually active + * if enableAuth but we don't have a token, when the connection + * to ws establish we only release the public related event + * and the private one remain hold until the LOGIN_EVENT get trigger + * @param {object} opts configuration + * @param {object} nspMap resolvers index by their namespace + * @param {object} ee EventEmitter + * @return {object} of resolvers + * @public + */ + function callersGenerator(opts, nspMap, ee) { + + var fns = [ + generateResolvers, + setupOnReadyListener, + setupNamespaceErrorListener + ]; + if (opts.enableAuth) { + // there is a problem here, when this is a public namespace + // it should not have a login logout event attach to it + fns.push(setupAuthMethods); + } + // we will always get back the [ obj, opts, ee ] + // then we only return the obj (wsClient) + // This has move outside of here, into the main method + // the reason is we could switch around the sequence much easier + fns.push(setupFinalStep); + // stupid reaon!!! + var executer = Reflect.apply(module.chainFns, null, fns); + // run it + return executer(opts, ee, nspMap[jsonqlConstants.NSP_GROUP]) + } + + var obj, obj$1; + + + + var configCheckMap = {}; + configCheckMap[jsonqlConstants.STANDALONE_PROP_KEY] = jsonqlParamsValidator.createConfig(false, [jsonqlConstants.BOOLEAN_TYPE]); + configCheckMap[jsonqlConstants.DEBUG_ON_PROP_KEY] = jsonqlParamsValidator.createConfig(false, [jsonqlConstants.BOOLEAN_TYPE]); + configCheckMap[jsonqlConstants.LOGIN_FN_NAME_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.LOGIN_FN_NAME, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.LOGOUT_FN_NAME_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.LOGOUT_FN_NAME, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.DISCONNECT_FN_NAME_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.DISCONNECT_FN_NAME, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.SWITCH_USER_FN_NAME_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.SWITCH_USER_FN_NAME, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.HOSTNAME_PROP_KEY] = jsonqlParamsValidator.createConfig(false, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.NAMESAPCE_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.JSONQL_PATH, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.WS_OPT_PROP_KEY] = jsonqlParamsValidator.createConfig({}, [jsonqlConstants.OBJECT_TYPE]); + configCheckMap[jsonqlConstants.CONTRACT_PROP_KEY] = jsonqlParamsValidator.createConfig({}, [jsonqlConstants.OBJECT_TYPE], ( obj = {}, obj[jsonqlConstants.CHECKER_KEY] = module.isContract, obj )); + configCheckMap[jsonqlConstants.ENABLE_AUTH_PROP_KEY] = jsonqlParamsValidator.createConfig(false, [jsonqlConstants.BOOLEAN_TYPE]); + configCheckMap[jsonqlConstants.TOKEN_PROP_KEY] = jsonqlParamsValidator.createConfig(false, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.CSRF_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.CSRF_HEADER_KEY, [jsonqlConstants.STRING_TYPE]); + configCheckMap[jsonqlConstants.SUSPEND_EVENT_PROP_KEY] = jsonqlParamsValidator.createConfig(false, [jsonqlConstants.BOOLEAN_TYPE]); + + // socket client + var socketCheckMap = {}; + socketCheckMap[jsonqlConstants.SOCKET_TYPE_PROP_KEY] = jsonqlParamsValidator.createConfig(null, [jsonqlConstants.STRING_TYPE], ( obj$1 = {}, obj$1[jsonqlConstants.ALIAS_KEY] = jsonqlConstants.SOCKET_TYPE_CLIENT_ALIAS, obj$1 )); + + var wsCoreCheckMap = Object.assign(configCheckMap, socketCheckMap); + + // constant props + var wsCoreConstProps = {}; + wsCoreConstProps[jsonqlConstants.USE_JWT_PROP_KEY] = true; + wsCoreConstProps.log = null; + wsCoreConstProps.eventEmitter = null; + wsCoreConstProps.nspClient = null; + wsCoreConstProps.nspAuthClient = null; + wsCoreConstProps.wssPath = ''; + wsCoreConstProps.publicNamespace = jsonqlConstants.PUBLIC_KEY; + wsCoreConstProps.privateNamespace = jsonqlConstants.PRIVATE_KEY; + + // create options + + + /** + * wrapper method to check this already did the pre check + * @param {object} config user supply config + * @param {object} defaultOptions for checking + * @param {object} constProps user supply const props + * @return {promise} resolve to the checked opitons + */ + function checkConfiguration(config, defaultOptions, constProps) { + var defaultCheckMap= Object.assign(wsCoreCheckMap, defaultOptions); + var wsConstProps = Object.assign(wsCoreConstProps, constProps); + + return jsonqlParamsValidator.checkConfigAsync(config, defaultCheckMap, wsConstProps) + } + + /** + * Taking the `then` part from the method below + * @param {object} opts + * @return {promise} opts all done + */ + function postCheckInjectOpts(opts) { + + return Promise.resolve(opts) + .then(function (opts) { + if (!opts.hostname) { + opts.hostname = getHostName(); + } + // @TODO the contract now will supply the namespace information + // and we need to use that to group the namespace call + + opts.wssPath = fixWss([opts.hostname, opts.namespace].join('/'), opts.serverType); + // get the log function here + opts.log = getLogFn(opts); + + opts.eventEmitter = getEventEmitter(opts); + + return opts + }) + } + + /** + * Don't want to make things confusing + * Breaking up the opts process in one place + * then generate the necessary parameter in another step + * @2020-3-20 here we suspend operation by it's namespace first + * Then in the framework part, after the connection establish we release + * the queue + * @param {object} opts checked --> merge --> injected + * @return {object} {opts, nspMap, ee} + */ + function createRequiredParams(opts) { + var nspMap = module.getNspInfoByConfig(opts); + var ee = opts.eventEmitter; + // @TODO here we are going to add suspend event to the namespace related methods + var log = opts.log; + var namespaces = nspMap.namespaces; + var publicNamespace = nspMap.publicNamespace; + log("namespaces", namespaces); + // next we loop the namespace and suspend all the events prefix with namespace + if (opts[jsonqlConstants.SUSPEND_EVENT_PROP_KEY] === true) { + // ON_READY_FN_NAME + // ON_LOGIN_FN_NAME + + // we create this as a function then we can call it again + // @TODO we need to add the onReady and the onLogin in the suspend list as well + opts.$suspendNamepsace = function () { + var eventNames = [jsonqlConstants.ON_RESULT_FN_NAME ].concat( namespaces); + if (opts.enableAuth) { + eventNames.push(jsonqlConstants.ON_LOGIN_FN_NAME); + } + // [ON_READY_FN_NAME, ON_LOGIN_FN_NAME, ...namespaces] + Reflect.apply(ee.$suspendEvent, ee, eventNames); + }; + // then we create a new method to releas the queue + // we prefix it with the $ to notify this is not a jsonql part methods + opts.$releaseNamespace = function () { + ee.$releaseEvent(jsonqlConstants.ON_RESULT_FN_NAME, publicNamespace); + }; + + if (opts.enableAuth) { + opts.$releasePrivateNamespace = function () { + ee.$releaseEvent(jsonqlConstants.ON_LOGIN_FN_NAME, namespaces[1]); + }; + } + + // now run it + opts.$suspendNamepsace(); + } + + return { opts: opts, nspMap: nspMap, ee: ee } + } + + // the top level API + + + /** + * 0.5.0 we break up the wsClientCore in two parts one without the config check + * @param {function} setupSocketClientListener just make sure what it said it does + * @return {function} to actually generate the client + */ + function wsClientCoreAction(setupSocketClientListener) { + /** + * This is a breaking change, to continue the onion skin design + * @param {object} config the already checked config + * @return {promise} resolve the client + */ + return function createClientAction(config) { + if ( config === void 0 ) config = {}; + + + return postCheckInjectOpts(config) + .then(createRequiredParams) + .then( + function (ref) { + var opts = ref.opts; + var nspMap = ref.nspMap; + var ee = ref.ee; + + return setupSocketClientListener(opts, nspMap, ee); + } + ) + .then( + function (ref) { + var opts = ref.opts; + var nspMap = ref.nspMap; + var ee = ref.ee; + + return callersGenerator(opts, nspMap, ee); + } + ) + .catch(function (err) { + console.error("[jsonql-ws-core-client init error]", err); + }) + } + } + + /** + * The main interface which will generate the socket clients and map all events + * @param {object} socketClientListerner this is the one method export by various clients + * @param {object} [configCheckMap={}] we should do all the checking in the core instead of the client + * @param {object} [constProps={}] add this to supply the constProps from the downstream client + * @return {function} accept a config then return the wsClient instance with all the available API + */ + function wsClientCore(socketClientListener, configCheckMap, constProps) { + if ( configCheckMap === void 0 ) configCheckMap = {}; + if ( constProps === void 0 ) constProps = {}; + + // we need to inject property to this client later + return function (config) { + if ( config === void 0 ) config = {}; + + return checkConfiguration(config, configCheckMap, constProps) + .then( + wsClientCoreAction(socketClientListener) + ); + } + } + + // this use by client-event-handler + + /** + * trigger errors on all the namespace onError handler + * @param {object} ee Event Emitter + * @param {array} namespaces nsps string + * @param {string} message optional + * @return {void} + */ + function triggerNamespacesOnError(ee, namespaces, message) { + namespaces.forEach( function (namespace) { + ee.$trigger( + module.createEvt(namespace, jsonqlConstants.ON_ERROR_FN_NAME), + [{ message: message, namespace: namespace }] + ); + }); + } + + /** + * Handle the onerror callback + * @param {object} ee event emitter + * @param {string} namespace which namespace has error + * @param {*} err error object + * @return {void} + */ + var handleNamespaceOnError = function (ee, namespace, err) { + ee.$trigger(module.createEvt(namespace, jsonqlConstants.ON_ERROR_FN_NAME), [err]); + }; + + // NOT IN USE AT THE MOMENT JUST KEEP IT HERE FOR THE TIME BEING + + /** + * A Event Listerner placeholder when it's not connect to the private nsp + * @param {string} namespace nsp + * @param {object} ee EventEmitter + * @param {object} opts configuration + * @return {void} + */ + var notLoginListener = function (namespace, ee, opts) { + var log = opts.log; + + ee.$only( + module.createEvt(namespace, EMIT_EVT), + function notLoginListernerCallback(resolverName, args) { + log('[notLoginListerner] hijack the ws call', namespace, resolverName, args); + var error = { message: jsonqlConstants.NOT_LOGIN_ERR_MSG }; + // It should just throw error here and should not call the result + // because that's channel for handling normal event not the fake one + ee.$call(module.createEvt(namespace, resolverName, jsonqlConstants.ON_ERROR_FN_NAME), [ error ]); + // also trigger the result Listerner, but wrap inside the error key + ee.$call(module.createEvt(namespace, resolverName, jsonqlConstants.ON_RESULT_FN_NAME), [{ error: error }]); + } + ); + }; + + /** + * Only when there is a private namespace then we bind to this event + * @param {object} nsps the available nsp(s) + * @param {array} namespaces available namespace + * @param {object} ee eventEmitter + * @param {object} opts configuration + * @return {void} + */ + var logoutEvtListener = function (nsps, namespaces, ee, opts) { + var log = opts.log; + // this will be available regardless enableAuth + // because the server can log the client out + ee.$on( + jsonqlConstants.LOGOUT_EVENT_NAME, + function logoutEvtCallback() { + var privateNamespace = getPrivateNamespace(namespaces); + log((jsonqlConstants.LOGOUT_EVENT_NAME + " event triggered")); + // disconnect(nsps, opts.serverType) + // we need to issue error to all the namespace onError Listerner + triggerNamespacesOnError(ee, [privateNamespace], jsonqlConstants.LOGOUT_EVENT_NAME); + // rebind all of the Listerner to the fake one + log(("logout from " + privateNamespace)); + + clearMainEmitEvt(ee, privateNamespace); + // we need to issue one more call to the server before we disconnect + // now this is a catch 22, here we are not suppose to do anything platform specific + // so that should fire before trigger this event + // clear out the nsp + nsps[privateNamespace] = null; + // add a NOT LOGIN error if call + notLoginWsListerner(privateNamespace, ee, opts); + } + ); + }; + + // This is share between different clients so we export it + + /** + * centralize all the comm in one place + * @param {function} bindSocketEventHandler binding the ee to ws --> this is the core bit + * @param {object} nsps namespaced nsp + * @return {void} nothing + */ + function namespaceEventListener(bindSocketEventListener, nsps) { + /** + * BREAKING CHANGE instead of one flat structure + * we return a function to accept the two + * @param {object} opts configuration + * @param {object} nspMap this is not in the opts + * @param {object} ee Event Emitter instance + * @return {array} although we return something but this is the last step and nothing to do further + */ + return function (opts, nspMap, ee) { + // since all these params already in the opts + var log = opts.log; + var namespaces = nspMap.namespaces; + // @1.1.3 add isPrivate prop to id which namespace is the private nsp + // then we can use this prop to determine if we need to fire the ON_LOGIN_PROP_NAME event + var privateNamespace = namespace.getPrivateNamespace(namespaces); + // The total number of namespaces (which is 2 at the moment) minus the private namespace number + var ctn = namespaces.length - 1; + // @NOTE we need to somehow id if this namespace already been connected + // and the event been released before + return namespaces.map(function (namespace) { + var isPrivate = privateNamespace === namespace; + log(namespace, (" --> " + (isPrivate ? 'private': 'public') + " nsp --> "), nsps[namespace] !== false); + if (nsps[namespace]) { + log('[call bindWsHandler]', isPrivate, namespace); + // we need to add one more property here to tell the bindSocketEventListener + // how many times it should call the onReady + var args = [namespace, nsps[namespace], ee, isPrivate, opts, --ctn]; + // Finally we binding everything together + Reflect.apply(bindSocketEventListener, null, args); + + } else { + log(("binding notLoginWsHandler to " + namespace)); + // a dummy placeholder + // @TODO but it should be a not connect handler + // when it's not login (or fail) this should be handle differently + notLoginListener(namespace, ee, opts); + } + if (isPrivate) { + log("Has private and add logoutEvtHandler"); + logoutEvtListener(nsps, namespaces, ee, opts); + } + // just return something its not going to get use anywhere + return isPrivate + }) + } + } + + /* + This two client is the final one that gets call + all it does is to create the url that connect to + and actually trigger the connection and return the socket + therefore they are as generic as it can be + */ + + /** + * wrapper method to create a nsp without login + * @param {string|boolean} namespace namespace url could be false + * @param {object} opts configuration + * @return {object} ws client instance + */ + function createNspClient(namespace, opts) { + var hostname = opts.hostname; + var wssPath = opts.wssPath; + var nspClient = opts.nspClient; + var log = opts.log; + var url = namespace ? [hostname, namespace].join('/') : wssPath; + log("createNspClient with URL --> ", url); + + return nspClient(url, opts) + } + + /** + * wrapper method to create a nsp with token auth + * @param {string} namespace namespace url + * @param {object} opts configuration + * @return {object} ws client instance + */ + function createNspAuthClient(namespace, opts) { + var hostname = opts.hostname; + var wssPath = opts.wssPath; + var token = opts.token; + var nspAuthClient = opts.nspAuthClient; + var log = opts.log; + var url = namespace ? [hostname, namespace].join('/') : wssPath; + + log("createNspAuthClient with URL -->", url); + + if (token && typeof token !== 'string') { + throw new Error(("Expect token to be string, but got " + token)) + } + // now we need to get an extra options for framework specific method, which is not great + // instead we just pass the entrie opts to the authClient + + return nspAuthClient(url, opts, token) + } + + var obj$2; + + var AVAILABLE_PLACES = [ + jsonqlConstants.TOKEN_IN_URL, + jsonqlConstants.TOKEN_IN_HEADER + ]; + + // constant props + var wsClientConstProps = { + version: 'version: 1.2.0 module: umd', // will get replace + serverType: jsonqlConstants.JS_WS_NAME + }; + + var wsClientCheckMap = {}; + wsClientCheckMap[jsonqlConstants.TOKEN_DELIVER_LOCATION_PROP_KEY] = jsonqlParamsValidator.createConfig(jsonqlConstants.TOKEN_IN_URL, [jsonqlConstants.STRING_TYPE], ( obj$2 = {}, obj$2[jsonqlConstants.ENUM_KEY] = AVAILABLE_PLACES, obj$2 )); + + // this is all the isormophic-ws is + var ws = null; + + if (typeof WebSocket !== 'undefined') { + ws = WebSocket; + } else if (typeof MozWebSocket !== 'undefined') { + ws = MozWebSocket; + } else if (typeof global !== 'undefined') { + ws = global.WebSocket || global.MozWebSocket; + } else if (typeof window !== 'undefined') { + ws = window.WebSocket || window.MozWebSocket; + } else if (typeof self !== 'undefined') { + ws = self.WebSocket || self.MozWebSocket; + } + + var ws$1 = ws; + + /** + * This will get re-use when we start using the disconnect event method + * @param {*} ws + * @return {void} + */ + function disconnect(ws) { + if (ws.terminate && module.isFunc(ws.terminate)) { + ws.terminate(); + } else if (ws.close && module.isFunc(ws.close)) { + ws.close(); + } + } + + // pass the different type of ws to generate the client + + /** + * + * @param {*} WebSocketClass + * @param {*} url + * @param {*} type + * @param {*} options + */ + function createWs(WebSocketClass, type, url, options) { + if (type === 'browser') { + var headers = options.headers; + if (headers) { + for (var key in headers) { + if (!cookies.get(key)) { + cookies.set(key, headers[key]); + } + } + } + } + var wsUrl = fixWss(url); + return type === 'node' ? new WebSocketClass(wsUrl, options) : new WebSocketClass(wsUrl) + } + + /** + * Group the ping and get respond create new client in one + * @param {object} ws + * @param {object} WebSocket + * @param {string} url + * @param {function} resolver + * @param {function} rejecter + * @param {boolean} auth client or not + * @return {promise} resolve the confirm client + */ + function initPingAction(ws, WebSocketClass, type, url, wsOptions, resolver, rejecter) { + + // @TODO how to we id this client can issue a CSRF + // by origin? + ws.onopen = function onOpenCallback() { + ws.send(createInitPing()); + }; + + ws.onmessage = function onMessageCallback(payload) { + try { + var header = extractPingResult(payload.data); + // delay or not show no different but just on the safe side + setTimeout(function () { + disconnect(ws); + }, 50); + var newWs = createWs(WebSocketClass, type, url, Object.assign(wsOptions, header)); + + resolver(newWs); + + } catch(e) { + rejecter(e); + } + }; + + ws.onerror = function onErrorCallback(err) { + rejecter(err); + }; + } + + /** + * less duplicated code the better + * @param {object} WebSocket + * @param {string} type we need to change the way how it deliver header for different platform + * @param {string} url formatted url + * @param {object} options or not + * @return {promise} resolve the actual verified client + */ + function asyncConnect(WebSocketClass, type, url, options) { + + return new Promise(function (resolver, rejecter) { + var unconfirmClient = createWs(WebSocketClass, type, url, options); + + return initPingAction(unconfirmClient, WebSocketClass, type, url, options, resolver, rejecter) + }) + } + + /** + * The bug was in the wsOptions where ws don't need it but socket.io do + * therefore the object was pass as second parameter! + * @NOTE here we only return a method to create the client, it might not get call + * @param {object} WebSocket the client or node version of ws + * @param {string} [type = 'browser'] we need to tell if this is browser or node + * @param {boolean} [auth = false] if it's auth then 3 param or just one + * @return {function} the client method to connect to the ws socket server + */ + function setupWebsocketClientFn(WebSocketClass, type, auth) { + if ( type === void 0 ) type = 'browser'; + if ( auth === void 0 ) auth = false; + + if (auth === false) { + /** + * Create a non-protected client + * @param {string} uri already constructed url + * @param {object} config from the ws-client-core this will be wsOptions taken out from opts + * @return {promise} resolve to the confirmed client + */ + return function createWsClient(uri, config) { + // const { log } = config + var ref = security.prepareConnectConfig(uri, config, false); + var url = ref.url; + var opts = ref.opts; + + return asyncConnect(WebSocketClass, type, url, opts) + } + } + + /** + * Create a client with auth token + * @param {string} uri start with ws:// @TODO check this? + * @param {object} config this is the full configuration because we need something from it + * @param {string} token the jwt token + * @return {object} ws instance + */ + return function createWsAuthClient(uri, config, token) { + // const { log } = config + var ref = security.prepareConnectConfig(uri, config, token); + var url = ref.url; + var opts = ref.opts; + + return asyncConnect(WebSocketClass, type, url, opts) + } + } + + // @BUG when call disconnected + + /** + * when we received a login event + * from the http-client or the standalone login call + * we received a token here --> update the opts then trigger + * the CONNECT_EVENT_NAME again + * @param {object} opts configurations + * @param {object} nspMap contain all the required info + * @param {object} ee event emitter + * @return {void} + */ + function loginEventListener(opts, nspMap, ee) { + var log = opts.log; + var namespaces = nspMap.namespaces; + + log("[4] loginEventHandler"); + + ee.$only(jsonqlConstants.LOGIN_EVENT_NAME, function loginEventHandlerCallback(tokenFromLoginAction) { + + log('createClient LOGIN_EVENT_NAME $only handler'); + // @NOTE this is wrong because whenever start it will connect the to the public + // but when login it should just start binding the private event + clearMainEmitEvt(ee, namespaces); + // reload the nsp and rebind all the events + opts.token = tokenFromLoginAction; + ee.$trigger(jsonqlConstants.CONNECT_EVENT_NAME, [opts, ee]); // don't need to pass the nspMap + }); + } + + // actually binding the event client to the socket client + + /** + * Because the nsps can be throw away so it doesn't matter the scope + * this will get reuse again + * @NOTE when we enable the standalone method this sequence will not change + * only call and reload + * @param {object} opts configuration + * @param {object} nspMap from contract + * @param {string|null} token whether we have the token at run time + * @return {promise} resolve the nsps namespace with namespace as key + */ + var createNsp = function(opts, nspMap, token) { + if ( token === void 0 ) token = null; + + // we leave the token param out because it could get call by another method + token = token || opts.token; + var publicNamespace = nspMap.publicNamespace; + var namespaces = nspMap.namespaces; + var log = opts.log; + log("createNspAction", 'publicNamespace', publicNamespace, 'namespaces', namespaces); + + // reverse the namespaces because it got stuck for some reason + // const reverseNamespaces = namespaces.reverse() + if (opts.enableAuth) { + return chainPromises.chainPromises( + namespaces.map(function (namespace, i) { + if (i === 0) { + if (token) { + opts.token = token; + log('create createNspAuthClient at run time'); + return createNspAuthClient(namespace, opts) + } + return Promise.resolve(false) + } + return createNspClient(namespace, opts) + }) + ) + .then(function (results) { return results.map(function (result, i) { + var obj; + + return (( obj = {}, obj[namespaces[i]] = result, obj )); + }) + .reduce(function (a, b) { return Object.assign(a, b); }, {}); } + ) + } + + return createNspClient(false, opts) + .then(function (nsp) { + var obj; + + return (( obj = {}, obj[publicNamespace] = nsp, obj )); + }) + }; + + // taken out from the bind-socket-event-handler + + /** + * This is the actual logout (terminate socket connection) handler + * There is another one that is handle what should do when this happen + * @param {object} ee eventEmitter + * @param {object} ws the WebSocket instance + * @return {void} + */ + function disconnectEventListener(ee, ws) { + // listen to the LOGOUT_EVENT_NAME when this is a private nsp + ee.$on(jsonqlConstants.DISCONNECT_EVENT_NAME, function closeEvtHandler() { + try { + // @TODO we need find a way to get the userdata + ws.send(createIntercomPayload(LOGOUT_EVENT_NAME)); + log('terminate ws connection'); + ws.terminate(); + } catch(e) { + console.error('ws.terminate error', e); + } + }); + } + + // the WebSocket main handler + + /** + * in some edge case we might not even have a resolverName, then + * we issue a global error for the developer to catch it + * @param {object} ee event emitter + * @param {string} namespace nsp + * @param {string} resolverName resolver + * @param {object} json decoded payload or error object + * @return {undefined} nothing return + */ + var errorTypeHandler = function (ee, namespace, resolverName, json) { + var evt = [namespace]; + if (resolverName) { + evt.push(resolverName); + } + evt.push(jsonqlConstants.ON_ERROR_FN_NAME); + var evtName = Reflect.apply(module.createEvt, null, evt); + // test if there is a data field + var payload = json.data || json; + ee.$trigger(evtName, [payload]); + }; + + /** + * Binding the event to socket normally + * @param {string} namespace + * @param {object} ws the nsp + * @param {object} ee EventEmitter + * @param {boolean} isPrivate to id if this namespace is private or not + * @param {object} opts configuration + * @param {number} ctnLeft in the namespaceEventListener count down how many namespace left to call + * @return {object} promise resolve after the onopen event + */ + function bindSocketEventHandler(namespace, ws, ee, isPrivate, opts, ctnLeft) { + var log = opts.log; + // setup the logut event listener + // this will hear the event and actually call the ws.terminate + if (isPrivate) { + log('Private namespace', namespace, ' binding to the DISCONNECT ws.terminate'); + disconnectEventListener(ee, ws); + } + // log(`log test, isPrivate:`, isPrivate) + // connection open + ws.onopen = function onOpenCallback() { + + log('client.ws.onopen listened -->', namespace); + /* + This is the change from before about the hooks + now only the public namespace will get trigger the onReady + and the private one will get the onLogin + this way, we won't get into the problem of multiple event + get trigger, and for developer they just have to place + the callback inside the right hook + */ + if (isPrivate) { + log(("isPrivate and fire the " + jsonqlConstants.ON_LOGIN_FN_NAME)); + ee.$call(jsonqlConstants.ON_LOGIN_FN_NAME)(namespace); + } else { + ee.$call(jsonqlConstants.ON_READY_FN_NAME)(namespace, ctnLeft); + // The namespaceEventListener will count this for here + // and this count will only count the public namespace + // it will always be 1 for now + log("isPublic onReady hook executed", ctnLeft); + if (ctnLeft === 0) { + ee.$off(jsonqlConstants.ON_READY_FN_NAME); + } + } + // add listener only after the open is called + ee.$only( + module.createEvt(namespace, jsonqlConstants.EMIT_REPLY_TYPE), + /** + * actually send the payload to server + * @param {string} resolverName + * @param {array} args NEED TO CHECK HOW WE PASS THIS! + */ + function wsMainOnEvtHandler(resolverName, args) { + var payload = module.createQueryStr(resolverName, args); + log('ws.onopen.send', resolverName, args, payload); + + ws.send(payload); + } + ); + }; + + // reply + // If we change it to the event callback style + // then the payload will just be the payload and fucks up the extractWsPayload call @TODO + ws.onmessage = function onMessageCallback(payload) { + + log("client.ws.onmessage raw payload", payload.data); + + // console.log(`on.message`, typeof payload, payload) + try { + // log(`ws.onmessage raw payload`, payload) + // @TODO the payload actually contain quite a few things - is that changed? + // type: message, data: data_send_from_server + var json = module.extractWsPayload(payload.data); + var resolverName = json.resolverName; + var type = json.type; + + log('Respond from server', type, json); + + switch (type) { + case jsonqlConstants.EMIT_REPLY_TYPE: + var e1 = module.createEvt(namespace, resolverName, jsonqlConstants.ON_MESSAGE_FN_NAME); + var r = ee.$call(e1)(json); + + log("EMIT_REPLY_TYPE", e1, r); + break + case jsonqlConstants.ACKNOWLEDGE_REPLY_TYPE: + var e2 = module.createEvt(namespace, resolverName, jsonqlConstants.ON_RESULT_FN_NAME); + var x2 = ee.$call(e2)(json); + + log("ACKNOWLEDGE_REPLY_TYPE", e2, x2); + break + case jsonqlConstants.ERROR_KEY: + // this is handled error and we won't throw it + // we need to extract the error from json + log("ERROR_KEY"); + errorTypeHandler(ee, namespace, resolverName, json); + break + // @TODO there should be an error type instead of roll into the other two types? TBC + default: + // if this happen then we should throw it and halt the operation all together + log('Unhandled event!', json); + errorTypeHandler(ee, namespace, resolverName, json); + // let error = {error: {'message': 'Unhandled event!', type}}; + // ee.$trigger(createEvt(namespace, resolverName, ON_RESULT_FN_NAME), [error]) + } + } catch(e) { + log("client.ws.onmessage error", e); + errorTypeHandler(ee, namespace, false, e); + } + }; + // when the server close the connection + ws.onclose = function onCloseCallback() { + log('client.ws.onclose callback'); + // @TODO what to do with this + // ee.$trigger(LOGOUT_EVENT_NAME, [namespace]) + }; + // add a onerror event handler here + ws.onerror = function onErrorCallback(err) { + // trigger a global error event + log("client.ws.onerror", err); + handleNamespaceOnError(ee, namespace, err); + }; + + // we don't bind the logut here and just return the ws + return ws + } + + // take out from the bind-framework-to-jsonql + + /** + * This is the hard of establishing the connection and binding to the jsonql events + * @param {*} nspMap + * @param {*} ee event emitter + * @param {function} log function to show internal + * @return {void} + */ + function connectEventListener(nspMap, ee, log) { + log("[2] setup the CONNECT_EVENT_NAME"); + // this is a automatic trigger from within the framework + ee.$only(jsonqlConstants.CONNECT_EVENT_NAME, function connectEventNameHandler($config, $ee) { + log("[3] CONNECT_EVENT_NAME", $config); + + return createNsp($config, nspMap) + .then(function (nsps) { return namespaceEventListener(bindSocketEventHandler, nsps); }) + .then(function (listenerFn) { return listenerFn($config, nspMap, $ee); }) + }); + } + + // share method to create the wsClientResolver + + /** + * Create the framework <---> jsonql client binding + * @param {object} WebSocketClass the different WebSocket module + * @param {string} [type=browser] we need different setup for browser or node + * @return {function} the wsClientResolver + */ + function setupConnectClient(WebSocketClass, type) { + if ( type === void 0 ) type = 'browser'; + + /** + * wsClientResolver + * @param {object} opts configuration + * @param {object} nspMap from the contract + * @param {object} ee instance of the eventEmitter + * @return {object} passing the same 3 input out with additional in the opts + */ + return function createClientBindingAction(opts, nspMap, ee) { + var log = opts.log; + + log("There is problem here with passing the opts", opts); + // this will put two callable methods into the opts + opts[jsonqlConstants.NSP_CLIENT] = setupWebsocketClientFn(WebSocketClass, type); + // we don't need this one unless enableAuth === true + if (opts[jsonqlConstants.ENABLE_AUTH_PROP_KEY] === true) { + opts[jsonqlConstants.NSP_AUTH_CLIENT] = setupWebsocketClientFn(WebSocketClass, type, true); + } + // debug + log("[1] bindWebsocketToJsonql", ee.$name, nspMap); + // @2020-03-20 @NOTE + + connectEventListener(nspMap, ee, log); + + // next we need to setup the login event handler + // But the same design (see above) when we received a login event + // from the http-client or the standalone login call + // we received a token here --> update the opts then trigger + // the CONNECT_EVENT_NAME again + loginEventListener(opts, nspMap, ee); + + log("just before returing the values for the next operation from createClientBindingAction"); + + // we just return what comes in + return { opts: opts, nspMap: nspMap, ee: ee } + } + } + + // this will be the news style interface that will pass to the jsonql-ws-client + + var setupSocketClientListener = setupConnectClient(ws$1); + + // this is the module entry point for ES6 for client + + // export back the function and that's it + function wsBrowserClient(config, constProps) { + if ( config === void 0 ) config = {}; + if ( constProps === void 0 ) constProps = {}; + + return wsClientCore( + setupSocketClientListener, + wsClientCheckMap, + Object.assign({}, wsClientConstProps, constProps) + )(config) + } + + // just export interface for browser + + return wsBrowserClient; + +}))); //# sourceMappingURL=jsonql-ws-client.umd.js.map diff --git a/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js.map b/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js.map index 1dde4399..c95a2c19 100644 --- a/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js.map +++ b/packages/@jsonql/ws/dist/jsonql-ws-client.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-ws-client.umd.js","sources":["../../../ws-client-core/node_modules/lodash-es/isObjectLike.js","../../../ws-client-core/node_modules/lodash-es/_arraySome.js","../../../ws-client-core/node_modules/@to1source/event/src/suspend.js","../../../ws-client-core/src/options/index.js"],"sourcesContent":["/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","// making all the functionality on it's own\n// import { WatchClass } from './watch'\n/*\nwe use a different way to do the same watch thing now\nthis.watch('suspend', function(value, prop, oldValue) {\n this.logger(`${prop} set from ${oldValue} to ${value}`)\n // it means it set the suspend = true then release it\n if (oldValue === true && value === false) {\n // we want this happen after the return happens\n setTimeout(() => {\n this.release()\n }, 1)\n }\n return value; // we need to return the value to store it\n})\n*/\nimport { getRegex, isRegExp } from './utils'\n\nimport BaseClass from './base'\n\nexport default class SuspendClass extends BaseClass {\n\n constructor() {\n super()\n // suspend, release and queue\n this.__suspend_state__ = null\n // to do this proper we don't use a new prop to hold the event name pattern\n // @1.2.2 this become an array so we can hold different events\n this.__pattern__ = []\n // key value pair store to store the queued calls\n this.queueStore = new Set()\n }\n\n /**\n * start suspend\n * @return {void}\n */\n $suspend() {\n this.logger(`---> SUSPEND ALL OPS <---`)\n this.__suspend__(true)\n }\n\n /**\n * release the queue\n * @return {void}\n */\n $release() {\n this.logger(`---> RELEASE ALL SUSPENDED QUEUE <---`)\n this.__suspend__(false)\n }\n\n /**\n * suspend event by pattern\n * @param {array.} patterns the pattern search matches the event name\n * @return {array} if the pattern return is registered or not\n */\n $suspendEvent(...patterns) {\n return patterns.map(pattern => {\n const regex = getRegex(pattern)\n if (isRegExp(regex)) {\n // check if it's already added \n if (this.__isPatternRegisterd(regex) === false) {\n this.__pattern__.push(regex)\n\n return this.__pattern__.length\n }\n return false\n }\n throw new Error(`We expect a pattern variable to be string or RegExp, but we got \"${typeof regex}\" instead`)\n })\n }\n\n /**\n * This is pair with $suspnedEvent to release part of the event queue by the pattern (eventName)\n * @param {array.<*>} patterns a eventName of partial eventName to create a RegExp\n * @return {number} should be the number of queue got released\n */\n $releaseEvent(...patterns) {\n return patterns.map(pattern => {\n this.logger(`($releaseEvent)`, pattern)\n const regex = getRegex(pattern)\n if (isRegExp(regex) && this.__isPatternRegisterd(regex)) {\n const self = this\n\n return this.__getToReleaseQueue(regex)\n .map((args, i) => {\n \n Reflect.apply(self.$trigger, self, args)\n\n return i \n }).reduce((a, b) => ++b, 0)\n }\n\n this.logger('$releaseEvent throw error ==========================>', this.__pattern__, regex)\n throw new Error(`We expect a pattern variable to be string or RegExp, but we got \"${typeof regex}\" instead`)\n })\n .reduce((x, y) => x + y, 0)\n }\n\n /**\n * queuing call up when it's in suspend mode,\n * it's currently suspending then add to store then the $trigger will do nothing\n * @param {string} evt the event name\n * @param {*} args unknown number of arguments\n * @return {boolean} true when added or false when it's not\n */\n $queue(evt, ...args) {\n switch (true) {\n case this.__suspend_state__ === true: // this will take priority over the pattern\n \n return this.__addToQueueStore(evt, args)\n case !!this.__pattern__.length === true: \n // check the pattern and decide if we want to suspend it or not\n if (!!this.__pattern__.filter(p => p.test(evt)).length) {\n \n return this.__addToQueueStore(evt, args)\n }\n this.logger(`($queue) ${evt} NOT added to $queueStore`, this.__pattern__)\n \n return false \n default:\n this.logger('($queue) get called NOTHING added')\n return false\n } \n }\n\n /**\n * a getter to get all the store queue\n * @return {array} Set turn into Array before return\n */\n get $queues() {\n let size = this.queueStore.size\n this.logger('($queues)', `size: ${size}`)\n if (size > 0) {\n return Array.from(this.queueStore)\n }\n return []\n }\n\n\n /**\n * The reason is before we call $trigger we need to remove the pattern from queue\n * otherwise, it will never get release\n * @param {*} pattern to find the queue \n * @return {array} queue to get execute \n */\n __getToReleaseQueue(regex) {\n // first get the list of events in the queue store that match this pattern\n const list = this.$queues\n // first index is the eventName\n .filter(content => regex.test(content[0]))\n .map(content => {\n this.logger(`[release] execute ${content[0]} matches ${regex}`, content)\n // we just remove it\n this.queueStore.delete(content)\n \n return content\n })\n if (list.length > 0) {\n // we need to remove this event from the pattern queue array \n this.__pattern__ = this.__pattern__.filter(p => p.toString() !== regex.toString()) \n }\n\n return list \n }\n\n /**\n * Wrapper method with a logger \n * @param {*} evt \n * @param {*} args \n * @return {boolean}\n */\n __addToQueueStore(evt, args) {\n this.logger(`($queue) ${evt} added to $queueStore`, args)\n\n // @TODO should we check if this already added? \n // what if that is a multiple call like $on\n this.queueStore.add([evt].concat(args))\n\n return true\n }\n\n /**\n * check if certain pattern already registered in the queue\n * @param {*} pattern\n * @return {boolean} \n */\n __isPatternRegisterd(pattern) {\n // this is a bit of a hack to compare two regex Object \n return !!this.__pattern__.filter(p => (\n p.toString() === pattern.toString()\n )).length \n }\n\n /**\n * to set the suspend and check if it's boolean value\n * @param {boolean} value to trigger\n */\n __suspend__(value) {\n if (typeof value === 'boolean') {\n const lastValue = this.__suspend_state__\n this.__suspend_state__ = value\n this.logger(`($suspend) Change from \"${lastValue}\" --> \"${value}\"`)\n if (lastValue === true && value === false) {\n this.__release__()\n }\n } else {\n throw new Error(`$suspend only accept Boolean value! we got ${typeof value}`)\n }\n }\n\n /**\n * Release the queue, this is a wholesale release ALL\n * @return {int} size if any\n */\n __release__() {\n let size = this.queueStore.size\n let pattern = this.__pattern__\n this.__pattern__ = []\n \n this.logger(`(release) was called with ${size}${pattern.length ? ' for \"' + pattern.join(',') + '\"': ''} item${size > 1 ? 's' : ''}`)\n \n if (size > 0) {\n const queue = Array.from(this.queueStore)\n this.logger('(release queue)', queue)\n\n queue.forEach(args => {\n this.logger(`[release] execute ${args[0]}`, args)\n\n Reflect.apply(this.$trigger, this, args)\n })\n\n this.queueStore.clear()\n this.logger(`Release size ${this.queueStore.size}`)\n }\n\n return size\n }\n}\n","// create options\nimport {\n checkConfigAsync,\n checkConfig\n} from 'jsonql-params-validator'\nimport {\n wsCoreCheckMap,\n wsCoreConstProps,\n socketCheckMap\n} from './defaults'\nimport {\n fixWss,\n getHostName,\n getEventEmitter,\n getNspInfoByConfig,\n getLogFn\n} from '../utils'\n\nimport {\n SUSPEND_EVENT_PROP_KEY\n} from 'jsonql-constants'\n\n/**\n * We need this to find the socket server type\n * @param {*} config\n * @return {string} the name of the socket server if any\n */\nfunction checkSocketClientType(config) {\n return checkConfig(config, socketCheckMap)\n}\n\n/**\n * Create a combine checkConfig for the creating the combine client\n * @param {*} configCheckMap\n * @param {*} constProps\n * @param {boolean} [withInject=false] if we need to run the postCheckInjectOpts \n * @return {function} takes the user input config then resolve the configuration\n */\nfunction createCombineConfigCheck(configCheckMap, constProps, withInject = false) {\n const combineCheckMap = Object.assign({}, wsCoreCheckMap, configCheckMap)\n const combineConstProps = Object.assign({}, wsCoreConstProps, constProps)\n\n return function runCheckConfigAsync(config) { \n return checkConfigAsync(config, combineCheckMap, combineConstProps)\n .then(opts => withInject ? postCheckInjectOpts(opts) : opts)\n }\n}\n\n\n/**\n * wrapper method to check this already did the pre check\n * @param {object} config user supply config\n * @param {object} defaultOptions for checking\n * @param {object} constProps user supply const props\n * @return {promise} resolve to the checked opitons\n */\nfunction checkConfiguration(config, defaultOptions, constProps) {\n const defaultCheckMap= Object.assign(wsCoreCheckMap, defaultOptions)\n const wsConstProps = Object.assign(wsCoreConstProps, constProps)\n\n return checkConfigAsync(config, defaultCheckMap, wsConstProps)\n}\n\n/**\n * Taking the `then` part from the method below\n * @param {object} opts\n * @return {promise} opts all done\n */\nfunction postCheckInjectOpts(opts) {\n \n return Promise.resolve(opts)\n .then(opts => {\n if (!opts.hostname) {\n opts.hostname = getHostName()\n }\n // @TODO the contract now will supply the namespace information\n // and we need to use that to group the namespace call\n \n opts.wssPath = fixWss([opts.hostname, opts.namespace].join('/'), opts.serverType)\n // get the log function here\n opts.log = getLogFn(opts)\n\n opts.eventEmitter = getEventEmitter(opts)\n \n return opts\n })\n}\n\n/**\n * Don't want to make things confusing\n * Breaking up the opts process in one place\n * then generate the necessary parameter in another step\n * @2020-3-20 here we suspend operation by it's namespace first\n * Then in the framework part, after the connection establish we release\n * the queue\n * @param {object} opts checked --> merge --> injected\n * @return {object} {opts, nspMap, ee}\n */\nfunction createRequiredParams(opts) {\n const nspMap = getNspInfoByConfig(opts)\n const ee = opts.eventEmitter\n // @TODO here we are going to add suspend event to the namespace related methods\n const { log } = opts \n const { namespaces } = nspMap\n log(`namespaces`, namespaces)\n // next we loop the namespace and suspend all the events prefix with namespace \n if (opts[SUSPEND_EVENT_PROP_KEY] === true) {\n // we create this as a function then we can call it again \n opts.$suspendNamepsace = () => namespaces.forEach(namespace => ee.$suspendEvent(namespace))\n // then we create a new method to releas the queue \n // we prefix it with the $ to notify this is not a jsonql part methods\n opts.$releaseNamespace = () => ee.$release()\n // now run it \n opts.$suspendNamepsace()\n }\n \n return { opts, nspMap, ee }\n}\n\nexport {\n // properties\n wsCoreCheckMap,\n wsCoreConstProps,\n // functions\n checkConfiguration,\n postCheckInjectOpts,\n createRequiredParams,\n // this will just get export for integration\n checkSocketClientType,\n createCombineConfigCheck\n}\n"],"names":["SetCache","Object","wsCoreConstProps"],"mappings":"4gCAAA,89vBCAAA,8tWCAAC,q3uCCAAC"} \ No newline at end of file +{"version":3,"file":"jsonql-ws-client.umd.js","sources":["../../../ws-client-core/src/callers/intercom-methods.js","../../../ws-client-core/src/utils/get-log-fn.js","../../../ws-client-core/src/utils/get-event-emitter.js","../../../ws-client-core/src/utils/helpers.js","../../../ws-client-core/src/options/constants.js","../../../ws-client-core/src/callers/respond-handler.js","../../../ws-client-core/src/callers/action-call.js","../../../ws-client-core/src/callers/setup-send-method.js","../../../ws-client-core/src/callers/setup-resolver.js","../../../ws-client-core/src/callers/generator-methods.js","../../../ws-client-core/src/listener/global-listeners.js","../../../ws-client-core/src/auth/setup-auth-methods.js","../../../ws-client-core/src/callers/setup-intercom.js","../../../ws-client-core/src/callers/setup-final-step.js","../../../ws-client-core/src/callers/callers-generator.js","../../../ws-client-core/src/options/defaults.js","../../../ws-client-core/src/options/index.js","../../../ws-client-core/src/api.js","../../../ws-client-core/src/listener/trigger-namespaces-on-error.js","../../../ws-client-core/src/listener/event-listeners.js","../../../ws-client-core/src/listener/namespace-event-listener.js","../../../ws-client-core/src/create-nsp-client.js","../src/options/index.js","../src/core/ws.js","../src/core/disconnect.js","../src/core/setup-connect-client/setup-websocket-client-fn.js","../src/core/setup-socket-listeners/login-event-listener.js","../src/core/create-nsp.js","../src/core/setup-socket-listeners/disconnect-event-listener.js","../src/core/setup-socket-listeners/bind-socket-event-handler.js","../src/core/setup-socket-listeners/connect-event-listener.js","../src/core/setup-connect-client/setup-connect-client.js","../src/core/setup-socket-client-listener.js","../src/browser-ws-client.js","../index.js"],"sourcesContent":["// this will be part of the init client sequence\n// as soon as we create a ws client\n// we listen to the on.connect event \n// then we send a init-ping event back to the server\n// and server issue a csrf token back to use \n// we use this token to create a new client and destroy the old one\nimport {\n INTERCOM_RESOLVER_NAME, \n SOCKET_PING_EVENT_NAME,\n HEADERS_KEY,\n DATA_KEY,\n CSRF_HEADER_KEY\n} from 'jsonql-constants'\nimport { \n createQueryStr, \n extractWsPayload,\n timestamp,\n toJson \n} from 'jsonql-utils/module'\nimport {\n JsonqlError\n} from 'jsonql-errors'\nconst CSRF_HEADER_NOT_EXIST_ERR = 'CSRF header is not in the received payload'\n\n/**\n * Util method \n * @param {string} payload return from server\n * @return {object} the useful bit \n */\nfunction extractSrvPayload(payload) {\n let json = toJson(payload)\n \n if (json && typeof json === 'object') {\n // note this method expect the json.data inside\n return extractWsPayload(json)\n }\n \n throw new JsonqlError('extractSrvPayload', json)\n}\n\n/**\n * call the server to get a csrf token \n * @return {string} formatted payload to send to the server \n */\nfunction createInitPing() {\n const ts = timestamp()\n\n return createQueryStr(INTERCOM_RESOLVER_NAME, [SOCKET_PING_EVENT_NAME, ts])\n}\n\n/**\n * Take the raw on.message result back then decoded it \n * @param {*} payload the raw result from server\n * @return {object} the csrf payload\n */\nfunction extractPingResult(payload) {\n const result = extractSrvPayload(payload)\n \n if (result && result[DATA_KEY] && result[DATA_KEY][CSRF_HEADER_KEY]) {\n return {\n [HEADERS_KEY]: result[DATA_KEY]\n }\n }\n\n throw new JsonqlError('extractPingResult', CSRF_HEADER_NOT_EXIST_ERR)\n}\n\n\n/**\n * Create a generic intercom method\n * @param {string} type the event type \n * @param {array} args if any \n * @return {string} formatted payload to send\n */\nfunction createIntercomPayload(type, ...args) {\n const ts = timestamp()\n let payload = [type].concat(args)\n payload.push(ts)\n return createQueryStr(INTERCOM_RESOLVER_NAME, payload)\n}\n\n\nexport { \n extractSrvPayload,\n createInitPing, \n extractPingResult, \n createIntercomPayload \n}","// move the get logger stuff here\n\n// it does nothing\nconst dummyLogger = () => {}\n\n/**\n * re-use the debugOn prop to control this log method\n * @param {object} opts configuration\n * @return {function} the log function\n */\nconst getLogger = (opts) => {\n const { debugOn } = opts \n if (debugOn) {\n return (...args) => {\n Reflect.apply(console.info, console, ['[jsonql-ws-client-core]', ...args])\n }\n }\n return dummyLogger\n}\n\n/**\n * Make sure there is a log method\n * @param {object} opts configuration\n * @return {object} opts\n */\nconst getLogFn = opts => {\n const { log } = opts // 1.3.9 if we pass a log method here then we use this\n if (!log || typeof log !== 'function') {\n return getLogger(opts)\n }\n opts.log('---> getLogFn user supplied log function <---', opts)\n return log\n}\n\nexport { getLogFn }","// this will generate a event emitter and will be use everywhere\nimport EventEmitterClass from '@to1source/event'\n// create a clone version so we know which one we actually is using\nclass JsonqlWsEvt extends EventEmitterClass {\n\n constructor(logger) {\n if (typeof logger !== 'function') {\n throw new Error(`Just die here the logger is not a function!`)\n }\n logger(`---> Create a new EventEmitter <---`)\n // this ee will always come with the logger\n // because we should take the ee from the configuration\n super({ logger })\n }\n\n get name() {\n return'jsonql-ws-client-core'\n }\n}\n\n/**\n * getting the event emitter\n * @param {object} opts configuration\n * @return {object} the event emitter instance\n */\nconst getEventEmitter = opts => {\n const { log, eventEmitter } = opts\n \n if (eventEmitter) {\n log(`eventEmitter is:`, eventEmitter.name)\n return eventEmitter\n }\n \n return new JsonqlWsEvt( opts.log )\n}\n\nexport { \n getEventEmitter, \n EventEmitterClass // for other module to build from \n}\n","// group all the small functions here\nimport { \n EMIT_REPLY_TYPE,\n IS_LOGIN_PROP_KEY,\n IS_READY_PROP_KEY \n} from 'jsonql-constants'\nimport { toArray, createEvt } from 'jsonql-utils/src/generic'\nimport { injectToFn } from 'jsonql-utils/src/obj-define-props'\nimport JsonqlValidationError from 'jsonql-errors/src/validation-error'\n\n/**\n * WebSocket is strict about the path, therefore we need to make sure before it goes in\n * @param {string} url input url\n * @return {string} url with correct path name\n */\nexport const fixWss = url => {\n const pattern = new RegExp('^(http|https)\\:\\/\\/', 'i')\n const result = url.match(pattern)\n if (result && result.length) {\n const target = result[1].toLowerCase()\n const replacement = target === 'https' ? 'wss' : 'ws'\n \n return url.replace(pattern, replacement + '://')\n }\n\n return url \n}\n\n\n/**\n * get a stock host name from browser\n */\nexport const getHostName = () => {\n try {\n return [window.location.protocol, window.location.host].join('//')\n } catch(e) {\n throw new JsonqlValidationError(e)\n }\n}\n\n/**\n * Unbind the event, this should only get call when it's disconnected\n * @param {object} ee EventEmitter\n * @param {string} namespace\n * @return {void}\n */\nexport const clearMainEmitEvt = (ee, namespace) => {\n let nsps = toArray(namespace)\n nsps.forEach(n => {\n ee.$off(createEvt(n, EMIT_REPLY_TYPE))\n })\n}\n\n/**\n * Setup the IS_LOGIN_PROP_KEY IS_READY_PROP_KEY \n * @param {*} client \n * @return {*} client \n */\nexport function setupStatePropKeys(client) {\n return [IS_READY_PROP_KEY, IS_LOGIN_PROP_KEY]\n // .map(key => injectToFn(client, key, false, true))\n .reduce((c, key) => {\n return injectToFn(c, key, false, true)\n }, client)\n}\n\n\n","// constants\n\nimport {\n EMIT_REPLY_TYPE,\n JS_WS_SOCKET_IO_NAME,\n JS_WS_NAME,\n ON_MESSAGE_FN_NAME,\n ON_RESULT_FN_NAME\n} from 'jsonql-constants'\n\nconst SOCKET_IO = JS_WS_SOCKET_IO_NAME\nconst WS = JS_WS_NAME\n\nconst AVAILABLE_SERVERS = [SOCKET_IO, WS]\n\nconst SOCKET_NOT_DEFINE_ERR = 'socket is not define in the contract file!'\n\nconst SERVER_NOT_SUPPORT_ERR = 'is not supported server name!'\n\nconst MISSING_PROP_ERR = 'Missing property in contract!'\n\nconst UNKNOWN_CLIENT_ERR = 'Unknown client type!'\n\nconst EMIT_EVT = EMIT_REPLY_TYPE\n\nconst NAMESPACE_KEY = 'namespaceMap'\n\nconst UNKNOWN_RESULT = 'UKNNOWN RESULT!'\n\nconst NOT_ALLOW_OP = 'This operation is not allow!'\n\nconst MY_NAMESPACE = 'myNamespace'\n\nconst CB_FN_NAME = 'on'\n// this is a socket only (for now) feature so we just put it here \nconst DISCONNECTED_ERROR_MSG = `You have disconnected from the socket server, please reconnect.`\n\nexport {\n SOCKET_IO,\n WS,\n AVAILABLE_SERVERS,\n SOCKET_NOT_DEFINE_ERR,\n SERVER_NOT_SUPPORT_ERR,\n MISSING_PROP_ERR,\n UNKNOWN_CLIENT_ERR,\n EMIT_EVT,\n ON_MESSAGE_FN_NAME,\n ON_RESULT_FN_NAME,\n NAMESPACE_KEY,\n UNKNOWN_RESULT,\n NOT_ALLOW_OP,\n MY_NAMESPACE,\n CB_FN_NAME,\n DISCONNECTED_ERROR_MSG\n}\n","// breaking it up further to share between methods\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { UNKNOWN_RESULT } from '../options/constants'\nimport { isObjectHasKey } from '../utils'\n\n/**\n * break out to use in different places to handle the return from server\n * @param {object} data from server\n * @param {function} resolver NOT from promise\n * @param {function} rejecter NOT from promise\n * @return {void} nothing\n */\nexport function respondHandler(data, resolver, rejecter) {\n if (isObjectHasKey(data, ERROR_KEY)) {\n // debugFn('-- rejecter called --', data[ERROR_KEY])\n rejecter(data[ERROR_KEY])\n } else if (isObjectHasKey(data, DATA_KEY)) {\n // debugFn('-- resolver called --', data[DATA_KEY])\n // @NOTE we change from calling it directly to use reflect \n // this could have another problem later when the return data is no in an array structure\n Reflect.apply(resolver, null, [...data[DATA_KEY]])\n } else {\n // debugFn('-- UNKNOWN_RESULT --', data)\n rejecter({message: UNKNOWN_RESULT, error: data})\n }\n}\n","// the actual trigger call method\nimport { ON_RESULT_FN_NAME, EMIT_REPLY_TYPE } from 'jsonql-constants'\nimport { createEvt, toArray } from '../utils'\nimport { respondHandler } from './respond-handler'\n\n/**\n * just wrapper\n * @param {object} ee EventEmitter\n * @param {string} namespace where this belongs\n * @param {string} resolverName resolver\n * @param {array} args arguments\n * @param {function} log function \n * @return {void} nothing\n */\nexport function actionCall(ee, namespace, resolverName, args = [], log) {\n // reply event \n const outEventName = createEvt(namespace, EMIT_REPLY_TYPE)\n\n log(`actionCall: ${outEventName} --> ${resolverName}`, args)\n // This is the out going call \n ee.$trigger(outEventName, [resolverName, toArray(args)])\n \n // then we need to listen to the event callback here as well\n return new Promise((resolver, rejecter) => {\n const inEventName = createEvt(namespace, resolverName, ON_RESULT_FN_NAME)\n // this cause the onResult got the result back first \n // and it should be the promise resolve first\n // @TODO we need to rewrote the respondHandler to change the problem stated above \n ee.$on(\n inEventName,\n function actionCallResultHandler(result) {\n log(`got the first result`, result)\n respondHandler(result, resolver, rejecter)\n }\n )\n })\n}\n","// setting up the send method \nimport { JsonqlValidationError } from 'jsonql-errors'\nimport {\n ON_ERROR_FN_NAME,\n SEND_MSG_FN_NAME\n} from 'jsonql-constants'\nimport { validateAsync } from 'jsonql-params-validator'\nimport { objDefineProps, createEvt, toArray, nil } from '../utils'\nimport { actionCall } from './action-call'\n\n/** \n * pairing with the server vesrion SEND_MSG_FN_NAME\n * last of the chain so only return the resolver (fn)\n * This is now change to a getter / setter method \n * and call like this: resolver.send(...args)\n * @param {function} fn the resolver function \n * @param {object} ee event emitter instance \n * @param {string} namespace the namespace it belongs to \n * @param {string} resolverName name of the resolver \n * @param {object} params from contract \n * @param {function} log a logger function\n * @return {function} return the resolver itself \n */ \nexport const setupSendMethod = (fn, ee, namespace, resolverName, params, log) => (\n objDefineProps(\n fn, \n SEND_MSG_FN_NAME, \n nil, \n function sendHandler() {\n log(`running call getter method`)\n // let _log = (...args) => Reflect.apply(console.info, console, ['[SEND]'].concat(args))\n /** \n * This will follow the same pattern like the resolver \n * @param {array} args list of unknown argument follow the resolver \n * @return {promise} resolve the result \n */\n return function sendCallback(...args) {\n return validateAsync(args, params.params, true)\n .then(_args => {\n // @TODO check the result \n // because the validation could failed with the list of fail properties \n log('execute send', namespace, resolverName, _args)\n return actionCall(ee, namespace, resolverName, _args, log)\n })\n .catch(err => {\n // @TODO it shouldn't be just a validation error \n // it could be server return error, so we need to check \n // what error we got back here first \n log('send error', err)\n // @TODO it might not an validation error need the finalCatch here\n ee.$call(\n createEvt(namespace, resolverName, ON_ERROR_FN_NAME),\n [new JsonqlValidationError(resolverName, err)]\n )\n })\n } \n })\n)\n","// break up the original setup resolver method here\n// import { JsonqlValidationError, finalCatch } from 'jsonql-errors'\nimport {\n ON_ERROR_FN_NAME,\n ON_MESSAGE_FN_NAME,\n ON_RESULT_FN_NAME\n} from 'jsonql-constants'\nimport { finalCatch } from 'jsonql-errors'\nimport { validateAsync } from 'jsonql-params-validator'\n// local\nimport { \n chainFns, \n objDefineProps, \n injectToFn, \n createEvt, \n isFunc \n} from '../utils'\nimport { actionCall } from './action-call'\nimport { MY_NAMESPACE } from '../options/constants'\nimport { respondHandler } from './respond-handler'\nimport { setupSendMethod } from './setup-send-method'\n\n\n/**\n * moved back from generator-methods \n * create the actual function to send message to server\n * @param {object} ee EventEmitter instance\n * @param {string} namespace this resolver end point\n * @param {string} resolverName name of resolver as event name\n * @param {object} params from contract\n * @param {function} log pass the log function\n * @return {function} resolver\n */\nfunction createResolver(ee, namespace, resolverName, params, log) {\n // note we pass the new withResult=true option\n return function resolver(...args) {\n return validateAsync(args, params.params, true)\n .then(_args => actionCall(ee, namespace, resolverName, _args, log))\n .catch(finalCatch)\n }\n}\n\n/**\n * The first one in the chain, just setup a namespace prop\n * the rest are passing through\n * @param {function} fn the resolver function\n * @param {object} ee the event emitter\n * @param {string} resolverName what it said\n * @param {object} params for resolver from contract\n * @param {function} log the logger function\n * @return {array}\n */\nconst setupNamespace = (fn, ee, namespace, resolverName, params, log) => [\n injectToFn(fn, MY_NAMESPACE, namespace),\n ee,\n namespace,\n resolverName,\n params,\n log\n]\n\n/**\n * onResult handler\n */\nconst setupOnResult = (fn, ee, namespace, resolverName, params, log) => [\n objDefineProps(fn, ON_RESULT_FN_NAME, function(resultCallback) {\n if (isFunc(resultCallback)) {\n ee.$on(\n createEvt(namespace, resolverName, ON_RESULT_FN_NAME),\n function resultHandler(result) {\n respondHandler(result, resultCallback, (error) => {\n log(`Catch error: \"${resolverName}\"`, error)\n ee.$trigger(\n createEvt(namespace, resolverName, ON_ERROR_FN_NAME),\n error\n )\n })\n }\n )\n }\n }),\n ee,\n namespace,\n resolverName,\n params,\n log\n]\n\n/**\n * we do need to add the send prop back because it's the only way to deal with\n * bi-directional data stream\n */\nconst setupOnMessage = (fn, ee, namespace, resolverName, params, log) => [\n objDefineProps(fn, ON_MESSAGE_FN_NAME, function(messageCallback) {\n // we expect this to be a function\n if (isFunc(messageCallback)) {\n // did that add to the callback\n let onMessageCallback = (args) => {\n log(`onMessageCallback`, args)\n respondHandler(\n args, \n messageCallback, \n (error) => {\n log(`Catch error: \"${resolverName}\"`, error)\n ee.$trigger(\n createEvt(namespace, resolverName, ON_ERROR_FN_NAME),\n error\n )\n })\n }\n // register the handler for this message event\n ee.$only(\n createEvt(namespace, resolverName, ON_MESSAGE_FN_NAME),\n onMessageCallback\n )\n }\n }),\n ee,\n namespace,\n resolverName,\n params,\n log\n]\n\n/**\n * ON_ERROR_FN_NAME handler\n */\nconst setupOnError = (fn, ee, namespace, resolverName, params, log) => [\n objDefineProps(fn, ON_ERROR_FN_NAME, function(resolverErrorHandler) {\n if (isFunc(resolverErrorHandler)) {\n // please note ON_ERROR_FN_NAME can add multiple listners\n ee.$only(\n createEvt(namespace, resolverName, ON_ERROR_FN_NAME),\n resolverErrorHandler\n )\n }\n }),\n ee,\n namespace,\n resolverName,\n params,\n log\n]\n\n/**\n * Add extra property / listeners to the resolver\n * @param {string} namespace where this belongs\n * @param {string} resolverName name as event name\n * @param {object} params from contract\n * @param {function} fn resolver function\n * @param {object} ee EventEmitter\n * @param {function} log function\n * @return {function} resolver\n */ \nfunction setupResolver(namespace, resolverName, params, fn, ee, log) {\n let fns = [\n setupNamespace,\n setupOnResult,\n setupOnMessage,\n setupOnError,\n setupSendMethod\n ]\n const executor = Reflect.apply(chainFns, null, fns)\n // get the executor\n return executor(fn, ee, namespace, resolverName, params, log)\n}\n\nexport { \n createResolver, \n setupResolver \n}","// put all the resolver related methods here to make it more clear\n\n// this will be a mini client server architect\n// The reason is when the enableAuth setup - the private route\n// might not be validated, but we need the callable point is ready\n// therefore this part will always take the contract and generate\n// callable api for the developer to setup their front end\n// the only thing is - when they call they might get an error or\n// NOT_LOGIN_IN and they can react to this error accordingly\n\nimport { createResolver, setupResolver } from './setup-resolver'\nimport { injectToFn } from '../utils'\n\n/**\n * step one get the clientmap with the namespace\n * @param {object} opts configuration\n * @param {object} ee EventEmitter\n * @param {object} nspGroup resolvers index by their namespace\n * @return {promise} resolve the clientmapped, and start the chain\n */\nexport function generateResolvers(opts, ee, nspGroup) {\n const { log } = opts\n let client= {}\n \n for (let namespace in nspGroup) {\n let list = nspGroup[namespace]\n for (let resolverName in list) {\n // resolverNames.push(resolverName)\n let params = list[resolverName]\n let fn = createResolver(ee, namespace, resolverName, params, log)\n // this should set as a getter therefore can not be overwrite by accident\n client = injectToFn(\n client,\n resolverName,\n setupResolver(namespace, resolverName, params, fn, ee, log)\n )\n }\n }\n // resolve the clientto start the chain\n // chain the result to allow the chain processing\n return [ client, opts, ee, nspGroup ]\n}\n\n","// move from generator-methods \n// they are global event listeners \nimport {\n createEvt,\n objDefineProps,\n isFunc\n} from '../utils'\nimport {\n ON_ERROR_FN_NAME,\n ON_READY_FN_NAME\n} from 'jsonql-constants'\n\n/**\n * This event will fire when the socket.io.on('connection') and ws.onopen\n * @param {object} client client itself\n * @param {object} opts configuration\n * @param {object} ee Event Emitter\n * @return {array} [ obj, opts, ee ]\n */\nexport function setupOnReadyListener(client, opts, ee) {\n return [\n objDefineProps(\n client,\n ON_READY_FN_NAME,\n function onReadyCallbackHandler(onReadyCallback) {\n if (isFunc(onReadyCallback)) {\n // reduce it down to just one flat level\n // @2020-03-19 only allow ONE onReady callback otherwise\n // it will get fire multiple times which is not what we want\n ee.$only(ON_READY_FN_NAME, onReadyCallback)\n }\n }\n ),\n opts,\n ee\n ]\n}\n\n/**\n * The problem is the namespace can have more than one\n * and we only have on onError message\n * @param {object} clientthe client itself\n * @param {object} opts configuration\n * @param {object} ee Event Emitter\n * @param {object} nspGroup namespace keys\n * @return {array} [obj, opts, ee]\n */\nexport function setupNamespaceErrorListener(client, opts, ee, nspGroup) {\n return [\n objDefineProps(\n client,\n ON_ERROR_FN_NAME,\n function namespaceErrorCallbackHandler(namespaceErrorHandler) {\n if (isFunc(namespaceErrorHandler)) {\n // please note ON_ERROR_FN_NAME can add multiple listners\n for (let namespace in nspGroup) {\n // this one is very tricky, we need to make sure the trigger is calling\n // with the namespace as well as the error\n ee.$on(createEvt(namespace, ON_ERROR_FN_NAME), namespaceErrorHandler)\n }\n }\n }\n ),\n opts,\n ee\n ]\n}\n\n","// take out from the resolver-methods\nimport {\n LOGIN_EVENT_NAME,\n LOGOUT_EVENT_NAME,\n ON_LOGIN_FN_NAME,\n IS_LOGIN_PROP_KEY,\n STANDALONE_PROP_KEY\n // SOCKET_AUTH_NAME\n} from 'jsonql-constants'\nimport { JsonqlValidationError } from 'jsonql-errors'\nimport { injectToFn, chainFns, isString, objDefineProps, isFunc } from '../utils'\n// import { validateAsync } from 'jsonql-params-validator'\n\n/**\n * @UPDATE it might be better if we decoup the two http-client only emit a login event\n * Here should catch it and reload the ws client @TBC\n * break out from createAuthMethods to allow chaining call\n * @TODO when this is using the standalone mode then this will have to be disable\n * or delegated to the login method from the contract\n * @param {object} obj the main client object\n * @param {object} opts configuration\n * @param {object} ee event emitter\n * @return {array} [ obj, opts, ee ] what comes in what goes out\n */\nconst setupLoginHandler = (obj, opts, ee) => [\n injectToFn(\n obj, \n opts.loginHandlerName, \n function loginHandler(token) {\n if (token && isString(token)) {\n opts.log(`Received ${LOGIN_EVENT_NAME} with ${token}`)\n // @TODO add the interceptor hook\n return ee.$trigger(LOGIN_EVENT_NAME, [token])\n }\n // should trigger a global error instead @TODO\n throw new JsonqlValidationError(opts.loginHandlerName, `Unexpected token ${token}`)\n }\n ),\n opts,\n ee\n]\n\n/**\n * Switch to this one when standalone mode is enable \n * @NOTE we don't actually have this because the public contract not included it\n * so we need to figure out a different way to include the auth method \n * that get expose to the public before we can continue with this standalone mode\n * const { contract, loginHandlerName } = opts \n * const params = contract[SOCKET_AUTH_NAME][loginHandlerName]\n * @param {*} obj \n * @param {*} opts \n * @param {*} ee \n */\nconst setupStandaloneLoginHandler = (obj, opts, ee) => [\n injectToFn(\n obj, \n loginHandlerName,\n function standaloneLoginHandler(...args) {\n // we only need to pass the argument \n // let the listener to handle the rest\n ee.$trigger(LOGIN_EVENT_NAME, args)\n }\n ),\n opts,\n ee \n]\n\n/**\n * break out from createAuthMethods to allow chaining call - final in chain\n * @param {object} obj the main client object\n * @param {object} opts configuration\n * @param {object} ee event emitter\n * @return {array} [ obj, opts, ee ] what comes in what goes out\n */\nconst setupLogoutHandler = (obj, opts, ee) => [\n injectToFn(\n obj, \n opts.logoutHandlerName, \n function logoutHandler(...args) {\n opts[IS_LOGIN_PROP_KEY] = true\n ee.$trigger(LOGOUT_EVENT_NAME, args)\n }\n ),\n opts,\n ee\n]\n\n/**\n * This event will fire when the socket.io.on('connection') and ws.onopen\n * Plus this will check if it's the private namespace that fired the event\n * @param {object} obj the client itself\n * @param {object} ee Event Emitter\n * @return {array} [ obj, opts, ee] what comes in what goes out\n */\nconst setupOnLoginListener = (obj, opts, ee) => [\n objDefineProps(\n obj, \n ON_LOGIN_FN_NAME, \n function onLoginCallbackHandler(onLoginCallback) {\n if (isFunc(onLoginCallback)) {\n // only one callback can registered with it, TBC\n // Should this be a $onlyOnce listener after the logout \n // we add it back? \n ee.$only(ON_LOGIN_FN_NAME, onLoginCallback)\n }\n }\n ),\n opts,\n ee\n]\n\n/**\n * Main Create auth related methods\n * @param {object} obj the client itself\n * @param {object} opts configuration\n * @param {object} ee Event Emitter\n * @return {array} [ obj, opts, ee ] what comes in what goes out\n */\nexport function setupAuthMethods(obj, opts, ee) {\n return chainFns(\n opts[STANDALONE_PROP_KEY] === true ? setupStandaloneLoginHandler : setupLoginHandler, \n setupLogoutHandler,\n setupOnLoginListener\n )(obj, opts, ee)\n}\n","// this is a new method that will create several\n// intercom method also reverse listen to the server\n// such as disconnect (server issue disconnect)\nimport { injectToFn, chainFns } from '../utils'\nimport { \n CONNECT_EVENT_NAME,\n CONNECTED_EVENT_NAME,\n DISCONNECT_EVENT_NAME,\n CONNECTED_PROP_KEY\n} from 'jsonql-constants'\n\n/**\n * Set up the CONNECTED_PROP_KEY to the client\n * @param {*} client \n * @param {*} opts \n * @param {*} ee \n */\nfunction setupConnectPropKey(client, opts, ee) {\n const { log } = opts \n log('[1] setupConnectPropKey')\n // we just inject a helloWorld method here\n // set up the init state of the connect\n client = injectToFn(client, CONNECTED_PROP_KEY , false, true)\n return [ client, opts, ee ]\n}\n\n\n/**\n * setup listener to the connect event \n * @param {*} client \n * @param {*} opts \n * @param {*} ee \n */\nfunction setupConnectEvtListener(client, opts, ee) {\n // @TODO do what at this point?\n const { log } = opts \n\n log(`[2] setupConnectEvtListener`)\n\n ee.$on(CONNECT_EVENT_NAME, function(...args) {\n log(`setupConnectEvtListener pass and do nothing at the moment`, args)\n })\n \n return [client, opts, ee]\n}\n\n/**\n * setup listener to the connected event \n * @param {*} client \n * @param {*} opts \n * @param {*} ee \n */\nfunction setupConnectedEvtListener(client, opts, ee) {\n const { log } = opts \n\n log(`[3] setupConnectedEvtListener`)\n\n ee.$on(CONNECTED_EVENT_NAME, function() {\n client[CONNECTED_PROP_KEY] = true\n // new action to take release the holded event queue \n const ctn = ee.$release()\n\n log(`CONNECTED_EVENT_NAME`, true, 'queue count', ctn)\n\n return {[CONNECTED_PROP_KEY]: true}\n })\n\n return [client, opts, ee]\n}\n\n/**\n * Listen to the disconnect event and set the property to the client \n * @param {*} client \n * @param {*} opts \n * @param {*} ee \n */\nfunction setupDisconnectListener(client, opts, ee) {\n const { log } = opts \n\n log(`[4] setupDisconnectListener`)\n\n ee.$on(DISCONNECT_EVENT_NAME, function() {\n client[CONNECTED_PROP_KEY] = false\n log(`CONNECTED_EVENT_NAME`, false)\n\n return {[CONNECTED_PROP_KEY]: false}\n })\n\n return [client, opts, ee]\n}\n\n/**\n * disconnect action\n * @param {*} client \n * @param {*} opts \n * @param {*} ee \n * @return {object} this is the final step to return the client\n */\nfunction setupDisconectAction(client, opts, ee) {\n const { disconnectHandlerName, log } = opts\n log(`[5] setupDisconectAction`)\n\n return injectToFn(\n client,\n disconnectHandlerName,\n function disconnectHandler(...args) {\n ee.$trigger(DISCONNECT_EVENT_NAME, args)\n }\n )\n}\n\n/**\n * this is the new method that setup the intercom handler\n * also this serve as the final call in the then chain to\n * output the client\n * @param {object} client the client\n * @param {object} opts configuration\n * @param {object} ee the event emitter\n * @return {object} client\n */\nexport function setupInterCom(client, opts, ee) {\n const fns = [\n setupConnectPropKey,\n setupConnectEvtListener,\n setupConnectedEvtListener,\n setupDisconnectListener,\n setupDisconectAction\n ]\n\n const executor = Reflect.apply(chainFns, null, fns)\n return executor(client, opts, ee)\n}\n","// The final step of the setup before it returns the client\nimport { \n CONNECT_EVENT_NAME, \n SUSPEND_EVENT_PROP_KEY\n} from 'jsonql-constants'\n\nimport { setupInterCom } from './setup-intercom'\nimport { setupStatePropKeys } from '../utils'\n\n\n/**\n * The final step to return the client\n * @param {object} obj the client\n * @param {object} opts configuration\n * @param {object} ee the event emitter\n * @return {object} client\n */\nfunction setupFinalStep(obj, opts, ee) {\n \n let client = setupInterCom(obj, opts, ee)\n // opts.log(`---> The final step to return the ws-client <---`)\n // add some debug functions\n client.verifyEventEmitter = () => ee.is\n // we add back the two things into the client\n // then when we do integration, we run it in reverse,\n // create the ws client first then the host client\n client.eventEmitter = opts.eventEmitter\n client.log = opts.log\n\n // now at this point, we are going to call the connect event\n ee.$trigger(CONNECT_EVENT_NAME, [opts, ee]) // just passing back the entire opts object\n // also we can release the queue here \n if (opts[SUSPEND_EVENT_PROP_KEY] === true) {\n opts.$releaseNamespace()\n }\n\n // finally inject some prop keys to the client \n return setupStatePropKeys(obj)\n}\n\n\nexport { setupFinalStep }\n","// resolvers generator\n// we change the interface to return promise from v1.0.3\n// this way we make sure the obj return is correct and timely\nimport { NSP_GROUP } from 'jsonql-constants'\nimport { chainFns } from '../utils'\n\nimport { generateResolvers } from './generator-methods'\nimport {\n setupOnReadyListener,\n setupNamespaceErrorListener\n} from '../listener/global-listeners'\n\nimport { setupAuthMethods } from '../auth'\n\nimport { setupFinalStep } from './setup-final-step'\n\n/**\n * This is the starting point of binding callable method to the \n * ws, and we have to determine which is actually active \n * if enableAuth but we don't have a token, when the connection \n * to ws establish we only release the public related event \n * and the private one remain hold until the LOGIN_EVENT get trigger\n * @param {object} opts configuration\n * @param {object} nspMap resolvers index by their namespace\n * @param {object} ee EventEmitter\n * @return {object} of resolvers\n * @public\n */\nexport function callersGenerator(opts, nspMap, ee) {\n \n let fns = [\n generateResolvers,\n setupOnReadyListener,\n setupNamespaceErrorListener\n ]\n if (opts.enableAuth) {\n // there is a problem here, when this is a public namespace\n // it should not have a login logout event attach to it\n fns.push(setupAuthMethods)\n }\n // we will always get back the [ obj, opts, ee ]\n // then we only return the obj (wsClient)\n // This has move outside of here, into the main method\n // the reason is we could switch around the sequence much easier\n fns.push(setupFinalStep)\n // stupid reaon!!!\n const executer = Reflect.apply(chainFns, null, fns)\n // run it\n return executer(opts, ee, nspMap[NSP_GROUP])\n}\n","// take the sharable default options out and put here\n// then we can export it and re-use on the downstream clients\nimport { createConfig } from 'jsonql-params-validator'\nimport { isContract } from '../utils'\nimport {\n STRING_TYPE,\n BOOLEAN_TYPE,\n OBJECT_TYPE,\n \n CHECKER_KEY,\n JSONQL_PATH,\n \n SOCKET_TYPE_CLIENT_ALIAS,\n \n ALIAS_KEY,\n LOGIN_FN_NAME,\n LOGOUT_FN_NAME,\n DISCONNECT_FN_NAME,\n SWITCH_USER_FN_NAME,\n\n SOCKET_TYPE_PROP_KEY,\n STANDALONE_PROP_KEY,\n DEBUG_ON_PROP_KEY,\n LOGIN_FN_NAME_PROP_KEY,\n LOGOUT_FN_NAME_PROP_KEY,\n DISCONNECT_FN_NAME_PROP_KEY,\n SWITCH_USER_FN_NAME_PROP_KEY,\n\n HOSTNAME_PROP_KEY,\n NAMESAPCE_PROP_KEY,\n WS_OPT_PROP_KEY,\n CONTRACT_PROP_KEY,\n ENABLE_AUTH_PROP_KEY,\n TOKEN_PROP_KEY,\n SUSPEND_EVENT_PROP_KEY,\n \n CSRF_PROP_KEY,\n CSRF_HEADER_KEY,\n USE_JWT_PROP_KEY,\n\n PUBLIC_KEY,\n PRIVATE_KEY,\n\n} from 'jsonql-constants'\n\n\n\nconst configCheckMap = {\n [STANDALONE_PROP_KEY]: createConfig(false, [BOOLEAN_TYPE]), // to turn on or off some of the features\n [DEBUG_ON_PROP_KEY]: createConfig(false, [BOOLEAN_TYPE]),\n // useCallbackStyle: createConfig(false, [BOOLEAN_TYPE]), abandoned in 0.6.0\n // Please note the login method will be a public available always \n // what if the developer wants to have a socket only setup to do a CORS SPA site\n [LOGIN_FN_NAME_PROP_KEY]: createConfig(LOGIN_FN_NAME, [STRING_TYPE]),\n [LOGOUT_FN_NAME_PROP_KEY]: createConfig(LOGOUT_FN_NAME, [STRING_TYPE]),\n // just matching the server side\n [DISCONNECT_FN_NAME_PROP_KEY]: createConfig(DISCONNECT_FN_NAME, [STRING_TYPE]),\n [SWITCH_USER_FN_NAME_PROP_KEY]: createConfig(SWITCH_USER_FN_NAME, [STRING_TYPE]),\n\n [HOSTNAME_PROP_KEY]: createConfig(false, [STRING_TYPE]),\n [NAMESAPCE_PROP_KEY]: createConfig(JSONQL_PATH, [STRING_TYPE]),\n [WS_OPT_PROP_KEY]: createConfig({}, [OBJECT_TYPE]),\n // make this null as default don't set this here, only set in the down stream\n // serverType: createConfig(null, [STRING_TYPE], {[ENUM_KEY]: AVAILABLE_SERVERS}),\n // we require the contract already generated and pass here\n [CONTRACT_PROP_KEY]: createConfig({}, [OBJECT_TYPE], {[CHECKER_KEY]: isContract}),\n [ENABLE_AUTH_PROP_KEY]: createConfig(false, [BOOLEAN_TYPE]),\n [TOKEN_PROP_KEY]: createConfig(false, [STRING_TYPE]),\n\n [CSRF_PROP_KEY]: createConfig(CSRF_HEADER_KEY, [STRING_TYPE]),\n // we will use this for determine the socket.io client type as well - @TODO remove or rename\n // [USE_JWT_PROP_KEY]: createConfig(true, [BOOLEAN_TYPE, STRING_TYPE]),\n // this is going to replace the use of useJwt === string next\n // @TODO remove this, use the interceptor to replace this options\n // authStrKey: createConfig(null, [STRING_TYPE]),\n // this is experimental to see the effects, might take downlater\n [SUSPEND_EVENT_PROP_KEY]: createConfig(false, [BOOLEAN_TYPE])\n // should this be moved to the framework instead\n\n}\n\n// socket client\nconst socketCheckMap = {\n // new prop for socket client\n [SOCKET_TYPE_PROP_KEY]: createConfig(null, [STRING_TYPE], {[ALIAS_KEY]: SOCKET_TYPE_CLIENT_ALIAS})\n // [ENUM_KEY]: [JS_WS_NAME, JS_WS_SOCKET_IO_NAME, JS_PRIMUS_NAME],\n}\n\nconst wsCoreCheckMap = Object.assign(configCheckMap, socketCheckMap)\n\n// constant props\nconst wsCoreConstProps = {\n [USE_JWT_PROP_KEY]: true, // should not allow to change anymore\n log: null,\n // contract: null, \n eventEmitter: null,\n // we unify the two different client into one now\n // only expect different parameter\n nspClient: null,\n nspAuthClient: null,\n // contructed path\n wssPath: '',\n // for generate the namespaces\n publicNamespace: PUBLIC_KEY,\n privateNamespace: PRIVATE_KEY\n}\n\nexport { \n wsCoreCheckMap, \n wsCoreConstProps, \n socketCheckMap \n}\n","// create options\nimport {\n checkConfigAsync,\n checkConfig\n} from 'jsonql-params-validator'\nimport {\n wsCoreCheckMap,\n wsCoreConstProps,\n socketCheckMap\n} from './defaults'\nimport {\n fixWss,\n getHostName,\n getEventEmitter,\n getNspInfoByConfig,\n getLogFn\n} from '../utils'\n\nimport {\n SUSPEND_EVENT_PROP_KEY,\n ON_RESULT_FN_NAME,\n ON_LOGIN_FN_NAME\n} from 'jsonql-constants'\n\n/**\n * We need this to find the socket server type\n * @param {*} config\n * @return {string} the name of the socket server if any\n */\nfunction checkSocketClientType(config) {\n return checkConfig(config, socketCheckMap)\n}\n\n/**\n * Create a combine checkConfig for the creating the combine client\n * @param {*} configCheckMap\n * @param {*} constProps\n * @param {boolean} [withInject=false] if we need to run the postCheckInjectOpts \n * @return {function} takes the user input config then resolve the configuration\n */\nfunction createCombineConfigCheck(configCheckMap, constProps, withInject = false) {\n const combineCheckMap = Object.assign({}, wsCoreCheckMap, configCheckMap)\n const combineConstProps = Object.assign({}, wsCoreConstProps, constProps)\n\n return function runCheckConfigAsync(config) { \n return checkConfigAsync(config, combineCheckMap, combineConstProps)\n .then(opts => withInject ? postCheckInjectOpts(opts) : opts)\n }\n}\n\n\n/**\n * wrapper method to check this already did the pre check\n * @param {object} config user supply config\n * @param {object} defaultOptions for checking\n * @param {object} constProps user supply const props\n * @return {promise} resolve to the checked opitons\n */\nfunction checkConfiguration(config, defaultOptions, constProps) {\n const defaultCheckMap= Object.assign(wsCoreCheckMap, defaultOptions)\n const wsConstProps = Object.assign(wsCoreConstProps, constProps)\n\n return checkConfigAsync(config, defaultCheckMap, wsConstProps)\n}\n\n/**\n * Taking the `then` part from the method below\n * @param {object} opts\n * @return {promise} opts all done\n */\nfunction postCheckInjectOpts(opts) {\n \n return Promise.resolve(opts)\n .then(opts => {\n if (!opts.hostname) {\n opts.hostname = getHostName()\n }\n // @TODO the contract now will supply the namespace information\n // and we need to use that to group the namespace call\n \n opts.wssPath = fixWss([opts.hostname, opts.namespace].join('/'), opts.serverType)\n // get the log function here\n opts.log = getLogFn(opts)\n\n opts.eventEmitter = getEventEmitter(opts)\n \n return opts\n })\n}\n\n/**\n * Don't want to make things confusing\n * Breaking up the opts process in one place\n * then generate the necessary parameter in another step\n * @2020-3-20 here we suspend operation by it's namespace first\n * Then in the framework part, after the connection establish we release\n * the queue\n * @param {object} opts checked --> merge --> injected\n * @return {object} {opts, nspMap, ee}\n */\nfunction createRequiredParams(opts) {\n const nspMap = getNspInfoByConfig(opts)\n const ee = opts.eventEmitter\n // @TODO here we are going to add suspend event to the namespace related methods\n const { log } = opts \n const { namespaces, publicNamespace } = nspMap\n log(`namespaces`, namespaces)\n // next we loop the namespace and suspend all the events prefix with namespace \n if (opts[SUSPEND_EVENT_PROP_KEY] === true) {\n // ON_READY_FN_NAME\n // ON_LOGIN_FN_NAME\n\n // we create this as a function then we can call it again \n // @TODO we need to add the onReady and the onLogin in the suspend list as well\n opts.$suspendNamepsace = () => {\n let eventNames = [ON_RESULT_FN_NAME, ...namespaces]\n if (opts.enableAuth) {\n eventNames.push(ON_LOGIN_FN_NAME)\n }\n // [ON_READY_FN_NAME, ON_LOGIN_FN_NAME, ...namespaces]\n Reflect.apply(ee.$suspendEvent, ee, eventNames)\n }\n // then we create a new method to releas the queue \n // we prefix it with the $ to notify this is not a jsonql part methods\n opts.$releaseNamespace = () => {\n ee.$releaseEvent(ON_RESULT_FN_NAME, publicNamespace)\n }\n\n if (opts.enableAuth) {\n opts.$releasePrivateNamespace = () => {\n ee.$releaseEvent(ON_LOGIN_FN_NAME, namespaces[1])\n }\n }\n\n // now run it \n opts.$suspendNamepsace()\n }\n \n return { opts, nspMap, ee }\n}\n\nexport {\n // properties\n wsCoreCheckMap,\n wsCoreConstProps,\n // functions\n checkConfiguration,\n postCheckInjectOpts,\n createRequiredParams,\n // this will just get export for integration\n checkSocketClientType,\n createCombineConfigCheck\n}\n","// the top level API\n// The goal is to create a generic method that will able to handle\n// any kind of clients\n// import { injectToFn } from 'jsonql-utils'\nimport { callersGenerator } from './callers'\nimport {\n checkConfiguration,\n postCheckInjectOpts,\n createRequiredParams\n} from './options'\n\n\n/**\n * 0.5.0 we break up the wsClientCore in two parts one without the config check\n * @param {function} setupSocketClientListener just make sure what it said it does\n * @return {function} to actually generate the client\n */\nexport function wsClientCoreAction(setupSocketClientListener) {\n /**\n * This is a breaking change, to continue the onion skin design\n * @param {object} config the already checked config\n * @return {promise} resolve the client\n */\n return function createClientAction(config = {}) {\n\n return postCheckInjectOpts(config)\n .then(createRequiredParams)\n .then(\n ({opts, nspMap, ee}) => setupSocketClientListener(opts, nspMap, ee)\n )\n .then(\n ({opts, nspMap, ee}) => callersGenerator(opts, nspMap, ee)\n )\n .catch(err => {\n console.error(`[jsonql-ws-core-client init error]`, err)\n })\n }\n}\n\n/**\n * The main interface which will generate the socket clients and map all events\n * @param {object} socketClientListerner this is the one method export by various clients\n * @param {object} [configCheckMap={}] we should do all the checking in the core instead of the client\n * @param {object} [constProps={}] add this to supply the constProps from the downstream client\n * @return {function} accept a config then return the wsClient instance with all the available API\n */\nexport function wsClientCore(socketClientListener, configCheckMap = {}, constProps = {}) {\n // we need to inject property to this client later\n return (config = {}) => checkConfiguration(config, configCheckMap, constProps)\n .then(\n wsClientCoreAction(socketClientListener)\n )\n}\n","// this use by client-event-handler\nimport { ON_ERROR_FN_NAME } from 'jsonql-constants'\nimport { createEvt } from '../utils'\n\n/**\n * trigger errors on all the namespace onError handler\n * @param {object} ee Event Emitter\n * @param {array} namespaces nsps string\n * @param {string} message optional\n * @return {void}\n */\nexport function triggerNamespacesOnError(ee, namespaces, message) {\n namespaces.forEach( namespace => {\n ee.$trigger(\n createEvt(namespace, ON_ERROR_FN_NAME), \n [{ message, namespace }]\n )\n })\n}\n\n/**\n * Handle the onerror callback \n * @param {object} ee event emitter \n * @param {string} namespace which namespace has error \n * @param {*} err error object\n * @return {void} \n */\nexport const handleNamespaceOnError = (ee, namespace, err) => {\n ee.$trigger(createEvt(namespace, ON_ERROR_FN_NAME), [err])\n}","// NOT IN USE AT THE MOMENT JUST KEEP IT HERE FOR THE TIME BEING \nimport {\n LOGOUT_EVENT_NAME,\n NOT_LOGIN_ERR_MSG,\n ON_ERROR_FN_NAME,\n ON_RESULT_FN_NAME,\n DISCONNECT_EVENT_NAME\n // SUSPEND_EVENT_PROP_KEY\n} from 'jsonql-constants'\nimport { EMIT_EVT, DISCONNECTED_ERROR_MSG } from '../options/constants'\nimport { createEvt, clearMainEmitEvt } from '../utils'\nimport { triggerNamespacesOnError } from './trigger-namespaces-on-error'\n\n/**\n * A Event Listerner placeholder when it's not connect to any nsp\n * @param {string} namespace nsp\n * @param {object} ee EventEmitter\n * @param {object} opts configuration\n * @return {void}\n */\nexport const notConnectedListener = (namespace, ee, opts) => {\n const { log } = opts \n\n ee.$only(\n createEvt(namespace, EMIT_EVT),\n function disconnectedEvtCallback(resolverName, args) {\n log(`[disconnectedListerner] hijack the ws call`, namespace, resolverName, args)\n // Now we suspend all the calls but note the existing one won't be affected \n // we need to update the methods to move everything across \n const error = {\n message: DISCONNECTED_ERROR_MSG\n }\n ee.$call(createEvt(namespace, resolverName, ON_ERROR_FN_NAME), [ error ])\n // also trigger the result Listerner, but wrap inside the error key\n ee.$call(createEvt(namespace, resolverName, ON_RESULT_FN_NAME), [{ error }])\n }\n )\n}\n\n\n/**\n * The disconnect event Listerner, now we log the client out from everything\n * @TODO now we are another problem they disconnect, how to reconnect\n * @param {object} nsps the available nsp(s)\n * @param {array} namespaces available namespace \n * @param {object} ee eventEmitter \n * @param {object} opts configuration\n * @return {void}\n */\nexport const disconnectListener = (nsps, namespaces, ee, opts) => {\n const { log } = opts \n ee.$on(\n DISCONNECT_EVENT_NAME, \n function disconnectEvtCallback() {\n triggerNamespacesOnError(ee, namespaces, DISCONNECT_EVENT_NAME)\n namespaces.forEach( namespace => { \n log(`disconnect from ${namespace}`)\n\n clearMainEmitEvt(ee, namespace)\n nsps[namespace] = null \n disconnectedListerner(namespace, ee, opts)\n })\n }\n )\n}\n\n/**\n * A Event Listerner placeholder when it's not connect to the private nsp\n * @param {string} namespace nsp\n * @param {object} ee EventEmitter\n * @param {object} opts configuration\n * @return {void}\n */\nexport const notLoginListener = (namespace, ee, opts) => {\n const { log } = opts \n\n ee.$only(\n createEvt(namespace, EMIT_EVT),\n function notLoginListernerCallback(resolverName, args) {\n log('[notLoginListerner] hijack the ws call', namespace, resolverName, args)\n const error = { message: NOT_LOGIN_ERR_MSG }\n // It should just throw error here and should not call the result\n // because that's channel for handling normal event not the fake one\n ee.$call(createEvt(namespace, resolverName, ON_ERROR_FN_NAME), [ error ])\n // also trigger the result Listerner, but wrap inside the error key\n ee.$call(createEvt(namespace, resolverName, ON_RESULT_FN_NAME), [{ error }])\n }\n )\n}\n\n/**\n * Only when there is a private namespace then we bind to this event\n * @param {object} nsps the available nsp(s)\n * @param {array} namespaces available namespace \n * @param {object} ee eventEmitter \n * @param {object} opts configuration\n * @return {void}\n */\nexport const logoutEvtListener = (nsps, namespaces, ee, opts) => {\n const { log } = opts \n // this will be available regardless enableAuth\n // because the server can log the client out\n ee.$on(\n LOGOUT_EVENT_NAME, \n function logoutEvtCallback() {\n const privateNamespace = getPrivateNamespace(namespaces)\n log(`${LOGOUT_EVENT_NAME} event triggered`)\n // disconnect(nsps, opts.serverType)\n // we need to issue error to all the namespace onError Listerner\n triggerNamespacesOnError(ee, [privateNamespace], LOGOUT_EVENT_NAME)\n // rebind all of the Listerner to the fake one\n log(`logout from ${privateNamespace}`)\n\n clearMainEmitEvt(ee, privateNamespace)\n // we need to issue one more call to the server before we disconnect\n // now this is a catch 22, here we are not suppose to do anything platform specific\n // so that should fire before trigger this event\n // clear out the nsp\n nsps[privateNamespace] = null \n // add a NOT LOGIN error if call\n notLoginWsListerner(privateNamespace, ee, opts)\n }\n )\n}\n\n","// This is share between different clients so we export it\n// @TODO port what is in the ws-main-handler\n// because all the client side call are via the ee\n// and that makes it re-usable between different client setup\n\n/*\nInside the map call but we take it out for now and until the WebSocket version is fully working\nimport { SOCKET_IO } from '../options/constants'\n // @TODO need to double check this\n if (opts.serverType === SOCKET_IO) {\n let { nspGroup } = nspMap\n args.push(nspGroup[namespace])\n }\n*/\nimport { getPrivateNamespace } from 'jsonql-utils/src/namespace'\nimport { logoutEvtListener, notLoginListener } from './event-listeners'\n\n/**\n * centralize all the comm in one place\n * @param {function} bindSocketEventHandler binding the ee to ws --> this is the core bit\n * @param {object} nsps namespaced nsp\n * @return {void} nothing\n */\nexport function namespaceEventListener(bindSocketEventListener, nsps) {\n /**\n * BREAKING CHANGE instead of one flat structure\n * we return a function to accept the two\n * @param {object} opts configuration\n * @param {object} nspMap this is not in the opts\n * @param {object} ee Event Emitter instance\n * @return {array} although we return something but this is the last step and nothing to do further\n */\n return (opts, nspMap, ee) => {\n // since all these params already in the opts\n const { log } = opts\n const { namespaces } = nspMap\n // @1.1.3 add isPrivate prop to id which namespace is the private nsp\n // then we can use this prop to determine if we need to fire the ON_LOGIN_PROP_NAME event\n const privateNamespace = getPrivateNamespace(namespaces)\n // The total number of namespaces (which is 2 at the moment) minus the private namespace number\n let ctn = namespaces.length - 1 \n // @NOTE we need to somehow id if this namespace already been connected \n // and the event been released before \n return namespaces.map(namespace => {\n let isPrivate = privateNamespace === namespace\n log(namespace, ` --> ${isPrivate ? 'private': 'public'} nsp --> `, nsps[namespace] !== false)\n if (nsps[namespace]) {\n log('[call bindWsHandler]', isPrivate, namespace)\n // we need to add one more property here to tell the bindSocketEventListener \n // how many times it should call the onReady \n let args = [namespace, nsps[namespace], ee, isPrivate, opts, --ctn]\n // Finally we binding everything together\n Reflect.apply(bindSocketEventListener, null, args)\n \n } else {\n log(`binding notLoginWsHandler to ${namespace}`)\n // a dummy placeholder\n // @TODO but it should be a not connect handler\n // when it's not login (or fail) this should be handle differently\n notLoginListener(namespace, ee, opts)\n }\n if (isPrivate) {\n log(`Has private and add logoutEvtHandler`)\n logoutEvtListener(nsps, namespaces, ee, opts)\n }\n // just return something its not going to get use anywhere\n return isPrivate\n })\n }\n}\n","/*\nThis two client is the final one that gets call \nall it does is to create the url that connect to \nand actually trigger the connection and return the socket \ntherefore they are as generic as it can be\n*/\n\n/**\n * wrapper method to create a nsp without login\n * @param {string|boolean} namespace namespace url could be false\n * @param {object} opts configuration\n * @return {object} ws client instance\n */\nfunction createNspClient(namespace, opts) {\n const { hostname, wssPath, nspClient, log } = opts\n const url = namespace ? [hostname, namespace].join('/') : wssPath\n log(`createNspClient with URL --> `, url)\n\n return nspClient(url, opts)\n}\n\n/**\n * wrapper method to create a nsp with token auth\n * @param {string} namespace namespace url\n * @param {object} opts configuration\n * @return {object} ws client instance\n */\nfunction createNspAuthClient(namespace, opts) {\n const { hostname, wssPath, token, nspAuthClient, log } = opts\n const url = namespace ? [hostname, namespace].join('/') : wssPath\n \n log(`createNspAuthClient with URL -->`, url)\n\n if (token && typeof token !== 'string') {\n throw new Error(`Expect token to be string, but got ${token}`)\n }\n // now we need to get an extra options for framework specific method, which is not great\n // instead we just pass the entrie opts to the authClient \n\n return nspAuthClient(url, opts, token)\n}\n\nexport {\n createNspClient,\n createNspAuthClient\n}\n","// jsonql-ws-core takes over the check configuration\n// here we only have to supply the options that is unique to this client\n// create options\nimport { \n JS_WS_NAME, \n ENUM_KEY,\n TOKEN_DELIVER_LOCATION_PROP_KEY, \n TOKEN_IN_URL,\n TOKEN_IN_HEADER,\n STRING_TYPE\n} from 'jsonql-constants'\nimport { \n createConfig \n} from 'jsonql-params-validator'\n\nconst AVAILABLE_PLACES = [\n TOKEN_IN_URL,\n TOKEN_IN_HEADER\n]\n\n// constant props\nconst wsClientConstProps = {\n version: '__PLACEHOLDER__', // will get replace\n serverType: JS_WS_NAME\n}\n\nconst wsClientCheckMap = {\n [TOKEN_DELIVER_LOCATION_PROP_KEY]: createConfig(TOKEN_IN_URL, [STRING_TYPE], {\n [ENUM_KEY]: AVAILABLE_PLACES\n })\n}\n\nexport { \n wsClientCheckMap, \n wsClientConstProps \n}\n","// this is all the isormophic-ws is\nvar ws = null\n\nif (typeof WebSocket !== 'undefined') {\n ws = WebSocket\n} else if (typeof MozWebSocket !== 'undefined') {\n ws = MozWebSocket\n} else if (typeof global !== 'undefined') {\n ws = global.WebSocket || global.MozWebSocket\n} else if (typeof window !== 'undefined') {\n ws = window.WebSocket || window.MozWebSocket\n} else if (typeof self !== 'undefined') {\n ws = self.WebSocket || self.MozWebSocket\n}\n\nexport default ws\n","import { isFunc } from 'jsonql-utils/module'\n\n/**\n * This will get re-use when we start using the disconnect event method\n * @param {*} ws \n * @return {void}\n */\nexport function disconnect(ws) {\n if (ws.terminate && isFunc(ws.terminate)) {\n ws.terminate()\n } else if (ws.close && isFunc(ws.close)) {\n ws.close()\n }\n}","// pass the different type of ws to generate the client\n// this is where the framework specific code get injected\nimport cookies from 'js-cookie'\nimport { disconnect } from '../disconnect'\nimport {\n createInitPing, \n extractPingResult,\n prepareConnectConfig,\n fixWss\n} from '../modules'\n\n/**\n * \n * @param {*} WebSocketClass \n * @param {*} url \n * @param {*} type \n * @param {*} options \n */\nfunction createWs(WebSocketClass, type, url, options) {\n if (type === 'browser') {\n const { headers } = options \n if (headers) {\n for (let key in headers) {\n if (!cookies.get(key)) {\n cookies.set(key, headers[key])\n }\n }\n }\n }\n let wsUrl = fixWss(url)\n return type === 'node' ? new WebSocketClass(wsUrl, options) : new WebSocketClass(wsUrl) \n}\n\n/**\n * Group the ping and get respond create new client in one\n * @param {object} ws \n * @param {object} WebSocket \n * @param {string} url\n * @param {function} resolver \n * @param {function} rejecter \n * @param {boolean} auth client or not\n * @return {promise} resolve the confirm client\n */\nfunction initPingAction(ws, WebSocketClass, type, url, wsOptions, resolver, rejecter) {\n\n // @TODO how to we id this client can issue a CSRF\n // by origin? \n ws.onopen = function onOpenCallback() {\n ws.send(createInitPing())\n }\n\n ws.onmessage = function onMessageCallback(payload) {\n try {\n const header = extractPingResult(payload.data)\n // delay or not show no different but just on the safe side\n setTimeout(() => { \n disconnect(ws)\n }, 50)\n const newWs = createWs(WebSocketClass, type, url, Object.assign(wsOptions, header)) \n \n resolver(newWs) \n \n } catch(e) {\n rejecter(e)\n }\n }\n\n ws.onerror = function onErrorCallback(err) {\n rejecter(err)\n }\n}\n\n/**\n * less duplicated code the better \n * @param {object} WebSocket \n * @param {string} type we need to change the way how it deliver header for different platform\n * @param {string} url formatted url\n * @param {object} options or not\n * @return {promise} resolve the actual verified client\n */\nfunction asyncConnect(WebSocketClass, type, url, options) {\n \n return new Promise((resolver, rejecter) => { \n const unconfirmClient = createWs(WebSocketClass, type, url, options)\n \n return initPingAction(unconfirmClient, WebSocketClass, type, url, options, resolver, rejecter)\n })\n}\n\n/**\n * The bug was in the wsOptions where ws don't need it but socket.io do\n * therefore the object was pass as second parameter!\n * @NOTE here we only return a method to create the client, it might not get call \n * @param {object} WebSocket the client or node version of ws\n * @param {string} [type = 'browser'] we need to tell if this is browser or node \n * @param {boolean} [auth = false] if it's auth then 3 param or just one\n * @return {function} the client method to connect to the ws socket server\n */\nfunction setupWebsocketClientFn(WebSocketClass, type = 'browser', auth = false) {\n if (auth === false) {\n /**\n * Create a non-protected client\n * @param {string} uri already constructed url \n * @param {object} config from the ws-client-core this will be wsOptions taken out from opts \n * @return {promise} resolve to the confirmed client\n */\n return function createWsClient(uri, config) {\n // const { log } = config\n const { url, opts } = prepareConnectConfig(uri, config, false)\n\n return asyncConnect(WebSocketClass, type, url, opts)\n }\n }\n\n /**\n * Create a client with auth token\n * @param {string} uri start with ws:// @TODO check this?\n * @param {object} config this is the full configuration because we need something from it\n * @param {string} token the jwt token\n * @return {object} ws instance\n */\n return function createWsAuthClient(uri, config, token) {\n // const { log } = config\n const { url, opts } = prepareConnectConfig(uri, config, token)\n\n return asyncConnect(WebSocketClass, type, url, opts)\n }\n}\n\nexport { setupWebsocketClientFn }","// @BUG when call disconnected\n// this keep causing an \"Disconnect call failed TypeError: Cannot read property 'readyState' of null\"\n// I think that is because it's not login then it can not be disconnect\n// how do we track this state globally\nimport { \n LOGIN_EVENT_NAME, \n CONNECT_EVENT_NAME \n} from 'jsonql-constants'\nimport { clearMainEmitEvt } from '../modules'\n\n/**\n * when we received a login event \n * from the http-client or the standalone login call \n * we received a token here --> update the opts then trigger \n * the CONNECT_EVENT_NAME again\n * @param {object} opts configurations\n * @param {object} nspMap contain all the required info\n * @param {object} ee event emitter\n * @return {void}\n */\nexport function loginEventListener(opts, nspMap, ee) {\n const { log } = opts\n const { namespaces } = nspMap\n\n log(`[4] loginEventHandler`)\n\n ee.$only(LOGIN_EVENT_NAME, function loginEventHandlerCallback(tokenFromLoginAction) {\n\n log('createClient LOGIN_EVENT_NAME $only handler')\n // @NOTE this is wrong because whenever start it will connect the to the public \n // but when login it should just start binding the private event\n clearMainEmitEvt(ee, namespaces)\n // reload the nsp and rebind all the events\n opts.token = tokenFromLoginAction \n ee.$trigger(CONNECT_EVENT_NAME, [opts, ee]) // don't need to pass the nspMap \n })\n}\n","// actually binding the event client to the socket client\nimport {\n createNspClient,\n createNspAuthClient\n} from './modules'\nimport {\n chainPromises \n} from 'jsonql-utils/src/chain-promises'\n\n/**\n * Because the nsps can be throw away so it doesn't matter the scope\n * this will get reuse again\n * @NOTE when we enable the standalone method this sequence will not change \n * only call and reload\n * @param {object} opts configuration\n * @param {object} nspMap from contract\n * @param {string|null} token whether we have the token at run time\n * @return {promise} resolve the nsps namespace with namespace as key\n */\nconst createNsp = function(opts, nspMap, token = null) {\n // we leave the token param out because it could get call by another method\n token = token || opts.token \n let { publicNamespace, namespaces } = nspMap\n const { log } = opts \n log(`createNspAction`, 'publicNamespace', publicNamespace, 'namespaces', namespaces)\n \n // reverse the namespaces because it got stuck for some reason\n // const reverseNamespaces = namespaces.reverse()\n if (opts.enableAuth) {\n return chainPromises(\n namespaces.map((namespace, i) => {\n if (i === 0) {\n if (token) {\n opts.token = token\n log('create createNspAuthClient at run time')\n return createNspAuthClient(namespace, opts)\n }\n return Promise.resolve(false)\n }\n return createNspClient(namespace, opts)\n })\n )\n .then(results => \n results.map((result, i) => \n ({ [namespaces[i]]: result }))\n .reduce((a, b) => Object.assign(a, b), {})\n )\n }\n \n return createNspClient(false, opts)\n .then(nsp => ({[publicNamespace]: nsp}))\n}\n\nexport { createNsp }\n","// taken out from the bind-socket-event-handler \nimport { DISCONNECT_EVENT_NAME } from 'jsonql-constants'\nimport { createIntercomPayload } from '../modules'\n\n/**\n * This is the actual logout (terminate socket connection) handler \n * There is another one that is handle what should do when this happen \n * @param {object} ee eventEmitter\n * @param {object} ws the WebSocket instance\n * @return {void}\n */\nexport function disconnectEventListener(ee, ws) {\n // listen to the LOGOUT_EVENT_NAME when this is a private nsp\n ee.$on(DISCONNECT_EVENT_NAME, function closeEvtHandler() {\n try {\n // @TODO we need find a way to get the userdata\n ws.send(createIntercomPayload(LOGOUT_EVENT_NAME))\n log('terminate ws connection')\n ws.terminate()\n } catch(e) {\n console.error('ws.terminate error', e)\n }\n })\n}","// the WebSocket main handler\nimport {\n ACKNOWLEDGE_REPLY_TYPE,\n EMIT_REPLY_TYPE,\n ERROR_KEY,\n ON_MESSAGE_FN_NAME,\n ON_RESULT_FN_NAME,\n ON_READY_FN_NAME,\n ON_LOGIN_FN_NAME,\n ON_ERROR_FN_NAME\n} from 'jsonql-constants'\nimport {\n createQueryStr,\n createEvt,\n extractWsPayload\n} from 'jsonql-utils/module'\nimport {\n handleNamespaceOnError\n} from '../modules'\nimport { \n disconnectEventListener\n} from './disconnect-event-listener'\n\n/**\n * in some edge case we might not even have a resolverName, then\n * we issue a global error for the developer to catch it\n * @param {object} ee event emitter\n * @param {string} namespace nsp\n * @param {string} resolverName resolver\n * @param {object} json decoded payload or error object\n * @return {undefined} nothing return\n */\nexport const errorTypeHandler = (ee, namespace, resolverName, json) => {\n let evt = [namespace]\n if (resolverName) {\n evt.push(resolverName)\n }\n evt.push(ON_ERROR_FN_NAME)\n let evtName = Reflect.apply(createEvt, null, evt)\n // test if there is a data field\n let payload = json.data || json\n ee.$trigger(evtName, [payload])\n}\n\n/**\n * Binding the event to socket normally\n * @param {string} namespace\n * @param {object} ws the nsp\n * @param {object} ee EventEmitter\n * @param {boolean} isPrivate to id if this namespace is private or not\n * @param {object} opts configuration\n * @param {number} ctnLeft in the namespaceEventListener count down how many namespace left to call \n * @return {object} promise resolve after the onopen event\n */\nexport function bindSocketEventHandler(namespace, ws, ee, isPrivate, opts, ctnLeft) {\n const { log } = opts\n // setup the logut event listener \n // this will hear the event and actually call the ws.terminate\n if (isPrivate) {\n log('Private namespace', namespace, ' binding to the DISCONNECT ws.terminate')\n disconnectEventListener(ee, ws)\n }\n // log(`log test, isPrivate:`, isPrivate)\n // connection open\n ws.onopen = function onOpenCallback() {\n\n log('client.ws.onopen listened -->', namespace)\n /*\n This is the change from before about the hooks \n now only the public namespace will get trigger the onReady \n and the private one will get the onLogin \n this way, we won't get into the problem of multiple event \n get trigger, and for developer they just have to place \n the callback inside the right hook\n */\n if (isPrivate) {\n log(`isPrivate and fire the ${ON_LOGIN_FN_NAME}`)\n ee.$call(ON_LOGIN_FN_NAME)(namespace)\n } else {\n ee.$call(ON_READY_FN_NAME)(namespace, ctnLeft)\n // The namespaceEventListener will count this for here\n // and this count will only count the public namespace \n // it will always be 1 for now\n log(`isPublic onReady hook executed`, ctnLeft)\n if (ctnLeft === 0) {\n ee.$off(ON_READY_FN_NAME)\n }\n }\n // add listener only after the open is called\n ee.$only(\n createEvt(namespace, EMIT_REPLY_TYPE),\n /**\n * actually send the payload to server\n * @param {string} resolverName\n * @param {array} args NEED TO CHECK HOW WE PASS THIS!\n */\n function wsMainOnEvtHandler(resolverName, args) {\n const payload = createQueryStr(resolverName, args)\n log('ws.onopen.send', resolverName, args, payload)\n\n ws.send(payload)\n }\n )\n }\n\n // reply\n // If we change it to the event callback style\n // then the payload will just be the payload and fucks up the extractWsPayload call @TODO\n ws.onmessage = function onMessageCallback(payload) {\n\n log(`client.ws.onmessage raw payload`, payload.data)\n \n // console.log(`on.message`, typeof payload, payload)\n try {\n // log(`ws.onmessage raw payload`, payload)\n // @TODO the payload actually contain quite a few things - is that changed?\n // type: message, data: data_send_from_server\n const json = extractWsPayload(payload.data)\n const { resolverName, type } = json\n\n log('Respond from server', type, json)\n\n switch (type) {\n case EMIT_REPLY_TYPE:\n let e1 = createEvt(namespace, resolverName, ON_MESSAGE_FN_NAME)\n let r = ee.$call(e1)(json)\n \n log(`EMIT_REPLY_TYPE`, e1, r)\n break\n case ACKNOWLEDGE_REPLY_TYPE:\n let e2 = createEvt(namespace, resolverName, ON_RESULT_FN_NAME)\n let x2 = ee.$call(e2)(json)\n\n log(`ACKNOWLEDGE_REPLY_TYPE`, e2, x2)\n break\n case ERROR_KEY:\n // this is handled error and we won't throw it\n // we need to extract the error from json\n log(`ERROR_KEY`)\n errorTypeHandler(ee, namespace, resolverName, json)\n break\n // @TODO there should be an error type instead of roll into the other two types? TBC\n default:\n // if this happen then we should throw it and halt the operation all together\n log('Unhandled event!', json)\n errorTypeHandler(ee, namespace, resolverName, json)\n // let error = {error: {'message': 'Unhandled event!', type}};\n // ee.$trigger(createEvt(namespace, resolverName, ON_RESULT_FN_NAME), [error])\n }\n } catch(e) {\n log(`client.ws.onmessage error`, e)\n errorTypeHandler(ee, namespace, false, e)\n }\n }\n // when the server close the connection\n ws.onclose = function onCloseCallback() {\n log('client.ws.onclose callback')\n // @TODO what to do with this\n // ee.$trigger(LOGOUT_EVENT_NAME, [namespace])\n }\n // add a onerror event handler here\n ws.onerror = function onErrorCallback(err) {\n // trigger a global error event\n log(`client.ws.onerror`, err)\n handleNamespaceOnError(ee, namespace, err)\n }\n \n // we don't bind the logut here and just return the ws \n return ws \n}\n","// take out from the bind-framework-to-jsonql \nimport { CONNECT_EVENT_NAME } from 'jsonql-constants'\nimport { createNsp } from '../create-nsp'\nimport { namespaceEventListener } from '../modules'\nimport { bindSocketEventHandler } from './bind-socket-event-handler'\n\n/**\n * This is the hard of establishing the connection and binding to the jsonql events \n * @param {*} nspMap \n * @param {*} ee event emitter\n * @param {function} log function to show internal \n * @return {void}\n */\nexport function connectEventListener(nspMap, ee, log) {\n log(`[2] setup the CONNECT_EVENT_NAME`)\n // this is a automatic trigger from within the framework\n ee.$only(CONNECT_EVENT_NAME, function connectEventNameHandler($config, $ee) {\n log(`[3] CONNECT_EVENT_NAME`, $config)\n\n return createNsp($config, nspMap)\n .then(nsps => namespaceEventListener(bindSocketEventHandler, nsps))\n .then(listenerFn => listenerFn($config, nspMap, $ee))\n })\n}","// share method to create the wsClientResolver\nimport { \n NSP_CLIENT, \n NSP_AUTH_CLIENT,\n ENABLE_AUTH_PROP_KEY\n} from 'jsonql-constants'\nimport { \n setupWebsocketClientFn \n} from './setup-websocket-client-fn'\nimport { \n loginEventListener, \n connectEventListener \n} from '../setup-socket-listeners'\n\n/**\n * Create the framework <---> jsonql client binding\n * @param {object} WebSocketClass the different WebSocket module\n * @param {string} [type=browser] we need different setup for browser or node\n * @return {function} the wsClientResolver\n */\nfunction setupConnectClient(WebSocketClass, type = 'browser') {\n /**\n * wsClientResolver\n * @param {object} opts configuration\n * @param {object} nspMap from the contract\n * @param {object} ee instance of the eventEmitter\n * @return {object} passing the same 3 input out with additional in the opts\n */\n return function createClientBindingAction(opts, nspMap, ee) {\n const { log } = opts\n\n log(`There is problem here with passing the opts`, opts)\n // this will put two callable methods into the opts \n opts[NSP_CLIENT] = setupWebsocketClientFn(WebSocketClass, type)\n // we don't need this one unless enableAuth === true \n if (opts[ENABLE_AUTH_PROP_KEY] === true) {\n opts[NSP_AUTH_CLIENT] = setupWebsocketClientFn(WebSocketClass, type, true)\n } \n // debug \n log(`[1] bindWebsocketToJsonql`, ee.$name, nspMap)\n // @2020-03-20 @NOTE \n \n connectEventListener(nspMap, ee, log)\n \n // next we need to setup the login event handler\n // But the same design (see above) when we received a login event \n // from the http-client or the standalone login call \n // we received a token here --> update the opts then trigger \n // the CONNECT_EVENT_NAME again\n loginEventListener(opts, nspMap, ee)\n\n log(`just before returing the values for the next operation from createClientBindingAction`)\n\n // we just return what comes in\n return { opts, nspMap, ee }\n }\n}\n\nexport { setupConnectClient }","// this will be the news style interface that will pass to the jsonql-ws-client\n// then return a function for accepting an opts to generate the final\n// client api\nimport ws from './ws'\nimport { setupConnectClient } from './setup-connect-client'\n\nconst setupSocketClientListener = setupConnectClient(ws)\n\n/**\n * We export it as a default and use the file name to id the function \n * but it just way too confusing, therefore we change it to a name export \n * @param {object} opts configuration\n * @param {object} nspMap from the contract\n * @param {object} ee instance of the eventEmitter\n * @return {object} passing the same 3 input out with additional in the opts\n */\nexport {\n setupSocketClientListener\n} \n","// this is the module entry point for ES6 for client\n// the main will point to the node.js server side setup\nimport { \n wsClientCore\n} from './core/modules' \nimport { \n wsClientCheckMap,\n wsClientConstProps\n} from './options'\nimport { \n setupSocketClientListener \n} from './core/setup-socket-client-listener'\n\n// export back the function and that's it\nexport default function wsBrowserClient(config = {}, constProps = {}) {\n return wsClientCore(\n setupSocketClientListener, \n wsClientCheckMap, \n Object.assign({}, wsClientConstProps, constProps)\n )(config)\n}\n","// just export interface for browser\nimport wsBrowserClient from './src/browser-ws-client'\n\nexport default wsBrowserClient"],"names":["const","let","toJson","extractWsPayload","JsonqlError","timestamp","createQueryStr","INTERCOM_RESOLVER_NAME","SOCKET_PING_EVENT_NAME","DATA_KEY","CSRF_HEADER_KEY","HEADERS_KEY","super","toArray","createEvt","EMIT_REPLY_TYPE","IS_READY_PROP_KEY","IS_LOGIN_PROP_KEY","injectToFn","isObjectHasKey","ERROR_KEY","ON_RESULT_FN_NAME","objDefineProps","SEND_MSG_FN_NAME","nil","validateAsync","ON_ERROR_FN_NAME","JsonqlValidationError","finalCatch","isFunc","ON_MESSAGE_FN_NAME","chainFns","ON_READY_FN_NAME","isString","LOGIN_EVENT_NAME","LOGOUT_EVENT_NAME","ON_LOGIN_FN_NAME","STANDALONE_PROP_KEY","CONNECTED_PROP_KEY","CONNECT_EVENT_NAME","CONNECTED_EVENT_NAME","DISCONNECT_EVENT_NAME","SUSPEND_EVENT_PROP_KEY","NSP_GROUP","createConfig","BOOLEAN_TYPE","DEBUG_ON_PROP_KEY","LOGIN_FN_NAME_PROP_KEY","LOGIN_FN_NAME","STRING_TYPE","LOGOUT_FN_NAME_PROP_KEY","LOGOUT_FN_NAME","DISCONNECT_FN_NAME_PROP_KEY","DISCONNECT_FN_NAME","SWITCH_USER_FN_NAME_PROP_KEY","SWITCH_USER_FN_NAME","HOSTNAME_PROP_KEY","NAMESAPCE_PROP_KEY","JSONQL_PATH","WS_OPT_PROP_KEY","OBJECT_TYPE","CONTRACT_PROP_KEY","CHECKER_KEY","isContract","ENABLE_AUTH_PROP_KEY","TOKEN_PROP_KEY","CSRF_PROP_KEY","SOCKET_TYPE_PROP_KEY","ALIAS_KEY","SOCKET_TYPE_CLIENT_ALIAS","USE_JWT_PROP_KEY","PUBLIC_KEY","PRIVATE_KEY","checkConfigAsync","getNspInfoByConfig","NOT_LOGIN_ERR_MSG","getPrivateNamespace","TOKEN_IN_URL","TOKEN_IN_HEADER","JS_WS_NAME","TOKEN_DELIVER_LOCATION_PROP_KEY","ENUM_KEY","prepareConnectConfig","chainPromises","ACKNOWLEDGE_REPLY_TYPE","NSP_CLIENT","NSP_AUTH_CLIENT","ws"],"mappings":";;;;;;;;;;EAAA;EAsBAA,IAAM,yBAAyB,GAAG,6CAA4C;AAC9E;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,iBAAiB,CAAC,OAAO,EAAE;EACpC,EAAEC,IAAI,IAAI,GAAGC,aAAM,CAAC,OAAO,EAAC;EAC5B;EACA,EAAE,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;EACxC;EACA,IAAI,OAAOC,uBAAgB,CAAC,IAAI,CAAC;EACjC,GAAG;EACH;EACA,EAAE,MAAM,IAAIC,wBAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC;EAClD,CAAC;AACD;EACA;EACA;EACA;EACA;EACA,SAAS,cAAc,GAAG;EAC1B,EAAEJ,IAAM,EAAE,GAAGK,gBAAS,GAAE;AACxB;EACA,EAAE,OAAOC,qBAAc,CAACC,sCAAsB,EAAE,CAACC,sCAAsB,EAAE,EAAE,CAAC,CAAC;EAC7E,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,iBAAiB,CAAC,OAAO,EAAE;;AAAC;EACrC,EAAER,IAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,EAAC;EAC3C;EACA,EAAE,IAAI,MAAM,IAAI,MAAM,CAACS,wBAAQ,CAAC,IAAI,MAAM,CAACA,wBAAQ,CAAC,CAACC,+BAAe,CAAC,EAAE;EACvE,IAAI,eAAO,EAAC,KACN,CAACC,2BAAW,IAAG,MAAM,CAACF,wBAAQ,QAC/B;EACL,GAAG;AACH;EACA,EAAE,MAAM,IAAIL,wBAAW,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;EACvE,CAAC;AACD;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,qBAAqB,CAAC,IAAa,EAAE;;;AAAC;EAC/C,EAAEJ,IAAM,EAAE,GAAGK,gBAAS,GAAE;EACxB,EAAEJ,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAC;EACnC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,EAAC;EAClB,EAAE,OAAOK,qBAAc,CAACC,sCAAsB,EAAE,OAAO,CAAC;EACxD;;EC/EA;AACA;EACA;EACAP,IAAM,WAAW,eAAS,GAAE;AAC5B;EACA;EACA;EACA;EACA;EACA;EACAA,IAAM,SAAS,aAAI,IAAI,EAAK;EAC5B,EAAU,2BAAgB;EAC1B,EAAE,IAAI,OAAO,EAAE;EACf,IAAI,mBAAoB;;;AAAC;EACzB,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,yBAAyB,WAAK,IAAI,CAAC,EAAC;EAChF,KAAK;EACL,GAAG;EACH,EAAE,OAAO,WAAW;EACpB,EAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACAA,IAAM,QAAQ,aAAG,MAAQ;EACzB,EAAU,mBAAY;EACtB,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;EACzC,IAAI,OAAO,SAAS,CAAC,IAAI,CAAC;EAC1B,GAAG;EACH,EAAE,IAAI,CAAC,GAAG,CAAC,+CAA+C,EAAE,IAAI,EAAC;EACjE,EAAE,OAAO,GAAG;EACZ;;EChCA;EAEA;EACA,IAAM,WAAW;IAEf,oBAAW,CAAC,MAAM,EAAE;EACtB,IAAI,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;EACtC,MAAM,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC;EACpE,KAAK;EACL,IAAI,MAAM,CAAC,qCAAqC,EAAC;EACjD;EACA;EACA,IAAIY,sBAAK,OAAC,UAAE,MAAM,EAAE,EAAC;EACrB;;;;;;8DAAG;AACH;EACA,EAAE,mBAAI,uBAAO;EACb,IAAI,OAAM,uBAAuB;EACjC;;;;;IAd0B,oBAezB;AACD;EACA;EACA;EACA;EACA;EACA;EACAZ,IAAM,eAAe,aAAG,MAAQ;EAChC,EAAU;IAAK,qCAAqB;EACpC;EACA,EAAE,IAAI,YAAY,EAAE;EACpB,IAAI,GAAG,CAAC,kBAAkB,EAAE,YAAY,CAAC,IAAI,EAAC;EAC9C,IAAI,OAAO,YAAY;EACvB,GAAG;EACH;EACA,EAAE,OAAO,IAAI,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;EACpC;;EClCA;AASA;EACA;EACA;EACA;EACA;EACA;EACOA,IAAM,MAAM,aAAG,KAAO;EAC7B,EAAEA,IAAM,OAAO,GAAG,IAAI,MAAM,CAAC,qBAAqB,EAAE,GAAG,EAAC;EACxD,EAAEA,IAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,EAAC;EACnC,EAAE,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE;EAC/B,IAAIA,IAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,GAAE;EAC1C,IAAIA,IAAM,WAAW,GAAG,MAAM,KAAK,OAAO,GAAG,KAAK,GAAG,KAAI;EACzD;EACA,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,KAAK,CAAC;EACpD,GAAG;AACH;EACA,EAAE,OAAO,GAAG;EACZ,EAAC;AACD;AACA;EACA;EACA;EACA;EACOA,IAAM,WAAW,eAAS;EACjC,EAAE,IAAI;EACN,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EACtE,GAAG,CAAC,MAAM,CAAC,EAAE;EACb,IAAI,MAAM,IAAI,qBAAqB,CAAC,CAAC,CAAC;EACtC,GAAG;EACH,EAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACOA,IAAM,gBAAgB,aAAI,EAAE,EAAE,SAAS,EAAK;EACnD,EAAEC,IAAI,IAAI,GAAGY,eAAO,CAAC,SAAS,EAAC;EAC/B,EAAE,IAAI,CAAC,OAAO,WAAC,GAAK;EACpB,IAAI,EAAE,CAAC,IAAI,CAACC,iBAAS,CAAC,CAAC,EAAEC,+BAAe,CAAC,EAAC;EAC1C,GAAG,EAAC;EACJ,EAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,kBAAkB,CAAC,MAAM,EAAE;EAC3C,EAAE,OAAO,CAACC,iCAAiB,EAAEC,iCAAiB,CAAC;EAC/C;EACA,KAAK,MAAM,WAAE,CAAC,EAAE,GAAG,EAAK;EACxB,MAAM,OAAOC,yBAAU,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC;EAC5C,KAAK,EAAE,MAAM,CAAC;EACd;;EChEA;AAsBA;EACAlB,IAAM,QAAQ,GAAGe,gCAAe;AAGhC;EACAf,IAAM,cAAc,GAAG,kBAAiB;AAGxC;EACAA,IAAM,YAAY,GAAG;;EC/BrB;AAIA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE;EACzD,EAAE,IAAImB,qBAAc,CAAC,IAAI,EAAEC,yBAAS,CAAC,EAAE;EACvC;EACA,IAAI,QAAQ,CAAC,IAAI,CAACA,yBAAS,CAAC,EAAC;EAC7B,GAAG,MAAM,IAAID,qBAAc,CAAC,IAAI,EAAEV,wBAAQ,CAAC,EAAE;EAC7C;EACA;EACA;EACA,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAI,IAAI,CAACA,wBAAQ,CAAC,EAAC,EAAC;EACtD,GAAG,MAAM;EACT;EACA,IAAI,QAAQ,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,EAAC;EACpD,GAAG;EACH;;ECzBA;AAIA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,IAAS,EAAE,GAAG,EAAE;+BAAZ,GAAG;AAAU;EACzE;EACA,EAAET,IAAM,YAAY,GAAGc,gBAAS,CAAC,SAAS,EAAEC,+BAAe,EAAC;AAC5D;EACA,EAAE,GAAG,mBAAgB,YAAY,aAAQ,eAAgB,IAAI,EAAC;EAC9D;EACA,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,YAAY,EAAEF,cAAO,CAAC,IAAI,CAAC,CAAC,EAAC;EAC1D;EACA;EACA,EAAE,OAAO,IAAI,OAAO,WAAE,QAAQ,EAAE,QAAQ,EAAK;EAC7C,IAAIb,IAAM,WAAW,GAAGc,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEO,iCAAiB,EAAC;EAC7E;EACA;EACA;EACA,IAAI,EAAE,CAAC,GAAG;EACV,MAAM,WAAW;EACjB,MAAM,SAAS,uBAAuB,CAAC,MAAM,EAAE;EAC/C,QAAQ,GAAG,CAAC,sBAAsB,EAAE,MAAM,EAAC;EAC3C,QAAQ,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAC;EAClD,OAAO;EACP,MAAK;EACL,GAAG,CAAC;EACJ;;ECpCA;AASA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACOrB,IAAM,eAAe,aAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG;EAC5E,EAAEsB,qBAAc;EAChB,IAAI,EAAE;EACN,IAAIC,gCAAgB;EACpB,IAAIC,UAAG;EACP,IAAI,SAAS,WAAW,GAAG;EAC3B,MAAM,GAAG,CAAC,4BAA4B,EAAC;EACvC;EACA;EACA;EACA;EACA;EACA;EACA,MAAM,OAAO,SAAS,YAAY,GAAU;;;AAAC;EAC7C,QAAQ,OAAOC,mCAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;EACvD,WAAW,IAAI,WAAC,OAAS;EACzB;EACA;EACA,YAAY,GAAG,CAAC,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAC;EAC/D,YAAY,OAAO,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC;EACtE,WAAW,CAAC;EACZ,WAAW,KAAK,WAAC,KAAO;EACxB;EACA;EACA;EACA,YAAY,GAAG,CAAC,YAAY,EAAE,GAAG,EAAC;EAClC;EACA,YAAY,EAAE,CAAC,KAAK;EACpB,cAAcX,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEY,gCAAgB,CAAC;EAClE,cAAc,CAAC,IAAIC,kCAAqB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;EAC5D,cAAa;EACb,WAAW,CAAC;EACZ,OAAO;EACP,KAAK,CAAC;EACN;;ECzDA;AAqBA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE;EAClE;EACA,EAAE,OAAO,SAAS,QAAQ,GAAU;;;AAAC;EACrC,IAAI,OAAOF,mCAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;EACnD,OAAO,IAAI,WAAC,gBAAS,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,IAAC,CAAC;EACzE,OAAO,KAAK,CAACG,uBAAU,CAAC;EACxB,GAAG;EACH,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA5B,IAAM,cAAc,aAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,WAAK;EACzE,EAAEkB,iBAAU,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC;EACzC,EAAE,EAAE;EACJ,EAAE,SAAS;EACX,EAAE,YAAY;EACd,EAAE,MAAM;EACR,EAAE,GAAG;EACL,KAAC;AACD;EACA;EACA;EACA;EACAlB,IAAM,aAAa,aAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,WAAK;EACxE,EAAEsB,qBAAc,CAAC,EAAE,EAAED,iCAAiB,EAAE,SAAS,cAAc,EAAE;EACjE,IAAI,IAAIQ,aAAM,CAAC,cAAc,CAAC,EAAE;EAChC,MAAM,EAAE,CAAC,GAAG;EACZ,QAAQf,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEO,iCAAiB,CAAC;EAC7D,QAAQ,SAAS,aAAa,CAAC,MAAM,EAAE;EACvC,UAAU,cAAc,CAAC,MAAM,EAAE,cAAc,YAAG,KAAK,EAAK;EAC5D,YAAY,GAAG,sBAAkB,YAAY,UAAK,KAAK,EAAC;EACxD,YAAY,EAAE,CAAC,QAAQ;EACvB,cAAcP,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEY,gCAAgB,CAAC;EAClE,cAAc,KAAK;EACnB,cAAa;EACb,WAAW,EAAC;EACZ,SAAS;EACT,QAAO;EACP,KAAK;EACL,GAAG,CAAC;EACJ,EAAE,EAAE;EACJ,EAAE,SAAS;EACX,EAAE,YAAY;EACd,EAAE,MAAM;EACR,EAAE,GAAG;EACL,KAAC;AACD;EACA;EACA;EACA;EACA;EACA1B,IAAM,cAAc,aAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,WAAK;EACzE,EAAEsB,qBAAc,CAAC,EAAE,EAAEQ,kCAAkB,EAAE,SAAS,eAAe,EAAE;EACnE;EACA,IAAI,IAAID,aAAM,CAAC,eAAe,CAAC,EAAE;EACjC;EACA,MAAM5B,IAAI,iBAAiB,aAAI,IAAI,EAAK;EACxC,QAAQ,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAC;EACtC,QAAQ,cAAc;EACtB,UAAU,IAAI;EACd,UAAU,eAAe;EACzB,oBAAW,KAAK,EAAK;EACrB,YAAY,GAAG,sBAAkB,YAAY,UAAK,KAAK,EAAC;EACxD,YAAY,EAAE,CAAC,QAAQ;EACvB,cAAca,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEY,gCAAgB,CAAC;EAClE,cAAc,KAAK;EACnB,cAAa;EACb,WAAW,EAAC;EACZ,UAAS;EACT;EACA,MAAM,EAAE,CAAC,KAAK;EACd,QAAQZ,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEgB,kCAAkB,CAAC;EAC9D,QAAQ,iBAAiB;EACzB,QAAO;EACP,KAAK;EACL,GAAG,CAAC;EACJ,EAAE,EAAE;EACJ,EAAE,SAAS;EACX,EAAE,YAAY;EACd,EAAE,MAAM;EACR,EAAE,GAAG;EACL,KAAC;AACD;EACA;EACA;EACA;EACA9B,IAAM,YAAY,aAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,WAAK;EACvE,EAAEsB,qBAAc,CAAC,EAAE,EAAEI,gCAAgB,EAAE,SAAS,oBAAoB,EAAE;EACtE,IAAI,IAAIG,aAAM,CAAC,oBAAoB,CAAC,EAAE;EACtC;EACA,MAAM,EAAE,CAAC,KAAK;EACd,QAAQf,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEY,gCAAgB,CAAC;EAC5D,QAAQ,oBAAoB;EAC5B,QAAO;EACP,KAAK;EACL,GAAG,CAAC;EACJ,EAAE,EAAE;EACJ,EAAE,SAAS;EACX,EAAE,YAAY;EACd,EAAE,MAAM;EACR,EAAE,GAAG;EACL,KAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;EACrE,EAAEzB,IAAI,GAAG,GAAG;EACZ,IAAI,cAAc;EAClB,IAAI,aAAa;EACjB,IAAI,cAAc;EAClB,IAAI,YAAY;EAChB,IAAI,eAAe;EACnB,IAAG;EACH,EAAED,IAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC+B,eAAQ,EAAE,IAAI,EAAE,GAAG,EAAC;EACrD;EACA,EAAE,OAAO,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC;EAC/D;;ECrKA;AAYA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,iBAAiB,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE;EACtD,EAAU,mBAAY;EACtB,EAAE9B,IAAI,MAAM,EAAE,GAAE;EAChB;EACA,EAAE,KAAKA,IAAI,SAAS,IAAI,QAAQ,EAAE;EAClC,IAAIA,IAAI,IAAI,GAAG,QAAQ,CAAC,SAAS,EAAC;EAClC,IAAI,KAAKA,IAAI,YAAY,IAAI,IAAI,EAAE;EACnC;EACA,MAAMA,IAAI,MAAM,GAAG,IAAI,CAAC,YAAY,EAAC;EACrC,MAAMA,IAAI,EAAE,GAAG,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAC;EACvE;EACA,MAAM,MAAM,GAAGiB,iBAAU;EACzB,QAAQ,MAAM;EACd,QAAQ,YAAY;EACpB,QAAQ,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC;EACnE,QAAO;EACP,KAAK;EACL,GAAG;EACH;EACA;EACA,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE;EACvC;;ECzCA;AAWA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EACvD,EAAE,OAAO;EACT,IAAII,qBAAc;EAClB,MAAM,MAAM;EACZ,MAAMU,gCAAgB;EACtB,MAAM,SAAS,sBAAsB,CAAC,eAAe,EAAE;EACvD,QAAQ,IAAIH,aAAM,CAAC,eAAe,CAAC,EAAE;EACrC;EACA;EACA;EACA,UAAU,EAAE,CAAC,KAAK,CAACG,gCAAgB,EAAE,eAAe,EAAC;EACrD,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,IAAI;EACR,IAAI,EAAE;EACN,GAAG;EACH,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,2BAA2B,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE;EACxE,EAAE,OAAO;EACT,IAAIV,qBAAc;EAClB,MAAM,MAAM;EACZ,MAAMI,gCAAgB;EACtB,MAAM,SAAS,6BAA6B,CAAC,qBAAqB,EAAE;EACpE,QAAQ,IAAIG,aAAM,CAAC,qBAAqB,CAAC,EAAE;EAC3C;EACA,UAAU,KAAK5B,IAAI,SAAS,IAAI,QAAQ,EAAE;EAC1C;EACA;EACA,YAAY,EAAE,CAAC,GAAG,CAACa,gBAAS,CAAC,SAAS,EAAEY,gCAAgB,CAAC,EAAE,qBAAqB,EAAC;EACjF,WAAW;EACX,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,IAAI;EACR,IAAI,EAAE;EACN,GAAG;EACH;;EClEA;EAWA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA1B,IAAM,iBAAiB,aAAI,GAAG,EAAE,IAAI,EAAE,EAAE,WAAK;EAC7C,EAAEkB,iBAAU;EACZ,IAAI,GAAG;EACP,IAAI,IAAI,CAAC,gBAAgB;EACzB,IAAI,SAAS,YAAY,CAAC,KAAK,EAAE;EACjC,MAAM,IAAI,KAAK,IAAIe,8BAAQ,CAAC,KAAK,CAAC,EAAE;EACpC,QAAQ,IAAI,CAAC,GAAG,gBAAaC,gCAAgB,cAAS,QAAQ;EAC9D;EACA,QAAQ,OAAO,EAAE,CAAC,QAAQ,CAACA,gCAAgB,EAAE,CAAC,KAAK,CAAC,CAAC;EACrD,OAAO;EACP;EACA,MAAM,MAAM,IAAIP,kCAAqB,CAAC,IAAI,CAAC,gBAAgB,yBAAsB,OAAQ;EACzF,KAAK;EACL,GAAG;EACH,EAAE,IAAI;EACN,EAAE,EAAE;EACJ,KAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA3B,IAAM,2BAA2B,aAAI,GAAG,EAAE,IAAI,EAAE,EAAE,WAAK;EACvD,EAAEkB,iBAAU;EACZ,IAAI,GAAG;EACP,IAAI,gBAAgB;EACpB,IAAI,SAAS,sBAAsB,GAAU;;;AAAC;EAC9C;EACA;EACA,MAAM,EAAE,CAAC,QAAQ,CAACgB,gCAAgB,EAAE,IAAI,EAAC;EACzC,KAAK;EACL,GAAG;EACH,EAAE,IAAI;EACN,EAAE,EAAE;EACJ,KAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACAlC,IAAM,kBAAkB,aAAI,GAAG,EAAE,IAAI,EAAE,EAAE,WAAK;EAC9C,EAAEkB,iBAAU;EACZ,IAAI,GAAG;EACP,IAAI,IAAI,CAAC,iBAAiB;EAC1B,IAAI,SAAS,aAAa,GAAU;;;AAAC;EACrC,MAAM,IAAI,CAACD,iCAAiB,CAAC,GAAG,KAAI;EACpC,MAAM,EAAE,CAAC,QAAQ,CAACkB,iCAAiB,EAAE,IAAI,EAAC;EAC1C,KAAK;EACL,GAAG;EACH,EAAE,IAAI;EACN,EAAE,EAAE;EACJ,KAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACAnC,IAAM,oBAAoB,aAAI,GAAG,EAAE,IAAI,EAAE,EAAE,WAAK;EAChD,EAAEsB,qBAAc;EAChB,IAAI,GAAG;EACP,IAAIc,gCAAgB;EACpB,IAAI,SAAS,sBAAsB,CAAC,eAAe,EAAE;EACrD,MAAM,IAAIP,aAAM,CAAC,eAAe,CAAC,EAAE;EACnC;EACA;EACA;EACA,QAAQ,EAAE,CAAC,KAAK,CAACO,gCAAgB,EAAE,eAAe,EAAC;EACnD,OAAO;EACP,KAAK;EACL,GAAG;EACH,EAAE,IAAI;EACN,EAAE,EAAE;EACJ,KAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;EAChD,EAAE,OAAOL,eAAQ;EACjB,IAAI,IAAI,CAACM,mCAAmB,CAAC,KAAK,IAAI,GAAG,2BAA2B,GAAG,iBAAiB;EACxF,IAAI,kBAAkB;EACtB,IAAI,oBAAoB;EACxB,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;EAClB;;EC5HA;AAUA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EAC/C,EAAU,mBAAY;EACtB,EAAE,GAAG,CAAC,yBAAyB,EAAC;EAChC;EACA;EACA,EAAE,MAAM,GAAGnB,iBAAU,CAAC,MAAM,EAAEoB,kCAAkB,GAAG,KAAK,EAAE,IAAI,EAAC;EAC/D,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EAC7B,CAAC;AACD;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EACnD;EACA,EAAU,mBAAY;AACtB;EACA,EAAE,GAAG,CAAC,6BAA6B,EAAC;AACpC;EACA,EAAE,EAAE,CAAC,GAAG,CAACC,kCAAkB,EAAE,WAAkB;;;AAAC;EAChD,IAAI,GAAG,CAAC,2DAA2D,EAAE,IAAI,EAAC;EAC1E,GAAG,EAAC;EACJ;EACA,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;EAC3B,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,yBAAyB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EACrD,EAAU,mBAAY;AACtB;EACA,EAAE,GAAG,CAAC,+BAA+B,EAAC;AACtC;EACA,EAAE,EAAE,CAAC,GAAG,CAACC,oCAAoB,EAAE,WAAW;;AAAC;EAC3C,IAAI,MAAM,CAACF,kCAAkB,CAAC,GAAG,KAAI;EACrC;EACA,IAAItC,IAAM,GAAG,GAAG,EAAE,CAAC,QAAQ,GAAE;AAC7B;EACA,IAAI,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAC;AACzD;EACA,EAAE,eAAO,OAAC,CAACsC,kCAAkB,IAAG,WAAK;EACrC,GAAG,EAAC;AACJ;EACA,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;EAC3B,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EACnD,EAAU,mBAAY;AACtB;EACA,EAAE,GAAG,CAAC,6BAA6B,EAAC;AACpC;EACA,EAAE,EAAE,CAAC,GAAG,CAACG,qCAAqB,EAAE,WAAW;;AAAC;EAC5C,IAAI,MAAM,CAACH,kCAAkB,CAAC,GAAG,MAAK;EACtC,IAAI,GAAG,CAAC,sBAAsB,EAAE,KAAK,EAAC;AACtC;EACA,EAAE,eAAO,OAAC,CAACA,kCAAkB,IAAG,YAAM;EACtC,GAAG,EAAC;AACJ;EACA,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;EAC3B,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EAChD,EAAU;IAAuB,mBAAY;EAC7C,EAAE,GAAG,CAAC,0BAA0B,EAAC;AACjC;EACA,EAAE,OAAOpB,iBAAU;EACnB,IAAI,MAAM;EACV,IAAI,qBAAqB;EACzB,IAAI,SAAS,iBAAiB,GAAU;;;AAAC;EACzC,MAAM,EAAE,CAAC,QAAQ,CAACuB,qCAAqB,EAAE,IAAI,EAAC;EAC9C,KAAK;EACL,GAAG;EACH,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;EAChD,EAAEzC,IAAM,GAAG,GAAG;EACd,IAAI,mBAAmB;EACvB,IAAI,uBAAuB;EAC3B,IAAI,yBAAyB;EAC7B,IAAI,uBAAuB;EAC3B,IAAI,oBAAoB;EACxB,IAAG;AACH;EACA,EAAEA,IAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC+B,eAAQ,EAAE,IAAI,EAAE,GAAG,EAAC;EACrD,EAAE,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;EACnC;;ECnIA;AAQA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;EACvC;EACA,EAAE9B,IAAI,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAC;EAC3C;EACA;EACA,EAAE,MAAM,CAAC,kBAAkB,wBAAS,EAAE,CAAC,MAAE;EACzC;EACA;EACA;EACA,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,aAAY;EACzC,EAAE,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,IAAG;AACvB;EACA;EACA,EAAE,EAAE,CAAC,QAAQ,CAACsC,kCAAkB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAC;EAC7C;EACA,EAAE,IAAI,IAAI,CAACG,sCAAsB,CAAC,KAAK,IAAI,EAAE;EAC7C,IAAI,IAAI,CAAC,iBAAiB,GAAE;EAC5B,GAAG;AACH;EACA;EACA,EAAE,OAAO,kBAAkB,CAAC,GAAG,CAAC;EAChC;;ECtCA;AAeA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;EACnD;EACA,EAAEzC,IAAI,GAAG,GAAG;EACZ,IAAI,iBAAiB;EACrB,IAAI,oBAAoB;EACxB,IAAI,2BAA2B;EAC/B,IAAG;EACH,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE;EACvB;EACA;EACA,IAAI,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAC;EAC9B,GAAG;EACH;EACA;EACA;EACA;EACA,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAC;EAC1B;EACA,EAAED,IAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC+B,eAAQ,EAAE,IAAI,EAAE,GAAG,EAAC;EACrD;EACA,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAACY,yBAAS,CAAC,CAAC;EAC9C;;;ACLA;AACA;AACA;EACA3C,IAAM,cAAc,GAAG,EAAC;gBACtB,CAACqC,mCAAmB,IAAGO,kCAAY,CAAC,KAAK,EAAE,CAACC,4BAAY,CAAC,CAAC;gBAC1D,CAACC,iCAAiB,IAAGF,kCAAY,CAAC,KAAK,EAAE,CAACC,4BAAY,CAAC,CAAC;gBAIxD,CAACE,sCAAsB,IAAGH,kCAAY,CAACI,6BAAa,EAAE,CAACC,2BAAW,CAAC,CAAC;gBACpE,CAACC,uCAAuB,IAAGN,kCAAY,CAACO,8BAAc,EAAE,CAACF,2BAAW,CAAC,CAAC;gBAEtE,CAACG,2CAA2B,IAAGR,kCAAY,CAACS,kCAAkB,EAAE,CAACJ,2BAAW,CAAC,CAAC;gBAC9E,CAACK,4CAA4B,IAAGV,kCAAY,CAACW,mCAAmB,EAAE,CAACN,2BAAW,CAAC,CAAC;gBAEhF,CAACO,iCAAiB,IAAGZ,kCAAY,CAAC,KAAK,EAAE,CAACK,2BAAW,CAAC,CAAC;gBACvD,CAACQ,kCAAkB,IAAGb,kCAAY,CAACc,2BAAW,EAAE,CAACT,2BAAW,CAAC,CAAC;gBAC9D,CAACU,+BAAe,IAAGf,kCAAY,CAAC,EAAE,EAAE,CAACgB,2BAAW,CAAC,CAAC;gBAIlD,CAACC,iCAAiB,IAAGjB,kCAAY,CAAC,EAAE,EAAE,CAACgB,2BAAW,CAAC,UAAE,OAAC,CAACE,2BAAW,IAAGC,yBAAY;gBACjF,CAACC,oCAAoB,IAAGpB,kCAAY,CAAC,KAAK,EAAE,CAACC,4BAAY,CAAC,CAAC;gBAC3D,CAACoB,8BAAc,IAAGrB,kCAAY,CAAC,KAAK,EAAE,CAACK,2BAAW,CAAC,CAAC;gBAEpD,CAACiB,6BAAa,IAAGtB,kCAAY,CAAClC,+BAAe,EAAE,CAACuC,2BAAW,CAAC,CAAC;gBAO7D,CAACP,sCAAsB,IAAGE,kCAAY,CAAC,KAAK,EAAE,CAACC,4BAAY,CAAC,EAG7D;AACD;EACA;EACA7C,IAAM,cAAc,GAAG,EAAC;gBAEtB,CAACmE,oCAAoB,IAAGvB,kCAAY,CAAC,IAAI,EAAE,CAACK,2BAAW,CAAC,YAAE,SAAC,CAACmB,yBAAS,IAAGC,mDAEzE;AACD;EACArE,IAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,cAAc,EAAC;AACpE;EACA;EACAA,IAAM,gBAAgB,GAAG,EAAC;kBACxB,CAACsE,gCAAgB,IAAG,IAAI;mBACxB,MAAK,IAAI;mBAET,eAAc,IAAI;mBAGlB,YAAW,IAAI;mBACf,gBAAe,IAAI;mBAEnB,UAAS,EAAE;mBAEX,kBAAiBC,0BAAU;mBAC3B,mBAAkBC;;ECxGpB;AAiDA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE;EAChE,EAAExE,IAAM,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,cAAc,EAAC;EACtE,EAAEA,IAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,UAAU,EAAC;AAClE;EACA,EAAE,OAAOyE,sCAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,YAAY,CAAC;EAChE,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,mBAAmB,CAAC,IAAI,EAAE;EACnC;EACA,EAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;EAC9B,KAAK,IAAI,WAAC,MAAQ;EAClB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;EAC1B,QAAQ,IAAI,CAAC,QAAQ,GAAG,WAAW,GAAE;EACrC,OAAO;EACP;EACA;EACA;EACA,MAAM,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,EAAC;EACvF;EACA,MAAM,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAC;AAC/B;EACA,MAAM,IAAI,CAAC,YAAY,GAAG,eAAe,CAAC,IAAI,EAAC;EAC/C;EACA,MAAM,OAAO,IAAI;EACjB,KAAK,CAAC;EACN,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,oBAAoB,CAAC,IAAI,EAAE;EACpC,EAAEzE,IAAM,MAAM,GAAG0E,yBAAkB,CAAC,IAAI,EAAC;EACzC,EAAE1E,IAAM,EAAE,GAAG,IAAI,CAAC,aAAY;EAC9B;EACA,EAAU,mBAAY;EACtB,EAAU;IAAY,6CAA0B;EAChD,EAAE,GAAG,CAAC,YAAY,EAAE,UAAU,EAAC;EAC/B;EACA,EAAE,IAAI,IAAI,CAAC0C,sCAAsB,CAAC,KAAK,IAAI,EAAE;EAC7C;EACA;AACA;EACA;EACA;EACA,IAAI,IAAI,CAAC,iBAAiB,eAAS;EACnC,MAAMzC,IAAI,UAAU,GAAG,CAACoB,iCAAiB,WAAK,UAAU,EAAC;EACzD,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE;EAC3B,QAAQ,UAAU,CAAC,IAAI,CAACe,gCAAgB,EAAC;EACzC,OAAO;EACP;EACA,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,EAAE,UAAU,EAAC;EACrD,MAAK;EACL;EACA;EACA,IAAI,IAAI,CAAC,iBAAiB,eAAS;EACnC,MAAM,EAAE,CAAC,aAAa,CAACf,iCAAiB,EAAE,eAAe,EAAC;EAC1D,MAAK;AACL;EACA,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,IAAI,CAAC,wBAAwB,eAAS;EAC5C,QAAQ,EAAE,CAAC,aAAa,CAACe,gCAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAC;EACzD,QAAO;EACP,KAAK;AACL;EACA;EACA,IAAI,IAAI,CAAC,iBAAiB,GAAE;EAC5B,GAAG;EACH;EACA,EAAE,OAAO,QAAE,IAAI,UAAE,MAAM,MAAE,EAAE,EAAE;EAC7B;;EC3IA;AAUA;AACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,kBAAkB,CAAC,yBAAyB,EAAE;EAC9D;EACA;EACA;EACA;EACA;EACA,EAAE,OAAO,SAAS,kBAAkB,CAAC,MAAW,EAAE;qCAAP,GAAG;AAAK;AACnD;EACA,IAAI,OAAO,mBAAmB,CAAC,MAAM,CAAC;EACtC,OAAO,IAAI,CAAC,oBAAoB,CAAC;EACjC,OAAO,IAAI;EACX,qBAA2B;gCAAX;oCAAQ;;;mBAAQ,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;OAAC;EAC3E,OAAO;EACP,OAAO,IAAI;EACX,qBAA2B;gCAAX;oCAAQ;;;mBAAQ,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;OAAC;EAClE,OAAO;EACP,OAAO,KAAK,WAAC,KAAO;EACpB,QAAQ,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,EAAC;EAChE,OAAO,CAAC;EACR,GAAG;EACH,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,YAAY,CAAC,oBAAoB,EAAE,cAAmB,EAAE,UAAe,EAAE;mDAAxB,GAAG;2CAAc,GAAG;AAAK;EAC1F;EACA,EAAE,iBAAQ,MAAW;qCAAL,GAAG;;aAAO,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,CAAC;EAChF,6BAA6B,IAAI;EACjC,8BAA8B,kBAAkB,CAAC,oBAAoB,CAAC;EACtE;KAA6B;EAC7B;;ECpDA;AAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,wBAAwB,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;EAClE,EAAE,UAAU,CAAC,OAAO,YAAE,WAAa;EACnC,IAAI,EAAE,CAAC,QAAQ;EACf,MAAMtB,gBAAS,CAAC,SAAS,EAAEY,gCAAgB,CAAC;EAC5C,MAAM,CAAC,WAAE,OAAO,aAAE,SAAS,EAAE,CAAC;EAC9B,MAAK;EACL,GAAG,EAAC;EACJ,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO1B,IAAM,sBAAsB,aAAI,EAAE,EAAE,SAAS,EAAE,GAAG,EAAK;EAC9D,EAAE,EAAE,CAAC,QAAQ,CAACc,gBAAS,CAAC,SAAS,EAAEY,gCAAgB,CAAC,EAAE,CAAC,GAAG,CAAC,EAAC;EAC5D;;EC7BA;AAiEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO1B,IAAM,gBAAgB,aAAI,SAAS,EAAE,EAAE,EAAE,IAAI,EAAK;EACzD,EAAU,mBAAY;AACtB;EACA,EAAE,EAAE,CAAC,KAAK;EACV,IAAIc,gBAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;EAClC,IAAI,SAAS,yBAAyB,CAAC,YAAY,EAAE,IAAI,EAAE;EAC3D,MAAM,GAAG,CAAC,wCAAwC,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAC;EAClF,MAAMd,IAAM,KAAK,GAAG,EAAE,OAAO,EAAE2E,iCAAiB,GAAE;EAClD;EACA;EACA,MAAM,EAAE,CAAC,KAAK,CAAC7D,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEY,gCAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,EAAC;EAC/E;EACA,MAAM,EAAE,CAAC,KAAK,CAACZ,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEO,iCAAiB,CAAC,EAAE,CAAC,SAAE,KAAK,EAAE,CAAC,EAAC;EAClF,KAAK;EACL,IAAG;EACH,EAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACOrB,IAAM,iBAAiB,aAAI,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAK;EACjE,EAAU,mBAAY;EACtB;EACA;EACA,EAAE,EAAE,CAAC,GAAG;EACR,IAAImC,iCAAiB;EACrB,IAAI,SAAS,iBAAiB,GAAG;EACjC,MAAMnC,IAAM,gBAAgB,GAAG,mBAAmB,CAAC,UAAU,EAAC;EAC9D,MAAM,GAAG,EAAImC,iCAAiB,wBAAmB;EACjD;EACA;EACA,MAAM,wBAAwB,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAEA,iCAAiB,EAAC;EACzE;EACA,MAAM,GAAG,mBAAgB,mBAAmB;AAC5C;EACA,MAAM,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,EAAC;EAC5C;EACA;EACA;EACA;EACA,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,KAAI;EACnC;EACA,MAAM,mBAAmB,CAAC,gBAAgB,EAAE,EAAE,EAAE,IAAI,EAAC;EACrD,KAAK;EACL,IAAG;EACH;;EC3HA;AAgBA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,sBAAsB,CAAC,uBAAuB,EAAE,IAAI,EAAE;EACtE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,iBAAQ,IAAI,EAAE,MAAM,EAAE,EAAE,EAAK;EAC/B;EACA,IAAY,mBAAY;EACxB,IAAY,mCAAqB;EACjC;EACA;EACA,IAAInC,IAAM,gBAAgB,GAAG4E,6BAAmB,CAAC,UAAU,EAAC;EAC5D;EACA,IAAI3E,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,GAAG,EAAC;EACnC;EACA;EACA,IAAI,OAAO,UAAU,CAAC,GAAG,WAAC,WAAa;EACvC,MAAMA,IAAI,SAAS,GAAG,gBAAgB,KAAK,UAAS;EACpD,MAAM,GAAG,CAAC,SAAS,cAAU,SAAS,GAAG,SAAS,EAAE,SAAQ,iBAAa,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,EAAC;EACnG,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE;EAC3B,QAAQ,GAAG,CAAC,sBAAsB,EAAE,SAAS,EAAE,SAAS,EAAC;EACzD;EACA;EACA,QAAQA,IAAI,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,GAAG,EAAC;EAC3E;EACA,QAAQ,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAC;EAC1D;EACA,OAAO,MAAM;EACb,QAAQ,GAAG,oCAAiC,YAAY;EACxD;EACA;EACA;EACA,QAAQ,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAC;EAC7C,OAAO;EACP,MAAM,IAAI,SAAS,EAAE;EACrB,QAAQ,GAAG,CAAC,sCAAsC,EAAC;EACnD,QAAQ,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAC;EACrD,OAAO;EACP;EACA,MAAM,OAAO,SAAS;EACtB,KAAK,CAAC;EACN,GAAG;EACH;;ECrEA;EACA;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE;EAC1C,EAAU;IAAU;IAAS;IAAW,mBAAY;EACpD,EAAED,IAAM,GAAG,GAAG,SAAS,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,QAAO;EACnE,EAAE,GAAG,CAAC,+BAA+B,EAAE,GAAG,EAAC;AAC3C;EACA,EAAE,OAAO,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC;EAC7B,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,mBAAmB,CAAC,SAAS,EAAE,IAAI,EAAE;EAC9C,EAAU;IAAU;IAAS;IAAO;IAAe,mBAAY;EAC/D,EAAEA,IAAM,GAAG,GAAG,SAAS,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,QAAO;EACnE;EACA,EAAE,GAAG,CAAC,kCAAkC,EAAE,GAAG,EAAC;AAC9C;EACA,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;EAC1C,IAAI,MAAM,IAAI,KAAK,0CAAuC,OAAQ;EAClE,GAAG;EACH;EACA;AACA;EACA,EAAE,OAAO,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC;EACxC;;;AC1BA;EACAA,IAAM,gBAAgB,GAAG;EACzB,EAAE6E,4BAAY;EACd,EAAEC,+BAAe;EACjB,EAAC;AACD;EACA;EACA9E,IAAM,kBAAkB,GAAG;EAC3B,EAAE,OAAO,EAAE,4BAAiB;EAC5B,EAAE,UAAU,EAAE+E,0BAAU;EACxB,EAAC;AACD;EACA/E,IAAM,gBAAgB,GAAG,EAAC;kBACxB,CAACgF,+CAA+B,IAAGpC,kCAAY,CAACiC,4BAAY,EAAE,CAAC5B,2BAAW,CAAC,YAAE,EAAC,OAC5E,CAACgC,wBAAQ,IAAG;;EC5BhB;EACA,IAAI,EAAE,GAAG,KAAI;AACb;EACA,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;EACtC,EAAE,EAAE,GAAG,UAAS;EAChB,CAAC,MAAM,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;EAChD,EAAE,EAAE,GAAG,aAAY;EACnB,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;EAC1C,EAAE,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAY;EAC9C,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;EAC1C,EAAE,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAY;EAC9C,CAAC,MAAM,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE;EACxC,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAY;EAC1C,CAAC;AACD;AACA,aAAe;;ECbf;EACA;EACA;EACA;EACA;EACO,SAAS,UAAU,CAAC,EAAE,EAAE;EAC/B,EAAE,IAAI,EAAE,CAAC,SAAS,IAAIpD,aAAM,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;EAC5C,IAAI,EAAE,CAAC,SAAS,GAAE;EAClB,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK,IAAIA,aAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;EAC3C,IAAI,EAAE,CAAC,KAAK,GAAE;EACd,GAAG;EACH;;ECbA;AAUA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,QAAQ,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE;EACtD,EAAE,IAAI,IAAI,KAAK,SAAS,EAAE;EAC1B,IAAY,8BAAmB;EAC/B,IAAI,IAAI,OAAO,EAAE;EACjB,MAAM,KAAK5B,IAAI,GAAG,IAAI,OAAO,EAAE;EAC/B,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;EAC/B,UAAU,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,EAAC;EACxC,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EACH,EAAEA,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,EAAC;EACzB,EAAE,OAAO,IAAI,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC;EACzF,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,cAAc,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE;AACtF;EACA;EACA;EACA,EAAE,EAAE,CAAC,MAAM,GAAG,SAAS,cAAc,GAAG;EACxC,IAAI,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,EAAC;EAC7B,IAAG;AACH;EACA,EAAE,EAAE,CAAC,SAAS,GAAG,SAAS,iBAAiB,CAAC,OAAO,EAAE;EACrD,IAAI,IAAI;EACR,MAAMD,IAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAC;EACpD;EACA,MAAM,UAAU,aAAO;EACvB,QAAQ,UAAU,CAAC,EAAE,EAAC;EACtB,OAAO,EAAE,EAAE,EAAC;EACZ,MAAMA,IAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAC;EACzF;EACA,MAAM,QAAQ,CAAC,KAAK,EAAC;EACrB;EACA,KAAK,CAAC,MAAM,CAAC,EAAE;EACf,MAAM,QAAQ,CAAC,CAAC,EAAC;EACjB,KAAK;EACL,IAAG;AACH;EACA,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,eAAe,CAAC,GAAG,EAAE;EAC7C,IAAI,QAAQ,CAAC,GAAG,EAAC;EACjB,IAAG;EACH,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,YAAY,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE;EAC1D;EACA,EAAE,OAAO,IAAI,OAAO,WAAE,QAAQ,EAAE,QAAQ,EAAK;EAC7C,IAAIA,IAAM,eAAe,GAAG,QAAQ,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAC;EACxE;EACA,IAAI,OAAO,cAAc,CAAC,eAAe,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;EAClG,GAAG,CAAC;EACJ,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,sBAAsB,CAAC,cAAc,EAAE,IAAgB,EAAE,IAAY,EAAE;+BAA5B,GAAG;+BAAe,GAAG;AAAQ;EACjF,EAAE,IAAI,IAAI,KAAK,KAAK,EAAE;EACtB;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,OAAO,SAAS,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE;EAChD;EACA,aAAyB,GAAGkF,6BAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK;QAArD;QAAK,oBAAiD;AACpE;EACA,MAAM,OAAO,YAAY,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;EAC1D,KAAK;EACL,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,OAAO,SAAS,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;EACzD;EACA,WAAuB,GAAGA,6BAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK;MAArD;MAAK,oBAAiD;AAClE;EACA,IAAI,OAAO,YAAY,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;EACxD,GAAG;EACH;;EC/HA;AASA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;EACrD,EAAU,mBAAY;EACtB,EAAU,mCAAqB;AAC/B;EACA,EAAE,GAAG,CAAC,uBAAuB,EAAC;AAC9B;EACA,EAAE,EAAE,CAAC,KAAK,CAAChD,gCAAgB,EAAE,SAAS,yBAAyB,CAAC,oBAAoB,EAAE;AACtF;EACA,IAAI,GAAG,CAAC,6CAA6C,EAAC;EACtD;EACA;EACA,IAAI,gBAAgB,CAAC,EAAE,EAAE,UAAU,EAAC;EACpC;EACA,IAAI,IAAI,CAAC,KAAK,GAAG,qBAAoB;EACrC,IAAI,EAAE,CAAC,QAAQ,CAACK,kCAAkB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAC;EAC/C,GAAG,EAAC;EACJ;;ECpCA;AAQA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACAvC,IAAM,SAAS,GAAG,SAAS,IAAI,EAAE,MAAM,EAAE,KAAY,EAAE;iCAAT,GAAG;AAAO;EACxD;EACA,EAAE,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,MAAK;EAC7B,EAAQ;IAAiB,mCAAqB;EAC9C,EAAU,mBAAY;EACtB,EAAE,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,EAAC;EACtF;EACA;EACA;EACA,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE;EACvB,IAAI,OAAOmF,2BAAa;EACxB,MAAM,UAAU,CAAC,GAAG,WAAE,SAAS,EAAE,CAAC,EAAK;EACvC,QAAQ,IAAI,CAAC,KAAK,CAAC,EAAE;EACrB,UAAU,IAAI,KAAK,EAAE;EACrB,YAAY,IAAI,CAAC,KAAK,GAAG,MAAK;EAC9B,YAAY,GAAG,CAAC,wCAAwC,EAAC;EACzD,YAAY,OAAO,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC;EACvD,WAAW;EACX,UAAU,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;EACvC,SAAS;EACT,QAAQ,OAAO,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC;EAC/C,OAAO,CAAC;EACR,KAAK;EACL,KAAK,IAAI,WAAC,kBACJ,OAAO,CAAC,GAAG,WAAE,MAAM,EAAE,CAAC;;;4BACnB,EAAC,KAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAG;WAAS,CAAC;EACtC,WAAW,MAAM,WAAE,CAAC,EAAE,CAAC,WAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAC,EAAE,EAAE,IAAC;EACpD,KAAK;EACL,GAAG;EACH;EACA,EAAE,OAAO,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC;EACrC,KAAK,IAAI,WAAC;;;wBAAQ,OAAC,CAAC,eAAe,IAAG;KAAK,CAAC;EAC5C;;ECnDA;AAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,uBAAuB,CAAC,EAAE,EAAE,EAAE,EAAE;EAChD;EACA,EAAE,EAAE,CAAC,GAAG,CAAC1C,qCAAqB,EAAE,SAAS,eAAe,GAAG;EAC3D,IAAI,IAAI;EACR;EACA,MAAM,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,EAAC;EACvD,MAAM,GAAG,CAAC,yBAAyB,EAAC;EACpC,MAAM,EAAE,CAAC,SAAS,GAAE;EACpB,KAAK,CAAC,MAAM,CAAC,EAAE;EACf,MAAM,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,EAAC;EAC5C,KAAK;EACL,GAAG,EAAC;EACJ;;ECvBA;AAsBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACOzC,IAAM,gBAAgB,aAAI,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAK;EACvE,EAAEC,IAAI,GAAG,GAAG,CAAC,SAAS,EAAC;EACvB,EAAE,IAAI,YAAY,EAAE;EACpB,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,EAAC;EAC1B,GAAG;EACH,EAAE,GAAG,CAAC,IAAI,CAACyB,gCAAgB,EAAC;EAC5B,EAAEzB,IAAI,OAAO,GAAG,OAAO,CAAC,KAAK,CAACa,gBAAS,EAAE,IAAI,EAAE,GAAG,EAAC;EACnD;EACA,EAAEb,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,KAAI;EACjC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAC;EACjC,EAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,sBAAsB,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE;EACpF,EAAU,mBAAY;EACtB;EACA;EACA,EAAE,IAAI,SAAS,EAAE;EACjB,IAAI,GAAG,CAAC,mBAAmB,EAAE,SAAS,EAAE,yCAAyC,EAAC;EAClF,IAAI,uBAAuB,CAAC,EAAE,EAAE,EAAE,EAAC;EACnC,GAAG;EACH;EACA;EACA,EAAE,EAAE,CAAC,MAAM,GAAG,SAAS,cAAc,GAAG;AACxC;EACA,IAAI,GAAG,CAAC,+BAA+B,EAAE,SAAS,EAAC;EACnD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,GAAG,8BAA2BmC,mCAAmB;EACvD,MAAM,EAAE,CAAC,KAAK,CAACA,gCAAgB,CAAC,CAAC,SAAS,EAAC;EAC3C,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,KAAK,CAACJ,gCAAgB,CAAC,CAAC,SAAS,EAAE,OAAO,EAAC;EACpD;EACA;EACA;EACA,MAAM,GAAG,CAAC,gCAAgC,EAAE,OAAO,EAAC;EACpD,MAAM,IAAI,OAAO,KAAK,CAAC,EAAE;EACzB,QAAQ,EAAE,CAAC,IAAI,CAACA,gCAAgB,EAAC;EACjC,OAAO;EACP,KAAK;EACL;EACA,IAAI,EAAE,CAAC,KAAK;EACZ,MAAMlB,gBAAS,CAAC,SAAS,EAAEC,+BAAe,CAAC;EAC3C;EACA;EACA;EACA;EACA;EACA,MAAM,SAAS,kBAAkB,CAAC,YAAY,EAAE,IAAI,EAAE;EACtD,QAAQf,IAAM,OAAO,GAAGM,qBAAc,CAAC,YAAY,EAAE,IAAI,EAAC;EAC1D,QAAQ,GAAG,CAAC,gBAAgB,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAC;AAC1D;EACA,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,EAAC;EACxB,OAAO;EACP,MAAK;EACL,IAAG;AACH;EACA;EACA;EACA;EACA,EAAE,EAAE,CAAC,SAAS,GAAG,SAAS,iBAAiB,CAAC,OAAO,EAAE;AACrD;EACA,IAAI,GAAG,CAAC,iCAAiC,EAAE,OAAO,CAAC,IAAI,EAAC;EACxD;EACA;EACA,IAAI,IAAI;EACR;EACA;EACA;EACA,MAAMN,IAAM,IAAI,GAAGG,uBAAgB,CAAC,OAAO,CAAC,IAAI,EAAC;EACjD,MAAc;QAAc,qBAAa;AACzC;EACA,MAAM,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,IAAI,EAAC;AAC5C;EACA,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAKY,+BAAe;EAC5B,UAAUd,IAAI,EAAE,GAAGa,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEgB,kCAAkB,EAAC;EACzE,UAAU7B,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAC;EACpC;EACA,UAAU,GAAG,CAAC,iBAAiB,EAAE,EAAE,EAAE,CAAC,EAAC;EACvC,UAAU,KAAK;EACf,QAAQ,KAAKmF,sCAAsB;EACnC,UAAUnF,IAAI,EAAE,GAAGa,gBAAS,CAAC,SAAS,EAAE,YAAY,EAAEO,iCAAiB,EAAC;EACxE,UAAUpB,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAC;AACrC;EACA,UAAU,GAAG,CAAC,wBAAwB,EAAE,EAAE,EAAE,EAAE,EAAC;EAC/C,UAAU,KAAK;EACf,QAAQ,KAAKmB,yBAAS;EACtB;EACA;EACA,UAAU,GAAG,CAAC,WAAW,EAAC;EAC1B,UAAU,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAC;EAC7D,UAAU,KAAK;EACf;EACA,QAAQ;EACR;EACA,UAAU,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAC;EACvC,UAAU,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAC;EAC7D;EACA;EACA,OAAO;EACP,KAAK,CAAC,MAAM,CAAC,EAAE;EACf,MAAM,GAAG,CAAC,2BAA2B,EAAE,CAAC,EAAC;EACzC,MAAM,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAC;EAC/C,KAAK;EACL,IAAG;EACH;EACA,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,eAAe,GAAG;EAC1C,IAAI,GAAG,CAAC,4BAA4B,EAAC;EACrC;EACA;EACA,IAAG;EACH;EACA,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,eAAe,CAAC,GAAG,EAAE;EAC7C;EACA,IAAI,GAAG,CAAC,mBAAmB,EAAE,GAAG,EAAC;EACjC,IAAI,sBAAsB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAC;EAC9C,IAAG;EACH;EACA;EACA,EAAE,OAAO,EAAE;EACX;;ECzKA;AAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,oBAAoB,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE;EACtD,EAAE,GAAG,CAAC,kCAAkC,EAAC;EACzC;EACA,EAAE,EAAE,CAAC,KAAK,CAACmB,kCAAkB,EAAE,SAAS,uBAAuB,CAAC,OAAO,EAAE,GAAG,EAAE;EAC9E,IAAI,GAAG,CAAC,wBAAwB,EAAE,OAAO,EAAC;AAC1C;EACA,IAAI,OAAO,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;EACrC,aAAa,IAAI,WAAC,eAAQ,sBAAsB,CAAC,sBAAsB,EAAE,IAAI,IAAC,CAAC;EAC/E,aAAa,IAAI,WAAC,qBAAc,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAC,CAAC;EACjE,GAAG,EAAC;EACJ;;ECvBA;AAaA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,kBAAkB,CAAC,cAAc,EAAE,IAAgB,EAAE;+BAAd,GAAG;AAAY;EAC/D;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,OAAO,SAAS,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;EAC9D,IAAY,mBAAY;AACxB;EACA,IAAI,GAAG,CAAC,6CAA6C,EAAE,IAAI,EAAC;EAC5D;EACA,IAAI,IAAI,CAAC8C,0BAAU,CAAC,GAAG,sBAAsB,CAAC,cAAc,EAAE,IAAI,EAAC;EACnE;EACA,IAAI,IAAI,IAAI,CAACrB,oCAAoB,CAAC,KAAK,IAAI,EAAE;EAC7C,MAAM,IAAI,CAACsB,+BAAe,CAAC,GAAG,sBAAsB,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAC;EAChF,KAAK;EACL;EACA,IAAI,GAAG,CAAC,2BAA2B,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAC;EACtD;EACA;EACA,IAAI,oBAAoB,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAC;EACzC;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAC;AACxC;EACA,IAAI,GAAG,CAAC,uFAAuF,EAAC;AAChG;EACA;EACA,IAAI,OAAO,QAAE,IAAI,UAAE,MAAM,MAAE,EAAE,EAAE;EAC/B,GAAG;EACH;;ECxDA;AAKA;EACAtF,IAAM,yBAAyB,GAAG,kBAAkB,CAACuF,IAAE;;ECNvD;AAYA;EACA;EACe,SAAS,eAAe,CAAC,MAAW,EAAE,UAAe,EAAE;mCAAxB,GAAG;2CAAc,GAAG;AAAK;EACvE,EAAE,OAAO,YAAY;EACrB,IAAI,yBAAyB;EAC7B,IAAI,gBAAgB;EACpB,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,kBAAkB,EAAE,UAAU,CAAC;EACrD,GAAG,CAAC,MAAM,CAAC;EACX;;ECpBA;;;;;;;;"} \ No newline at end of file diff --git a/packages/@jsonql/ws/package.json b/packages/@jsonql/ws/package.json index 54ffc50d..a282df19 100644 --- a/packages/@jsonql/ws/package.json +++ b/packages/@jsonql/ws/package.json @@ -59,6 +59,7 @@ "ws": "^7.2.3" }, "devDependencies": { + "@babel/core": "^7.9.0", "@rollup/plugin-alias": "^3.1.0", "@rollup/plugin-buble": "^0.21.3", "@rollup/plugin-commonjs": "^11.1.0", @@ -79,6 +80,7 @@ "koa-bodyparser": "^4.3.0", "rollup": "^2.6.1", "rollup-plugin-async": "^1.2.0", + "rollup-plugin-babel": "^4.4.0", "rollup-plugin-bundle-size": "^1.0.3", "rollup-plugin-copy": "^3.3.0", "rollup-plugin-json": "^4.0.0", @@ -88,6 +90,11 @@ "rollup-plugin-terser": "^5.3.0", "server-io-core": "^1.3.3" }, + "peerDependencies": { + "rollup": "^1.20.0", + "acorn": "^6.0.0", + "@babel/core": "^7.0.0" + }, "ava": { "files": [ "tests/*.test.js" diff --git a/packages/@jsonql/ws/rollup.config.js b/packages/@jsonql/ws/rollup.config.js index c7a3a359..3c0c28de 100644 --- a/packages/@jsonql/ws/rollup.config.js +++ b/packages/@jsonql/ws/rollup.config.js @@ -3,46 +3,49 @@ */ import { join } from 'path' -import buble from '@rollup/plugin-buble' +// import buble from '@rollup/plugin-buble' import replace from '@rollup/plugin-replace' import commonjs from '@rollup/plugin-commonjs' import json from '@rollup/plugin-json' import nodeResolve from '@rollup/plugin-node-resolve' import { terser } from "rollup-plugin-terser" +import size from 'rollup-plugin-bundle-size' + +import babel from 'rollup-plugin-babel' +/* import nodeGlobals from 'rollup-plugin-node-globals' import builtins from 'rollup-plugin-node-builtins' -import size from 'rollup-plugin-bundle-size' // support async functions import async from 'rollup-plugin-async' // get the version info +*/ + import { version } from './package.json' const env = process.env.NODE_ENV const target = process.env.TARGET let plugins = [ - json({ - preferConst: true - }), - buble({ - objectAssign: 'Object.assign', - transforms: { dangerousForOf: true } - }), - nodeResolve({ - - }), commonjs({ include: 'node_modules/**' }), - nodeGlobals(), - builtins(), - async(), + nodeResolve(), replace({ 'process.env.NODE_ENV': JSON.stringify('production'), '__PLACEHOLDER__': `version: ${version} module: ${target}` + }), + json({ + preferConst: true + }), + babel({ + exclude: 'node_modules/**' }) + // buble() + // nodeGlobals(), + // builtins(), + // async(), ] if (env === 'production') { diff --git a/packages/@jsonql/ws/src/core/setup-socket-listeners/connect-event-listener.js b/packages/@jsonql/ws/src/core/setup-socket-listeners/connect-event-listener.js index 4c517587..9391d3bd 100644 --- a/packages/@jsonql/ws/src/core/setup-socket-listeners/connect-event-listener.js +++ b/packages/@jsonql/ws/src/core/setup-socket-listeners/connect-event-listener.js @@ -21,6 +21,4 @@ export function connectEventListener(nspMap, ee, log) { .then(nsps => namespaceEventListener(bindSocketEventHandler, nsps)) .then(listenerFn => listenerFn($config, nspMap, $ee)) }) - - // log(`[3] after setup the CONNECT_EVENT_NAME`) } \ No newline at end of file diff --git a/packages/ws-client-core/src/auth/setup-auth-methods.js b/packages/ws-client-core/src/auth/setup-auth-methods.js index fcaaff39..25e63a10 100644 --- a/packages/ws-client-core/src/auth/setup-auth-methods.js +++ b/packages/ws-client-core/src/auth/setup-auth-methods.js @@ -98,10 +98,6 @@ const setupOnLoginListener = (obj, opts, ee) => [ ON_LOGIN_FN_NAME, function onLoginCallbackHandler(onLoginCallback) { if (isFunc(onLoginCallback)) { - // @NOTE just put this here for the time being - // if the obj (client) is not mutated then we need to put this elsewhere - opts[IS_LOGIN_PROP_KEY] = true - // only one callback can registered with it, TBC // Should this be a $onlyOnce listener after the logout // we add it back? -- Gitee From a2e6fdc6a4683bc833f232226a6a4fb9b67253f9 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 13 Apr 2020 15:10:47 +0800 Subject: [PATCH 4/6] rename the read-files-output-contract --- packages/contract-cli/package.json | 12 ++++++------ packages/contract-cli/src/generator/index.js | 4 ++-- ...out-contract.js => read-files-output-contract.js} | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) rename packages/contract-cli/src/generator/{read-files-out-contract.js => read-files-output-contract.js} (96%) diff --git a/packages/contract-cli/package.json b/packages/contract-cli/package.json index 68e57132..2de97555 100755 --- a/packages/contract-cli/package.json +++ b/packages/contract-cli/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-contract", - "version": "1.9.1", + "version": "1.9.2", "description": "JS API / command line tool to generate the contract.json for jsonql", "main": "index.js", "files": [ @@ -55,18 +55,18 @@ "fs-extra": "^9.0.0", "glob": "^7.1.6", "jsdoc-api": "^5.0.4", - "jsonql-constants": "^2.1.0", + "jsonql-constants": "^2.1.3", "jsonql-errors": "^1.2.1", - "jsonql-params-validator": "^1.6.2", - "jsonql-utils": "^1.2.6", + "jsonql-params-validator": "^1.6.3", + "jsonql-utils": "^1.2.7", "kefir": "^3.8.6", "lodash": "^4.17.15", "nb-split-tasks": "^0.6.0", "yargs": "^15.3.1" }, "devDependencies": { - "ava": "^3.5.2", - "nyc": "^15.0.0" + "ava": "^3.6.0", + "nyc": "^15.0.1" }, "ava": { "files": [ diff --git a/packages/contract-cli/src/generator/index.js b/packages/contract-cli/src/generator/index.js index e67310e5..f85bf7e7 100644 --- a/packages/contract-cli/src/generator/index.js +++ b/packages/contract-cli/src/generator/index.js @@ -13,7 +13,7 @@ const debug = require('debug')('jsonql-contract:generator') const { PUBLIC_CONTRACT_FILE_NAME } = require('jsonql-constants') const { publicContractGenerator } = require('../public-contract') -const { readFilesOutContract } = require('./read-files-out-contract') +const { readFilesOutputContract } = require('./read-files-output-contract') const { generateOutput } = require('./generate-output') const { isContractExisted } = require('./files-op') @@ -60,7 +60,7 @@ const callPublicGenerator = (config, contract) => ( */ const generateNewContract = (config) => { // const { resolverDir, contractDir } = config; - return readFilesOutContract(config) + return readFilesOutputContract(config) .then(([sourceType, contract]) => { if (config.public === true) { // we can get the sourceType from the contract diff --git a/packages/contract-cli/src/generator/read-files-out-contract.js b/packages/contract-cli/src/generator/read-files-output-contract.js similarity index 96% rename from packages/contract-cli/src/generator/read-files-out-contract.js rename to packages/contract-cli/src/generator/read-files-output-contract.js index b1a98095..620694a8 100644 --- a/packages/contract-cli/src/generator/read-files-out-contract.js +++ b/packages/contract-cli/src/generator/read-files-output-contract.js @@ -38,7 +38,7 @@ function getResolverFiles(resolverDir, fileType) { * @param {object} config pass config to the underlying method * @return {object} query / mutation */ -function readFilesOutContract(config) { +function readFilesOutputContract(config) { const { resolverDir } = config let fileType = config.ext || EXT let timestart = Date.now() @@ -60,5 +60,5 @@ function readFilesOutContract(config) { module.exports = { getResolverFiles, - readFilesOutContract + readFilesOutputContract } -- Gitee From 2304038442b7c356a115d4f7f6c50e0822b73254 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 13 Apr 2020 15:20:37 +0800 Subject: [PATCH 5/6] resolve all the renaming problems --- packages/contract-cli/src/generator/get-resolver.js | 2 +- .../src/generator/get-socket-auth-resolver.js | 2 +- packages/contract-cli/src/generator/index.js | 2 +- packages/contract-cli/src/generator/process-file.js | 4 ++-- packages/contract-cli/src/get-paths.js | 4 ++-- packages/contract-cli/src/public-contract/index.js | 4 ++-- packages/contract-cli/tests/split-task.test.js | 8 +++++--- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/contract-cli/src/generator/get-resolver.js b/packages/contract-cli/src/generator/get-resolver.js index bbf05364..e95ff259 100644 --- a/packages/contract-cli/src/generator/get-resolver.js +++ b/packages/contract-cli/src/generator/get-resolver.js @@ -20,7 +20,7 @@ const { getDebug, getTimestamp } = require('../utils') const { getSourceType } = require('./get-source-type') const { parseFileToAst } = require('./parse-file-to-ast') -const debug = getDebug('generator:get-resolvers') +// const debug = getDebug('generator:get-resolvers') /** * Breaking out from the getResolver because we need to hook another method into it diff --git a/packages/contract-cli/src/generator/get-socket-auth-resolver.js b/packages/contract-cli/src/generator/get-socket-auth-resolver.js index 54542a55..f7db5e74 100644 --- a/packages/contract-cli/src/generator/get-socket-auth-resolver.js +++ b/packages/contract-cli/src/generator/get-socket-auth-resolver.js @@ -18,7 +18,7 @@ const { const { removeSrvAuthFromContract } = require('../utils') -const { getResolverFiles } = require('./read-files-out-contract') +const { getResolverFiles } = require('./read-files-output-contract') const { getSourceType } = require('./get-source-type') const { parseFileToAst } = require('./parse-file-to-ast') diff --git a/packages/contract-cli/src/generator/index.js b/packages/contract-cli/src/generator/index.js index f85bf7e7..d2bc3c11 100644 --- a/packages/contract-cli/src/generator/index.js +++ b/packages/contract-cli/src/generator/index.js @@ -8,7 +8,7 @@ const { merge } = require('lodash') const colors = require('colors/safe') -const debug = require('debug')('jsonql-contract:generator') +// const debug = require('debug')('jsonql-contract:generator') const { PUBLIC_CONTRACT_FILE_NAME } = require('jsonql-constants') diff --git a/packages/contract-cli/src/generator/process-file.js b/packages/contract-cli/src/generator/process-file.js index cd55dac5..d49e5579 100644 --- a/packages/contract-cli/src/generator/process-file.js +++ b/packages/contract-cli/src/generator/process-file.js @@ -12,8 +12,8 @@ const { splitTask } = require('./split-task') const { NOT_ENOUGH_CPU } = require('nb-split-tasks/constants') const { JsonqlError } = require('jsonql-errors') -const { getDebug } = require('../utils') -const debug = getDebug('process-file') +// const { getDebug } = require('../utils') +// const debug = getDebug('process-file') /** * @NOTE this should be replace with the split task diff --git a/packages/contract-cli/src/get-paths.js b/packages/contract-cli/src/get-paths.js index 10b0dbc0..3e68e33b 100755 --- a/packages/contract-cli/src/get-paths.js +++ b/packages/contract-cli/src/get-paths.js @@ -1,8 +1,8 @@ const fs = require('fs') const { resolve } = require('path') -const { getDebug } = require('./utils') -const debug = getDebug('paths') +// const { getDebug } = require('./utils') +// const debug = getDebug('paths') /** * The input from cmd and include are different and cause problem for client diff --git a/packages/contract-cli/src/public-contract/index.js b/packages/contract-cli/src/public-contract/index.js index 6a712f8e..2e0e3dc7 100644 --- a/packages/contract-cli/src/public-contract/index.js +++ b/packages/contract-cli/src/public-contract/index.js @@ -2,7 +2,7 @@ const { join } = require('path') const fsx = require('fs-extra') const { merge } = require('lodash') -const { JsonqlError } = require('jsonql-errors') +// const { JsonqlError } = require('jsonql-errors') const { isObjectHasKey } = require('jsonql-params-validator') const { SOCKET_NAME, @@ -16,7 +16,7 @@ const { STANDALONE_PROP_KEY } = require('jsonql-constants') -const colors = require('colors/safe') +// const colors = require('colors/safe') const { getDebug, removeSrvAuthFromContract } = require('../utils') const debug = getDebug('public-contract') diff --git a/packages/contract-cli/tests/split-task.test.js b/packages/contract-cli/tests/split-task.test.js index e1363dc3..21492e21 100644 --- a/packages/contract-cli/tests/split-task.test.js +++ b/packages/contract-cli/tests/split-task.test.js @@ -4,20 +4,22 @@ const test = require('ava') const { join } = require('path') const debug = require('debug')('jsonql-contract:test:split') const { EXT } = require('jsonql-constants') -const nbSplitTasks = require('nb-split-tasks') + const fsx = require('fs-extra') // import method frr testing -const { getResolverFiles } = require('../src/generator/read-files-out-contract') +const { getResolverFiles } = require('../src/generator/read-files-output-contract') const { splitTask } = require('../src/generator/split-task') const { splitContractGenerator } = require('../extra') const { applyDefaultOptions } = require('../src') +/* +const nbSplitTasks = require('nb-split-tasks') const { getResolver, getSourceType, getContractBase } = require('../src/generator/get-resolver') - +*/ const resolverDir = join(__dirname, 'fixtures', 'koa-resolvers') const contractDir = join(__dirname, 'tmp', 'split-test') -- Gitee From 3ae98e7d3af761db3a1954ce072a3a7b2d6e9a86 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 13 Apr 2020 15:29:02 +0800 Subject: [PATCH 6/6] verify the socket auth is presented in the public contract --- packages/contract-cli/src/public-contract/index.js | 2 +- packages/contract-cli/src/utils.js | 1 + packages/contract-cli/tests/socket.test.js | 11 ++++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/contract-cli/src/public-contract/index.js b/packages/contract-cli/src/public-contract/index.js index 2e0e3dc7..5c8edec1 100644 --- a/packages/contract-cli/src/public-contract/index.js +++ b/packages/contract-cli/src/public-contract/index.js @@ -61,7 +61,7 @@ const cleanForPublic = (json, config) => { // @TODO when socket is not in standalone mode all the auth method // login, logout should not get expose to the client - // at this point there is no SOCKET_AUT_NAME yet, we need to take this out + // at this point there is no SOCKET_AUTH_NAME yet, we need to take this out json = removeSrvAuthFromContract(json, AUTH_NAME, config) // this is ugly because it happens in two places, need to refactor this bit at the very end if (config[STANDALONE_PROP_KEY] !== true) { diff --git a/packages/contract-cli/src/utils.js b/packages/contract-cli/src/utils.js index 6ec62833..1a523fe2 100644 --- a/packages/contract-cli/src/utils.js +++ b/packages/contract-cli/src/utils.js @@ -112,6 +112,7 @@ const checkFile = config => { /** * ported from the public-contract/index to avoid a circular referenc * take this out on it's own and also export it for use later + * @1.9.1 we keep the login method if this is a standalone * @param {object} contract to process * @param {string} key the type key * @param {object} config for extract the validatorHandlerName diff --git a/packages/contract-cli/tests/socket.test.js b/packages/contract-cli/tests/socket.test.js index 750fd39e..515d4ae7 100644 --- a/packages/contract-cli/tests/socket.test.js +++ b/packages/contract-cli/tests/socket.test.js @@ -6,7 +6,6 @@ const colors = require('colors/safe') const { HELLO_FN, SOCKET_NAME, - AUTH_TYPE, RETURN_AS_JSON, SOCKET_AUTH_NAME, DEFAULT_CONTRACT_FILE_NAME, @@ -24,15 +23,15 @@ const getConfig = require('./fixtures/socket/config') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'socket-with-auth') -const baseContractFile = join(contractDir, DEFAULT_CONTRACT_FILE_NAME) -const publicContractFile = join(contractDir, PUBLIC_CONTRACT_FILE_NAME) +// const baseContractFile = join(contractDir, DEFAULT_CONTRACT_FILE_NAME) +// const publicContractFile = join(contractDir, PUBLIC_CONTRACT_FILE_NAME) const debug = require('debug')('jsonql-contract:test:socket') const colorDebug = (str, ...args) => Reflect.apply(debug, null, [colors.black.bgBrightCyan(str)].concat(args)) test.before(async t => { t.context.config = await getConfig({ - [STANDALONE_PROP_KEY]: true, // this is very import for the public contract + [STANDALONE_PROP_KEY]: true, // this is very import for the socket public contract enableAuth: true, resolverDir }) @@ -91,7 +90,7 @@ test.cb(`It should able to generate new entry when socket / auth has content`, t }) test.cb(`Now test the public contract with socket`, t => { - t.plan(3) + t.plan(4) generator({ [STANDALONE_PROP_KEY]: true, @@ -107,6 +106,8 @@ test.cb(`Now test the public contract with socket`, t => { t.truthy(result[SOCKET_AUTH_NAME], `It should have the ${SOCKET_AUTH_NAME} part`) + t.truthy(result[SOCKET_AUTH_NAME].login, `It should have a login method defined in the socket auth`) + t.truthy(result[SOCKET_NAME][HELLO_FN], `It should have a ${HELLO_FN} in ${SOCKET_NAME}`) t.falsy(result[SOCKET_AUTH_NAME].validator) -- Gitee