Socket
Socket
Sign inDemoInstall

typeson

Package Overview
Dependencies
Maintainers
2
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typeson - npm Package Compare versions

Comparing version 7.0.2 to 8.0.0

577

dist/typeson.esm.js

@@ -0,4 +1,30 @@

function _iterableToArrayLimit(arr, i) {
var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];
if (null != _i) {
var _s,
_e,
_x,
_r,
_arr = [],
_n = !0,
_d = !1;
try {
if (_x = (_i = _i.call(arr)).next, 0 === i) {
if (Object(_i) !== _i) return;
_n = !1;
} else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);
} catch (err) {
_d = !0, _e = err;
} finally {
try {
if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return;
} finally {
if (_d) throw _e;
}
}
return _arr;
}
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {

@@ -10,6 +36,4 @@ var symbols = Object.getOwnPropertySymbols(object);

}
return keys;
}
function _objectSpread2(target) {

@@ -24,6 +48,4 @@ for (var i = 1; i < arguments.length; i++) {

}
return target;
}
function _typeof(obj) {

@@ -38,3 +60,2 @@ "@babel/helpers - typeof";

}
function _classCallCheck(instance, Constructor) {

@@ -45,3 +66,2 @@ if (!(instance instanceof Constructor)) {

}
function _defineProperties(target, props) {

@@ -53,6 +73,5 @@ for (var i = 0; i < props.length; i++) {

if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {

@@ -66,4 +85,4 @@ if (protoProps) _defineProperties(Constructor.prototype, protoProps);

}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {

@@ -79,56 +98,19 @@ Object.defineProperty(obj, key, {

}
return obj;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _iterableToArrayLimit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {

@@ -142,18 +124,27 @@ if (!o) return;

}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
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 _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 _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}

@@ -164,3 +155,2 @@ /**

*/
/**

@@ -170,3 +160,2 @@ * @callback TypesonRejected

*/
/**

@@ -177,3 +166,2 @@ * @callback TypesonResolve

*/
/**

@@ -184,3 +172,2 @@ * @callback TypesonReject

*/
/**

@@ -192,7 +179,5 @@ * @callback TypesonResolveReject

*/
/* eslint-disable block-spacing, space-before-function-paren,
space-before-blocks, space-infix-ops, semi, promise/avoid-new,
jsdoc/require-jsdoc */
/**

@@ -208,3 +193,2 @@ * We keep this function minimized so if using two instances of this

_classCallCheck(this, TypesonPromise);
this.p = new Promise(f);

@@ -217,8 +201,6 @@ });

// class TypesonPromise extends Promise {get[Symbol.toStringTag](){return 'TypesonPromise'};} // eslint-disable-line keyword-spacing, space-before-function-paren, space-before-blocks, block-spacing, semi
TypesonPromise.__typeson__type__ = 'TypesonPromise';
TypesonPromise.__typeson__type__ = 'TypesonPromise'; // Note: core-js-bundle provides a `Symbol` polyfill
// Note: core-js-bundle provides a `Symbol` polyfill
/* istanbul ignore else */
if (typeof Symbol !== 'undefined') {

@@ -228,4 +210,4 @@ // Ensure `isUserObject` will return `false` for `TypesonPromise`

}
/* eslint-disable unicorn/no-thenable -- Desired to be Promise-like */
/**

@@ -237,7 +219,4 @@ *

*/
TypesonPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
return new TypesonPromise(function (typesonResolve, typesonReject) {

@@ -253,2 +232,3 @@ // eslint-disable-next-line promise/catch-or-return

};
/**

@@ -259,4 +239,2 @@ *

*/
TypesonPromise.prototype["catch"] = function (onRejected) {

@@ -270,4 +248,2 @@ return this.then(null, onRejected);

*/
TypesonPromise.resolve = function (v) {

@@ -283,4 +259,2 @@ return new TypesonPromise(function (typesonResolve) {

*/
TypesonPromise.reject = function (v) {

@@ -291,3 +265,2 @@ return new TypesonPromise(function (typesonResolve, typesonReject) {

};
['all', 'race', 'allSettled'].forEach(function (meth) {

@@ -310,6 +283,7 @@ /**

var _ref = {},
toStr = _ref.toString,
hasOwn$1 = {}.hasOwnProperty,
getProto = Object.getPrototypeOf,
fnToString = hasOwn$1.toString;
toStr = _ref.toString,
hasOwn$1 = {}.hasOwnProperty,
getProto = Object.getPrototypeOf,
fnToString = hasOwn$1.toString;
/**

@@ -321,6 +295,6 @@ * Second argument not in use internally, but provided for utility.

*/
function isThenable(v, catchCheck) {
return isObject(v) && typeof v.then === 'function' && (!catchCheck || typeof v["catch"] === 'function');
}
/**

@@ -331,7 +305,6 @@ *

*/
function toStringTag(val) {
return toStr.call(val).slice(8, -1);
}
/**

@@ -344,4 +317,2 @@ * This function is dependent on both constructors

*/
function hasConstructorOf(a, b) {

@@ -351,30 +322,24 @@ if (!a || _typeof(a) !== 'object') {

}
var proto = getProto(a);
if (!proto) {
return b === null;
}
var Ctor = hasOwn$1.call(proto, 'constructor') && proto.constructor;
if (typeof Ctor !== 'function') {
return b === null;
}
if (b === Ctor) {
return true;
}
if (b !== null && fnToString.call(Ctor) === fnToString.call(b)) {
return true;
} // eslint-disable-next-line sonarjs/prefer-single-boolean-return -- Cleaner
}
// eslint-disable-next-line sonarjs/prefer-single-boolean-return -- Cleaner
if (typeof b === 'function' && typeof Ctor.__typeson__type__ === 'string' && Ctor.__typeson__type__ === b.__typeson__type__) {
return true;
}
return false;
}
/**

@@ -385,4 +350,2 @@ *

*/
function isPlainObject(val) {

@@ -393,5 +356,3 @@ // Mirrors jQuery's

}
var proto = getProto(val);
if (!proto) {

@@ -401,5 +362,5 @@ // `Object.create(null)`

}
return hasConstructorOf(val, Object);
}
/**

@@ -410,4 +371,2 @@ *

*/
function isUserObject(val) {

@@ -417,5 +376,3 @@ if (!val || toStringTag(val) !== 'Object') {

}
var proto = getProto(val);
if (!proto) {

@@ -425,5 +382,5 @@ // `Object.create(null)`

}
return hasConstructorOf(val, Object) || isUserObject(proto);
}
/**

@@ -434,7 +391,6 @@ *

*/
function isObject(v) {
return v && _typeof(v) === 'object';
}
/**

@@ -445,7 +401,6 @@ *

*/
function escapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~/g, '~0').replace(/\./g, '~1');
return keyPathComponent.replaceAll("''", "''''").replace(/^$/, "''").replace(/~/g, '~0').replace(/\./g, '~1');
}
/**

@@ -456,7 +411,6 @@ *

*/
function unescapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~');
return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~').replace(/^''$/, '').replaceAll("''''", "''");
}
/**

@@ -467,4 +421,2 @@ * @param {PlainObject|GenericArray} obj

*/
function getByKeyPath(obj, keyPath) {

@@ -474,5 +426,3 @@ if (keyPath === '') {

}
var period = keyPath.indexOf('.');
if (period > -1) {

@@ -482,5 +432,5 @@ var innerObj = obj[unescapeKeyPathComponent(keyPath.slice(0, period))];

}
return obj[unescapeKeyPathComponent(keyPath)];
}
/**

@@ -493,4 +443,2 @@ *

*/
function setAtKeyPath(obj, keyPath, value) {

@@ -500,5 +448,3 @@ if (keyPath === '') {

}
var period = keyPath.indexOf('.');
if (period > -1) {

@@ -508,6 +454,6 @@ var innerObj = obj[unescapeKeyPathComponent(keyPath.slice(0, period))];

}
obj[unescapeKeyPathComponent(keyPath)] = value;
return obj;
}
/**

@@ -519,4 +465,2 @@ *

*/
function getJSONType(value) {

@@ -530,14 +474,12 @@ return value === null ? 'null' : Array.isArray(value) ? 'array' : _typeof(value);

}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
var keys = Object.keys,
isArray = Array.isArray,
hasOwn = {}.hasOwnProperty,
internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric'];
var keys = Object.keys,
isArray = Array.isArray,
hasOwn = {}.hasOwnProperty,
internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric'];
/**

@@ -557,3 +499,2 @@ * Handle plain object revivers first so reference setting can use

}
try {

@@ -565,9 +506,8 @@ return Promise.resolve(f.apply(this, args));

};
}
/**
* @callback Tester
* @param {any} value
* @param {StateObject} stateobj
* @returns {boolean}
*/
} /**
* @callback Tester
* @param {any} value
* @param {StateObject} stateobj
* @returns {boolean}
*/

@@ -603,13 +543,9 @@ /**

function _invoke(body, then) {
var result = body();
if (result && result.then) {
return result.then(then);
}
return then(result);
}
function nestedPathsFirst(a, b) {

@@ -619,17 +555,12 @@ if (a.keypath === '') {

}
var as = a.keypath.match(/\./g) || 0;
var bs = b.keypath.match(/\./g) || 0;
if (as) {
as = as.length;
}
if (bs) {
bs = bs.length;
}
return as > bs ? -1 : as < bs ? 1 : a.keypath < b.keypath ? -1 : a.keypath > b.keypath;
}
var Typeson = /*#__PURE__*/function () {

@@ -641,15 +572,17 @@ /**

_classCallCheck(this, Typeson);
this.options = options;
this.options = options; // Replacers signature: replace (value). Returns falsy if not
// Replacers signature: replace (value). Returns falsy if not
// replacing. Otherwise ['Date', value.getTime()]
this.plainObjectReplacers = [];
this.nonplainObjectReplacers = [];
this.plainObjectReplacers = [];
this.nonplainObjectReplacers = []; // Revivers: [{type => reviver}, {plain: boolean}].
// Revivers: [{type => reviver}, {plain: boolean}].
// Sample: [{'Date': value => new Date(value)}, {plain: false}]
this.revivers = {};
this.revivers = {};
/** Types registered via `register()`. */
this.types = {};
}
/**

@@ -677,4 +610,2 @@ * @typedef {null|boolean|number|string|GenericArray|PlainObject} JSON

*/
_createClass(Typeson, [{

@@ -687,7 +618,5 @@ key: "stringify",

var encapsulated = this.encapsulate(obj, null, opts);
if (isArray(encapsulated)) {
return JSON.stringify(encapsulated[0], replacer, space);
}
return encapsulated.then(function (res) {

@@ -697,2 +626,3 @@ return JSON.stringify(res, replacer, space);

}
/**

@@ -706,3 +636,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -717,2 +646,3 @@ key: "stringifySync",

}
/**

@@ -726,3 +656,2 @@ *

*/
}, {

@@ -737,2 +666,3 @@ key: "stringifyAsync",

}
/**

@@ -754,3 +684,2 @@ * @callback JSONReviver

*/
}, {

@@ -764,2 +693,3 @@ key: "parse",

}
/**

@@ -773,3 +703,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -791,3 +720,2 @@ key: "parseSync",

*/
}, {

@@ -802,2 +730,3 @@ key: "parseAsync",

}
/**

@@ -814,3 +743,2 @@ * @typedef {} StateObject

*/
}, {

@@ -823,2 +751,3 @@ key: "specialTypeNames",

}
/**

@@ -831,3 +760,2 @@ *

*/
}, {

@@ -840,2 +768,3 @@ key: "rootTypeName",

}
/**

@@ -851,3 +780,2 @@ * Encapsulate a complex object into a plain Object by replacing

*/
}, {

@@ -869,20 +797,16 @@ key: "encapsulate",

var newPromisesData = [];
var _promisesData$splice = promisesData.splice(0, 1),
_promisesData$splice2 = _slicedToArray(_promisesData$splice, 1),
prData = _promisesData$splice2[0];
_promisesData$splice2 = _slicedToArray(_promisesData$splice, 1),
prData = _promisesData$splice2[0];
var _prData = _slicedToArray(prData, 7),
keyPath = _prData[0],
cyclic = _prData[2],
stateObj = _prData[3],
parentObj = _prData[4],
key = _prData[5],
detectedType = _prData[6];
keyPath = _prData[0],
cyclic = _prData[2],
stateObj = _prData[3],
parentObj = _prData[4],
key = _prData[5],
detectedType = _prData[6];
var encaps = _encapsulate(keyPath, promResult, cyclic, stateObj, newPromisesData, true, detectedType);
var isTypesonPromise = hasConstructorOf(encaps, TypesonPromise); // Handle case where an embedded custom type itself
var isTypesonPromise = hasConstructorOf(encaps, TypesonPromise);
// Handle case where an embedded custom type itself
// returns a `TypesonPromise`
return _invoke(function () {

@@ -892,5 +816,3 @@ if (keyPath && isTypesonPromise) {

parentObj[key] = encaps2;
var _checkPromises = checkPromises(ret, newPromisesData);
_exit = true;

@@ -902,3 +824,2 @@ return _checkPromises;

if (_exit) return _result;
if (keyPath) {

@@ -918,3 +839,2 @@ parentObj[key] = encaps;

}
return checkPromises(ret, newPromisesData);

@@ -931,3 +851,2 @@ });

*/
/**

@@ -937,3 +856,2 @@ * @callback BuiltinStateObjectPropertiesCallback

*/
/**

@@ -946,4 +864,2 @@ *

*/
opts = _objectSpread2(_objectSpread2({

@@ -953,17 +869,18 @@ sync: true

var _opts = opts,
sync = _opts.sync;
sync = _opts.sync;
var that = this,
types = {},
refObjs = [],
// For checking cyclic references
refKeys = [],
// For checking cyclic references
promisesDataRoot = []; // Clone the object deeply while at the same time replacing any
types = {},
refObjs = [],
// For checking cyclic references
refKeys = [],
// For checking cyclic references
promisesDataRoot = [];
// Clone the object deeply while at the same time replacing any
// special types or cyclic reference:
var cyclic = 'cyclic' in opts ? opts.cyclic : true;
var _opts2 = opts,
encapsulateObserver = _opts2.encapsulateObserver;
encapsulateObserver = _opts2.encapsulateObserver;
var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot);
var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot);
/**

@@ -974,4 +891,2 @@ *

*/
function finish(ret) {

@@ -981,3 +896,2 @@ // Add `$types` to result only if we ever bumped into a

var typeNames = Object.values(types);
if (opts.iterateNone) {

@@ -987,14 +901,13 @@ if (typeNames.length) {

}
return getJSONType(ret);
}
if (typeNames.length) {
if (opts.returnTypeNames) {
return _toConsumableArray(new Set(typeNames));
} // Special if array (or a primitive) was serialized
}
// Special if array (or a primitive) was serialized
// because JSON would ignore custom `$types` prop on it
if (!ret || !isPlainObject(ret) || // Also need to handle if this is an object with its
if (!ret || !isPlainObject(ret) ||
// Also need to handle if this is an object with its
// own `$types` property (to avoid ambiguity)

@@ -1010,4 +923,4 @@ hasOwn.call(ret, '$types')) {

ret.$types = types;
} // No special types
}
// No special types
} else if (isObject(ret) && hasOwn.call(ret, '$types')) {

@@ -1019,10 +932,7 @@ ret = {

}
if (opts.returnTypeNames) {
return false;
}
return ret;
}
function _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, cb) {

@@ -1034,4 +944,4 @@ Object.assign(stateObj, ownKeysObj);

return tmp;
}); // eslint-disable-next-line node/callback-return
});
// eslint-disable-next-line n/callback-return
cb();

@@ -1042,2 +952,3 @@ internalStateObjPropsToIgnore.forEach(function (prop, i) {

}
/**

@@ -1054,10 +965,6 @@ *

*/
function _encapsulate(keypath, value, cyclic, stateObj, promisesData, resolvingTypesonPromise, detectedType) {
var ret;
var observerData = {};
var $typeof = _typeof(value);
var runObserver = encapsulateObserver ? function (obj) {

@@ -1077,7 +984,5 @@ var type = detectedType || stateObj.type || getJSONType(value);

} : null;
if (['string', 'boolean', 'number', 'undefined'].includes($typeof)) {
if (value === undefined || Number.isNaN(value) || value === Number.NEGATIVE_INFINITY || value === Number.POSITIVE_INFINITY) {
ret = stateObj.replaced ? value : replace(keypath, value, stateObj, promisesData, false, resolvingTypesonPromise, runObserver);
if (ret !== value) {

@@ -1091,10 +996,7 @@ observerData = {

}
if (runObserver) {
runObserver();
}
return ret;
}
if (value === null) {

@@ -1104,6 +1006,4 @@ if (runObserver) {

}
return value;
}
if (cyclic && !stateObj.iterateIn && !stateObj.iterateUnsetNumeric && value && _typeof(value) === 'object') {

@@ -1113,3 +1013,2 @@ // Options set to detect cyclic references and be able

var refIndex = refObjs.indexOf(value);
if (refIndex < 0) {

@@ -1122,3 +1021,2 @@ if (cyclic === true) {

types[keypath] = '#';
if (runObserver) {

@@ -1129,16 +1027,16 @@ runObserver({

}
return '#' + refKeys[refIndex];
}
}
var isPlainObj = isPlainObject(value);
var isArr = isArray(value);
var replaced = // Running replace will cause infinite loop as will test
var replaced =
// Running replace will cause infinite loop as will test
// positive again
(isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn // Optimization: if plain object and no plain-object
(isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn
// Optimization: if plain object and no plain-object
// replacers, don't try finding a replacer
? value : replace(keypath, value, stateObj, promisesData, isPlainObj || isArr, null, runObserver);
var clone;
if (replaced !== value) {

@@ -1162,7 +1060,5 @@ ret = replaced;

clone = {};
if (stateObj.addLength) {
clone.length = value.length;
}
observerData = {

@@ -1179,12 +1075,10 @@ clone: clone

}
if (opts.iterateNone) {
return clone || ret;
}
if (!clone) {
return ret;
} // Iterate object or array
}
// Iterate object or array
if (stateObj.iterateIn) {

@@ -1195,8 +1089,5 @@ var _loop = function _loop(key) {

};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key);
var val = _encapsulate(kp, value[key], Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1209,3 +1100,2 @@ promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, key, stateObj.type]);

};
// eslint-disable-next-line guard-for-in

@@ -1215,3 +1105,2 @@ for (var key in value) {

}
if (runObserver) {

@@ -1233,6 +1122,4 @@ runObserver({

};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, value[key], Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1245,3 +1132,2 @@ promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, key, stateObj.type]);

});
if (runObserver) {

@@ -1253,10 +1139,8 @@ runObserver({

}
} // Iterate array for non-own numeric properties (we can't
}
// Iterate array for non-own numeric properties (we can't
// replace the prior loop though as it iterates non-integer
// keys)
if (stateObj.iterateUnsetNumeric) {
var vl = value.length;
var _loop2 = function _loop2(i) {

@@ -1269,6 +1153,4 @@ if (!(i in value)) {

};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, undefined, Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1282,7 +1164,5 @@ promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, i, stateObj.type]);

};
for (var i = 0; i < vl; i++) {
_loop2(i);
}
if (runObserver) {

@@ -1295,5 +1175,5 @@ runObserver({

}
return clone;
}
/**

@@ -1344,4 +1224,2 @@ * @typedef {PlainObject} KeyPathEvent

*/
function replace(keypath, value, stateObj, promisesData, plainObject, resolvingTypesonPromise, runObserver) {

@@ -1351,9 +1229,6 @@ // Encapsulate registered types

var i = replacers.length;
while (i--) {
var replacer = replacers[i];
if (replacer.test(value, stateObj)) {
var type = replacer.type;
if (that.revivers[type]) {

@@ -1366,8 +1241,7 @@ // Record the type only if a corresponding reviver

// the need to revive it.
var existing = types[keypath]; // type can comprise an array of types (see test
var existing = types[keypath];
// type can comprise an array of types (see test
// "should support intermediate types")
types[keypath] = existing ? [type].concat(existing) : type;
}
Object.assign(stateObj, {

@@ -1377,3 +1251,2 @@ type: type,

});
if ((sync || !replacer.replaceAsync) && !replacer.replace) {

@@ -1385,6 +1258,4 @@ if (runObserver) {

}
return _encapsulate(keypath, value, cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);
}
if (runObserver) {

@@ -1394,6 +1265,6 @@ runObserver({

});
} // Now, also traverse the result in case it contains its
}
// Now, also traverse the result in case it contains its
// own types to replace
var replaceMethod = sync || !replacer.replaceAsync ? 'replace' : 'replaceAsync';

@@ -1403,6 +1274,4 @@ return _encapsulate(keypath, replacer[replaceMethod](value, stateObj), cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);

}
return value;
}
return promisesDataRoot.length ? sync && opts.throwOnBadSyncType ? function () {

@@ -1412,3 +1281,4 @@ throw new TypeError('Sync method requested but async result obtained');

throw new TypeError('Async method requested but sync result obtained');
}() // If this is a synchronous request for stringification, yet
}()
// If this is a synchronous request for stringification, yet
// a promise is the result, we don't want to resolve leading

@@ -1419,2 +1289,3 @@ // to an async result, so we return an array to avoid

}
/**

@@ -1427,3 +1298,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -1438,2 +1308,3 @@ key: "encapsulateSync",

}
/**

@@ -1445,3 +1316,2 @@ * @param {any} obj

*/
}, {

@@ -1456,2 +1326,3 @@ key: "encapsulateAsync",

}
/**

@@ -1468,18 +1339,17 @@ * Revive an encapsulated object.

*/
}, {
key: "revive",
value: function revive(obj, opts) {
var types = obj && obj.$types; // No type info added. Revival not needed.
var types = obj && obj.$types;
// No type info added. Revival not needed.
if (!types) {
return obj;
} // Object happened to have own `$types` property but with
}
// Object happened to have own `$types` property but with
// no actual types, so we unescape and return that object
if (types === true) {
return obj.$;
}
opts = _objectSpread2(_objectSpread2({

@@ -1489,9 +1359,9 @@ sync: true

var _opts3 = opts,
sync = _opts3.sync;
sync = _opts3.sync;
var keyPathResolutions = [];
var stateObj = {};
var ignore$Types = true; // Special when root object is not a trivial Object, it will
var ignore$Types = true;
// Special when root object is not a trivial Object, it will
// be encapsulated in `$`. It will also be encapsulated in
// `$` if it has its own `$` property to avoid ambiguity
if (types.$ && isPlainObject(types.$)) {

@@ -1502,4 +1372,4 @@ obj = obj.$;

}
var that = this;
var that = this;
/**

@@ -1519,16 +1389,14 @@ * @callback RevivalReducer

*/
function executeReviver(type, val) {
var _ref = that.revivers[type] || [],
_ref2 = _slicedToArray(_ref, 1),
reviver = _ref2[0];
_ref2 = _slicedToArray(_ref, 1),
reviver = _ref2[0];
if (!reviver) {
throw new Error('Unregistered type: ' + type);
} // Only `sync` expected here, as problematic async would
}
// Only `sync` expected here, as problematic async would
// be missing both `reviver` and `reviverAsync`, and
// encapsulation shouldn't have added types, so
// should have made an early exit
if (sync && !('revive' in reviver)) {

@@ -1538,5 +1406,5 @@ // Just return value as is

}
return reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj);
}
/**

@@ -1546,4 +1414,2 @@ *

*/
function revivePlainObjects() {

@@ -1555,5 +1421,4 @@ // const references = [];

var _ref4 = _slicedToArray(_ref3, 2),
keypath = _ref4[0],
type = _ref4[1];
keypath = _ref4[0],
type = _ref4[1];
if (type === '#') {

@@ -1568,8 +1433,6 @@ /*

}
[].concat(type).forEach(function (type) {
var _ref5 = that.revivers[type] || [null, {}],
_ref6 = _slicedToArray(_ref5, 2),
plain = _ref6[1].plain;
_ref6 = _slicedToArray(_ref5, 2),
plain = _ref6[1].plain;
if (!plain) {

@@ -1579,3 +1442,2 @@ // reviveTypes.push({keypath, type});

}
plainObjectTypes.push({

@@ -1591,4 +1453,5 @@ keypath: keypath,

return undefined;
} // console.log(plainObjectTypes.sort(nestedPathsFirst));
}
// console.log(plainObjectTypes.sort(nestedPathsFirst));
/**

@@ -1599,8 +1462,5 @@ * @typedef {PlainObject} PlainObjectType

*/
return plainObjectTypes.sort(nestedPathsFirst).reduce(function reducer(possibleTypesonPromise, _ref7) {
var keypath = _ref7.keypath,
type = _ref7.type;
type = _ref7.type;
if (isThenable(possibleTypesonPromise)) {

@@ -1613,29 +1473,23 @@ return possibleTypesonPromise.then(function (val) {

});
} // console.log('obj', JSON.stringify(keypath), obj);
}
// console.log('obj', JSON.stringify(keypath), obj);
var val = getByKeyPath(obj, keypath);
val = executeReviver(type, val);
if (hasConstructorOf(val, TypesonPromise)) {
return val.then(function (v) {
var newVal = setAtKeyPath(obj, keypath, v);
if (newVal === v) {
obj = newVal;
}
return undefined;
});
}
var newVal = setAtKeyPath(obj, keypath, val);
if (newVal === val) {
obj = newVal;
}
return undefined;
}, undefined // This argument must be explicit
); // references.forEach(({keypath, reference}) => {});
);
// references.forEach(({keypath, reference}) => {});
// reviveTypes.sort(nestedPathsFirst).forEach(() => {});

@@ -1654,3 +1508,2 @@ }

*/
function _revive(keypath, value, target, clone, key) {

@@ -1660,14 +1513,10 @@ if (ignore$Types && keypath === '$types') {

}
var type = types[keypath];
var isArr = isArray(value);
if (isArr || isPlainObject(value)) {
// eslint-disable-next-line unicorn/no-new-array -- Sparse
var _clone = isArr ? new Array(value.length) : {}; // Iterate object or array
var _clone = isArr ? new Array(value.length) : {};
// Iterate object or array
keys(value).forEach(function (k) {
var val = _revive(keypath + (keypath ? '.' : '') + escapeKeyPathComponent(k), value[k], target || _clone, _clone, k);
var set = function set(v) {

@@ -1679,6 +1528,4 @@ if (hasConstructorOf(v, Undefined)) {

}
return v;
};
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1692,14 +1539,13 @@ revivalPromises.push(val.then(function (ret) {

});
value = _clone; // Try to resolve cyclic reference as soon as available
value = _clone;
// Try to resolve cyclic reference as soon as available
while (keyPathResolutions.length) {
var _keyPathResolutions$ = _slicedToArray(keyPathResolutions[0], 4),
_target = _keyPathResolutions$[0],
keyPath = _keyPathResolutions$[1],
_clone2 = _keyPathResolutions$[2],
k = _keyPathResolutions$[3];
var val = getByKeyPath(_target, keyPath); // Typeson.Undefined not expected here as not cyclic or
_target = _keyPathResolutions$[0],
keyPath = _keyPathResolutions$[1],
_clone2 = _keyPathResolutions$[2],
k = _keyPathResolutions$[3];
var val = getByKeyPath(_target, keyPath);
// Typeson.Undefined not expected here as not cyclic or
// `undefined`
if (val !== undefined) {

@@ -1710,14 +1556,10 @@ _clone2[k] = val;

}
keyPathResolutions.splice(0, 1);
}
}
if (!type) {
return value;
}
if (type === '#') {
var _ret = getByKeyPath(target, value.slice(1));
if (_ret === undefined) {

@@ -1727,7 +1569,6 @@ // Cyclic reference not yet available

}
return _ret;
} // `type` can be an array here
}
// `type` can be an array here
return [].concat(type).reduce(function reducer(val, typ) {

@@ -1740,6 +1581,6 @@ if (hasConstructorOf(val, TypesonPromise)) {

}
return executeReviver(typ, val);
}, value);
}
/**

@@ -1750,11 +1591,7 @@ *

*/
function checkUndefined(retrn) {
return hasConstructorOf(retrn, Undefined) ? undefined : retrn;
}
var possibleTypesonPromise = revivePlainObjects();
var ret;
if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) {

@@ -1766,12 +1603,11 @@ ret = possibleTypesonPromise.then(function () {

ret = _revive('', obj, null);
if (revivalPromises.length) {
// Ensure children resolved
ret = TypesonPromise.resolve(ret).then(function (r) {
return TypesonPromise.all([// May be a TypesonPromise or not
return TypesonPromise.all([
// May be a TypesonPromise or not
r].concat(revivalPromises));
}).then(function (_ref8) {
var _ref9 = _slicedToArray(_ref8, 1),
r = _ref9[0];
r = _ref9[0];
return r;

@@ -1781,3 +1617,2 @@ });

}
return isThenable(ret) ? sync && opts.throwOnBadSyncType ? function () {

@@ -1789,2 +1624,3 @@ throw new TypeError('Sync method requested but async result obtained');

}
/**

@@ -1796,3 +1632,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -1807,2 +1642,3 @@ key: "reviveSync",

}
/**

@@ -1813,3 +1649,2 @@ * @param {any} obj

*/
}, {

@@ -1824,2 +1659,3 @@ key: "reviveAsync",

}
/**

@@ -1838,3 +1674,2 @@ * @typedef {Tester|Replacer|Reviver} Spec

*/
}, {

@@ -1844,5 +1679,3 @@ key: "register",

var _this = this;
opts = opts || {};
var R = function R(typeSpec) {

@@ -1856,3 +1689,2 @@ // Allow arrays of arrays of arrays...

}
typeSpec && keys(typeSpec).forEach(function (typeId) {

@@ -1864,3 +1696,2 @@ if (typeId === '#') {

}
var spec = typeSpec[typeId];

@@ -1871,3 +1702,2 @@ var replacers = spec && spec.testPlainObjects ? _this.plainObjectReplacers : _this.nonplainObjectReplacers;

});
if (existingReplacer.length) {

@@ -1879,3 +1709,2 @@ // Remove existing spec and replace with this one.

}
if (typeof spec === 'function') {

@@ -1897,7 +1726,6 @@ // Support registering just a class without replacer/reviver

var _spec = spec,
_spec2 = _slicedToArray(_spec, 3),
test = _spec2[0],
replace = _spec2[1],
revive = _spec2[2];
_spec2 = _slicedToArray(_spec, 3),
test = _spec2[0],
replace = _spec2[1],
revive = _spec2[2];
spec = {

@@ -1909,7 +1737,5 @@ test: test,

}
if (!spec || !spec.test) {
return;
}
var replacerObj = {

@@ -1919,13 +1745,9 @@ type: typeId,

};
if (spec.replace) {
replacerObj.replace = spec.replace.bind(spec);
}
if (spec.replaceAsync) {
replacerObj.replaceAsync = spec.replaceAsync.bind(spec);
}
var start = typeof opts.fallback === 'number' ? opts.fallback : opts.fallback ? 0 : Number.POSITIVE_INFINITY;
if (spec.testPlainObjects) {

@@ -1935,26 +1757,21 @@ _this.plainObjectReplacers.splice(start, 0, replacerObj);

_this.nonplainObjectReplacers.splice(start, 0, replacerObj);
} // Todo: We might consider a testAsync type
}
// Todo: We might consider a testAsync type
if (spec.revive || spec.reviveAsync) {
var reviverObj = {};
if (spec.revive) {
reviverObj.revive = spec.revive.bind(spec);
}
if (spec.reviveAsync) {
reviverObj.reviveAsync = spec.reviveAsync.bind(spec);
}
_this.revivers[typeId] = [reviverObj, {
plain: spec.testPlainObjects
}];
} // Record to be retrieved via public types property.
}
// Record to be retrieved via public types property.
_this.types[typeId] = spec;
});
};
[].concat(typeSpecSets).forEach(function (typeSpec) {

@@ -1966,3 +1783,2 @@ return R(typeSpec);

}]);
return Typeson;

@@ -1976,10 +1792,9 @@ }();

*/
var Undefined = /*#__PURE__*/_createClass(function Undefined() {
_classCallCheck(this, Undefined);
}); // eslint-disable-line space-before-blocks
Undefined.__typeson__type__ = 'TypesonUndefined';
// The following provide classes meant to avoid clashes with other values
Undefined.__typeson__type__ = 'TypesonUndefined'; // The following provide classes meant to avoid clashes with other values
// Typeson.Undefined is to insist `undefined` should be added

@@ -1986,0 +1801,0 @@ // TypesonPromise is to support async encapsulation/stringification

@@ -1,1 +0,1 @@

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 _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})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}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,n.key,n)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,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)return;var n,a,o=[],i=!0,c=!1;try{for(r=r.call(e);!(i=(n=r.next()).done)&&(o.push(n.value),!t||o.length!==t);i=!0);}catch(e){c=!0,a=e}finally{try{i||null==r.return||r.return()}finally{if(c)throw a}}return o}(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 _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.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}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var e=_createClass((function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)}));e.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&(e.prototype[Symbol.toStringTag]="TypesonPromise"),e.prototype.then=function(t,r){var n=this;return new e((function(e,a){n.p.then((function(r){e(t?t(r):r)})).catch((function(e){return r?r(e):Promise.reject(e)})).then(e,a)}))},e.prototype.catch=function(e){return this.then(null,e)},e.resolve=function(t){return new e((function(e){e(t)}))},e.reject=function(t){return new e((function(e,r){r(t)}))},["all","race","allSettled"].forEach((function(t){e[t]=function(r){return new e((function(e,n){Promise[t](r.map((function(e){return e&&e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,n)}))}}));var t={}.toString,r={}.hasOwnProperty,n=Object.getPrototypeOf,a=r.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return t.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.call(o,"constructor")&&o.constructor;return"function"!=typeof i?null===t:t===i||(null!==t&&a.call(i)===a.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 isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=n(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~")}function getByKeyPath(e,t){if(""===t)return e;var r=t.indexOf(".");if(r>-1){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;var n=t.indexOf(".");return n>-1?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 r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var o=Object.keys,i=Array.isArray,c={}.hasOwnProperty,s=["type","replaced","iterateIn","iterateUnsetNumeric"];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){if(""===e.keypath)return-1;var r=e.keypath.match(/\./g)||0,n=t.keypath.match(/\./g)||0;return r&&(r=r.length),n&&(n=n.length),r>n?-1:r<n?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var u=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return _createClass(Typeson,[{key:"stringify",value:function stringify(e,t,r,n){n=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),n),{},{stringification:!0});var a=this.encapsulate(e,null,n);return i(a)?JSON.stringify(a[0],t,r):a.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(t,r,n){var a=_async((function(t,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=[],c=_slicedToArray(r.splice(0,1),1),s=_slicedToArray(c[0],7),u=s[0],p=s[2],y=s[3],l=s[4],f=s[5],h=s[6],v=_encapsulate(u,n,p,y,i,!0,h),d=hasConstructorOf(v,e);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(u&&d)return _await(v.p,(function(e){l[f]=e;var r=a(t,i);return o=!0,r}))}),(function(e){return o?e:(u?l[f]=v:t=d?v.p:v,a(t,i))}))})))),(function(){return t}))}))})),u=(n=_objectSpread2(_objectSpread2({sync:!0},this.options),n)).sync,p=this,y={},l=[],f=[],h=[],v=!("cyclic"in n)||n.cyclic,d=n.encapsulateObserver,b=_encapsulate("",t,v,r||{},h);function finish(e){var t=Object.values(y);if(n.iterateNone)return t.length?t[0]:getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!c.call(e,"$types")?e.$types=y:e={$:e,$types:{$:y}}}else isObject(e)&&c.call(e,"$types")&&(e={$:e,$types:!0});return!n.returnTypeNames&&e}function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=s.map((function(t){var r=e[t];return delete e[t],r}));r(),s.forEach((function(t,r){e[t]=n[r]}))}function _encapsulate(t,r,a,s,u,h,v){var b,_={},O=_typeof(r),j=d?function(n){var o=v||s.type||getJSONType(r);d(Object.assign(n||_,{keypath:t,value:r,cyclic:a,stateObj:s,promisesData:u,resolvingTypesonPromise:h,awaitingTypesonPromise:hasConstructorOf(r,e)},{type:o}))}:null;if(["string","boolean","number","undefined"].includes(O))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY?(b=s.replaced?r:replace(t,r,s,u,!1,h,j))!==r&&(_={replaced:b}):b=r,j&&j(),b;if(null===r)return j&&j(),r;if(a&&!s.iterateIn&&!s.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var m=l.indexOf(r);if(!(m<0))return y[t]="#",j&&j({cyclicKeypath:f[m]}),"#"+f[m];!0===a&&(l.push(r),f.push(t))}var S,g=isPlainObject(r),P=i(r),T=(g||P)&&(!p.plainObjectReplacers.length||s.replaced)||s.iterateIn?r:replace(t,r,s,u,g||P,null,j);if(T!==r?(b=T,_={replaced:T}):""===t&&hasConstructorOf(r,e)?(u.push([t,r,a,s,void 0,void 0,s.type]),b=r):P&&"object"!==s.iterateIn||"array"===s.iterateIn?(S=new Array(r.length),_={clone:S}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,e)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!g&&"object"!==s.iterateIn?b=r:(S={},s.addLength&&(S.length=r.length),_={clone:S}),j&&j(),n.iterateNone)return S||b;if(!S)return b;if(s.iterateIn){var w=function _loop(n){var o={ownKeys:c.call(r,n)};_adaptBuiltinStateObjectProperties(s,o,(function(){var o=t+(t?".":"")+escapeKeyPathComponent(n),i=_encapsulate(o,r[n],Boolean(a),s,u,h);hasConstructorOf(i,e)?u.push([o,i,Boolean(a),s,S,n,s.type]):void 0!==i&&(S[n]=i)}))};for(var A in r)w(A);j&&j({endIterateIn:!0,end:!0})}else o(r).forEach((function(n){var o=t+(t?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(s,{ownKeys:!0},(function(){var t=_encapsulate(o,r[n],Boolean(a),s,u,h);hasConstructorOf(t,e)?u.push([o,t,Boolean(a),s,S,n,s.type]):void 0!==t&&(S[n]=t)}))})),j&&j({endIterateOwn:!0,end:!0});if(s.iterateUnsetNumeric){for(var C=r.length,k=function _loop2(n){if(!(n in r)){var o=t+(t?".":"")+n;_adaptBuiltinStateObjectProperties(s,{ownKeys:!1},(function(){var t=_encapsulate(o,void 0,Boolean(a),s,u,h);hasConstructorOf(t,e)?u.push([o,t,Boolean(a),s,S,n,s.type]):void 0!==t&&(S[n]=t)}))}},N=0;N<C;N++)k(N);j&&j({endIterateUnsetNumeric:!0,end:!0})}return S}function replace(e,t,r,n,a,o,i){for(var c=a?p.plainObjectReplacers:p.nonplainObjectReplacers,s=c.length;s--;){var l=c[s];if(l.test(t,r)){var f=l.type;if(p.revivers[f]){var h=y[e];y[e]=h?[f].concat(h):f}return Object.assign(r,{type:f,replaced:!0}),!u&&l.replaceAsync||l.replace?(i&&i({replacing:!0}),_encapsulate(e,l[u||!l.replaceAsync?"replace":"replaceAsync"](t,r),v&&"readonly",r,n,o,f)):(i&&i({typeDetected:!0}),_encapsulate(e,t,v&&"readonly",r,n,o,f))}}return t}return h.length?u&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(a(b,h)).then(finish):!u&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&u?[finish(b)]:u?finish(b):Promise.resolve(finish(b))}},{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(t,r){var n=t&&t.$types;if(!n)return t;if(!0===n)return t.$;var a=(r=_objectSpread2(_objectSpread2({sync:!0},this.options),r)).sync,c=[],s={},u=!0;n.$&&isPlainObject(n.$)&&(t=t.$,n=n.$,u=!1);var y=this;function executeReviver(e,t){var r=_slicedToArray(y.revivers[e]||[],1)[0];if(!r)throw new Error("Unregistered type: "+e);return a&&!("revive"in r)?t:r[a&&r.revive?"revive":!a&&r.reviveAsync?"reviveAsync":"revive"](t,s)}var l=[];function checkUndefined(e){return hasConstructorOf(e,p)?void 0:e}var f,h=function revivePlainObjects(){var r=[];if(Object.entries(n).forEach((function(e){var t=_slicedToArray(e,2),a=t[0],o=t[1];"#"!==o&&[].concat(o).forEach((function(e){_slicedToArray(y.revivers[e]||[null,{}],2)[1].plain&&(r.push({keypath:a,type:e}),delete n[a])}))})),r.length)return r.sort(nestedPathsFirst).reduce((function reducer(r,n){var a=n.keypath,o=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:a,type:o})}));var i=getByKeyPath(t,a);if(hasConstructorOf(i=executeReviver(o,i),e))return i.then((function(e){var r=setAtKeyPath(t,a,e);r===e&&(t=r)}));var c=setAtKeyPath(t,a,i);c===i&&(t=c)}),void 0)}();return hasConstructorOf(h,e)?f=h.then((function(){return t})):(f=function _revive(t,r,a,s,y){if(!u||"$types"!==t){var f=n[t],h=i(r);if(h||isPlainObject(r)){var v=h?new Array(r.length):{};for(o(r).forEach((function(n){var o=_revive(t+(t?".":"")+escapeKeyPathComponent(n),r[n],a||v,v,n),i=function set(e){return hasConstructorOf(e,p)?v[n]=void 0:void 0!==e&&(v[n]=e),e};hasConstructorOf(o,e)?l.push(o.then((function(e){return i(e)}))):i(o)})),r=v;c.length;){var d=_slicedToArray(c[0],4),b=d[0],_=d[1],O=d[2],j=d[3],m=getByKeyPath(b,_);if(void 0===m)break;O[j]=m,c.splice(0,1)}}if(!f)return r;if("#"===f){var S=getByKeyPath(a,r.slice(1));return void 0===S&&c.push([a,r.slice(1),s,y]),S}return[].concat(f).reduce((function reducer(t,r){return hasConstructorOf(t,e)?t.then((function(e){return reducer(e,r)})):executeReviver(r,t)}),r)}}("",t,null),l.length&&(f=e.resolve(f).then((function(t){return e.all([t].concat(l))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(f)?a&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(f,e)?f.p.then(checkUndefined):f:!a&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():a?checkUndefined(f):Promise.resolve(checkUndefined(f))}},{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;t=t||{};var n=function R(e){i(e)?e.forEach((function(e){return R(e)})):e&&o(e).forEach((function(n){if("#"===n)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(y.includes(n))throw new TypeError("Plain JSON object types are reserved as type names");var a=e[n],o=a&&a.testPlainObjects?r.plainObjectReplacers:r.nonplainObjectReplacers,c=o.filter((function(e){return e.type===n}));if(c.length&&(o.splice(o.indexOf(c[0]),1),delete r.revivers[n],delete r.types[n]),"function"==typeof a){var s=a;a={test:function test(e){return e&&e.constructor===s},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(s.prototype),e)}}}else if(i(a)){var u=_slicedToArray(a,3);a={test:u[0],replace:u[1],revive:u[2]}}if(a&&a.test){var p={type:n,test:a.test.bind(a)};a.replace&&(p.replace=a.replace.bind(a)),a.replaceAsync&&(p.replaceAsync=a.replaceAsync.bind(a));var l="number"==typeof t.fallback?t.fallback:t.fallback?0:Number.POSITIVE_INFINITY;if(a.testPlainObjects?r.plainObjectReplacers.splice(l,0,p):r.nonplainObjectReplacers.splice(l,0,p),a.revive||a.reviveAsync){var f={};a.revive&&(f.revive=a.revive.bind(a)),a.reviveAsync&&(f.reviveAsync=a.reviveAsync.bind(a)),r.revivers[n]=[f,{plain:a.testPlainObjects}]}r.types[n]=a}}))};return[].concat(e).forEach((function(e){return n(e)})),this}}]),Typeson}(),p=_createClass((function Undefined(){_classCallCheck(this,Undefined)}));p.__typeson__type__="TypesonUndefined";var y=["null","boolean","number","string","array","object"];export{y as JSON_TYPES,u as Typeson,e as TypesonPromise,p as Undefined,escapeKeyPathComponent,getByKeyPath,getJSONType,hasConstructorOf,isObject,isPlainObject,isThenable,isUserObject,setAtKeyPath,toStringTag,unescapeKeyPathComponent};
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 _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 _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}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)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),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 _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,a,i,c=[],s=!0,u=!1;try{if(a=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=a.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&&(i=r.return(),Object(i)!==i))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 _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.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}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _toPropertyKey(e){var t=function _toPrimitive(e,t){if("object"!=typeof e||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}var e=_createClass((function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)}));e.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&(e.prototype[Symbol.toStringTag]="TypesonPromise"),e.prototype.then=function(t,r){var n=this;return new e((function(e,o){n.p.then((function(r){e(t?t(r):r)})).catch((function(e){return r?r(e):Promise.reject(e)})).then(e,o)}))},e.prototype.catch=function(e){return this.then(null,e)},e.resolve=function(t){return new e((function(e){e(t)}))},e.reject=function(t){return new e((function(e,r){r(t)}))},["all","race","allSettled"].forEach((function(t){e[t]=function(r){return new e((function(e,n){Promise[t](r.map((function(e){return e&&e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,n)}))}}));var t={}.toString,r={}.hasOwnProperty,n=Object.getPrototypeOf,o=r.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return t.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var a=n(e);if(!a)return null===t;var i=r.call(a,"constructor")&&a.constructor;return"function"!=typeof i?null===t:t===i||(null!==t&&o.call(i)===o.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 isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=n(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replaceAll("''","''''").replace(/^$/,"''").replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~").replace(/^''$/,"").replaceAll("''''","''")}function getByKeyPath(e,t){if(""===t)return e;var r=t.indexOf(".");if(r>-1){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;var n=t.indexOf(".");return n>-1?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 r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var a=Object.keys,i=Array.isArray,c={}.hasOwnProperty,s=["type","replaced","iterateIn","iterateUnsetNumeric"];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){if(""===e.keypath)return-1;var r=e.keypath.match(/\./g)||0,n=t.keypath.match(/\./g)||0;return r&&(r=r.length),n&&(n=n.length),r>n?-1:r<n?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var u=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return _createClass(Typeson,[{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 i(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(t,r,n){var o=_async((function(t,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 a=!1,i=[],c=_slicedToArray(r.splice(0,1),1),s=_slicedToArray(c[0],7),u=s[0],l=s[2],p=s[3],y=s[4],f=s[5],h=s[6],v=_encapsulate(u,n,l,p,i,!0,h),b=hasConstructorOf(v,e);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(u&&b)return _await(v.p,(function(e){y[f]=e;var r=o(t,i);return a=!0,r}))}),(function(e){return a?e:(u?y[f]=v:t=b?v.p:v,o(t,i))}))})))),(function(){return t}))}))})),u=(n=_objectSpread2(_objectSpread2({sync:!0},this.options),n)).sync,l=this,p={},y=[],f=[],h=[],v=!("cyclic"in n)||n.cyclic,b=n.encapsulateObserver,d=_encapsulate("",t,v,r||{},h);function finish(e){var t=Object.values(p);if(n.iterateNone)return t.length?t[0]:getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!c.call(e,"$types")?e.$types=p:e={$:e,$types:{$:p}}}else isObject(e)&&c.call(e,"$types")&&(e={$:e,$types:!0});return!n.returnTypeNames&&e}function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=s.map((function(t){var r=e[t];return delete e[t],r}));r(),s.forEach((function(t,r){e[t]=n[r]}))}function _encapsulate(t,r,o,s,u,h,v){var d,_={},O=_typeof(r),j=b?function(n){var a=v||s.type||getJSONType(r);b(Object.assign(n||_,{keypath:t,value:r,cyclic:o,stateObj:s,promisesData:u,resolvingTypesonPromise:h,awaitingTypesonPromise:hasConstructorOf(r,e)},{type:a}))}:null;if(["string","boolean","number","undefined"].includes(O))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY?(d=s.replaced?r:replace(t,r,s,u,!1,h,j))!==r&&(_={replaced:d}):d=r,j&&j(),d;if(null===r)return j&&j(),r;if(o&&!s.iterateIn&&!s.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var m=y.indexOf(r);if(!(m<0))return p[t]="#",j&&j({cyclicKeypath:f[m]}),"#"+f[m];!0===o&&(y.push(r),f.push(t))}var S,g=isPlainObject(r),P=i(r),T=(g||P)&&(!l.plainObjectReplacers.length||s.replaced)||s.iterateIn?r:replace(t,r,s,u,g||P,null,j);if(T!==r?(d=T,_={replaced:T}):""===t&&hasConstructorOf(r,e)?(u.push([t,r,o,s,void 0,void 0,s.type]),d=r):P&&"object"!==s.iterateIn||"array"===s.iterateIn?(S=new Array(r.length),_={clone:S}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,e)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!g&&"object"!==s.iterateIn?d=r:(S={},s.addLength&&(S.length=r.length),_={clone:S}),j&&j(),n.iterateNone)return S||d;if(!S)return d;if(s.iterateIn){var w=function _loop(n){var a={ownKeys:c.call(r,n)};_adaptBuiltinStateObjectProperties(s,a,(function(){var a=t+(t?".":"")+escapeKeyPathComponent(n),i=_encapsulate(a,r[n],Boolean(o),s,u,h);hasConstructorOf(i,e)?u.push([a,i,Boolean(o),s,S,n,s.type]):void 0!==i&&(S[n]=i)}))};for(var A in r)w(A);j&&j({endIterateIn:!0,end:!0})}else a(r).forEach((function(n){var a=t+(t?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(s,{ownKeys:!0},(function(){var t=_encapsulate(a,r[n],Boolean(o),s,u,h);hasConstructorOf(t,e)?u.push([a,t,Boolean(o),s,S,n,s.type]):void 0!==t&&(S[n]=t)}))})),j&&j({endIterateOwn:!0,end:!0});if(s.iterateUnsetNumeric){for(var C=r.length,k=function _loop2(n){if(!(n in r)){var a=t+(t?".":"")+n;_adaptBuiltinStateObjectProperties(s,{ownKeys:!1},(function(){var t=_encapsulate(a,void 0,Boolean(o),s,u,h);hasConstructorOf(t,e)?u.push([a,t,Boolean(o),s,S,n,s.type]):void 0!==t&&(S[n]=t)}))}},N=0;N<C;N++)k(N);j&&j({endIterateUnsetNumeric:!0,end:!0})}return S}function replace(e,t,r,n,o,a,i){for(var c=o?l.plainObjectReplacers:l.nonplainObjectReplacers,s=c.length;s--;){var y=c[s];if(y.test(t,r)){var f=y.type;if(l.revivers[f]){var h=p[e];p[e]=h?[f].concat(h):f}return Object.assign(r,{type:f,replaced:!0}),!u&&y.replaceAsync||y.replace?(i&&i({replacing:!0}),_encapsulate(e,y[u||!y.replaceAsync?"replace":"replaceAsync"](t,r),v&&"readonly",r,n,a,f)):(i&&i({typeDetected:!0}),_encapsulate(e,t,v&&"readonly",r,n,a,f))}}return t}return h.length?u&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(o(d,h)).then(finish):!u&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&u?[finish(d)]:u?finish(d):Promise.resolve(finish(d))}},{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(t,r){var n=t&&t.$types;if(!n)return t;if(!0===n)return t.$;var o=(r=_objectSpread2(_objectSpread2({sync:!0},this.options),r)).sync,c=[],s={},u=!0;n.$&&isPlainObject(n.$)&&(t=t.$,n=n.$,u=!1);var p=this;function executeReviver(e,t){var r=_slicedToArray(p.revivers[e]||[],1)[0];if(!r)throw new Error("Unregistered type: "+e);return o&&!("revive"in r)?t:r[o&&r.revive?"revive":!o&&r.reviveAsync?"reviveAsync":"revive"](t,s)}var y=[];function checkUndefined(e){return hasConstructorOf(e,l)?void 0:e}var f,h=function revivePlainObjects(){var r=[];if(Object.entries(n).forEach((function(e){var t=_slicedToArray(e,2),o=t[0],a=t[1];"#"!==a&&[].concat(a).forEach((function(e){_slicedToArray(p.revivers[e]||[null,{}],2)[1].plain&&(r.push({keypath:o,type:e}),delete n[o])}))})),r.length)return r.sort(nestedPathsFirst).reduce((function reducer(r,n){var o=n.keypath,a=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:o,type:a})}));var i=getByKeyPath(t,o);if(hasConstructorOf(i=executeReviver(a,i),e))return i.then((function(e){var r=setAtKeyPath(t,o,e);r===e&&(t=r)}));var c=setAtKeyPath(t,o,i);c===i&&(t=c)}),void 0)}();return hasConstructorOf(h,e)?f=h.then((function(){return t})):(f=function _revive(t,r,o,s,p){if(!u||"$types"!==t){var f=n[t],h=i(r);if(h||isPlainObject(r)){var v=h?new Array(r.length):{};for(a(r).forEach((function(n){var a=_revive(t+(t?".":"")+escapeKeyPathComponent(n),r[n],o||v,v,n),i=function set(e){return hasConstructorOf(e,l)?v[n]=void 0:void 0!==e&&(v[n]=e),e};hasConstructorOf(a,e)?y.push(a.then((function(e){return i(e)}))):i(a)})),r=v;c.length;){var b=_slicedToArray(c[0],4),d=b[0],_=b[1],O=b[2],j=b[3],m=getByKeyPath(d,_);if(void 0===m)break;O[j]=m,c.splice(0,1)}}if(!f)return r;if("#"===f){var S=getByKeyPath(o,r.slice(1));return void 0===S&&c.push([o,r.slice(1),s,p]),S}return[].concat(f).reduce((function reducer(t,r){return hasConstructorOf(t,e)?t.then((function(e){return reducer(e,r)})):executeReviver(r,t)}),r)}}("",t,null),y.length&&(f=e.resolve(f).then((function(t){return e.all([t].concat(y))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(f)?o&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(f,e)?f.p.then(checkUndefined):f:!o&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():o?checkUndefined(f):Promise.resolve(checkUndefined(f))}},{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;t=t||{};var n=function R(e){i(e)?e.forEach((function(e){return R(e)})):e&&a(e).forEach((function(n){if("#"===n)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(p.includes(n))throw new TypeError("Plain JSON object types are reserved as type names");var o=e[n],a=o&&o.testPlainObjects?r.plainObjectReplacers:r.nonplainObjectReplacers,c=a.filter((function(e){return e.type===n}));if(c.length&&(a.splice(a.indexOf(c[0]),1),delete r.revivers[n],delete r.types[n]),"function"==typeof o){var s=o;o={test:function test(e){return e&&e.constructor===s},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(s.prototype),e)}}}else if(i(o)){var u=_slicedToArray(o,3);o={test:u[0],replace:u[1],revive:u[2]}}if(o&&o.test){var l={type:n,test:o.test.bind(o)};o.replace&&(l.replace=o.replace.bind(o)),o.replaceAsync&&(l.replaceAsync=o.replaceAsync.bind(o));var y="number"==typeof t.fallback?t.fallback:t.fallback?0:Number.POSITIVE_INFINITY;if(o.testPlainObjects?r.plainObjectReplacers.splice(y,0,l):r.nonplainObjectReplacers.splice(y,0,l),o.revive||o.reviveAsync){var f={};o.revive&&(f.revive=o.revive.bind(o)),o.reviveAsync&&(f.reviveAsync=o.reviveAsync.bind(o)),r.revivers[n]=[f,{plain:o.testPlainObjects}]}r.types[n]=o}}))};return[].concat(e).forEach((function(e){return n(e)})),this}}]),Typeson}(),l=_createClass((function Undefined(){_classCallCheck(this,Undefined)}));l.__typeson__type__="TypesonUndefined";var p=["null","boolean","number","string","array","object"];export{p as JSON_TYPES,u as Typeson,e as TypesonPromise,l as Undefined,escapeKeyPathComponent,getByKeyPath,getJSONType,hasConstructorOf,isObject,isPlainObject,isThenable,isUserObject,setAtKeyPath,toStringTag,unescapeKeyPathComponent};

@@ -7,5 +7,31 @@ (function (global, factory) {

function _iterableToArrayLimit(arr, i) {
var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];
if (null != _i) {
var _s,
_e,
_x,
_r,
_arr = [],
_n = !0,
_d = !1;
try {
if (_x = (_i = _i.call(arr)).next, 0 === i) {
if (Object(_i) !== _i) return;
_n = !1;
} else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);
} catch (err) {
_d = !0, _e = err;
} finally {
try {
if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return;
} finally {
if (_d) throw _e;
}
}
return _arr;
}
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {

@@ -17,6 +43,4 @@ var symbols = Object.getOwnPropertySymbols(object);

}
return keys;
}
function _objectSpread2(target) {

@@ -31,6 +55,4 @@ for (var i = 1; i < arguments.length; i++) {

}
return target;
}
function _typeof(obj) {

@@ -45,3 +67,2 @@ "@babel/helpers - typeof";

}
function _classCallCheck(instance, Constructor) {

@@ -52,3 +73,2 @@ if (!(instance instanceof Constructor)) {

}
function _defineProperties(target, props) {

@@ -60,6 +80,5 @@ for (var i = 0; i < props.length; i++) {

if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {

@@ -73,4 +92,4 @@ if (protoProps) _defineProperties(Constructor.prototype, protoProps);

}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {

@@ -86,56 +105,19 @@ Object.defineProperty(obj, key, {

}
return obj;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _iterableToArrayLimit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {

@@ -149,18 +131,27 @@ if (!o) return;

}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
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 _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 _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}

@@ -171,3 +162,2 @@ /**

*/
/**

@@ -177,3 +167,2 @@ * @callback TypesonRejected

*/
/**

@@ -184,3 +173,2 @@ * @callback TypesonResolve

*/
/**

@@ -191,3 +179,2 @@ * @callback TypesonReject

*/
/**

@@ -199,7 +186,5 @@ * @callback TypesonResolveReject

*/
/* eslint-disable block-spacing, space-before-function-paren,
space-before-blocks, space-infix-ops, semi, promise/avoid-new,
jsdoc/require-jsdoc */
/**

@@ -215,3 +200,2 @@ * We keep this function minimized so if using two instances of this

_classCallCheck(this, TypesonPromise);
this.p = new Promise(f);

@@ -224,8 +208,6 @@ });

// class TypesonPromise extends Promise {get[Symbol.toStringTag](){return 'TypesonPromise'};} // eslint-disable-line keyword-spacing, space-before-function-paren, space-before-blocks, block-spacing, semi
TypesonPromise.__typeson__type__ = 'TypesonPromise';
TypesonPromise.__typeson__type__ = 'TypesonPromise'; // Note: core-js-bundle provides a `Symbol` polyfill
// Note: core-js-bundle provides a `Symbol` polyfill
/* istanbul ignore else */
if (typeof Symbol !== 'undefined') {

@@ -235,4 +217,4 @@ // Ensure `isUserObject` will return `false` for `TypesonPromise`

}
/* eslint-disable unicorn/no-thenable -- Desired to be Promise-like */
/**

@@ -244,7 +226,4 @@ *

*/
TypesonPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
return new TypesonPromise(function (typesonResolve, typesonReject) {

@@ -260,2 +239,3 @@ // eslint-disable-next-line promise/catch-or-return

};
/**

@@ -266,4 +246,2 @@ *

*/
TypesonPromise.prototype["catch"] = function (onRejected) {

@@ -277,4 +255,2 @@ return this.then(null, onRejected);

*/
TypesonPromise.resolve = function (v) {

@@ -290,4 +266,2 @@ return new TypesonPromise(function (typesonResolve) {

*/
TypesonPromise.reject = function (v) {

@@ -298,3 +272,2 @@ return new TypesonPromise(function (typesonResolve, typesonReject) {

};
['all', 'race', 'allSettled'].forEach(function (meth) {

@@ -317,6 +290,7 @@ /**

var _ref = {},
toStr = _ref.toString,
hasOwn$1 = {}.hasOwnProperty,
getProto = Object.getPrototypeOf,
fnToString = hasOwn$1.toString;
toStr = _ref.toString,
hasOwn$1 = {}.hasOwnProperty,
getProto = Object.getPrototypeOf,
fnToString = hasOwn$1.toString;
/**

@@ -328,6 +302,6 @@ * Second argument not in use internally, but provided for utility.

*/
function isThenable(v, catchCheck) {
return isObject(v) && typeof v.then === 'function' && (!catchCheck || typeof v["catch"] === 'function');
}
/**

@@ -338,7 +312,6 @@ *

*/
function toStringTag(val) {
return toStr.call(val).slice(8, -1);
}
/**

@@ -351,4 +324,2 @@ * This function is dependent on both constructors

*/
function hasConstructorOf(a, b) {

@@ -358,30 +329,24 @@ if (!a || _typeof(a) !== 'object') {

}
var proto = getProto(a);
if (!proto) {
return b === null;
}
var Ctor = hasOwn$1.call(proto, 'constructor') && proto.constructor;
if (typeof Ctor !== 'function') {
return b === null;
}
if (b === Ctor) {
return true;
}
if (b !== null && fnToString.call(Ctor) === fnToString.call(b)) {
return true;
} // eslint-disable-next-line sonarjs/prefer-single-boolean-return -- Cleaner
}
// eslint-disable-next-line sonarjs/prefer-single-boolean-return -- Cleaner
if (typeof b === 'function' && typeof Ctor.__typeson__type__ === 'string' && Ctor.__typeson__type__ === b.__typeson__type__) {
return true;
}
return false;
}
/**

@@ -392,4 +357,2 @@ *

*/
function isPlainObject(val) {

@@ -400,5 +363,3 @@ // Mirrors jQuery's

}
var proto = getProto(val);
if (!proto) {

@@ -408,5 +369,5 @@ // `Object.create(null)`

}
return hasConstructorOf(val, Object);
}
/**

@@ -417,4 +378,2 @@ *

*/
function isUserObject(val) {

@@ -424,5 +383,3 @@ if (!val || toStringTag(val) !== 'Object') {

}
var proto = getProto(val);
if (!proto) {

@@ -432,5 +389,5 @@ // `Object.create(null)`

}
return hasConstructorOf(val, Object) || isUserObject(proto);
}
/**

@@ -441,7 +398,6 @@ *

*/
function isObject(v) {
return v && _typeof(v) === 'object';
}
/**

@@ -452,7 +408,6 @@ *

*/
function escapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~/g, '~0').replace(/\./g, '~1');
return keyPathComponent.replaceAll("''", "''''").replace(/^$/, "''").replace(/~/g, '~0').replace(/\./g, '~1');
}
/**

@@ -463,7 +418,6 @@ *

*/
function unescapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~');
return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~').replace(/^''$/, '').replaceAll("''''", "''");
}
/**

@@ -474,4 +428,2 @@ * @param {PlainObject|GenericArray} obj

*/
function getByKeyPath(obj, keyPath) {

@@ -481,5 +433,3 @@ if (keyPath === '') {

}
var period = keyPath.indexOf('.');
if (period > -1) {

@@ -489,5 +439,5 @@ var innerObj = obj[unescapeKeyPathComponent(keyPath.slice(0, period))];

}
return obj[unescapeKeyPathComponent(keyPath)];
}
/**

@@ -500,4 +450,2 @@ *

*/
function setAtKeyPath(obj, keyPath, value) {

@@ -507,5 +455,3 @@ if (keyPath === '') {

}
var period = keyPath.indexOf('.');
if (period > -1) {

@@ -515,6 +461,6 @@ var innerObj = obj[unescapeKeyPathComponent(keyPath.slice(0, period))];

}
obj[unescapeKeyPathComponent(keyPath)] = value;
return obj;
}
/**

@@ -526,4 +472,2 @@ *

*/
function getJSONType(value) {

@@ -537,14 +481,12 @@ return value === null ? 'null' : Array.isArray(value) ? 'array' : _typeof(value);

}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
var keys = Object.keys,
isArray = Array.isArray,
hasOwn = {}.hasOwnProperty,
internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric'];
var keys = Object.keys,
isArray = Array.isArray,
hasOwn = {}.hasOwnProperty,
internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric'];
/**

@@ -564,3 +506,2 @@ * Handle plain object revivers first so reference setting can use

}
try {

@@ -572,9 +513,8 @@ return Promise.resolve(f.apply(this, args));

};
}
/**
* @callback Tester
* @param {any} value
* @param {StateObject} stateobj
* @returns {boolean}
*/
} /**
* @callback Tester
* @param {any} value
* @param {StateObject} stateobj
* @returns {boolean}
*/

@@ -610,13 +550,9 @@ /**

function _invoke(body, then) {
var result = body();
if (result && result.then) {
return result.then(then);
}
return then(result);
}
function nestedPathsFirst(a, b) {

@@ -626,17 +562,12 @@ if (a.keypath === '') {

}
var as = a.keypath.match(/\./g) || 0;
var bs = b.keypath.match(/\./g) || 0;
if (as) {
as = as.length;
}
if (bs) {
bs = bs.length;
}
return as > bs ? -1 : as < bs ? 1 : a.keypath < b.keypath ? -1 : a.keypath > b.keypath;
}
var Typeson = /*#__PURE__*/function () {

@@ -648,15 +579,17 @@ /**

_classCallCheck(this, Typeson);
this.options = options;
this.options = options; // Replacers signature: replace (value). Returns falsy if not
// Replacers signature: replace (value). Returns falsy if not
// replacing. Otherwise ['Date', value.getTime()]
this.plainObjectReplacers = [];
this.nonplainObjectReplacers = [];
this.plainObjectReplacers = [];
this.nonplainObjectReplacers = []; // Revivers: [{type => reviver}, {plain: boolean}].
// Revivers: [{type => reviver}, {plain: boolean}].
// Sample: [{'Date': value => new Date(value)}, {plain: false}]
this.revivers = {};
this.revivers = {};
/** Types registered via `register()`. */
this.types = {};
}
/**

@@ -684,4 +617,2 @@ * @typedef {null|boolean|number|string|GenericArray|PlainObject} JSON

*/
_createClass(Typeson, [{

@@ -694,7 +625,5 @@ key: "stringify",

var encapsulated = this.encapsulate(obj, null, opts);
if (isArray(encapsulated)) {
return JSON.stringify(encapsulated[0], replacer, space);
}
return encapsulated.then(function (res) {

@@ -704,2 +633,3 @@ return JSON.stringify(res, replacer, space);

}
/**

@@ -713,3 +643,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -724,2 +653,3 @@ key: "stringifySync",

}
/**

@@ -733,3 +663,2 @@ *

*/
}, {

@@ -744,2 +673,3 @@ key: "stringifyAsync",

}
/**

@@ -761,3 +691,2 @@ * @callback JSONReviver

*/
}, {

@@ -771,2 +700,3 @@ key: "parse",

}
/**

@@ -780,3 +710,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -798,3 +727,2 @@ key: "parseSync",

*/
}, {

@@ -809,2 +737,3 @@ key: "parseAsync",

}
/**

@@ -821,3 +750,2 @@ * @typedef {} StateObject

*/
}, {

@@ -830,2 +758,3 @@ key: "specialTypeNames",

}
/**

@@ -838,3 +767,2 @@ *

*/
}, {

@@ -847,2 +775,3 @@ key: "rootTypeName",

}
/**

@@ -858,3 +787,2 @@ * Encapsulate a complex object into a plain Object by replacing

*/
}, {

@@ -876,20 +804,16 @@ key: "encapsulate",

var newPromisesData = [];
var _promisesData$splice = promisesData.splice(0, 1),
_promisesData$splice2 = _slicedToArray(_promisesData$splice, 1),
prData = _promisesData$splice2[0];
_promisesData$splice2 = _slicedToArray(_promisesData$splice, 1),
prData = _promisesData$splice2[0];
var _prData = _slicedToArray(prData, 7),
keyPath = _prData[0],
cyclic = _prData[2],
stateObj = _prData[3],
parentObj = _prData[4],
key = _prData[5],
detectedType = _prData[6];
keyPath = _prData[0],
cyclic = _prData[2],
stateObj = _prData[3],
parentObj = _prData[4],
key = _prData[5],
detectedType = _prData[6];
var encaps = _encapsulate(keyPath, promResult, cyclic, stateObj, newPromisesData, true, detectedType);
var isTypesonPromise = hasConstructorOf(encaps, TypesonPromise); // Handle case where an embedded custom type itself
var isTypesonPromise = hasConstructorOf(encaps, TypesonPromise);
// Handle case where an embedded custom type itself
// returns a `TypesonPromise`
return _invoke(function () {

@@ -899,5 +823,3 @@ if (keyPath && isTypesonPromise) {

parentObj[key] = encaps2;
var _checkPromises = checkPromises(ret, newPromisesData);
_exit = true;

@@ -909,3 +831,2 @@ return _checkPromises;

if (_exit) return _result;
if (keyPath) {

@@ -925,3 +846,2 @@ parentObj[key] = encaps;

}
return checkPromises(ret, newPromisesData);

@@ -938,3 +858,2 @@ });

*/
/**

@@ -944,3 +863,2 @@ * @callback BuiltinStateObjectPropertiesCallback

*/
/**

@@ -953,4 +871,2 @@ *

*/
opts = _objectSpread2(_objectSpread2({

@@ -960,17 +876,18 @@ sync: true

var _opts = opts,
sync = _opts.sync;
sync = _opts.sync;
var that = this,
types = {},
refObjs = [],
// For checking cyclic references
refKeys = [],
// For checking cyclic references
promisesDataRoot = []; // Clone the object deeply while at the same time replacing any
types = {},
refObjs = [],
// For checking cyclic references
refKeys = [],
// For checking cyclic references
promisesDataRoot = [];
// Clone the object deeply while at the same time replacing any
// special types or cyclic reference:
var cyclic = 'cyclic' in opts ? opts.cyclic : true;
var _opts2 = opts,
encapsulateObserver = _opts2.encapsulateObserver;
encapsulateObserver = _opts2.encapsulateObserver;
var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot);
var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot);
/**

@@ -981,4 +898,2 @@ *

*/
function finish(ret) {

@@ -988,3 +903,2 @@ // Add `$types` to result only if we ever bumped into a

var typeNames = Object.values(types);
if (opts.iterateNone) {

@@ -994,14 +908,13 @@ if (typeNames.length) {

}
return getJSONType(ret);
}
if (typeNames.length) {
if (opts.returnTypeNames) {
return _toConsumableArray(new Set(typeNames));
} // Special if array (or a primitive) was serialized
}
// Special if array (or a primitive) was serialized
// because JSON would ignore custom `$types` prop on it
if (!ret || !isPlainObject(ret) || // Also need to handle if this is an object with its
if (!ret || !isPlainObject(ret) ||
// Also need to handle if this is an object with its
// own `$types` property (to avoid ambiguity)

@@ -1017,4 +930,4 @@ hasOwn.call(ret, '$types')) {

ret.$types = types;
} // No special types
}
// No special types
} else if (isObject(ret) && hasOwn.call(ret, '$types')) {

@@ -1026,10 +939,7 @@ ret = {

}
if (opts.returnTypeNames) {
return false;
}
return ret;
}
function _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, cb) {

@@ -1041,4 +951,4 @@ Object.assign(stateObj, ownKeysObj);

return tmp;
}); // eslint-disable-next-line node/callback-return
});
// eslint-disable-next-line n/callback-return
cb();

@@ -1049,2 +959,3 @@ internalStateObjPropsToIgnore.forEach(function (prop, i) {

}
/**

@@ -1061,10 +972,6 @@ *

*/
function _encapsulate(keypath, value, cyclic, stateObj, promisesData, resolvingTypesonPromise, detectedType) {
var ret;
var observerData = {};
var $typeof = _typeof(value);
var runObserver = encapsulateObserver ? function (obj) {

@@ -1084,7 +991,5 @@ var type = detectedType || stateObj.type || getJSONType(value);

} : null;
if (['string', 'boolean', 'number', 'undefined'].includes($typeof)) {
if (value === undefined || Number.isNaN(value) || value === Number.NEGATIVE_INFINITY || value === Number.POSITIVE_INFINITY) {
ret = stateObj.replaced ? value : replace(keypath, value, stateObj, promisesData, false, resolvingTypesonPromise, runObserver);
if (ret !== value) {

@@ -1098,10 +1003,7 @@ observerData = {

}
if (runObserver) {
runObserver();
}
return ret;
}
if (value === null) {

@@ -1111,6 +1013,4 @@ if (runObserver) {

}
return value;
}
if (cyclic && !stateObj.iterateIn && !stateObj.iterateUnsetNumeric && value && _typeof(value) === 'object') {

@@ -1120,3 +1020,2 @@ // Options set to detect cyclic references and be able

var refIndex = refObjs.indexOf(value);
if (refIndex < 0) {

@@ -1129,3 +1028,2 @@ if (cyclic === true) {

types[keypath] = '#';
if (runObserver) {

@@ -1136,16 +1034,16 @@ runObserver({

}
return '#' + refKeys[refIndex];
}
}
var isPlainObj = isPlainObject(value);
var isArr = isArray(value);
var replaced = // Running replace will cause infinite loop as will test
var replaced =
// Running replace will cause infinite loop as will test
// positive again
(isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn // Optimization: if plain object and no plain-object
(isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn
// Optimization: if plain object and no plain-object
// replacers, don't try finding a replacer
? value : replace(keypath, value, stateObj, promisesData, isPlainObj || isArr, null, runObserver);
var clone;
if (replaced !== value) {

@@ -1169,7 +1067,5 @@ ret = replaced;

clone = {};
if (stateObj.addLength) {
clone.length = value.length;
}
observerData = {

@@ -1186,12 +1082,10 @@ clone: clone

}
if (opts.iterateNone) {
return clone || ret;
}
if (!clone) {
return ret;
} // Iterate object or array
}
// Iterate object or array
if (stateObj.iterateIn) {

@@ -1202,8 +1096,5 @@ var _loop = function _loop(key) {

};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key);
var val = _encapsulate(kp, value[key], Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1216,3 +1107,2 @@ promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, key, stateObj.type]);

};
// eslint-disable-next-line guard-for-in

@@ -1222,3 +1112,2 @@ for (var key in value) {

}
if (runObserver) {

@@ -1240,6 +1129,4 @@ runObserver({

};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, value[key], Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1252,3 +1139,2 @@ promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, key, stateObj.type]);

});
if (runObserver) {

@@ -1260,10 +1146,8 @@ runObserver({

}
} // Iterate array for non-own numeric properties (we can't
}
// Iterate array for non-own numeric properties (we can't
// replace the prior loop though as it iterates non-integer
// keys)
if (stateObj.iterateUnsetNumeric) {
var vl = value.length;
var _loop2 = function _loop2(i) {

@@ -1276,6 +1160,4 @@ if (!(i in value)) {

};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, undefined, Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1289,7 +1171,5 @@ promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, i, stateObj.type]);

};
for (var i = 0; i < vl; i++) {
_loop2(i);
}
if (runObserver) {

@@ -1302,5 +1182,5 @@ runObserver({

}
return clone;
}
/**

@@ -1351,4 +1231,2 @@ * @typedef {PlainObject} KeyPathEvent

*/
function replace(keypath, value, stateObj, promisesData, plainObject, resolvingTypesonPromise, runObserver) {

@@ -1358,9 +1236,6 @@ // Encapsulate registered types

var i = replacers.length;
while (i--) {
var replacer = replacers[i];
if (replacer.test(value, stateObj)) {
var type = replacer.type;
if (that.revivers[type]) {

@@ -1373,8 +1248,7 @@ // Record the type only if a corresponding reviver

// the need to revive it.
var existing = types[keypath]; // type can comprise an array of types (see test
var existing = types[keypath];
// type can comprise an array of types (see test
// "should support intermediate types")
types[keypath] = existing ? [type].concat(existing) : type;
}
Object.assign(stateObj, {

@@ -1384,3 +1258,2 @@ type: type,

});
if ((sync || !replacer.replaceAsync) && !replacer.replace) {

@@ -1392,6 +1265,4 @@ if (runObserver) {

}
return _encapsulate(keypath, value, cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);
}
if (runObserver) {

@@ -1401,6 +1272,6 @@ runObserver({

});
} // Now, also traverse the result in case it contains its
}
// Now, also traverse the result in case it contains its
// own types to replace
var replaceMethod = sync || !replacer.replaceAsync ? 'replace' : 'replaceAsync';

@@ -1410,6 +1281,4 @@ return _encapsulate(keypath, replacer[replaceMethod](value, stateObj), cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);

}
return value;
}
return promisesDataRoot.length ? sync && opts.throwOnBadSyncType ? function () {

@@ -1419,3 +1288,4 @@ throw new TypeError('Sync method requested but async result obtained');

throw new TypeError('Async method requested but sync result obtained');
}() // If this is a synchronous request for stringification, yet
}()
// If this is a synchronous request for stringification, yet
// a promise is the result, we don't want to resolve leading

@@ -1426,2 +1296,3 @@ // to an async result, so we return an array to avoid

}
/**

@@ -1434,3 +1305,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -1445,2 +1315,3 @@ key: "encapsulateSync",

}
/**

@@ -1452,3 +1323,2 @@ * @param {any} obj

*/
}, {

@@ -1463,2 +1333,3 @@ key: "encapsulateAsync",

}
/**

@@ -1475,18 +1346,17 @@ * Revive an encapsulated object.

*/
}, {
key: "revive",
value: function revive(obj, opts) {
var types = obj && obj.$types; // No type info added. Revival not needed.
var types = obj && obj.$types;
// No type info added. Revival not needed.
if (!types) {
return obj;
} // Object happened to have own `$types` property but with
}
// Object happened to have own `$types` property but with
// no actual types, so we unescape and return that object
if (types === true) {
return obj.$;
}
opts = _objectSpread2(_objectSpread2({

@@ -1496,9 +1366,9 @@ sync: true

var _opts3 = opts,
sync = _opts3.sync;
sync = _opts3.sync;
var keyPathResolutions = [];
var stateObj = {};
var ignore$Types = true; // Special when root object is not a trivial Object, it will
var ignore$Types = true;
// Special when root object is not a trivial Object, it will
// be encapsulated in `$`. It will also be encapsulated in
// `$` if it has its own `$` property to avoid ambiguity
if (types.$ && isPlainObject(types.$)) {

@@ -1509,4 +1379,4 @@ obj = obj.$;

}
var that = this;
var that = this;
/**

@@ -1526,16 +1396,14 @@ * @callback RevivalReducer

*/
function executeReviver(type, val) {
var _ref = that.revivers[type] || [],
_ref2 = _slicedToArray(_ref, 1),
reviver = _ref2[0];
_ref2 = _slicedToArray(_ref, 1),
reviver = _ref2[0];
if (!reviver) {
throw new Error('Unregistered type: ' + type);
} // Only `sync` expected here, as problematic async would
}
// Only `sync` expected here, as problematic async would
// be missing both `reviver` and `reviverAsync`, and
// encapsulation shouldn't have added types, so
// should have made an early exit
if (sync && !('revive' in reviver)) {

@@ -1545,5 +1413,5 @@ // Just return value as is

}
return reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj);
}
/**

@@ -1553,4 +1421,2 @@ *

*/
function revivePlainObjects() {

@@ -1562,5 +1428,4 @@ // const references = [];

var _ref4 = _slicedToArray(_ref3, 2),
keypath = _ref4[0],
type = _ref4[1];
keypath = _ref4[0],
type = _ref4[1];
if (type === '#') {

@@ -1575,8 +1440,6 @@ /*

}
[].concat(type).forEach(function (type) {
var _ref5 = that.revivers[type] || [null, {}],
_ref6 = _slicedToArray(_ref5, 2),
plain = _ref6[1].plain;
_ref6 = _slicedToArray(_ref5, 2),
plain = _ref6[1].plain;
if (!plain) {

@@ -1586,3 +1449,2 @@ // reviveTypes.push({keypath, type});

}
plainObjectTypes.push({

@@ -1598,4 +1460,5 @@ keypath: keypath,

return undefined;
} // console.log(plainObjectTypes.sort(nestedPathsFirst));
}
// console.log(plainObjectTypes.sort(nestedPathsFirst));
/**

@@ -1606,8 +1469,5 @@ * @typedef {PlainObject} PlainObjectType

*/
return plainObjectTypes.sort(nestedPathsFirst).reduce(function reducer(possibleTypesonPromise, _ref7) {
var keypath = _ref7.keypath,
type = _ref7.type;
type = _ref7.type;
if (isThenable(possibleTypesonPromise)) {

@@ -1620,29 +1480,23 @@ return possibleTypesonPromise.then(function (val) {

});
} // console.log('obj', JSON.stringify(keypath), obj);
}
// console.log('obj', JSON.stringify(keypath), obj);
var val = getByKeyPath(obj, keypath);
val = executeReviver(type, val);
if (hasConstructorOf(val, TypesonPromise)) {
return val.then(function (v) {
var newVal = setAtKeyPath(obj, keypath, v);
if (newVal === v) {
obj = newVal;
}
return undefined;
});
}
var newVal = setAtKeyPath(obj, keypath, val);
if (newVal === val) {
obj = newVal;
}
return undefined;
}, undefined // This argument must be explicit
); // references.forEach(({keypath, reference}) => {});
);
// references.forEach(({keypath, reference}) => {});
// reviveTypes.sort(nestedPathsFirst).forEach(() => {});

@@ -1661,3 +1515,2 @@ }

*/
function _revive(keypath, value, target, clone, key) {

@@ -1667,14 +1520,10 @@ if (ignore$Types && keypath === '$types') {

}
var type = types[keypath];
var isArr = isArray(value);
if (isArr || isPlainObject(value)) {
// eslint-disable-next-line unicorn/no-new-array -- Sparse
var _clone = isArr ? new Array(value.length) : {}; // Iterate object or array
var _clone = isArr ? new Array(value.length) : {};
// Iterate object or array
keys(value).forEach(function (k) {
var val = _revive(keypath + (keypath ? '.' : '') + escapeKeyPathComponent(k), value[k], target || _clone, _clone, k);
var set = function set(v) {

@@ -1686,6 +1535,4 @@ if (hasConstructorOf(v, Undefined)) {

}
return v;
};
if (hasConstructorOf(val, TypesonPromise)) {

@@ -1699,14 +1546,13 @@ revivalPromises.push(val.then(function (ret) {

});
value = _clone; // Try to resolve cyclic reference as soon as available
value = _clone;
// Try to resolve cyclic reference as soon as available
while (keyPathResolutions.length) {
var _keyPathResolutions$ = _slicedToArray(keyPathResolutions[0], 4),
_target = _keyPathResolutions$[0],
keyPath = _keyPathResolutions$[1],
_clone2 = _keyPathResolutions$[2],
k = _keyPathResolutions$[3];
var val = getByKeyPath(_target, keyPath); // Typeson.Undefined not expected here as not cyclic or
_target = _keyPathResolutions$[0],
keyPath = _keyPathResolutions$[1],
_clone2 = _keyPathResolutions$[2],
k = _keyPathResolutions$[3];
var val = getByKeyPath(_target, keyPath);
// Typeson.Undefined not expected here as not cyclic or
// `undefined`
if (val !== undefined) {

@@ -1717,14 +1563,10 @@ _clone2[k] = val;

}
keyPathResolutions.splice(0, 1);
}
}
if (!type) {
return value;
}
if (type === '#') {
var _ret = getByKeyPath(target, value.slice(1));
if (_ret === undefined) {

@@ -1734,7 +1576,6 @@ // Cyclic reference not yet available

}
return _ret;
} // `type` can be an array here
}
// `type` can be an array here
return [].concat(type).reduce(function reducer(val, typ) {

@@ -1747,6 +1588,6 @@ if (hasConstructorOf(val, TypesonPromise)) {

}
return executeReviver(typ, val);
}, value);
}
/**

@@ -1757,11 +1598,7 @@ *

*/
function checkUndefined(retrn) {
return hasConstructorOf(retrn, Undefined) ? undefined : retrn;
}
var possibleTypesonPromise = revivePlainObjects();
var ret;
if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) {

@@ -1773,12 +1610,11 @@ ret = possibleTypesonPromise.then(function () {

ret = _revive('', obj, null);
if (revivalPromises.length) {
// Ensure children resolved
ret = TypesonPromise.resolve(ret).then(function (r) {
return TypesonPromise.all([// May be a TypesonPromise or not
return TypesonPromise.all([
// May be a TypesonPromise or not
r].concat(revivalPromises));
}).then(function (_ref8) {
var _ref9 = _slicedToArray(_ref8, 1),
r = _ref9[0];
r = _ref9[0];
return r;

@@ -1788,3 +1624,2 @@ });

}
return isThenable(ret) ? sync && opts.throwOnBadSyncType ? function () {

@@ -1796,2 +1631,3 @@ throw new TypeError('Sync method requested but async result obtained');

}
/**

@@ -1803,3 +1639,2 @@ * Also sync but throws on non-sync result.

*/
}, {

@@ -1814,2 +1649,3 @@ key: "reviveSync",

}
/**

@@ -1820,3 +1656,2 @@ * @param {any} obj

*/
}, {

@@ -1831,2 +1666,3 @@ key: "reviveAsync",

}
/**

@@ -1845,3 +1681,2 @@ * @typedef {Tester|Replacer|Reviver} Spec

*/
}, {

@@ -1851,5 +1686,3 @@ key: "register",

var _this = this;
opts = opts || {};
var R = function R(typeSpec) {

@@ -1863,3 +1696,2 @@ // Allow arrays of arrays of arrays...

}
typeSpec && keys(typeSpec).forEach(function (typeId) {

@@ -1871,3 +1703,2 @@ if (typeId === '#') {

}
var spec = typeSpec[typeId];

@@ -1878,3 +1709,2 @@ var replacers = spec && spec.testPlainObjects ? _this.plainObjectReplacers : _this.nonplainObjectReplacers;

});
if (existingReplacer.length) {

@@ -1886,3 +1716,2 @@ // Remove existing spec and replace with this one.

}
if (typeof spec === 'function') {

@@ -1904,7 +1733,6 @@ // Support registering just a class without replacer/reviver

var _spec = spec,
_spec2 = _slicedToArray(_spec, 3),
test = _spec2[0],
replace = _spec2[1],
revive = _spec2[2];
_spec2 = _slicedToArray(_spec, 3),
test = _spec2[0],
replace = _spec2[1],
revive = _spec2[2];
spec = {

@@ -1916,7 +1744,5 @@ test: test,

}
if (!spec || !spec.test) {
return;
}
var replacerObj = {

@@ -1926,13 +1752,9 @@ type: typeId,

};
if (spec.replace) {
replacerObj.replace = spec.replace.bind(spec);
}
if (spec.replaceAsync) {
replacerObj.replaceAsync = spec.replaceAsync.bind(spec);
}
var start = typeof opts.fallback === 'number' ? opts.fallback : opts.fallback ? 0 : Number.POSITIVE_INFINITY;
if (spec.testPlainObjects) {

@@ -1942,26 +1764,21 @@ _this.plainObjectReplacers.splice(start, 0, replacerObj);

_this.nonplainObjectReplacers.splice(start, 0, replacerObj);
} // Todo: We might consider a testAsync type
}
// Todo: We might consider a testAsync type
if (spec.revive || spec.reviveAsync) {
var reviverObj = {};
if (spec.revive) {
reviverObj.revive = spec.revive.bind(spec);
}
if (spec.reviveAsync) {
reviverObj.reviveAsync = spec.reviveAsync.bind(spec);
}
_this.revivers[typeId] = [reviverObj, {
plain: spec.testPlainObjects
}];
} // Record to be retrieved via public types property.
}
// Record to be retrieved via public types property.
_this.types[typeId] = spec;
});
};
[].concat(typeSpecSets).forEach(function (typeSpec) {

@@ -1973,3 +1790,2 @@ return R(typeSpec);

}]);
return Typeson;

@@ -1983,10 +1799,9 @@ }();

*/
var Undefined = /*#__PURE__*/_createClass(function Undefined() {
_classCallCheck(this, Undefined);
}); // eslint-disable-line space-before-blocks
Undefined.__typeson__type__ = 'TypesonUndefined';
// The following provide classes meant to avoid clashes with other values
Undefined.__typeson__type__ = 'TypesonUndefined'; // The following provide classes meant to avoid clashes with other values
// Typeson.Undefined is to insist `undefined` should be added

@@ -2014,4 +1829,2 @@ // TypesonPromise is to support async encapsulation/stringification

Object.defineProperty(exports, '__esModule', { value: true });
}));

@@ -1,1 +0,1 @@

!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 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 _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})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}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,n.key,n)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,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)return;var n,o,a=[],i=!0,c=!1;try{for(r=r.call(e);!(i=(n=r.next()).done)&&(a.push(n.value),!t||a.length!==t);i=!0);}catch(e){c=!0,o=e}finally{try{i||null==r.return||r.return()}finally{if(c)throw o}}return a}(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 _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.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}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var t=_createClass((function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)}));t.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&(t.prototype[Symbol.toStringTag]="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(null,e)},t.resolve=function(e){return new t((function(t){t(e)}))},t.reject=function(e){return new t((function(t,r){r(e)}))},["all","race","allSettled"].forEach((function(e){t[e]=function(r){return new t((function(t,n){Promise[e](r.map((function(e){return e&&e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(t,n)}))}}));var r={}.toString,n={}.hasOwnProperty,o=Object.getPrototypeOf,a=n.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return r.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var r=o(e);if(!r)return null===t;var i=n.call(r,"constructor")&&r.constructor;return"function"!=typeof i?null===t:t===i||(null!==t&&a.call(i)===a.call(t)||"function"==typeof t&&"string"==typeof i.__typeson__type__&&i.__typeson__type__===t.__typeson__type__)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!o(e)||hasConstructorOf(e,Object))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~")}function getByKeyPath(e,t){if(""===t)return e;var r=t.indexOf(".");if(r>-1){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;var n=t.indexOf(".");return n>-1?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 r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var i=Object.keys,c=Array.isArray,s={}.hasOwnProperty,u=["type","replaced","iterateIn","iterateUnsetNumeric"];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){if(""===e.keypath)return-1;var r=e.keypath.match(/\./g)||0,n=t.keypath.match(/\./g)||0;return r&&(r=r.length),n&&(n=n.length),r>n?-1:r<n?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var p=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return _createClass(Typeson,[{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 c(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 o=_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 a=!1,i=[],c=_slicedToArray(r.splice(0,1),1),s=_slicedToArray(c[0],7),u=s[0],p=s[2],y=s[3],l=s[4],f=s[5],h=s[6],v=_encapsulate(u,n,p,y,i,!0,h),d=hasConstructorOf(v,t);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(u&&d)return _await(v.p,(function(t){l[f]=t;var r=o(e,i);return a=!0,r}))}),(function(t){return a?t:(u?l[f]=v:e=d?v.p:v,o(e,i))}))})))),(function(){return e}))}))})),a=(n=_objectSpread2(_objectSpread2({sync:!0},this.options),n)).sync,p=this,y={},l=[],f=[],h=[],v=!("cyclic"in n)||n.cyclic,d=n.encapsulateObserver,b=_encapsulate("",e,v,r||{},h);function finish(e){var t=Object.values(y);if(n.iterateNone)return t.length?t[0]:getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!s.call(e,"$types")?e.$types=y:e={$:e,$types:{$:y}}}else isObject(e)&&s.call(e,"$types")&&(e={$:e,$types:!0});return!n.returnTypeNames&&e}function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=u.map((function(t){var r=e[t];return delete e[t],r}));r(),u.forEach((function(t,r){e[t]=n[r]}))}function _encapsulate(e,r,o,a,u,h,v){var b,_={},O=_typeof(r),j=d?function(n){var i=v||a.type||getJSONType(r);d(Object.assign(n||_,{keypath:e,value:r,cyclic:o,stateObj:a,promisesData:u,resolvingTypesonPromise:h,awaitingTypesonPromise:hasConstructorOf(r,t)},{type:i}))}:null;if(["string","boolean","number","undefined"].includes(O))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY?(b=a.replaced?r:replace(e,r,a,u,!1,h,j))!==r&&(_={replaced:b}):b=r,j&&j(),b;if(null===r)return j&&j(),r;if(o&&!a.iterateIn&&!a.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var m=l.indexOf(r);if(!(m<0))return y[e]="#",j&&j({cyclicKeypath:f[m]}),"#"+f[m];!0===o&&(l.push(r),f.push(e))}var g,S=isPlainObject(r),P=c(r),T=(S||P)&&(!p.plainObjectReplacers.length||a.replaced)||a.iterateIn?r:replace(e,r,a,u,S||P,null,j);if(T!==r?(b=T,_={replaced:T}):""===e&&hasConstructorOf(r,t)?(u.push([e,r,o,a,void 0,void 0,a.type]),b=r):P&&"object"!==a.iterateIn||"array"===a.iterateIn?(g=new Array(r.length),_={clone:g}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,t)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!S&&"object"!==a.iterateIn?b=r:(g={},a.addLength&&(g.length=r.length),_={clone:g}),j&&j(),n.iterateNone)return g||b;if(!g)return b;if(a.iterateIn){var w=function _loop(n){var i={ownKeys:s.call(r,n)};_adaptBuiltinStateObjectProperties(a,i,(function(){var i=e+(e?".":"")+escapeKeyPathComponent(n),c=_encapsulate(i,r[n],Boolean(o),a,u,h);hasConstructorOf(c,t)?u.push([i,c,Boolean(o),a,g,n,a.type]):void 0!==c&&(g[n]=c)}))};for(var A in r)w(A);j&&j({endIterateIn:!0,end:!0})}else i(r).forEach((function(n){var i=e+(e?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(a,{ownKeys:!0},(function(){var e=_encapsulate(i,r[n],Boolean(o),a,u,h);hasConstructorOf(e,t)?u.push([i,e,Boolean(o),a,g,n,a.type]):void 0!==e&&(g[n]=e)}))})),j&&j({endIterateOwn:!0,end:!0});if(a.iterateUnsetNumeric){for(var C=r.length,k=function _loop2(n){if(!(n in r)){var i=e+(e?".":"")+n;_adaptBuiltinStateObjectProperties(a,{ownKeys:!1},(function(){var e=_encapsulate(i,void 0,Boolean(o),a,u,h);hasConstructorOf(e,t)?u.push([i,e,Boolean(o),a,g,n,a.type]):void 0!==e&&(g[n]=e)}))}},N=0;N<C;N++)k(N);j&&j({endIterateUnsetNumeric:!0,end:!0})}return g}function replace(e,t,r,n,o,i,c){for(var s=o?p.plainObjectReplacers:p.nonplainObjectReplacers,u=s.length;u--;){var l=s[u];if(l.test(t,r)){var f=l.type;if(p.revivers[f]){var h=y[e];y[e]=h?[f].concat(h):f}return Object.assign(r,{type:f,replaced:!0}),!a&&l.replaceAsync||l.replace?(c&&c({replacing:!0}),_encapsulate(e,l[a||!l.replaceAsync?"replace":"replaceAsync"](t,r),v&&"readonly",r,n,i,f)):(c&&c({typeDetected:!0}),_encapsulate(e,t,v&&"readonly",r,n,i,f))}}return t}return h.length?a&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(o(b,h)).then(finish):!a&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&a?[finish(b)]:a?finish(b):Promise.resolve(finish(b))}},{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=e&&e.$types;if(!n)return e;if(!0===n)return e.$;var o=(r=_objectSpread2(_objectSpread2({sync:!0},this.options),r)).sync,a=[],s={},u=!0;n.$&&isPlainObject(n.$)&&(e=e.$,n=n.$,u=!1);var p=this;function executeReviver(e,t){var r=_slicedToArray(p.revivers[e]||[],1)[0];if(!r)throw new Error("Unregistered type: "+e);return o&&!("revive"in r)?t:r[o&&r.revive?"revive":!o&&r.reviveAsync?"reviveAsync":"revive"](t,s)}var l=[];function checkUndefined(e){return hasConstructorOf(e,y)?void 0:e}var f,h=function revivePlainObjects(){var r=[];if(Object.entries(n).forEach((function(e){var t=_slicedToArray(e,2),o=t[0],a=t[1];"#"!==a&&[].concat(a).forEach((function(e){_slicedToArray(p.revivers[e]||[null,{}],2)[1].plain&&(r.push({keypath:o,type:e}),delete n[o])}))})),r.length)return r.sort(nestedPathsFirst).reduce((function reducer(r,n){var o=n.keypath,a=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:o,type:a})}));var i=getByKeyPath(e,o);if(hasConstructorOf(i=executeReviver(a,i),t))return i.then((function(t){var r=setAtKeyPath(e,o,t);r===t&&(e=r)}));var c=setAtKeyPath(e,o,i);c===i&&(e=c)}),void 0)}();return hasConstructorOf(h,t)?f=h.then((function(){return e})):(f=function _revive(e,r,o,s,p){if(!u||"$types"!==e){var f=n[e],h=c(r);if(h||isPlainObject(r)){var v=h?new Array(r.length):{};for(i(r).forEach((function(n){var a=_revive(e+(e?".":"")+escapeKeyPathComponent(n),r[n],o||v,v,n),i=function set(e){return hasConstructorOf(e,y)?v[n]=void 0:void 0!==e&&(v[n]=e),e};hasConstructorOf(a,t)?l.push(a.then((function(e){return i(e)}))):i(a)})),r=v;a.length;){var d=_slicedToArray(a[0],4),b=d[0],_=d[1],O=d[2],j=d[3],m=getByKeyPath(b,_);if(void 0===m)break;O[j]=m,a.splice(0,1)}}if(!f)return r;if("#"===f){var g=getByKeyPath(o,r.slice(1));return void 0===g&&a.push([o,r.slice(1),s,p]),g}return[].concat(f).reduce((function reducer(e,r){return hasConstructorOf(e,t)?e.then((function(e){return reducer(e,r)})):executeReviver(r,e)}),r)}}("",e,null),l.length&&(f=t.resolve(f).then((function(e){return t.all([e].concat(l))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(f)?o&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(f,t)?f.p.then(checkUndefined):f:!o&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():o?checkUndefined(f):Promise.resolve(checkUndefined(f))}},{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;t=t||{};var n=function R(e){c(e)?e.forEach((function(e){return R(e)})):e&&i(e).forEach((function(n){if("#"===n)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(l.includes(n))throw new TypeError("Plain JSON object types are reserved as type names");var o=e[n],a=o&&o.testPlainObjects?r.plainObjectReplacers:r.nonplainObjectReplacers,i=a.filter((function(e){return e.type===n}));if(i.length&&(a.splice(a.indexOf(i[0]),1),delete r.revivers[n],delete r.types[n]),"function"==typeof o){var s=o;o={test:function test(e){return e&&e.constructor===s},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(s.prototype),e)}}}else if(c(o)){var u=_slicedToArray(o,3);o={test:u[0],replace:u[1],revive:u[2]}}if(o&&o.test){var p={type:n,test:o.test.bind(o)};o.replace&&(p.replace=o.replace.bind(o)),o.replaceAsync&&(p.replaceAsync=o.replaceAsync.bind(o));var y="number"==typeof t.fallback?t.fallback:t.fallback?0:Number.POSITIVE_INFINITY;if(o.testPlainObjects?r.plainObjectReplacers.splice(y,0,p):r.nonplainObjectReplacers.splice(y,0,p),o.revive||o.reviveAsync){var f={};o.revive&&(f.revive=o.revive.bind(o)),o.reviveAsync&&(f.reviveAsync=o.reviveAsync.bind(o)),r.revivers[n]=[f,{plain:o.testPlainObjects}]}r.types[n]=o}}))};return[].concat(e).forEach((function(e){return n(e)})),this}}]),Typeson}(),y=_createClass((function Undefined(){_classCallCheck(this,Undefined)}));y.__typeson__type__="TypesonUndefined";var l=["null","boolean","number","string","array","object"];e.JSON_TYPES=l,e.Typeson=p,e.TypesonPromise=t,e.Undefined=y,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=o(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))},e.setAtKeyPath=setAtKeyPath,e.toStringTag=toStringTag,e.unescapeKeyPathComponent=unescapeKeyPathComponent,Object.defineProperty(e,"__esModule",{value:!0})}));
!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 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 _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 _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}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)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),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 _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,a,i,c=[],s=!0,u=!1;try{if(a=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=a.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&&(i=r.return(),Object(i)!==i))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 _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.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}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _toPropertyKey(e){var t=function _toPrimitive(e,t){if("object"!=typeof e||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}var t=_createClass((function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)}));t.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&(t.prototype[Symbol.toStringTag]="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(null,e)},t.resolve=function(e){return new t((function(t){t(e)}))},t.reject=function(e){return new t((function(t,r){r(e)}))},["all","race","allSettled"].forEach((function(e){t[e]=function(r){return new t((function(t,n){Promise[e](r.map((function(e){return e&&e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(t,n)}))}}));var r={}.toString,n={}.hasOwnProperty,o=Object.getPrototypeOf,a=n.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return r.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var r=o(e);if(!r)return null===t;var i=n.call(r,"constructor")&&r.constructor;return"function"!=typeof i?null===t:t===i||(null!==t&&a.call(i)===a.call(t)||"function"==typeof t&&"string"==typeof i.__typeson__type__&&i.__typeson__type__===t.__typeson__type__)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!o(e)||hasConstructorOf(e,Object))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replaceAll("''","''''").replace(/^$/,"''").replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~").replace(/^''$/,"").replaceAll("''''","''")}function getByKeyPath(e,t){if(""===t)return e;var r=t.indexOf(".");if(r>-1){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;var n=t.indexOf(".");return n>-1?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 r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var i=Object.keys,c=Array.isArray,s={}.hasOwnProperty,u=["type","replaced","iterateIn","iterateUnsetNumeric"];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){if(""===e.keypath)return-1;var r=e.keypath.match(/\./g)||0,n=t.keypath.match(/\./g)||0;return r&&(r=r.length),n&&(n=n.length),r>n?-1:r<n?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var p=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return _createClass(Typeson,[{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 c(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 o=_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 a=!1,i=[],c=_slicedToArray(r.splice(0,1),1),s=_slicedToArray(c[0],7),u=s[0],p=s[2],y=s[3],l=s[4],f=s[5],h=s[6],v=_encapsulate(u,n,p,y,i,!0,h),d=hasConstructorOf(v,t);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(u&&d)return _await(v.p,(function(t){l[f]=t;var r=o(e,i);return a=!0,r}))}),(function(t){return a?t:(u?l[f]=v:e=d?v.p:v,o(e,i))}))})))),(function(){return e}))}))})),a=(n=_objectSpread2(_objectSpread2({sync:!0},this.options),n)).sync,p=this,y={},l=[],f=[],h=[],v=!("cyclic"in n)||n.cyclic,d=n.encapsulateObserver,b=_encapsulate("",e,v,r||{},h);function finish(e){var t=Object.values(y);if(n.iterateNone)return t.length?t[0]:getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!s.call(e,"$types")?e.$types=y:e={$:e,$types:{$:y}}}else isObject(e)&&s.call(e,"$types")&&(e={$:e,$types:!0});return!n.returnTypeNames&&e}function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=u.map((function(t){var r=e[t];return delete e[t],r}));r(),u.forEach((function(t,r){e[t]=n[r]}))}function _encapsulate(e,r,o,a,u,h,v){var b,_={},O=_typeof(r),m=d?function(n){var i=v||a.type||getJSONType(r);d(Object.assign(n||_,{keypath:e,value:r,cyclic:o,stateObj:a,promisesData:u,resolvingTypesonPromise:h,awaitingTypesonPromise:hasConstructorOf(r,t)},{type:i}))}:null;if(["string","boolean","number","undefined"].includes(O))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY?(b=a.replaced?r:replace(e,r,a,u,!1,h,m))!==r&&(_={replaced:b}):b=r,m&&m(),b;if(null===r)return m&&m(),r;if(o&&!a.iterateIn&&!a.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var j=l.indexOf(r);if(!(j<0))return y[e]="#",m&&m({cyclicKeypath:f[j]}),"#"+f[j];!0===o&&(l.push(r),f.push(e))}var g,S=isPlainObject(r),P=c(r),T=(S||P)&&(!p.plainObjectReplacers.length||a.replaced)||a.iterateIn?r:replace(e,r,a,u,S||P,null,m);if(T!==r?(b=T,_={replaced:T}):""===e&&hasConstructorOf(r,t)?(u.push([e,r,o,a,void 0,void 0,a.type]),b=r):P&&"object"!==a.iterateIn||"array"===a.iterateIn?(g=new Array(r.length),_={clone:g}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,t)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!S&&"object"!==a.iterateIn?b=r:(g={},a.addLength&&(g.length=r.length),_={clone:g}),m&&m(),n.iterateNone)return g||b;if(!g)return b;if(a.iterateIn){var w=function _loop(n){var i={ownKeys:s.call(r,n)};_adaptBuiltinStateObjectProperties(a,i,(function(){var i=e+(e?".":"")+escapeKeyPathComponent(n),c=_encapsulate(i,r[n],Boolean(o),a,u,h);hasConstructorOf(c,t)?u.push([i,c,Boolean(o),a,g,n,a.type]):void 0!==c&&(g[n]=c)}))};for(var A in r)w(A);m&&m({endIterateIn:!0,end:!0})}else i(r).forEach((function(n){var i=e+(e?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(a,{ownKeys:!0},(function(){var e=_encapsulate(i,r[n],Boolean(o),a,u,h);hasConstructorOf(e,t)?u.push([i,e,Boolean(o),a,g,n,a.type]):void 0!==e&&(g[n]=e)}))})),m&&m({endIterateOwn:!0,end:!0});if(a.iterateUnsetNumeric){for(var C=r.length,k=function _loop2(n){if(!(n in r)){var i=e+(e?".":"")+n;_adaptBuiltinStateObjectProperties(a,{ownKeys:!1},(function(){var e=_encapsulate(i,void 0,Boolean(o),a,u,h);hasConstructorOf(e,t)?u.push([i,e,Boolean(o),a,g,n,a.type]):void 0!==e&&(g[n]=e)}))}},N=0;N<C;N++)k(N);m&&m({endIterateUnsetNumeric:!0,end:!0})}return g}function replace(e,t,r,n,o,i,c){for(var s=o?p.plainObjectReplacers:p.nonplainObjectReplacers,u=s.length;u--;){var l=s[u];if(l.test(t,r)){var f=l.type;if(p.revivers[f]){var h=y[e];y[e]=h?[f].concat(h):f}return Object.assign(r,{type:f,replaced:!0}),!a&&l.replaceAsync||l.replace?(c&&c({replacing:!0}),_encapsulate(e,l[a||!l.replaceAsync?"replace":"replaceAsync"](t,r),v&&"readonly",r,n,i,f)):(c&&c({typeDetected:!0}),_encapsulate(e,t,v&&"readonly",r,n,i,f))}}return t}return h.length?a&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(o(b,h)).then(finish):!a&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&a?[finish(b)]:a?finish(b):Promise.resolve(finish(b))}},{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=e&&e.$types;if(!n)return e;if(!0===n)return e.$;var o=(r=_objectSpread2(_objectSpread2({sync:!0},this.options),r)).sync,a=[],s={},u=!0;n.$&&isPlainObject(n.$)&&(e=e.$,n=n.$,u=!1);var p=this;function executeReviver(e,t){var r=_slicedToArray(p.revivers[e]||[],1)[0];if(!r)throw new Error("Unregistered type: "+e);return o&&!("revive"in r)?t:r[o&&r.revive?"revive":!o&&r.reviveAsync?"reviveAsync":"revive"](t,s)}var l=[];function checkUndefined(e){return hasConstructorOf(e,y)?void 0:e}var f,h=function revivePlainObjects(){var r=[];if(Object.entries(n).forEach((function(e){var t=_slicedToArray(e,2),o=t[0],a=t[1];"#"!==a&&[].concat(a).forEach((function(e){_slicedToArray(p.revivers[e]||[null,{}],2)[1].plain&&(r.push({keypath:o,type:e}),delete n[o])}))})),r.length)return r.sort(nestedPathsFirst).reduce((function reducer(r,n){var o=n.keypath,a=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:o,type:a})}));var i=getByKeyPath(e,o);if(hasConstructorOf(i=executeReviver(a,i),t))return i.then((function(t){var r=setAtKeyPath(e,o,t);r===t&&(e=r)}));var c=setAtKeyPath(e,o,i);c===i&&(e=c)}),void 0)}();return hasConstructorOf(h,t)?f=h.then((function(){return e})):(f=function _revive(e,r,o,s,p){if(!u||"$types"!==e){var f=n[e],h=c(r);if(h||isPlainObject(r)){var v=h?new Array(r.length):{};for(i(r).forEach((function(n){var a=_revive(e+(e?".":"")+escapeKeyPathComponent(n),r[n],o||v,v,n),i=function set(e){return hasConstructorOf(e,y)?v[n]=void 0:void 0!==e&&(v[n]=e),e};hasConstructorOf(a,t)?l.push(a.then((function(e){return i(e)}))):i(a)})),r=v;a.length;){var d=_slicedToArray(a[0],4),b=d[0],_=d[1],O=d[2],m=d[3],j=getByKeyPath(b,_);if(void 0===j)break;O[m]=j,a.splice(0,1)}}if(!f)return r;if("#"===f){var g=getByKeyPath(o,r.slice(1));return void 0===g&&a.push([o,r.slice(1),s,p]),g}return[].concat(f).reduce((function reducer(e,r){return hasConstructorOf(e,t)?e.then((function(e){return reducer(e,r)})):executeReviver(r,e)}),r)}}("",e,null),l.length&&(f=t.resolve(f).then((function(e){return t.all([e].concat(l))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(f)?o&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(f,t)?f.p.then(checkUndefined):f:!o&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():o?checkUndefined(f):Promise.resolve(checkUndefined(f))}},{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;t=t||{};var n=function R(e){c(e)?e.forEach((function(e){return R(e)})):e&&i(e).forEach((function(n){if("#"===n)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(l.includes(n))throw new TypeError("Plain JSON object types are reserved as type names");var o=e[n],a=o&&o.testPlainObjects?r.plainObjectReplacers:r.nonplainObjectReplacers,i=a.filter((function(e){return e.type===n}));if(i.length&&(a.splice(a.indexOf(i[0]),1),delete r.revivers[n],delete r.types[n]),"function"==typeof o){var s=o;o={test:function test(e){return e&&e.constructor===s},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(s.prototype),e)}}}else if(c(o)){var u=_slicedToArray(o,3);o={test:u[0],replace:u[1],revive:u[2]}}if(o&&o.test){var p={type:n,test:o.test.bind(o)};o.replace&&(p.replace=o.replace.bind(o)),o.replaceAsync&&(p.replaceAsync=o.replaceAsync.bind(o));var y="number"==typeof t.fallback?t.fallback:t.fallback?0:Number.POSITIVE_INFINITY;if(o.testPlainObjects?r.plainObjectReplacers.splice(y,0,p):r.nonplainObjectReplacers.splice(y,0,p),o.revive||o.reviveAsync){var f={};o.revive&&(f.revive=o.revive.bind(o)),o.reviveAsync&&(f.reviveAsync=o.reviveAsync.bind(o)),r.revivers[n]=[f,{plain:o.testPlainObjects}]}r.types[n]=o}}))};return[].concat(e).forEach((function(e){return n(e)})),this}}]),Typeson}(),y=_createClass((function Undefined(){_classCallCheck(this,Undefined)}));y.__typeson__type__="TypesonUndefined";var l=["null","boolean","number","string","array","object"];e.JSON_TYPES=l,e.Typeson=p,e.TypesonPromise=t,e.Undefined=y,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=o(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))},e.setAtKeyPath=setAtKeyPath,e.toStringTag=toStringTag,e.unescapeKeyPathComponent=unescapeKeyPathComponent}));
{
"name": "typeson",
"version": "7.0.2",
"version": "8.0.0",
"description": "Preserves types over JSON, BSON or socket.io",

@@ -49,13 +49,14 @@ "main": "./dist/typeson-commonjs2.min.cjs",

"devDependencies": {
"@babel/core": "^7.17.5",
"@babel/preset-env": "^7.16.11",
"@babel/core": "^7.20.7",
"@babel/preset-env": "^7.20.2",
"@brettz9/eslint-plugin": "^1.0.4",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-terser": "^0.2.1",
"babel-plugin-transform-async-to-promises": "^0.8.18",
"base64-arraybuffer-es6": "^1.0.0",
"c8": "^7.11.0",
"chai": "^4.3.6",
"eslint": "^8.10.0",
"eslint-config-ash-nazg": "32.5.0",
"eslint-config-standard": "^16.0.3",
"c8": "^7.12.0",
"chai": "^4.3.7",
"eslint": "^8.30.0",
"eslint-config-ash-nazg": "34.6.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-array-func": "^3.1.7",

@@ -66,19 +67,19 @@ "eslint-plugin-chai-expect": "^3.0.0",

"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-html": "^6.2.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsdoc": "^37.9.6",
"eslint-plugin-markdown": "^2.2.1",
"eslint-plugin-no-unsanitized": "^4.0.1",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^39.6.4",
"eslint-plugin-markdown": "^3.0.0",
"eslint-plugin-n": "^15.6.0",
"eslint-plugin-no-unsanitized": "^4.0.2",
"eslint-plugin-no-use-extend-native": "^0.5.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-sonarjs": "^0.12.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-sonarjs": "^0.17.0",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-unicorn": "^41.0.0",
"http-server": "^14.1.0",
"mocha": "^9.2.1",
"open-cli": "^7.0.1",
"rollup": "2.69.0",
"rollup-plugin-re": "^1.0.7",
"rollup-plugin-terser": "^7.0.2"
"eslint-plugin-unicorn": "^45.0.2",
"http-server": "^14.1.1",
"mocha": "^10.2.0",
"open-cli": "^7.1.0",
"rollup": "3.8.1",
"rollup-plugin-re": "^1.0.7"
},

@@ -97,4 +98,3 @@ "tonicExample": "var Typeson = require('typeson');\nvar TSON = new Typeson().register(require('typeson-registry/presets/builtin'));\n\nTSON.stringify({foo: new Date()}, null, 2);",

"test": "npm run rollup && npm run eslint && npm run mocha-cov"
},
"readme": "# typeson.js\n\nPreserves types over JSON, BSON or socket.io.\n\n*typeson.js is tiny. 2.6 kb minified. ~1 kb gzipped.*\n\n## Example of how a stringified object can look\n\n```js\nconst objs = [\n {foo: 'bar'},\n // {\"foo\":\"bar\"} (simple types gives plain JSON)\n {foo: new Date()},\n // {\"foo\":1464049031538, \"$types\":{\"foo\":\"Date\"}}\n {foo: new Set([new Date()])},\n // {\"foo\":[1464127925971], \"$types\":{\"foo\":\"Set\",\"foo.0\":\"Date\"}}\n {foo: {sub: /bar/iu}},\n // {\"foo\":{\"sub\":{\"source\":\"bar\",\"flags\":\"i\"}}, \"$types\":{\"foo.sub\":\"RegExp\"}}\n {foo: new Int8Array(3)},\n // {\"foo\":\"AAAA\", \"$types\":{\"foo\":\"Int8Array\"}}\n new Date()\n // {\"$\":1464128478593, \"$types\":{\"$\":{\"\":\"Date\"}}} (special format at root)\n];\n```\n\n## Why?\n\nJSON can only contain strings, numbers, booleans, `null`, arrays and objects. If you want to serialize other types over HTTP, WebSocket, `postMessage()` or other channels, this module makes it possible to serialize any type over channels that normally only accept vanilla objects. Typeson adds a metadata property `$types` to the result that maps each non-trivial property to a type name. (In the case of arrays or encoded primitives, a new object will instead be created with a `$` property that can be preserved by JSON.) The type name is a reference to a registered type specification that you need to have the same on both the stringifying and the parsing side.\n\n## Type Registry\n\n[typeson-registry](https://github.com/dfahlander/typeson-registry) contains encapsulation rules for standard JavaScript types such as `Date`, `Error`, `ArrayBuffer`, etc. Pick the types you need, use a preset or write your own.\n\n```js\nconst typeson = new Typeson().register([\n require('typeson-registry/types/date'),\n require('typeson-registry/types/set'),\n require('typeson-registry/types/regexp'),\n require('typeson-registry/types/typed-arrays')\n]);\n```\nor if you want support for all built-in JavaScript classes:\n```js\nconst typeson = new Typeson().register([\n require('typeson-registry/presets/builtin')\n]);\n```\nThe module `typeson-registry/presets/builtin` is 1.6 kb minified and gzipped and adds support 32 builtin JavaScript types: *Date, RegExp, NaN, Infinity, -Infinity, Set, Map, ArrayBuffer, DataView, Uint8Array, Int8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, Error, SyntaxError, TypeError, RangeError, ReferenceError, EvalError, URIError, InternalError, Intl.Collator, Intl.DateTimeFormat, Intl.NumberFormat, Object String, Object Number and Object Boolean*.\n\n## Compatibility\n\n- Node\n- Browser\n- Worker\n- ES5\n\n## Features\n\n- Can stringify custom and standard ES5 / ES6 classes.\n- Produces standard JSON with an additional `$types` property in case it is needed (or a new object if representing a primitive or array at root).\n- Resolves cyclic references, such as lists of objects where each object has a reference to the list\n- You can register (almost) any type to be stringifiable (serializable) with your typeson instance.\n- Output will be identical to that of `JSON.stringify()` in case your object doesnt contain special types or cyclic references.\n- Type specs may encapsulate its type in other registered types. For example, `ImageData` is encapsulated as `{array: Uint8ClampedArray, width: number, height: number}`, expecting another spec to convert the `Uint8ClampedArray`. With the [builtin](https://github.com/dfahlander/typeson-registry/blob/master/presets/builtin.js) preset this means it's gonna be converted to base64, but with the [socketio](https://github.com/dfahlander/typeson-registry/blob/master/presets/socketio.js) preset, its gonna be converted to an `ArrayBuffer` that is left as-is and streamed binary over the WebSocket channel!\n\n## Limitations\n\nSince typeson has a synchronous API, it cannot encapsulate and revive async types such as `Blob`, `File` or `Observable`. Encapsulating an async object requires to be able to emit streamed content asynchronically. Remoting libraries could however complement typeson with a streaming channel that handles the emitting of stream content. For example, a remoting library could define a typeson rule that encapsulates an [Observable](https://github.com/zenparsing/es-observable) to an id (string or number for example), then starts subscribing to it and emitting the chunks to the peer as they arrive. The peer could revive the id to an observable that when subscribed to, will listen to the channel for chunks destinated to the encapsulated ID.\n\n## Usage\n\n```\nnpm install typeson\n```\n\n```js\n// Require typeson. It's an UMD module so you could also use requirejs\n// or plain script tags.\nconst Typeson = require('typeson');\n\nconst typeson = new Typeson().register({\n Date: [\n (x) => x instanceof Date, // test function\n (d) => d.getTime(), // encapsulator function\n (number) => new Date(number) // reviver function\n ],\n Error: [\n (x) => x instanceof Error, // tester\n (e) => ({name: e.name, message: e.message}), // encapsulator\n (data) => {\n // reviver\n const e = new Error(data.message);\n e.name = data.name;\n return e;\n }\n ],\n SimpleClass // Default rules apply. See \"register (typeSpec)\"\n});\n\nfunction SimpleClass (foo) {\n this.foo = foo;\n}\n\n// Encapsulate to a JSON friendly format:\nconst jsonFriendly = typeson.encapsulate({\n date: new Date(),\n e: new Error('Oops'),\n c: new SimpleClass('bar')\n});\n// Stringify using good old JSON.stringify()\nconst json = JSON.stringify(jsonFriendly, null, 2);\n/*\n{\n \"date\": 1464049031538,\n \"e\": {\n \"name\": \"Error\",\n \"message\": \"Oops\"\n },\n \"c\": {\n \"foo\": \"bar\"\n },\n \"$types\": {\n \"date\": \"Date\",\n \"e\": \"Error\",\n \"c\": \"SimpleClass\"\n }\n}\n*/\n\n// Parse using good old JSON.parse()\nconst parsed = JSON.parse(json);\n// Revive back again:\nconst revived = typeson.revive(parsed);\n```\n\n*The above sample separates Typeson.encapsulate() from JSON.stringify(). Could also have used Typeson.stringify().*\n\n## Environment/Format support\n\n### Use with socket.io\n\nSocket.io can stream `ArrayBuffer`s as real binary data. This is more efficient than encapsulating it in base64/JSON. Typeson can leave certain types, like `ArrayBuffer`, untouched, and leave the stringification / binarization part to other libs (use `Typeson.encapsulate()` and not `Typeson.stringify()`).\n\nWhat socket.io doesn't do though, is preserve `Date`s, `Error`s or your custom types.\n\nSo to get the best of two worlds:\n\n- Register preset 'typeson-registry/presets/socketio' as well as your custom types.\n- Use `Typeson.encapsulate()` to generate an object ready for socket-io `emit()`\n- Use `Typeson.revive()` to revive the encapsulated object at the other end.\n\n```js\nconst Typeson = require('typeson'),\n presetSocketIo = require('typeson-registry/presets/socketio.js');\n\nconst TSON = new Typeson()\n .register(presetSocketIo)\n .register({\n CustomClass: [\n (x) => x instanceof CustomClass,\n (c) => ({foo: c.foo, bar: c.bar}),\n (o) => new CustomClass(o.foo, o.bar)\n ]\n });\n\nconst array = new Float64Array(65536);\narray.fill(42, 0, 65536);\n\nconst data = {\n date: new Date(),\n error: new SyntaxError('Ooops!'),\n array,\n custom: new CustomClass('foo', 'bar')\n};\n\nsocket.emit('myEvent', TSON.encapsulate(data));\n```\n\nThe `encapsulate()` method will not stringify but just traverse the object and return a simpler structure where certain properties are replaced with a substitute. The resulting object will also have a `$types` property containing the type metadata.\n\nPacking it up at the other end:\n\n```js\nsocket.on('myEvent', function (data) {\n const revived = TSON.revive(data);\n // Here we have a true `Date`, `SyntaxError`, `Float64Array`\n // and `Custom` to play with.\n});\n```\n*NOTE: Both peers must have the same types registered.*\n\n### Use with [BSON](https://www.npmjs.com/package/bson)\n\nThe BSON format can serialize object over a binary channel. It supports just the standard JSON types plus `Date`, `Error` and optionally `Function`. You can use Typeson to encapsulate and revive other types as well with BSON as bearer. Use it the same way as shown above with socket.io.\n\n### Use with Worker.postMessage()\n\nWeb Workers have the `onmessage` and `postMessage()` communication channel that has built-in support for transferring structures using the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). It supports `Date`, `ArrayBuffer`and many other standard types, but not `Error`s or your own custom classes. To support `Error` and custom types over web worker channels, register just the types that are needed (`Error`s and your custom types), and then use `Typeson.encapsulate()` before posting a message, and `Typeson.revive()` in the `onmessage` callback.\n\n## API\n\n### constructor ([options])\n\n```js\nconst typeson = new Typeson([options]);\n```\n\nCreates an instance of Typeson, on which you may configure additional types to support, or call `encapsulate()`, `revive()`, `stringify()` or `parse()` on.\n\n#### Arguments\n\n##### options (optional):\n\n```\n{\n cyclic?: boolean, // Default true to allow cyclic objects\n encapsulateObserver?: function, // Default no-op\n sync?: true, // Don't force a promise response regardless of type\n throwOnBadSyncType?: true // Default to throw when mismatch with `TypesonPromise` obtained for sync request or not returned for async\n}\n```\n\n###### `cyclic`: boolean\n\nWhether or not to support cyclic references. Defaults to `true` unless explicitly set to `false`. If this property is `false`, the parsing algorithm becomes a little faster and in case a single object occurs on multiple properties, it will be duplicated in the output (as `JSON.stringify()` would do). If this property is `true`, several instances of same object will only occur once in the generated JSON and other references will just contain a pointer to the single reference.\n\n###### `encapsulateObserver`: object (see description)\n\nFor encapsulations/stringifications, this callback will be executed as objects are iterated and types are detected. An observer might be used to build an interface based on the original object taking advantage of serialized values (the `replaced` property) passed to the observer along the way, even potentially without concern to the actual encapsulated result.\n\n`encapsulateObserver` is passed an object with the following properties:\n\n- `type` - If a type was detected, whether at either the `awaitingTypesonPromise` or\n `resolvingTypesonPromise` stage, this property will indicate the detected type. If\n this is a regular JSON type, its name ('null', 'boolean', 'number', 'string', 'array',\n or 'object') will be reported\n- `keypath` - The keypath at which the observer is reporting.\n- `value` - The original value found at this stage by the observer. (`replaced`, on the other hand, can be consulted to obtain any type replacement value.)\n- `cyclic` - A boolean indicating whether the current state is expecting cyclics. Will be `\"readonly\"` if this iteration is due to a recursive replacement.\n- `stateObj` - The state object at the time of observation.\n- `promisesData` - The promises array.\n- `resolvingTypesonPromise` - A boolean indicating whether or not this observation is occurring at the (Typeson) promise stage.\n- `awaitingTypesonPromise` - Will be `true` if still awaiting the full resolution; this could be ignored or used to set a placeholder.\n\nThe following properties are also present in particular cases:\n- `typeDetected` - Set to `true` when a Typeson-detected type is found but no relevant replacer is present to be performed.\n- `replacing` - Set to `true` preceding a Typeson-detected type replacement. Use this to get at the original object value before encapsulation\n- `clone` - If a plain object or array is found or if `iterateIn` is set, this property holds the clone of that object or array.\n- `replaced` - This property will be set when a type was detected. This value is useful for obtaining the serialization of types.\n- `cyclicKeypath` - Will be present if a cyclic object (including array) were detected; refers to the key path of the prior detected object.\n- `endIterateIn` - Will be `true` if finishing iteration of `in` properties.\n- `endIterateOwn` - Will be `true` if finishing iteration of \"own\" properties.\n- `endIterateUnsetNumeric` - Will be `true` if finishing iteration of unset numeric properties.\n- `end` - Convenience property that will be `true` if `endIterateIn`, `endIterateOwn`, or `endIterateUnsetNumeric` is `true`.\n\n###### `sync`: boolean (Internal property)\n\nTypes can utilize `TypesonPromise` to allow asynchronous encapsulation and stringification.\n\nWhen such a type returns a `TypesonPromise`, a regular `Promise` will be returned to the user.\n\n(This property is used internally for ensuring a regular `Promise` was not intended as the result.\nNote that its resolved value is also recursively checked for types.)\n\nTo ensure that a regular `Promise` is always returned and thereby to allow the same API to be\nused regardless of the types in effect, the `sync` option is set to `false` by the\n`*Async` methods.\n\nNote that this has no bearing on `revive`/`parse` since they can construct any object they\nwish for a return value, including a `Promise`, a stream, etc.\n\n###### `throwOnBadSyncType`: boolean\n\nThe default is to throw when an async result is received from a synchronous method or vice versa.\nThis assures you that you are receiving the intended result type.\n\nThis option can be set to `false`, however, to return the raw synchronous result or the promise, allowing you the least unambiguous results (since you can discern whether a returned `Promise` was\nthe actual result of a revival/parsing or just the inevitable return of using an async method).\n\n#### Sample\n\n```js\nconst Typeson = require('typeson');\nconst typeson = new Typeson()\n .register(require('typeson-registry/presets/builtin'));\n\nconst tson = typeson.stringify(complexObject);\nconsole.log(tson);\nconst obj = typeson.parse(tson);\n```\n\n### Properties\n\n#### `types`\n\nA map between type identifier and type-rules. Same (object-based) structure as passed to `register()`. Use this property if you want to create a new Typeson containing all types from another Typeson.\n\n##### Sample\n\n```js\nconst commonTypeson = new Typeson().register([\n require('typeson-registry/presets/builtin')\n]);\n\nconst myTypeson = new Typeson().register([\n commonTypeson.types, // Derive from commonTypeson\n myOwnSpecificTypes // Add your extra types\n]);\n```\n\n### Instance methods\n\n#### `stringify` (obj, [replacer], [space], [options])\n\n*Initial arguments identical to those of JSON.stringify()*\n\nGenerates JSON based on the given `obj`. Applies `JSON.stringify()` on the result of any relevant `replace` encapsulators.\n\nIf the supplied `obj` has special types or cyclic references, the produced JSON will contain a `$types` property on the root upon which type info relies (a map of keypath to type where the keypath is dot-separated; see `escapeKeyPathComponent` on escaping).\n\nThe `options` object argument can include a setting for `cyclic` which overrides the default or any behavior supplied for this option in the Typeson constructor.\n\nMay also return a `Promise` if a type's `replace` encapsulator returns `TypesonPromise`. See the documentation under `TypesonPromise`.\n\n##### Stringification format\n\nIf enabled, the cyclic \"type\" will be represented as `#` and cyclic references will be encoded as `#` plus the path to the referenced object.\n\nIf an array or primitive is encoded at root, an object will be created with a property `$` and a `$types` property that is an object with `$` as a key and instead of a type string as value, a keypath-type object will be its value (with the empty string indicating the root path).\n\n##### Sample\n\n```js\nconst TSON = new Typeson().register(require('typeson-registry/types/date'));\n\nTSON.stringify({date: new Date()});\n```\nOutput:\n```json\n{\"date\": 1463667643065, \"$types\": {\"date\": \"Date\"}}\n```\n\n#### `stringifySync` (obj, [replacer], [space], [options])\n\nAs with `stringify` but automatically throws upon obtaining a `TypesonPromise` return result from a `replace` encapsulator (as that is expected for asynchronous types).\n\n#### `stringifyAsync` (obj, [replacer], [space], [options])\n\nAs with `stringify` but automatically throws upon obtaining a non-`TypesonPromise` return result from a `replace` encapsulator (as only a `TypesonPromise` is expected for asynchronous types).\n\n#### `parse` (obj, [reviver])\n\n*Arguments identical to those of JSON.parse()*\n\nParses Typeson-generated JSON back into the original complex structure again.\n\nApplies `JSON.parse()` and then any relevant `revive` methods that are detected.\n\nMay also return a `Promise` if a type's reviver returns `TypesonPromise`. See\nthe documentation under `TypesonPromise`.\n\n##### Sample\n\n```js\nconst date = require('typeson-registry/types/date');\n\nconst TSON = new Typeson().register(date);\nTSON.parse('{\"date\": 1463667643065, \"$types\": {\"date\": \"Date\"}}');\n```\n\n#### `parseSync` (obj, [reviver])\n\nAs with `parse` but automatically throws upon obtaining a `TypesonPromise` return result from the reviver (as that is expected for asynchronous types).\n\n#### `parseAsync` (obj, [reviver])\n\nAs with `parse` but automatically throws upon obtaining a non-`TypesonPromise` return result from the reviver (as only a `TypesonPromise` is expected for asynchronous types).\n\n#### `encapsulate` (obj, [stateObj], [opts])\n\nEncapsulates an object but leaves the stringification part to you. Pass your encapsulated object further to socket.io, `postMessage()`, BSON or IndexedDB.\n\nApplies the `replace` method on `test`-matching spec objects. Will return the result regardless\nof whether it is an asynchronous (indicated by a `TypesonPromise`) or synchronous result.\n\nThe `options` object argument can include a setting for `cyclic` which overrides the default or any behavior supplied for this option in the Typeson constructor.\n\n#### `encapsulateSync` (obj, [opts])\n\nAs with `encapsulate` but automatically throws upon obtaining a `TypesonPromise` return result from the replacer (as that is expected for asynchronous types).\n\n#### `encapsulateAsync` (obj, [opts])\n\nAs with `encapsulate` but automatically throws upon obtaining a non-`TypesonPromise` return result from the replacer (as only a `Typeson-Promise` is expected for asynchronous types).\n\n##### Sample\n\n```js\nconst encapsulated = typeson.encapsulate(new Date());\nconst revived = typeson.revive(encapsulated);\nassert(revived instanceof Date);\n```\n\n#### `revive` / `reviveSync` / `reviveAsync` (obj)\n\nRevives an encapsulated object. See `encapsulate()`.\n\n#### `register` (typeSpec, opts = {fallback: boolean|number})\n\nIf `opts.fallback` is set, lower priority will be given (the default is that the last registered item\nhas highest priority during match testing). If a number is given, it will be used as the index of the placement.\n\n##### typeSpec\n\nAn object that maps a type-name to a specification of how to test, encapsulate and revive that type.\n\n`{TypeName => constructor-function | [tester, encapsulator, reviver] | specObject = {test: function, replace: function, replaceAsync: function, revive: function, reviveAsync: function, testPlainObjects: boolean=false}}` or an array of such structures.\n\nPlease note that if an array is supplied, the tester (and upon matching, the encapsulator)\nexecute in a last-in, first out order. (Calls to `register` can set `fallback` to `true` to\nlower the priority of a recent addition.)\n\n`this` will refer to the specification object.\n\nSubsequent calls to `register` will similarly be given higher priority so be sure to add\ncatch-all matchers *before* more precise ones.\n\nIf `testPlainObjects` is set to `true`, a tester will be checked against plain objects and\nallow replacements without recursion.\n\nNote that you can supply `null` as a spec to remove a regular previously\nregistered spec, and supply an object with only `testPlainObjects: true`\nto remove a previously registered spec which can remove a previously\nregistered spec with a plain object replacer.\n\n###### constructor-function\n\nA class (constructor function) that would use default test, encapsulation and revival rules, which is:\n\n- `test`: check if x.constructor === constructor-function.\n- `replace`: copy all enumerable own props into a vanilla object\n- `revive`: Uses `Object.create()` to revive the correct type and copies all properties into it.\n- `testPlainObjects`: `false`: Tests non-plain objects only.\n\n###### `test` (obj : any, stateObj : {ownKeys: boolean, iterateIn: ('array'|'object'), iterateUnsetNumeric: boolean}) : boolean\n\nFunction that tests whether an instance is of your type and returns a truthy value if it is.\n\nIf the context is iteration over non-\"own\" integer string properties of an array (i.e.,\nan absent (`undefined`) item in a sparse array), `ownKeys` will be set to `false`.\nOtherwise, when iterating an object or array, it will be set to `true`. The default\nfor the `stateObj` is just an empty object.\n\nIf you wish to have exceptions thrown upon encountering a certain type of\nvalue, you may leverage the tester to do so.\n\nYou may also set values on the state object.\n\nNormally, only the \"own\" keys of an object will be iterated.\nSetting `iterateIn` changes the behavior to iterate all properties\n\"in\" the object for cloning (though note that doing so will add a\nperformance cost). The value of `iterateIn` (as 'array' or 'object')\ndetermines what type of object will be created. Normally, 'object'\nwill be more useful as non-array-index properties do not\nsurvive stringification on an array.\n\nOne special case not covered by iterating all \"own\" keys or enabling \"in\"\niteration is where one may wish to iterate the keys not \"in\" the object\nbut still part of it, i.e., the unset numeric indexes of a sparse array\n(e.g., for the sake of ensuring they are ignored entirely rather than\nconverted to `null` by a `stringify` call). Thus encapsulators have the\nability to set `iterateUnsetNumeric: true` on their state object, but\nnote that doing so will add a performance cost.\n\n###### `replace` (obj: YourType, stateObj : {ownKeys: boolean, iterateIn: ('array'|'object'), iterateUnsetNumeric: boolean}) : Object\n\nFunction that maps your instance to a JSON-serializable object. Can also be called an\n`encapsulator`. For the `stateObj`, see `tester`. In a property context (for arrays\nor objects), returning `undefined` will prevent the addition of the property.\n\nSee the `tester` for a discussion of the `stateObj`.\n\nNote that replacement results will themselves be recursed for state changes\nand type detection.\n\n###### `replaceAsync` (obj: YourType, stateObj : {ownKeys: boolean, iterateIn: ('array'|'object'), iterateUnsetNumeric: boolean}) : `TypesonPromise`\n\nExpected to return a `TypesonPromise` which resolves to the replaced value.\nSee `replace`.\n\n###### `revive` (obj: Object, stateObj : {}) : YourType\n\nFunction that maps your JSON-serializable object into a real instance of your type.\nIn a property context (for arrays or objects), returning `undefined`\nwill prevent the addition of the property. To explicitly add `undefined`, see\n`Undefined`.\n\n##### Sample\n\n```js\nconst typeson = new Typeson();\n\nfunction CustomType (foo) {\n this.foo = foo;\n}\n\ntypeson.register({\n // simple style - provide just a constructor function.\n // This style works for any trivial js class without hidden closures.\n CustomType,\n\n // Date is native and hides it's internal state.\n // We must define encapsulator and reviver that always works.\n Date: [\n (x) => x instanceof Date, // tester\n (date) => date.getTime(), // encapsulator\n (obj) => new Date(obj) // reviver\n ],\n\n RegExp: [\n (x) = x instanceof RegExp,\n (re) => [re.source, re.flags],\n ([source, flags]) => new RegExp(source, flags)\n ]\n});\n\nconsole.log(typeson.stringify({\n ct: new CustomType('hello'),\n d: new Date(),\n r: /foo/giu\n}));\n// {\"ct\":{\"foo\":\"hello\"},\"d\":1464049031538,\"r\":[\"foo\",\"gi\"],\n// $types:{\"ct\":\"CustomType\",\"d\":\"Date\",\"r\":\"RegExp\"}}\n```\n\n###### `reviveAsync` (obj: Object) : YourType\n\nExpected to return a `TypesonPromise` which resolves to the revived value.\nSee `revive`.\n\n#### `specialTypeNames` (obj, [stateObj], [opts])\n\nThis method returns an array of the unique Typeson type names. To return all\ntype names including JSON type names or duplicates, use an `encapsulateObserver`.\n\n#### `rootTypeName` (obj, [stateObj], [opts])\n\nThis method returns a single type name string of the supplied\nobject at root: a Typeson type if present or a JSON type otherwise.\nThis method avoids iterating whole object/array structures.\n\n### Other exported classes\n\n#### `Undefined` class\n\nDuring encapsulation, `undefined` will not be set for property values,\nof objects or arrays (including sparse ones and replaced values)\n(`undefined` will be converted to `null` if stringified\nanyways). During revival, however, since `undefined` is also used in\nthis context to indicate a value will not be added, if you wish to\nhave an explicit `undefined` added, you can return\n`new Typeson.Undefined()` to ensure a value is set explicitly to\n`undefined`.\n\nThis distinction is used by the `undefined` type in `typeson-registry`\nto allow reconstruction of explicit `undefined` values (and its\n`sparseUndefined` type will ensure that sparse arrays can be\nreconstructed).\n\n#### `TypesonPromise` class\n\nIf you have a type which you wish to have resolved asynchronously, you\ncan can return a `Typeson.Promise` (which works otherwise like a `Promise`)\nand call its first supplied argument (`resolve`) when ready.\n\nThe reason we expect this class to be used here instead of regular `Promise`s\nas types might wish to serialize them in their own manner (or perhaps more\nlikely, to be able to throw when encountering them if they\nare not expected).\n\n##### Sample\n\n```js\nfunction MyAsync (prop) {\n this.prop = prop;\n}\n\nconst typeson = new Typeson({sync: false}).register({\n myAsyncType: [\n function (x) { return x instanceof MyAsync; },\n function (o) {\n return new Typeson.Promise(function (resolve, reject) {\n setTimeout(function () {\n // Do something more useful in real code\n if (Date.now() % 2) {\n reject(new Error('Better luck next time'));\n return;\n }\n resolve(o.prop);\n }, 800);\n });\n },\n function (data) {\n return new MyAsync(data);\n }\n ]\n});\n\nconst mya = new MyAsync(500);\n\n(async () => {\nconst result = await typeson.stringify(mya);\nconst back = typeson.parse(result, null, {sync: true});\nconsole.log(back.prop); // 500\n})();\n```\n\n### Other exported methods\n\n#### `toStringTag`\n\nA simple utility for getting the former ``[[Class]]`` internal slot of an object\n(i.e., The string between `[Object ` and `]` as returned from\n`Object.prototype.toString`) or what is known in HTML as the [\"class string\"](https://heycam.github.io/webidl/#dfn-class-string).\n\nSince [`Symbol.toStringTag`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag)\ncan set the value for other objects and is defined by JavaScript itself, we\nuse that within the method name.\n\nThe method can be used for cross-frame detection of your objects as well\nas objects associated with all\n[platform objects](https://heycam.github.io/webidl/#idl-objects)\n(i.e., non-callback interfaces or `DOMException`s) tied to WebIDL\n(such as the interfaces in HTML). The platform object's [identifier](https://heycam.github.io/webidl/#es-platform-objects) (i.e., the\ninterface name) is, per the WebIDL spec, the string to be returned.\n\nAlthough it is unfortunately not immune to forgery, it may in some\ncases be more appealing than (or usable in addition to) duck typing\nso this tiny utility is bundled for convenience.\n\n#### `hasConstructorOf` (objWithPrototypeConstructor, classToCompare: constructor or null) : boolean\n\nAnother approach for class comparisons involves checking a `constructor`\nfunction and comparing its `toString`. This is required for some classes\nwhich otherwise do not define `toStringTag`s which differ from other\nobjects. The first argument will be an object to check (whose prototoype\nwill be searched for a `constructor` property) whereas the second is a\nclass constructor to compare.\n\nIf no valid `constructor` is found, `false` will be returned unless\n`null` was supplied as the `classToCompare` in which case `true` will\nbe returned when finding a `null` prototype (and `false` otherwise).\n\n#### `isObject` (val)\n\nSimple but frequently-needed type-checking utility for\n`val && typeof val === 'object'` to avoid `null` being treated as an object.\n\n#### `isPlainObject` (val)\n\nChecks for a simple non-inherited object. Adapted from jQuery's `isPlainObject`.\n\n#### `isUserObject` (val)\n\nAllows for inherited objects but ensures the prototype chain inherits from\n`Object` (or `null`).\n\n#### `isThenable` (val, catchCheck=boolean)\n\nChecks whether an object is \"thenable\" (usable as a promise). If the second\nargument is supplied as `true`, it will also ensure it has a `catch` method.\nA regular `Promise` or `TypesonPromise` will return `true`.\n\n#### `escapeKeyPathComponent` (unescapedKeyPathComponent)\n\nEscapes a component of a key path.\n\nDots in property names are escaped as `~1`, and the tilde escape character is\nitself escaped as `~0`.\n\n#### `unescapeKeyPathComponent` (escapedKeyPathComponent)\n\nUnescapes a key path component. See `escapeKeyPathComponent`.\n\n#### `getByKeyPath` (obj, keyPath)\n\nRetrieves a value pointed to by a key path on an object.\n\n#### `getJSONType` (obj)\n\nUtility that returns 'null', 'boolean', 'number', 'string', 'array',\nor 'object' depending on JSON type.\n\n### Exported properties\n\n#### `JSON_TYPES`\n\nSet to the following array of JSON type names.\n\n`['null', 'boolean', 'number', 'string', 'array', 'object']`\n\n## Finding types and groups of types\n\n[typeson-registry](https://github.com/dfahlander/typeson-registry) contains ready-to-use types and presets to register with your Typeson instances.\n"
}
}

@@ -13,15 +13,50 @@ # typeson.js

// {"foo":"bar"} (simple types gives plain JSON)
{foo: new Date()},
// {"foo":1464049031538, "$types":{"foo":"Date"}}
{foo: new Set([new Date()])},
// {"foo":[1464127925971], "$types":{"foo":"Set","foo.0":"Date"}}
{foo: {sub: /bar/iu}},
// {"foo":{"sub":{"source":"bar","flags":"i"}}, "$types":{"foo.sub":"RegExp"}}
{foo: new Int8Array(3)},
// {"foo":"AAAA", "$types":{"foo":"Int8Array"}}
new Date()
// {"$":1464128478593, "$types":{"$":{"":"Date"}}} (special format at root)
new Date(),
// {"$":1464128478593, "$types":{"$":{"":"Date"}}}
// Needs $ escaping for object at root and "" for whole object
{$types: {}},
// {"$":{"$types":{}},"$types":true}
// Needs $ escaping for special "$types"
{$types: {}, abc: new Date()},
// {"$":{"$types":{},"abc":1672338131954},"$types":{"$":{"abc":"Date"}}}
// Needs $ escaping for special "$types"
{'': new Date(), "''": new Date()}
// {"":1672504445626,"''":1672504445626,"$types":{"''":"Date","''''":"Date"}}
// Needs escaping of empty string (as double astrophes) and escaping of double
// apostrophes (doubled apostrophes)
];
```
Or a cyclic array:
```js
const arr = [];
arr[0] = arr;
// {"$":["#"],"$types":{"$":{"0":"#"}}}
```
Or a cyclic object:
```js
const obj = {};
obj[''] = obj;
// {"":"#","$types":{"''":"#"}}
```
## Why?

@@ -612,7 +647,5 @@

(async () => {
const result = await typeson.stringify(mya);
const back = typeson.parse(result, null, {sync: true});
console.log(back.prop); // 500
})();
```

@@ -619,0 +652,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc