Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ES6 Map and Set in Serializer. With Tests. #965

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions dist/localforage.js
Expand Up @@ -1456,6 +1456,8 @@ var TYPE_UINT16ARRAY = 'ur16';
var TYPE_UINT32ARRAY = 'ui32';
var TYPE_FLOAT32ARRAY = 'fl32';
var TYPE_FLOAT64ARRAY = 'fl64';
var TYPE_ES6MAP = '6map';
var TYPE_ES6SET = '6set';
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;

var toString$1 = Object.prototype.toString;
Expand Down Expand Up @@ -1578,6 +1580,11 @@ function serialize(value, callback) {
};

fileReader.readAsArrayBuffer(value);
} else if (valueType === '[object Map]') {
// [...value] is transpiled to [].concat(value) and does not work. So use Array.from(value).
callback(SERIALIZED_MARKER + TYPE_ES6MAP + JSON.stringify(Array.from(value)));
} else if (valueType === '[object Set]') {
callback(SERIALIZED_MARKER + TYPE_ES6SET + JSON.stringify(Array.from(value)));
} else {
try {
callback(JSON.stringify(value));
Expand Down Expand Up @@ -1646,6 +1653,10 @@ function deserialize(value) {
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
case TYPE_ES6MAP:
return new Map(JSON.parse(serializedString));
case TYPE_ES6SET:
return new Set(JSON.parse(serializedString));
default:
throw new Error('Unkown type: ' + type);
}
Expand Down
2 changes: 1 addition & 1 deletion dist/localforage.min.js

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions dist/localforage.nopromises.js
Expand Up @@ -1120,6 +1120,8 @@ var TYPE_UINT16ARRAY = 'ur16';
var TYPE_UINT32ARRAY = 'ui32';
var TYPE_FLOAT32ARRAY = 'fl32';
var TYPE_FLOAT64ARRAY = 'fl64';
var TYPE_ES6MAP = '6map';
var TYPE_ES6SET = '6set';
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;

var toString$1 = Object.prototype.toString;
Expand Down Expand Up @@ -1242,6 +1244,11 @@ function serialize(value, callback) {
};

fileReader.readAsArrayBuffer(value);
} else if (valueType === '[object Map]') {
// [...value] is transpiled to [].concat(value) and does not work. So use Array.from(value).
callback(SERIALIZED_MARKER + TYPE_ES6MAP + JSON.stringify(Array.from(value)));
} else if (valueType === '[object Set]') {
callback(SERIALIZED_MARKER + TYPE_ES6SET + JSON.stringify(Array.from(value)));
} else {
try {
callback(JSON.stringify(value));
Expand Down Expand Up @@ -1310,6 +1317,10 @@ function deserialize(value) {
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
case TYPE_ES6MAP:
return new Map(JSON.parse(serializedString));
case TYPE_ES6SET:
return new Set(JSON.parse(serializedString));
default:
throw new Error('Unkown type: ' + type);
}
Expand Down
2 changes: 1 addition & 1 deletion dist/localforage.nopromises.min.js

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions src/utils/serializer.js
Expand Up @@ -25,6 +25,8 @@ var TYPE_UINT16ARRAY = 'ur16';
var TYPE_UINT32ARRAY = 'ui32';
var TYPE_FLOAT32ARRAY = 'fl32';
var TYPE_FLOAT64ARRAY = 'fl64';
var TYPE_ES6MAP = '6map';
var TYPE_ES6SET = '6set';
var TYPE_SERIALIZED_MARKER_LENGTH =
SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;

Expand Down Expand Up @@ -159,6 +161,15 @@ function serialize(value, callback) {
};

fileReader.readAsArrayBuffer(value);
} else if (valueType === '[object Map]') {
// [...value] is transpiled to [].concat(value) and does not work. So use Array.from(value).
callback(
SERIALIZED_MARKER + TYPE_ES6MAP + JSON.stringify(Array.from(value))
);
} else if (valueType === '[object Set]') {
callback(
SERIALIZED_MARKER + TYPE_ES6SET + JSON.stringify(Array.from(value))
);
} else {
try {
callback(JSON.stringify(value));
Expand Down Expand Up @@ -230,6 +241,10 @@ function deserialize(value) {
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
case TYPE_ES6MAP:
return new Map(JSON.parse(serializedString));
case TYPE_ES6SET:
return new Set(JSON.parse(serializedString));
default:
throw new Error('Unkown type: ' + type);
}
Expand Down
10 changes: 10 additions & 0 deletions test/dummyStorageDriver.js
Expand Up @@ -35,6 +35,8 @@
var TYPE_UINT32ARRAY = 'ui32';
var TYPE_FLOAT32ARRAY = 'fl32';
var TYPE_FLOAT64ARRAY = 'fl64';
var TYPE_ES6MAP = '6map';
var TYPE_ES6SET = '6set';
var TYPE_SERIALIZED_MARKER_LENGTH =
SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;

Expand Down Expand Up @@ -318,6 +320,10 @@
marker += TYPE_FLOAT32ARRAY;
} else if (valueString === '[object Float64Array]') {
marker += TYPE_FLOAT64ARRAY;
} else if (valueString === '[object Map]') {
marker += TYPE_ES6MAP;
} else if (valueString === '[object Set]') {
marker += TYPE_ES6SET;
} else {
callback(new Error('Failed to get type for BinaryArray'));
}
Expand Down Expand Up @@ -402,6 +408,10 @@
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
case TYPE_ES6MAP:
return new Map(JSON.parse(serializedString));
case TYPE_ES6SET:
return new Set(JSON.parse(serializedString));
default:
throw new Error('Unkown type: ' + type);
}
Expand Down
96 changes: 92 additions & 4 deletions test/test.datatypes.js
Expand Up @@ -15,10 +15,10 @@ function createBlob(parts, properties) {
typeof BlobBuilder !== 'undefined'
? BlobBuilder
: typeof MSBlobBuilder !== 'undefined'
? MSBlobBuilder
: typeof MozBlobBuilder !== 'undefined'
? MozBlobBuilder
: WebKitBlobBuilder;
? MSBlobBuilder
: typeof MozBlobBuilder !== 'undefined'
? MozBlobBuilder
: WebKitBlobBuilder;
var builder = new Builder();
for (var i = 0; i < parts.length; i += 1) {
builder.append(parts[i]);
Expand Down Expand Up @@ -261,6 +261,37 @@ DRIVERS.forEach(function(driverName) {
});
});

var setToSave = new Set([2, 'one', true]);
it('saves a set [callback]', function(done) {
localforage.setItem('array', setToSave, function(err, setValue) {
expect(setValue.length).to.be(setToSave.length);
expect(setValue instanceof Set).to.be(true);

localforage.getItem('array', function(err, value) {
expect(value.length).to.be(setToSave.length);
expect(value instanceof Set).to.be(true);
expect(value[1]).to.be.a('string');
done();
});
});
});
it('saves a set [promise]', function(done) {
localforage
.setItem('array', setToSave)
.then(function(setValue) {
expect(setValue.length).to.be(setToSave.length);
expect(setValue instanceof Set).to.be(true);

return localforage.getItem('array');
})
.then(function(value) {
expect(value.length).to.be(setToSave.length);
expect(value instanceof Set).to.be(true);
expect(value[1]).to.be.a('string');
done();
});
});

var objectToSave = {
floating: 43.01,
nested: {
Expand Down Expand Up @@ -318,6 +349,63 @@ DRIVERS.forEach(function(driverName) {
});
});

var mapToSave = new Map({
floating: 43.01,
nested: {
array: [1, 2, 3]
},
nestedObjects: [
{ truth: true },
{ theCake: 'is a lie' },
{ happiness: 'is a warm gun' },
false
],
string: 'bar'
});
it('saves a nested map [callback]', function(done) {
localforage.setItem('obj', mapToSave, function(err, setValue) {
expect(Object.keys(setValue).length).to.be(
Object.keys(mapToSave).length
);
expect(setValue instanceof Map).to.be(true);

localforage.getItem('obj', function(err, value) {
expect(Object.keys(value).length).to.be(
Object.keys(mapToSave).length
);
expect(value).to.be.an('object');
expect(value.nested).to.be.an('object');
expect(value.nestedObjects[0].truth).to.be.a('boolean');
expect(value.nestedObjects[1].theCake).to.be.a('string');
expect(value.nestedObjects[3]).to.be(false);
done();
});
});
});
it('saves a nested map [promise]', function(done) {
localforage
.setItem('obj', mapToSave)
.then(function(setValue) {
expect(Object.keys(setValue).length).to.be(
Object.keys(mapToSave).length
);
expect(setValue instanceof Map).to.be(true);

return localforage.getItem('obj');
})
.then(function(value) {
expect(Object.keys(value).length).to.be(
Object.keys(mapToSave).length
);
expect(value).to.be.an('object');
expect(value.nested).to.be.an('object');
expect(value.nestedObjects[0].truth).to.be.a('boolean');
expect(value.nestedObjects[1].theCake).to.be.a('string');
expect(value.nestedObjects[3]).to.be(false);
done();
});
});

// Skip binary (ArrayBuffer) data tests if Array Buffer isn't supported.
if (typeof ArrayBuffer !== 'undefined') {
var runBinaryTest = function(url, done) {
Expand Down