serialijse
Advanced tools
Comparing version 0.1.3 to 0.3.0
@@ -9,3 +9,3 @@ { | ||
], | ||
"version": "0.0.17", | ||
"version": "0.1.0", | ||
"homepage": "https://github.com/erossignon/serialijse", | ||
@@ -12,0 +12,0 @@ "authors": [ |
@@ -0,0 +0,0 @@ // var s = require("serialijse"); |
@@ -0,0 +0,0 @@ /*global exports,require*/ |
declare module "serialijse" { | ||
export function serialize<T>(object: T, options?: object): string; | ||
export type IgnoreSpec = string | RegExp | ||
export interface SerializeContext { | ||
index: any[], | ||
objects: any[] | ||
} | ||
export interface SerializeOptions { | ||
ignored?: IgnoreSpec[]|IgnoreSpec | ||
errorHandler?: (context: SerializeContext, options: SerializeOptions, object: any, _throw: () => any) => any; | ||
} | ||
export function serialize<T>(object: T, options?: SerializeOptions): string; | ||
export function deserialize<T>(serializationString: string): T; | ||
@@ -5,0 +17,0 @@ |
(function (exports) { | ||
"use strict"; | ||
var assert = require("assert"); | ||
var b = require("buffer"); | ||
var g_classInfos = {}; | ||
@@ -14,6 +16,6 @@ | ||
function merge_options(options1,options2) { | ||
return objectAssign({},options1, options2); | ||
function merge_options(options1, options2) { | ||
return objectAssign({}, options1, options2); | ||
} | ||
function serializeObject(context, object, rawData , global_options ) { | ||
function serializeObject(context, object, rawData, global_options) { | ||
@@ -26,3 +28,3 @@ assert(!rawData.hasOwnProperty("d")); | ||
if (object.constructor && object.constructor.serialijseOptions) { | ||
options = merge_options(options,object.constructor.serialijseOptions); | ||
options = merge_options(options, object.constructor.serialijseOptions); | ||
} | ||
@@ -36,3 +38,5 @@ if (options.ignored) { | ||
if (object[property] !== null) { | ||
rawData.d[property] = _serialize(context,object[property], options); | ||
rawData.d[property] = _serialize(context, options, object[property]); | ||
} else { | ||
rawData.d[property] = null; | ||
} | ||
@@ -51,2 +55,4 @@ } | ||
var rawData = object_definition.d; | ||
// istanbul ignore next | ||
if (!rawData) { | ||
@@ -59,5 +65,7 @@ return; // no properties | ||
try { | ||
object[property] = deserialize_node_or_value(context,rawData[property]); | ||
object[property] = deserialize_node_or_value(context, rawData[property]); | ||
} | ||
catch (err) { | ||
catch (err) | ||
// istanbul ignore next | ||
{ | ||
console.log(" property : ", property); | ||
@@ -74,4 +82,4 @@ console.log(err); | ||
function serializeTypedArray(context,typedArray,rawData) { | ||
rawData.a = new Buffer(typedArray.buffer).toString("base64"); | ||
function serializeTypedArray(context, typedArray, rawData) { | ||
rawData.a = Buffer.from(typedArray.buffer).toString("base64"); | ||
} | ||
@@ -83,3 +91,3 @@ | ||
assert(typeof rawData.a === "string"); | ||
var buf = Buffer.from(rawData.a,"base64"); | ||
var buf = Buffer.from(rawData.a, "base64"); | ||
var tmp = new Uint8Array(buf); | ||
@@ -92,6 +100,6 @@ var obj = new classInfo.constructor(tmp.buffer); | ||
function deserialize_node_or_value(context,node) { | ||
function deserialize_node_or_value(context, node) { | ||
assert(context); | ||
if ("object" === typeof node) { | ||
return deserialize_node(context,node); | ||
return deserialize_node(context, node); | ||
} | ||
@@ -112,5 +120,8 @@ return node; | ||
// istanbul ignore next | ||
if (g_classInfos.hasOwnProperty(className)) { | ||
console.warn("declarePersistable warning: declarePersistable : class " + className + " already registered"); | ||
} | ||
// istanbul ignore next | ||
if (!(constructor instanceof Function) && !constructor.prototype) { | ||
@@ -130,2 +141,3 @@ throw new Error("declarePersistable: Cannot find constructor for " + className); | ||
// istanbul ignore next | ||
if (!global[typeArrayName]) { | ||
@@ -138,3 +150,4 @@ console.log("warning : " + typeArrayName + " is not supported in this environment"); | ||
// repair constructor name if any | ||
if(!constructor.name) { | ||
// istanbul ignore next | ||
if (!constructor.name) { | ||
constructor.name = typeArrayName; | ||
@@ -151,2 +164,3 @@ } | ||
declareTypedArrayPersistable("Float32Array"); | ||
declareTypedArrayPersistable("Float64Array"); | ||
declareTypedArrayPersistable("Uint32Array"); | ||
@@ -165,3 +179,3 @@ declareTypedArrayPersistable("Uint16Array"); | ||
*/ | ||
function isPropertyPersistable(obj, propertyName ,options) { | ||
function isPropertyPersistable(obj, propertyName, options) { | ||
if (!obj.hasOwnProperty(propertyName)) { | ||
@@ -191,3 +205,3 @@ return false; | ||
function find_object(context,obj) { | ||
function find_object(context, obj) { | ||
if (obj.____index !== undefined) { | ||
@@ -209,19 +223,115 @@ assert(context.objects[obj.____index] === obj); | ||
function extract_object_classname(object) { | ||
var className = object.constructor.name; | ||
var className = object.constructor.name; | ||
if (className) { | ||
return className; | ||
} | ||
if(object instanceof Float32Array) { return "Float32Array"; } | ||
if(object instanceof Uint32Array) { return "Uint32Array"; } | ||
if(object instanceof Uint16Array) { return "Uint16Array"; } | ||
if(object instanceof Uint8Array) { return "Uint8Array"; } | ||
if(object instanceof Int32Array) { return "Int32Array"; } | ||
if(object instanceof Int16Array) { return "Int16Array"; } | ||
if(object instanceof Int8Array) { return "Int8Array"; } | ||
/* in some old version of node className could be null */ | ||
// istanbul ignore next | ||
if (true) { | ||
if (object instanceof Float32Array) { return "Float32Array"; } | ||
if (object instanceof Uint32Array) { return "Uint32Array"; } | ||
if (object instanceof Uint16Array) { return "Uint16Array"; } | ||
if (object instanceof Uint8Array) { return "Uint8Array"; } | ||
if (object instanceof Int32Array) { return "Int32Array"; } | ||
if (object instanceof Int16Array) { return "Int16Array"; } | ||
if (object instanceof Int8Array) { return "Int8Array"; } | ||
} | ||
} | ||
function _serialize_object(context, serializingObject, object , options) { | ||
function _serialize_xxx(context, options, object, construct, serialize) { | ||
// check if the object has already been serialized | ||
let id = find_object(context, object); | ||
if (id === -1) { | ||
const stuff = construct(); | ||
id = add_object_in_index(context, object, stuff); | ||
serialize(context, object, stuff, options); | ||
} | ||
return id; | ||
} | ||
function _deserialize_xxx(context, object_id, contruct, deserialize) { | ||
assert(object_id); | ||
// check if this object has already been de-serialized | ||
if (context.cache[object_id] !== undefined) { | ||
return context.cache[object_id]; | ||
} | ||
const newStuff = contruct(); | ||
context.cache[object_id] = newStuff; | ||
const serializing_data = context.index[object_id]; | ||
deserialize(context, newStuff, serializing_data); | ||
return newStuff; | ||
} | ||
function _serialize_map(context, options, object) { | ||
return _serialize_xxx(context, options, object, | ||
() => [], | ||
(context, object, mapJson, options) => { | ||
for (const [key, value] of object.entries()) { | ||
mapJson.push([ | ||
_serialize(context, options, key), | ||
_serialize(context, options, value), | ||
]) | ||
} | ||
}); | ||
} | ||
function _deserialize_map(context, object_id) { | ||
return _deserialize_xxx(context, object_id, | ||
() => new Map(), | ||
(context, newMap, serializing_data) => { | ||
for (const [key, value] of serializing_data) { | ||
const k = deserialize_node_or_value(context, key); | ||
const v = deserialize_node_or_value(context, value); | ||
newMap.set(k, v); | ||
} | ||
}) | ||
} | ||
function _serialize_set(context, options, object) { | ||
return _serialize_xxx(context, options, object, | ||
() => [], | ||
(context, object, setJson, options) => { | ||
for (const value of object.values()) { | ||
setJson.push(_serialize(context, options, value)) | ||
} | ||
}); | ||
} | ||
function _deserialize_set(context, object_id) { | ||
return _deserialize_xxx(context, object_id, | ||
() => new Set(), | ||
(context, newSet, serializing_data) => { | ||
for (const value of serializing_data) { | ||
const v = deserialize_node_or_value(context, value); | ||
newSet.add(v) | ||
} | ||
}) | ||
} | ||
function _serialize_basic_object(context, options, object) { | ||
const className = extract_object_classname(object); | ||
// istanbul ignore next | ||
if (className !== "Object" && !g_classInfos.hasOwnProperty(className)) { | ||
console.log(object); | ||
throw new Error("class " + className + " is not registered in class Factory - deserialization will not be possible"); | ||
} | ||
return _serialize_xxx(context, options, object, | ||
() => ({ c: className }), | ||
(context, object, s, options) => | ||
g_classInfos[className].serializeFunc(context, object, s, options)); | ||
} | ||
function _deserialize_basic_object(context, object_id) { | ||
if (object_id === null) { | ||
return null; | ||
} | ||
// check if this object has already been de-serialized | ||
if (context.cache[object_id] !== undefined) { | ||
return context.cache[object_id]; | ||
} | ||
var serializing_data = context.index[object_id]; | ||
var cache_object = _deserialize_object(context, serializing_data, object_id); | ||
assert(context.cache[object_id] === cache_object); | ||
return cache_object; | ||
} | ||
function _serialize_object(context, options, serializingObject, object) { | ||
assert(context); | ||
assert(object !== undefined); | ||
if (object === null) { | ||
@@ -231,6 +341,4 @@ serializingObject.o = null; | ||
} | ||
const className = extract_object_classname(object); | ||
var className =extract_object_classname(object), s, id; | ||
// j => json object to follow | ||
@@ -242,33 +350,22 @@ // d => date | ||
// @ => already serialized object | ||
// s => Set | ||
// m => Map | ||
if (className === "Array") { | ||
serializingObject["a"] = object.map(_serialize.bind(null,context)); | ||
return; | ||
serializingObject.a = object.map(_serialize.bind(null, context, options)); | ||
} else if (object.constructor === Map) { | ||
serializingObject.m = _serialize_map(context, options, object); | ||
} else if (object.constructor === Set) { | ||
serializingObject.s = _serialize_set(context, options, object); | ||
} else if (className === "Date") { | ||
serializingObject.d = object.getTime(); | ||
} else { | ||
serializingObject.o = _serialize_basic_object(context, options, object); | ||
} | ||
if (className === "Date") { | ||
serializingObject["d"] = object.getTime(); | ||
return; | ||
} | ||
if (className !== "Object" && !g_classInfos.hasOwnProperty(className)) { | ||
console.log(object); | ||
throw new Error("class " + className + " is not registered in class Factory - deserialization will not be possible"); | ||
} | ||
// check if the object has already been serialized | ||
id = find_object(context,object); | ||
if (id === -1) { // not found | ||
// object hasn't yet been serialized | ||
s = {c: className }; | ||
id = add_object_in_index(context,object, s); | ||
g_classInfos[className].serializeFunc(context,object, s, options); | ||
} | ||
serializingObject.o = id; | ||
return serializingObject; | ||
} | ||
function _serialize(context, object, options ) { | ||
function _serialize(context, options, object) { | ||
assert(context); | ||
// istanbul ignore next | ||
if (object === undefined) { | ||
@@ -279,2 +376,5 @@ return undefined; | ||
var serializingObject = {}; | ||
var _throw = function () { | ||
throw new Error("invalid typeof " + typeof object + " " + JSON.stringify(object, null, " ")); | ||
} | ||
@@ -288,8 +388,11 @@ switch (typeof object) { | ||
case 'object': | ||
_serialize_object(context,serializingObject, object, options); | ||
_serialize_object(context, options, serializingObject, object); | ||
break; | ||
default: | ||
throw new Error("invalid typeof " + typeof object + " " + JSON.stringify(object, null, " ")); | ||
if (options.errorHandler) { | ||
options.errorHandler(context, options, object, _throw) | ||
} else { | ||
_throw() | ||
} | ||
} | ||
return serializingObject; | ||
@@ -305,3 +408,3 @@ } | ||
*/ | ||
function serialize(object,options) { | ||
function serialize(object, options) { | ||
@@ -315,3 +418,3 @@ assert(object !== undefined, "serialize: expect a valid object to serialize "); | ||
var obj = _serialize(context, object, options); | ||
var obj = _serialize(context, options, object); | ||
@@ -330,32 +433,20 @@ // unset temporary ___index properties | ||
// special treatment | ||
if (!node) { | ||
return null; | ||
if (node === null || node === undefined) { | ||
return node; | ||
} | ||
if (node.hasOwnProperty("d")) { | ||
if (node.hasOwnProperty("s")) { | ||
return _deserialize_set(context, node.s); | ||
} else if (node.hasOwnProperty("m")) { | ||
return _deserialize_map(context, node.m); | ||
} else if (node.hasOwnProperty("d")) { | ||
return new Date(node.d); | ||
} else if (node.hasOwnProperty("j")) { | ||
return node.j; | ||
} else if (node.hasOwnProperty("o")) { | ||
var object_id = node.o; | ||
if (object_id === null) { | ||
return null; | ||
} | ||
// check if this object has already been de-serialized | ||
if (context.cache[object_id] !== undefined) { | ||
return context.cache[object_id]; | ||
} | ||
var serializing_data = context.index[object_id]; | ||
var cache_object = _deserialize_object(context, serializing_data, object_id); | ||
assert(context.cache[object_id] === cache_object); | ||
return cache_object; | ||
return _deserialize_basic_object(context, node.o); | ||
} else if (node.hasOwnProperty("a")) { | ||
// return _deserialize_object(node.o); | ||
return node.a.map(deserialize_node_or_value.bind(null,context)); | ||
return node.a.map(deserialize_node_or_value.bind(null, context)); | ||
} | ||
throw new Error("Unsupported deserialize_node" + JSON.stringify(node)); | ||
// istanbul ignore next | ||
throw new Error("Unsupported deserialize_node " + JSON.stringify(node)); | ||
} | ||
@@ -370,2 +461,3 @@ | ||
// istanbul ignore next | ||
if (!classInfo) { | ||
@@ -377,5 +469,7 @@ throw new Error(" Cannot find constructor to deserialize class of type " + className + ". use declarePersistable(Constructor)"); | ||
var obj = classInfo.deserializeFunc(context,object_id, object_definition); | ||
var obj = classInfo.deserializeFunc(context, object_id, object_definition); | ||
if (constructor && constructor.serialijseOptions) { | ||
// onDeserialize is called immediately after object has been created | ||
@@ -401,5 +495,7 @@ if (constructor.serialijseOptions.onDeserialize) { | ||
} | ||
if (!(data instanceof Array) ) { | ||
// istanbul ignore next | ||
if (!(data instanceof Array)) { | ||
throw new Error("Invalid Serialization data"); | ||
} | ||
// istanbul ignore next | ||
if (data.length !== 2) { | ||
@@ -411,8 +507,8 @@ throw new Error("Invalid Serialization data"); | ||
var context = { | ||
index : data[0], | ||
cache : [], | ||
index: data[0], | ||
cache: [], | ||
postDeserialiseActions: [] | ||
}; | ||
var deserializedObject = deserialize_node(context, rawObject); | ||
var deserializedObject = deserialize_node_or_value(context, rawObject); | ||
@@ -434,2 +530,3 @@ context.postDeserialiseActions.forEach(function (o) { | ||
zlib.deflate(str, function (err, buff) { | ||
// istanbul ignore next | ||
if (err) { | ||
@@ -445,2 +542,3 @@ return callback(err); | ||
zlib.inflate(data, function (err, buff) { | ||
// istanbul ignore next | ||
if (err) { | ||
@@ -447,0 +545,0 @@ return callback(err); |
{ | ||
"name": "serialijse", | ||
"version": "0.1.3", | ||
"version": "0.3.0", | ||
"description": "serialize and deserialize your javascript objects, preserve your object model ", | ||
"main": "index.js", | ||
"scripts": { | ||
"pretest": "browserify index.js --standalone serialijse > dist/serialijse.bundle.js && uglifyjs dist/serialijse.bundle.js -o dist/serialijse.bundle.min.js", | ||
"test": "mocha -R spec && mocha-phantomjs -R spec test_html/demo.html" | ||
"pretest": "npx browserify index.js --standalone serialijse > dist/serialijse.bundle.js && uglifyjs dist/serialijse.bundle.js -o dist/serialijse.bundle.min.js", | ||
"test": "npx mocha -R spec && npx mocha-headless-chrome -a no-sandbox -f test_html/demo.html" | ||
}, | ||
@@ -46,12 +46,12 @@ "engines": { | ||
"devDependencies": { | ||
"mocha": "^3.5.0", | ||
"should": "^13.0.1", | ||
"uglify-js": "^3.0.28" | ||
"mocha": "^8.3.2", | ||
"should": "^13.2.3", | ||
"uglify-js": "^3.13.5" | ||
}, | ||
"optionalDependencies": { | ||
"buffer": "^6.0.3", | ||
"object-assign": "^4.1.1", | ||
"zlib": "1.0.5" | ||
}, | ||
"dependencies": {}, | ||
"types": "./lib/serialijse.d.ts" | ||
} |
@@ -50,13 +50,15 @@ serialijse | ||
<script> | ||
var serialize = serialijse.serialize; | ||
var deserialize = serialijse.deserialize; | ||
var declarePersistable = serialijse.declarePersistable; | ||
var serializeZ = serialijse.serializeZ; | ||
var deserializeZ = serialijse.deserializeZ; | ||
const { | ||
serialize, | ||
deserialize, | ||
declarePersistable, | ||
serializeZ, | ||
deserializeZ, | ||
} = serialijse; | ||
var vehicule = new Vehicule(); | ||
const vehicule = new Vehicule(); | ||
... | ||
var serializationString = serialize(vehicule); | ||
const serializationString = serialize(vehicule); | ||
... | ||
var reconstructedObject = deserialize(serializationString); | ||
const reconstructedObject = deserialize(serializationString); | ||
@@ -212,1 +214,21 @@ </script> | ||
## ignoring some members during serialization | ||
Sometime, you may want to ignore some members in serialization | ||
```javascript | ||
class MyClassWithUnpersistableMembers { | ||
constructor() { | ||
this.name = "unset"; | ||
this._cache = []; | ||
this.$someOtherStuff = 0; | ||
} | ||
} | ||
MyClassWithUnpersistableMembers.serialijseOptions = { | ||
ignored: [ | ||
"_cache", // list here the mebmer you want to ignore | ||
/$.*/ // use regExp if you need to as well. | ||
] | ||
}; | ||
declarePersistable(MyClassWithUnpersistableMembers); | ||
``` |
/*global describe, it*/ | ||
var Should; | ||
var should; | ||
if (typeof require !== "undefined") { | ||
Should = require("should"); | ||
should = require("should"); | ||
var serialijse = require("../"); | ||
} | ||
Should(true).eql(true); | ||
@@ -29,2 +27,3 @@ var serialize = serialijse.serialize; | ||
this.created_on = new Date("04 May 1956 GMT"); | ||
this.second_hand = false | ||
} | ||
@@ -38,5 +37,50 @@ | ||
it("should serialize true", function () { | ||
var bool = true; | ||
var serializationString = serialize(bool); | ||
var reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.eql(true); | ||
}); | ||
it("should serialize false", function () { | ||
var serializationString = serialize(false); | ||
var reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.eql(false); | ||
}); | ||
it("should serialize string", function () { | ||
var str = "Vehicule"; | ||
var serializationString = serialize(str); | ||
var reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.eql(str); | ||
}); | ||
it("should serialize number", function () { | ||
var pi = Math.PI | ||
var serializationString = serialize(pi); | ||
var reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.eql(pi); | ||
}); | ||
it("should serialize null", function () { | ||
var serializationString = serialize(null); | ||
var reconstructedObject = deserialize(serializationString); | ||
should.equal(reconstructedObject, null); | ||
}); | ||
it("should fail to serialize undefined", function () { | ||
should.throws(function() {serialize(undefined)}); | ||
}); | ||
it("should persist a simple javascript object (pojo)", function () { | ||
var vehicule = {name: "GM"}; | ||
var vehicule = { name: "GM" }; | ||
var serializationString = serialize(vehicule); | ||
@@ -106,8 +150,6 @@ //xx console.log(serializationString); | ||
Should(the_vehicule.____index).eql(undefined); | ||
should(the_vehicule.____index).eql(undefined); | ||
var expected = '[[' + | ||
'{"c":"Vehicule","d":{"brand":"Citroen","price":95000,"color":{"o":1},"created_on":{"d":-651981600000}}},' + | ||
'{"c":"Color","d":{"name":"blue"}}' + | ||
'],' + '{"a":[{"o":0},{"o":0}]}]'; | ||
var expected = | ||
`[[{"c":"Vehicule","d":{"brand":"Citroen","price":95000,"color":{"o":1},"created_on":{"d":-651981600000},"second_hand":false}},{"c":"Color","d":{"name":"blue"}}],{"a":[{"o":0},{"o":0}]}]`; | ||
@@ -168,3 +210,3 @@ serializationString.should.eql(expected); | ||
var compression_ratio = Math.round(100.0 - 100.0 * (buffer.length / uncompressed_serializationString.length)); | ||
console.log(" = ", uncompressed_serializationString.length, "compressed =", buffer.length, " ratio ", compression_ratio, "%"); | ||
// console.log(" = ", uncompressed_serializationString.length, "compressed =", buffer.length, " ratio ", compression_ratio, "%"); | ||
deserializeZ(buffer, function (err, reconstructedObject) { | ||
@@ -201,5 +243,3 @@ done(err); | ||
// delete it as it should not interfere | ||
delete vehicule.toto; | ||
var reconstructedObject = deserialize(serializationString); | ||
@@ -266,4 +306,4 @@ reconstructedObject.should.eql(vehicule); | ||
var mark = new Person("mark"), | ||
valery = mark.addChild("valery"), | ||
edgar = mark.addChild("edgar"); | ||
valery = mark.addChild("valery"), | ||
edgar = mark.addChild("edgar"); | ||
@@ -273,3 +313,3 @@ valery.parent.should.equal(mark); | ||
Should(function () { | ||
should(function () { | ||
JSON.stringify(mark); | ||
@@ -322,7 +362,7 @@ }).throwError(); // Circular | ||
Should.exist(reconstructedObject.name); | ||
Should.exist(reconstructedObject._cache); | ||
Should.exist(reconstructedObject.$someOtherStuff); | ||
should.exist(reconstructedObject.name); | ||
should.exist(reconstructedObject._cache); | ||
should.exist(reconstructedObject.$someOtherStuff); | ||
Should.not.exist(reconstructedObject.$$key); | ||
should.not.exist(reconstructedObject.$$key); | ||
reconstructedObject._cache.should.eql([]); | ||
@@ -360,3 +400,3 @@ reconstructedObject.$someOtherStuff.should.eql(0); | ||
}); | ||
it("should persist typed array such as Float32Array", function () { | ||
@@ -394,26 +434,146 @@ | ||
}); | ||
}); | ||
it("should be possible to filter out member we don't want to serialize at any level (such as $$ angular extra prop)",function() { | ||
var obj = { | ||
name:"foo", | ||
$$key:1, | ||
address: { | ||
city: "Paris", | ||
$$key:2, | ||
} | ||
}; | ||
it("should be possible to filter out member we don't want to serialize at any level (such as $$ angular extra prop)", function () { | ||
var data = serialize(obj,{ignored: [/^\$\$.*/]}); | ||
var obj2 = deserialize(data); | ||
var obj = { | ||
name: "foo", | ||
$$key: 1, | ||
address: { | ||
city: "Paris", | ||
$$key: 2, | ||
} | ||
}; | ||
obj2.should.have.property("name"); | ||
obj2.should.have.property("address"); | ||
obj2.address.should.have.property("city"); | ||
var data = serialize(obj, { ignored: [/^\$\$.*/] }); | ||
var obj2 = deserialize(data); | ||
obj2.should.not.have.property("$$key"); | ||
obj2.address.should.not.have.property("$$key"); | ||
obj2.should.have.property("name"); | ||
obj2.should.have.property("address"); | ||
obj2.address.should.have.property("city"); | ||
obj2.should.not.have.property("$$key"); | ||
obj2.address.should.not.have.property("$$key"); | ||
}); | ||
it("should persist a Map", () => { | ||
const obj = { | ||
map: new Map() | ||
}; | ||
obj.map.set("A", 1); | ||
obj.map.set("B", { c: "d" }); | ||
obj.map.set("C", obj.map); /// << Circumar | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.map.should.be.instanceOf(Map); | ||
reconstructedObject.map.get("A").should.eql(1); | ||
reconstructedObject.map.get("B").should.eql({c:"d"}); | ||
reconstructedObject.map.get("C").should.eql(reconstructedObject.map); | ||
}) | ||
it("should persist a Set", () => { | ||
const obj = { | ||
c: { c: "d"}, | ||
set: new Set() | ||
}; | ||
obj.d = { d: obj.set }; | ||
obj.set.add("A"); | ||
obj.set.add(obj.c); | ||
obj.set.add(obj.d); | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
// xx console.log(serializationString); | ||
// xx console.log(reconstructedObject); | ||
reconstructedObject.set.has("A").should.eql(true); | ||
reconstructedObject.set.has(reconstructedObject.c).should.eql(true); | ||
}); | ||
it("should persist a Uint8Array", ()=>{ | ||
const obj = new Uint8Array([1,2,3,4]); | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.be.instanceof(Uint8Array); | ||
obj.toString().should.eql(reconstructedObject.toString()); | ||
}); | ||
it("should persist a Uint16Array", ()=>{ | ||
const obj = new Uint16Array([1,2,3,4]); | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.be.instanceof(Uint16Array); | ||
obj.toString().should.eql(reconstructedObject.toString()); | ||
}) | ||
it("should persist a Uint32Array", ()=>{ | ||
const obj = new Uint32Array([1,2,3,4]); | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.be.instanceof(Uint32Array); | ||
obj.toString().should.eql(reconstructedObject.toString()); | ||
}) | ||
it("should persist a Float32Array", ()=>{ | ||
const obj = new Float32Array([1,2,3,4]); | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.be.instanceof(Float32Array); | ||
obj.toString().should.eql(reconstructedObject.toString()); | ||
}) | ||
it("should persist a Float64Array", ()=>{ | ||
const obj = new Float64Array([1,2,3,4]); | ||
const serializationString = serialize(obj); | ||
const reconstructedObject = deserialize(serializationString); | ||
reconstructedObject.should.be.instanceof(Float64Array); | ||
obj.toString().should.eql(reconstructedObject.toString()); | ||
}); | ||
it("onDeserialize options", ()=>{ | ||
function SomeClassXYZ() { | ||
this.name = "unset"; | ||
this._cache = []; | ||
this.$someOtherStuff = 0; | ||
} | ||
SomeClassXYZ.serialijseOptions = { | ||
ignored: [ | ||
"_cache", | ||
/$.*/ | ||
], | ||
onDeserialize: (o) =>{ | ||
o._wasHere =true; | ||
} | ||
}; | ||
declarePersistable(SomeClassXYZ); | ||
const rect1 = new SomeClassXYZ(); | ||
rect1.name = "100"; | ||
const serializationString = serialize(rect1); | ||
const rect2 = deserialize(serializationString); | ||
rect2._wasHere.should.eql(true); | ||
}) | ||
}); | ||
}()); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
233
12
843674
3
18
15315
7