typeson
Version:
Preserves types over JSON, BSON or socket.io
2 lines (1 loc) • 19.2 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Typeson={})}(this,(function(e){"use strict";function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _createClass(e,t,r){return t&&function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,_toPropertyKey(n.key),n)}}(e.prototype,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return(t=_toPropertyKey(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function _objectSpread2(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ownKeys(Object(r),!0).forEach((function(t){_defineProperty(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ownKeys(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function _slicedToArray(e,t){return function _arrayWithHoles(e){if(Array.isArray(e))return e}(e)||function _iterableToArrayLimit(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,c=[],s=!0,u=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);s=!0);}catch(e){u=!0,o=e}finally{try{if(!s&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(u)throw o}}return c}}(e,t)||_unsupportedIterableToArray(e,t)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _toConsumableArray(e){return function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}(e)||function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||_unsupportedIterableToArray(e)||function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _toPropertyKey(e){var t=function _toPrimitive(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t);if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof t?t:t+""}function _typeof(e){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_typeof(e)}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}var t=_createClass((function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)}));t.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&Object.defineProperty(t.prototype,Symbol.toStringTag,{get:function get(){return"TypesonPromise"}}),t.prototype.then=function(e,r){var n=this;return new t((function(t,o){n.p.then((function(r){t(e?e(r):r)})).catch((function(e){return r?r(e):Promise.reject(e)})).then(t,o)}))},t.prototype.catch=function(e){return this.then((function(){}),e)},t.resolve=function(e){return new t((function(t){t(e)}))},t.reject=function(e){return new t((function(t,r){r(e)}))},t.all=function(e){return new t((function(t,r){Promise.all(e.map((function(e){return null!=e&&e.constructor&&"__typeson__type__"in e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(t,r)}))},t.race=function(e){return new t((function(t,r){Promise.race(e.map((function(e){return null!=e&&e.constructor&&"__typeson__type__"in e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(t,r)}))},t.allSettled=function(e){return new t((function(t,r){Promise.allSettled(e.map((function(e){return null!=e&&e.constructor&&"__typeson__type__"in e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(t,r)}))};var r=Object.hasOwn,n=Object.getPrototypeOf;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return Object.prototype.toString.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var o=n(e);if(!o)return null===t;var i=r(o,"constructor")&&o.constructor;return"function"!=typeof i?null===t:t===i||(null!==t&&Function.prototype.toString.call(i)===Function.prototype.toString.call(t)||"function"==typeof t&&"string"==typeof i.__typeson__type__&&i.__typeson__type__===t.__typeson__type__)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!n(e)||hasConstructorOf(e,Object))}function isObject(e){return null!==e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replaceAll("''","''''").replace(/^$/,"''").replaceAll("~","~0").replaceAll(".","~1")}function unescapeKeyPathComponent(e){return e.replaceAll("~1",".").replaceAll("~0","~").replace(/^''$/,"").replaceAll("''''","''")}function getByKeyPath(e,t){if(""===t)return e;if(null===e||"object"!==_typeof(e))throw new TypeError("Unexpected non-object type");var r=t.indexOf(".");if(-1!==r){var n=e[unescapeKeyPathComponent(t.slice(0,r))];return void 0===n?void 0:getByKeyPath(n,t.slice(r+1))}return e[unescapeKeyPathComponent(t)]}function setAtKeyPath(e,t,r){if(""===t)return r;if(!e||"object"!==_typeof(e))throw new TypeError("Unexpected non-object type");if("__proto__"===t)throw new TypeError("Invalid property");var n=t.indexOf(".");return-1!==n?setAtKeyPath(e[unescapeKeyPathComponent(t.slice(0,n))],t.slice(n+1),r):(e[unescapeKeyPathComponent(t)]=r,e)}function getJSONType(e){return null===e?"null":Array.isArray(e)?"array":_typeof(e)}function _await(e,t,r){return e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e}var o=Object.keys,i=Object.hasOwn,a=Array.isArray,c=["type","replaced","iterateIn","iterateUnsetNumeric","addLength"];function _async(e){return function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function nestedPathsFirst(e,t){var r,n;if(""===e.keypath)return-1;var o=null!==(r=e.keypath.match(/\./g))&&void 0!==r?r:0,i=null!==(n=t.keypath.match(/\./g))&&void 0!==n?n:0;return o&&(o=o.length),i&&(i=i.length),o>i?-1:o<i?1:e.keypath<t.keypath?-1:e.keypath>t.keypath?1:0}var s=function(){return _createClass((function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}),[{key:"stringify",value:function stringify(e,t,r,n){n=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),n),{},{stringification:!0});var o=this.encapsulate(e,null,n);return a(o)?JSON.stringify(o[0],t,r):o.then((function(e){return JSON.stringify(e,t,r)}))}},{key:"stringifySync",value:function stringifySync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!1}))}},{key:"parse",value:function parse(e,t,r){return r=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),r),{},{parse:!0}),this.revive(JSON.parse(e,t),r)}},{key:"parseSync",value:function parseSync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"parseAsync",value:function parseAsync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.returnTypeNames=!0,this.encapsulate(e,t,r)}},{key:"rootTypeName",value:function rootTypeName(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.iterateNone=!0,this.encapsulate(e,t,r)}},{key:"encapsulate",value:function encapsulate(e,r,n){var s=this,u=_objectSpread2(_objectSpread2({sync:!0},this.options),n),y=u.sync,l={},p=[],f=[],h=[],v=!("cyclic"in u)||u.cyclic,d=u.encapsulateObserver,b=function finish(e){var t=Object.values(l);if(u.iterateNone)return t.length?t[0]:getJSONType(e);if(t.length){if(u.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!i(e,"$types")?e.$types=l:e={$:e,$types:{$:l}}}else isObject(e)&&i(e,"$types")&&(e={$:e,$types:!0});return!u.returnTypeNames&&e},_=_async((function(e,r){return _await(Promise.all(r.map((function(e){return e[1].p}))),(function(n){return _await(Promise.all(n.map(_async((function(n){var o=!1,i=[],a=_slicedToArray(r.splice(0,1),1),c=_slicedToArray(a[0],7),s=c[0],u=c[2],y=c[3],l=c[4],p=c[5],f=c[6],h=m(s,n,u,y,i,!0,f),v=hasConstructorOf(h,t);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(s&&v)return _await(h.p,(function(t){l[p]=t;var r=_(e,i);return o=!0,r}))}),(function(t){return o?t:(s?l[p]=h:e=v?h.p:h,_(e,i))}))})))),(function(){return e}))}))})),O=function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=c.map((function(t){var r=e[t];return delete e[t],r}));r(),c.forEach((function(t,r){e[t]=n[r]}))},m=function _encapsulate(e,r,n,c,y,h,v){var b,_={},g=_typeof(r),S=d?function(o){var i,a=null!==(i=null!=v?v:c.type)&&void 0!==i?i:getJSONType(r);d(Object.assign(null!=o?o:_,{keypath:e,value:r,cyclic:n,stateObj:c,promisesData:y,resolvingTypesonPromise:h,awaitingTypesonPromise:hasConstructorOf(r,t)},{type:a}))}:null;if(["string","boolean","number","undefined"].includes(g))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY||0===r?(b=c.replaced?r:j(e,r,c,y,!1,h,S))!==r&&(_={replaced:b}):b=r,S&&S(),b;if(null===r)return S&&S(),r;if(n&&!c.iterateIn&&!c.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var T=p.indexOf(r);if(-1!==T)return l[e]="#",S&&S({cyclicKeypath:f[T]}),"#"+f[T];!0===n&&(p.push(r),f.push(e))}var P,w=isPlainObject(r),A=a(r),C=(w||A)&&(!s.plainObjectReplacers.length||c.replaced)||c.iterateIn?r:j(e,r,c,y,w||A,null,S);if(C!==r?(b=C,_={replaced:C}):""===e&&hasConstructorOf(r,t)?(y.push([e,r,n,c,void 0,void 0,c.type]),b=r):A&&"object"!==c.iterateIn||"array"===c.iterateIn?(P=new Array(r.length),_={clone:P}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,t)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!w&&"object"!==c.iterateIn?b=r:(P={},c.addLength&&(P.length=r.length),_={clone:P}),S&&S(),u.iterateNone)return null!=P?P:b;if(!P)return b;if(c.iterateIn){var k=function _loop(o){var a={ownKeys:i(r,o)};O(c,a,(function(){var i=e+(e?".":"")+escapeKeyPathComponent(o),a=m(i,r[o],Boolean(n),c,y,h);hasConstructorOf(a,t)?y.push([i,a,Boolean(n),c,P,o,c.type]):void 0!==a&&(P[o]=a)}))};for(var N in r)k(N);S&&S({endIterateIn:!0,end:!0})}else o(r).forEach((function(o){var i=e+(e?".":"")+escapeKeyPathComponent(o);O(c,{ownKeys:!0},(function(){var e=m(i,r[o],Boolean(n),c,y,h);hasConstructorOf(e,t)?y.push([i,e,Boolean(n),c,P,o,c.type]):void 0!==e&&(P[o]=e)}))})),S&&S({endIterateOwn:!0,end:!0});if(c.iterateUnsetNumeric){for(var I=r.length,K=function _loop2(o){if(!(o in r)){var i="".concat(e).concat(e?".":"").concat(String(o));O(c,{ownKeys:!1},(function(){var e=m(i,void 0,Boolean(n),c,y,h);hasConstructorOf(e,t)?y.push([i,e,Boolean(n),c,P,o,c.type]):void 0!==e&&(P[o]=e)}))}},E=0;E<I;E++)K(E);S&&S({endIterateUnsetNumeric:!0,end:!0})}return P},j=function replace(e,t,r,n,o,i,a){for(var c=o?s.plainObjectReplacers:s.nonplainObjectReplacers,u=c.length;u--;){var p=c[u];if(p.test(t,r)){var f=p.type;if(s.revivers[f]){var h=l[e];l[e]=h?[f].concat(h):f}if(Object.assign(r,{type:f,replaced:!0}),(y||!p.replaceAsync)&&!p.replace)return a&&a({typeDetected:!0}),m(e,t,v&&"readonly",r,n,i,f);a&&a({replacing:!0});var d=void 0;if(y||!p.replaceAsync){if(void 0===p.replace)throw new TypeError("Missing replacer");d=p.replace(t,r)}else d=p.replaceAsync(t,r);return m(e,d,v&&"readonly",r,n,i,f)}}return t},g=m("",e,v,null!=r?r:{},h);if(h.length)return y&&u.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(_(g,h)).then(b);if(!y&&u.throwOnBadSyncType)throw new TypeError("Async method requested but sync result obtained");return u.stringification&&y?[b(g)]:y?b(g):Promise.resolve(b(g))}},{key:"encapsulateSync",value:function encapsulateSync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"revive",value:function revive(e,r){var n=this,i=_objectSpread2(_objectSpread2({sync:!0},this.options),r),c=i.sync;function finishRevival(e){if(c)return e;if(i.throwOnBadSyncType)throw new TypeError("Async method requested but sync result obtained");return Promise.resolve(e)}if(!e||"object"!==_typeof(e)||Array.isArray(e))return finishRevival(e);var s=e.$types;if(!0===s)return finishRevival(e.$);if(!s||"object"!==_typeof(s)||Array.isArray(s))return finishRevival(e);var y=[],l={},p=!0;s.$&&isPlainObject(s.$)&&(e=e.$,s=s.$,p=!1);var f=function executeReviver(e,t){var r,o=_slicedToArray(null!==(r=n.revivers[e])&&void 0!==r?r:[],1)[0];if(!o)throw new Error("Unregistered type: "+e);if(c&&!("revive"in o))return t;if(!c&&o.reviveAsync)return o.reviveAsync(t,l);if(o.revive)return o.revive(t,l);throw new Error("Missing reviver")},h=[];function checkUndefined(e){return hasConstructorOf(e,u)?void 0:e}var v,d=function revivePlainObjects(){var r=[];if(!s)throw new Error("Found bad `types`");if(Object.entries(s).forEach((function(e){var t=_slicedToArray(e,2),o=t[0],i=t[1];"#"!==i&&[].concat(i).forEach((function(e){var t;_slicedToArray(null!==(t=n.revivers[e])&&void 0!==t?t:[null,{}],2)[1].plain&&(r.push({keypath:o,type:e}),delete s[o])}))})),r.length)return r.sort(nestedPathsFirst),r.reduce((function reducer(r,n){var o=n.keypath,i=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:o,type:i})}));var a=getByKeyPath(e,o);if(hasConstructorOf(a=f(i,a),t))return a.then((function(t){var r=setAtKeyPath(e,o,t);r===t&&(e=r)}));var c=setAtKeyPath(e,o,a);c===a&&(e=c)}),void 0)}();return hasConstructorOf(d,t)?v=d.then((function(){return e})):(v=function _revive(e,r,n,i,c){if(!p||"$types"!==e){var l=s[e],v=a(r);if(v||isPlainObject(r)){var d=v?new Array(r.length):{};for(o(r).forEach((function(o){var i=_revive(e+(e?".":"")+escapeKeyPathComponent(o),r[o],null!=n?n:d,d,o),a=function set(e){return hasConstructorOf(e,u)?d[o]=void 0:void 0!==e&&(d[o]=e),e};hasConstructorOf(i,t)?h.push(i.then((function(e){return a(e)}))):a(i)})),r=d;y.length;){var b=_slicedToArray(y[0],4),_=b[0],O=b[1],m=b[2],j=b[3],g=getByKeyPath(_,O);if(void 0===g)break;m[j]=g,y.splice(0,1)}}if(!l)return r;if("#"===l){var S=getByKeyPath(n,r.slice(1));return void 0===S&&y.push([n,r.slice(1),i,c]),S}return[].concat(l).reduce((function reducer(e,r){if(hasConstructorOf(e,t))return e.then((function(e){return reducer(e,r)}));if("string"!=typeof r)throw new TypeError("Bad type JSON");return f(r,e)}),r)}}("",e,null),h.length&&(v=t.resolve(v).then((function(e){return t.all([e].concat(h))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(v)?c&&i.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(v,t)?v.p.then(checkUndefined):v:!c&&i.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():c?checkUndefined(v):Promise.resolve(checkUndefined(v))}},{key:"reviveSync",value:function reviveSync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!1}))}},{key:"register",value:function register(e,t){var r=this,n=null!=t?t:{},i=function reg(e){a(e)?e.forEach((function(e){i(e)})):o(e).forEach((function(t){var o;if("#"===t)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(y.includes(t))throw new TypeError("Plain JSON object types are reserved as type names");var i=e[t],c=i&&"function"!=typeof i&&!Array.isArray(i)&&i.testPlainObjects?r.plainObjectReplacers:r.nonplainObjectReplacers,s=c.filter((function(e){return e.type===t}));if(s.length&&(c.splice(c.indexOf(s[0]),1),delete r.revivers[t],delete r.types[t]),"function"==typeof i){var u=i;i={test:function test(e){return e&&e.constructor===u},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(u.prototype),e)}}}else if(a(i)){var l=_slicedToArray(i,3);i={test:l[0],replace:l[1],revive:l[2]}}if(null!==(o=i)&&void 0!==o&&o.test){var p={type:t,test:i.test.bind(i)};i.replace&&(p.replace=i.replace.bind(i)),i.replaceAsync&&(p.replaceAsync=i.replaceAsync.bind(i));var f="number"==typeof n.fallback?n.fallback:n.fallback?0:Number.POSITIVE_INFINITY;if(i.testPlainObjects?r.plainObjectReplacers.splice(f,0,p):r.nonplainObjectReplacers.splice(f,0,p),i.revive||i.reviveAsync){var h={};i.revive&&(h.revive=i.revive.bind(i)),i.reviveAsync&&(h.reviveAsync=i.reviveAsync.bind(i)),r.revivers[t]=[h,{plain:i.testPlainObjects}]}r.types[t]=i}}))};return[].concat(e).forEach((function(e){i(e)})),this}}])}(),u=_createClass((function Undefined(){_classCallCheck(this,Undefined)}));u.__typeson__type__="TypesonUndefined";var y=["null","boolean","number","string","array","object"];e.JSON_TYPES=y,e.Typeson=s,e.TypesonPromise=t,e.Undefined=u,e.escapeKeyPathComponent=escapeKeyPathComponent,e.getByKeyPath=getByKeyPath,e.getJSONType=getJSONType,e.hasConstructorOf=hasConstructorOf,e.isObject=isObject,e.isPlainObject=isPlainObject,e.isThenable=isThenable,e.isUserObject=function isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=n(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))},e.setAtKeyPath=setAtKeyPath,e.toStringTag=toStringTag,e.unescapeKeyPathComponent=unescapeKeyPathComponent}));