Comparing version 1.2.1 to 1.2.2
@@ -24,10 +24,20 @@ import Benchmark from "benchmark"; | ||
suite | ||
.add("Object#assign", async function () { | ||
let test: any; | ||
test = { ...test, test: 2 }; | ||
.add("Array#ForOf", async function () { | ||
const g = []; | ||
for (const test of array) { | ||
g.push(test); | ||
} | ||
}) | ||
.add("Object#spread", async function () { | ||
let test: any; | ||
test = Object.assign({}, test, { test: 2 }); | ||
.add("Array#index", async function () { | ||
const g = []; | ||
for (let i = 0, len = array.length; i < len; i++) { | ||
g.push(array[i]); | ||
} | ||
}) | ||
.add("Array#indexWithTemp", async function () { | ||
const g = []; | ||
for (let i = 0, temp = array[i]; i < array.length; temp = array[++i]) { | ||
g.push(temp); | ||
} | ||
}) | ||
// add listeners | ||
@@ -34,0 +44,0 @@ .on("cycle", function (event: any) { |
@@ -18,2 +18,3 @@ import Benchmark from "benchmark"; | ||
depth: 0, // Change to 2 to see the difference | ||
cache: true | ||
}); | ||
@@ -38,6 +39,7 @@ let CommentSerializer = new Serializer<Comment>("comments"); | ||
const user = User.storage[0]; | ||
// add tests | ||
suite | ||
.add("Serializer#Test", async function () { | ||
const user = User.storage[0]; | ||
await UserSerializer.serialize(user); | ||
@@ -44,0 +46,0 @@ }) |
@@ -8,2 +8,9 @@ # Changelog | ||
## [1.2.2] - 2020-05-27 | ||
### Added | ||
* A new `Cache` class is now available to use for caching. You can set this in the `cache` option for a `Serializer` (use `true` if you want the built in cache). | ||
* With caching, there is a ~586% speed improvement (412,768 ops/sec over the previous 70,435 ops/sec). Without-caching rates have stayed the same. | ||
## [1.2.1] - 2020-05-27 | ||
@@ -37,3 +44,3 @@ | ||
* Serializer `projection` option has changed significantly (see the option itself) with `nullish` values. | ||
* There is a ~33% speed improvement. (70,435 ops/sec over 52,843 ops/sec) | ||
* There is a ~33% speed improvement. (70,435 ops/sec over 52,843 ops/sec on a low-end Macbook Pro 15") | ||
@@ -40,0 +47,0 @@ ### Added |
@@ -49,13 +49,2 @@ "use strict"; | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -85,2 +74,3 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
var serializer_utils_1 = require("../utils/serializer.utils"); | ||
var cache_1 = __importDefault(require("./cache")); | ||
/** | ||
@@ -104,5 +94,12 @@ * The {@linkcode Serializer} class is the main class used to serializer data | ||
if (options === void 0) { options = {}; } | ||
/** | ||
* Caching | ||
*/ | ||
this.cache = new cache_1["default"](); | ||
// Setting default options. | ||
this.options = merge_1["default"]({}, Serializer.defaultOptions, options); | ||
this.options.relators = serializer_utils_1.normalizeRelators(this.options.relators); | ||
this.helpers = new serializer_utils_1.Helpers(this.options); | ||
if (this.options.cache && this.options.cache instanceof cache_1["default"]) { | ||
this.cache = this.options.cache; | ||
} | ||
// Setting type name. | ||
@@ -115,3 +112,3 @@ this.collectionName = collectionName; | ||
Serializer.prototype.getRelators = function () { | ||
return this.options.relators; | ||
return this.helpers.relators; | ||
}; | ||
@@ -122,3 +119,4 @@ /** | ||
Serializer.prototype.setRelators = function (relators) { | ||
this.options.relators = serializer_utils_1.normalizeRelators(relators); | ||
this.options.relators = relators; | ||
this.helpers = new serializer_utils_1.Helpers(this.options); | ||
}; | ||
@@ -137,13 +135,14 @@ /** @internal Generates a `ResourceIdentifier`. */ | ||
/** @internal Generates a `Resource`. */ | ||
Serializer.prototype.createResource = function (data, options) { | ||
Serializer.prototype.createResource = function (data, options, helpers) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var resourceOptions, id, type, type_1, _a, _b, key, _c, _d, key, relationships_1; | ||
var e_1, _e, e_2, _f; | ||
var resourceOptions, id, type, relationships_1; | ||
var _this = this; | ||
return __generator(this, function (_g) { | ||
switch (_g.label) { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
// Get options | ||
if (options === undefined) | ||
if (options === undefined || helpers === undefined) { | ||
options = this.options; | ||
helpers = this.helpers; | ||
} | ||
resourceOptions = {}; | ||
@@ -153,47 +152,6 @@ id = data[options.idKey]; | ||
// Get attributes | ||
if (options.projection !== undefined) { | ||
if (options.projection === null) { | ||
resourceOptions.attributes = __assign({}, data); | ||
} | ||
else { | ||
resourceOptions.attributes = {}; | ||
type_1 = Object.values(options.projection)[0]; | ||
if (type_1 === 0) { | ||
try { | ||
for (_a = __values(Object.keys(data)), _b = _a.next(); !_b.done; _b = _a.next()) { | ||
key = _b.value; | ||
if (!(key in options.projection)) { | ||
resourceOptions.attributes[key] = data[key]; | ||
} | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_b && !_b.done && (_e = _a["return"])) _e.call(_a); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
} | ||
else { | ||
try { | ||
for (_c = __values(Object.keys(options.projection)), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
key = _d.value; | ||
resourceOptions.attributes[key] = data[key]; | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_f = _c["return"])) _f.call(_c); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
} | ||
} | ||
delete resourceOptions.attributes[options.idKey]; | ||
} | ||
if (!options.relators) return [3 /*break*/, 2]; | ||
resourceOptions.attributes = helpers.projectAttributes(data); | ||
if (!helpers.relators) return [3 /*break*/, 2]; | ||
relationships_1 = {}; | ||
return [4 /*yield*/, Promise.all(Object.entries(options.relators).map(function (_a) { | ||
return [4 /*yield*/, Promise.all(Object.entries(helpers.relators).map(function (_a) { | ||
var _b = __read(_a, 2), name = _b[0], relator = _b[1]; | ||
@@ -216,5 +174,5 @@ return __awaiter(_this, void 0, void 0, function () { | ||
case 1: | ||
_g.sent(); | ||
_a.sent(); | ||
resourceOptions.relationships = relationships_1; | ||
_g.label = 2; | ||
_a.label = 2; | ||
case 2: | ||
@@ -241,3 +199,3 @@ // Handling links | ||
return __awaiter(this, void 0, void 0, function () { | ||
var o, document, relator_1, relatedData, links, meta, createIdentifier, keys_1, relators, createResource, _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, pagination, createIdentifier, keys_2, relators, createResource, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; | ||
var o, h, cache, storedDocument, document, relator_1, relatedData, links, meta, createIdentifier, keys_1, relators, createResource, _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, pagination, createIdentifier, keys_2, relators, createResource, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; | ||
var _this = this; | ||
@@ -247,4 +205,15 @@ return __generator(this, function (_w) { | ||
case 0: | ||
o = options ? merge_1["default"]({}, this.options, options) : this.options; | ||
o.relators = serializer_utils_1.normalizeRelators(o.relators); | ||
o = this.options; | ||
h = this.helpers; | ||
if (options !== undefined) { | ||
o = merge_1["default"]({}, o, options); | ||
h = new serializer_utils_1.Helpers(o); | ||
} | ||
cache = o.cache instanceof cache_1["default"] ? o.cache : this.cache; | ||
if (o.cache) { | ||
storedDocument = cache.get(data, options); | ||
if (storedDocument) { | ||
return [2 /*return*/, storedDocument]; | ||
} | ||
} | ||
document = {}; | ||
@@ -260,3 +229,3 @@ // Document versioning | ||
// Validate options. | ||
if (o.relators === undefined) { | ||
if (h.relators === undefined) { | ||
throw new TypeError("\"relators\" must be defined when using \"onlyRelationship\""); | ||
@@ -267,3 +236,3 @@ } | ||
} | ||
relator_1 = o.relators[o.onlyRelationship]; | ||
relator_1 = h.relators[o.onlyRelationship]; | ||
if (relator_1 === undefined) { | ||
@@ -282,7 +251,7 @@ throw new TypeError("\"onlyRelationship\" is not the name of any collection name among the relators listed in \"relators\""); | ||
if (relatedData === undefined) { | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
if (o.nullData || relatedData === null) { | ||
document.data = null; | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -295,3 +264,3 @@ createIdentifier = function (datum) { return relator_1.getRelatedIdentifier(datum); }; | ||
: createIdentifier(relatedData); | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -357,3 +326,3 @@ keys_1 = []; | ||
_w.label = 14; | ||
case 14: return [2 /*return*/, document]; | ||
case 14: return [2 /*return*/, cache.set(data, document, options)]; | ||
case 15: | ||
@@ -369,7 +338,7 @@ // Handle meta | ||
if (data === undefined) { | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
if (o.nullData || data === null) { | ||
document.data = null; | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -387,6 +356,6 @@ // Data-based document links | ||
document.data = Array.isArray(data) ? data.map(createIdentifier) : createIdentifier(data); | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
keys_2 = []; | ||
relators = o.relators; | ||
relators = h.relators; | ||
createResource = function (datum) { return __awaiter(_this, void 0, void 0, function () { | ||
@@ -396,3 +365,3 @@ var resource; | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.createResource(datum, o)]; | ||
case 0: return [4 /*yield*/, this.createResource(datum, o, h)]; | ||
case 1: | ||
@@ -450,3 +419,3 @@ resource = _a.sent(); | ||
_w.label = 28; | ||
case 28: return [2 /*return*/, document]; | ||
case 28: return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -466,2 +435,3 @@ }); | ||
onlyRelationship: false, | ||
cache: false, | ||
depth: 0, | ||
@@ -468,0 +438,0 @@ projection: null, |
@@ -6,3 +6,4 @@ import { DataDocument } from "../interfaces/json:api.interface"; | ||
import { Dictionary, nullish, SingleOrArray } from "../types/global.types"; | ||
import Relator from "./relator"; | ||
import { Helpers } from "../utils/serializer.utils"; | ||
import Cache from "./cache"; | ||
/** | ||
@@ -28,2 +29,3 @@ * The {@linkcode Serializer} class is the main class used to serializer data | ||
onlyRelationship: boolean; | ||
cache: boolean; | ||
depth: number; | ||
@@ -43,2 +45,10 @@ projection: null; | ||
/** | ||
* The set of helper functions for the serializer | ||
*/ | ||
helpers: Helpers<PrimaryType>; | ||
/** | ||
* Caching | ||
*/ | ||
cache: Cache<PrimaryType>; | ||
/** | ||
* Creates a {@linkcode Serializer}. | ||
@@ -53,3 +63,3 @@ * | ||
*/ | ||
getRelators(): Record<string, Relator<PrimaryType, any>> | undefined; | ||
getRelators(): Record<string, import("./relator").default<PrimaryType, any>> | undefined; | ||
/** | ||
@@ -62,3 +72,3 @@ * Sets the {@linkcode Relator}s associated with this serializer | ||
/** @internal Generates a `Resource`. */ | ||
createResource(data: PrimaryType, options?: SerializerOptions<PrimaryType>): Promise<Resource<PrimaryType>>; | ||
createResource(data: PrimaryType, options?: SerializerOptions<PrimaryType>, helpers?: Helpers<PrimaryType>): Promise<Resource<PrimaryType>>; | ||
/** | ||
@@ -65,0 +75,0 @@ * The actual serialization function. |
@@ -49,13 +49,2 @@ "use strict"; | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -85,2 +74,3 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
var serializer_utils_1 = require("../utils/serializer.utils"); | ||
var cache_1 = __importDefault(require("./cache")); | ||
/** | ||
@@ -104,5 +94,12 @@ * The {@linkcode Serializer} class is the main class used to serializer data | ||
if (options === void 0) { options = {}; } | ||
/** | ||
* Caching | ||
*/ | ||
this.cache = new cache_1["default"](); | ||
// Setting default options. | ||
this.options = merge_1["default"]({}, Serializer.defaultOptions, options); | ||
this.options.relators = serializer_utils_1.normalizeRelators(this.options.relators); | ||
this.helpers = new serializer_utils_1.Helpers(this.options); | ||
if (this.options.cache && this.options.cache instanceof cache_1["default"]) { | ||
this.cache = this.options.cache; | ||
} | ||
// Setting type name. | ||
@@ -115,3 +112,3 @@ this.collectionName = collectionName; | ||
Serializer.prototype.getRelators = function () { | ||
return this.options.relators; | ||
return this.helpers.relators; | ||
}; | ||
@@ -122,3 +119,4 @@ /** | ||
Serializer.prototype.setRelators = function (relators) { | ||
this.options.relators = serializer_utils_1.normalizeRelators(relators); | ||
this.options.relators = relators; | ||
this.helpers = new serializer_utils_1.Helpers(this.options); | ||
}; | ||
@@ -137,13 +135,14 @@ /** @internal Generates a `ResourceIdentifier`. */ | ||
/** @internal Generates a `Resource`. */ | ||
Serializer.prototype.createResource = function (data, options) { | ||
Serializer.prototype.createResource = function (data, options, helpers) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var resourceOptions, id, type, type_1, _a, _b, key, _c, _d, key, relationships_1; | ||
var e_1, _e, e_2, _f; | ||
var resourceOptions, id, type, relationships_1; | ||
var _this = this; | ||
return __generator(this, function (_g) { | ||
switch (_g.label) { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
// Get options | ||
if (options === undefined) | ||
if (options === undefined || helpers === undefined) { | ||
options = this.options; | ||
helpers = this.helpers; | ||
} | ||
resourceOptions = {}; | ||
@@ -153,47 +152,6 @@ id = data[options.idKey]; | ||
// Get attributes | ||
if (options.projection !== undefined) { | ||
if (options.projection === null) { | ||
resourceOptions.attributes = __assign({}, data); | ||
} | ||
else { | ||
resourceOptions.attributes = {}; | ||
type_1 = Object.values(options.projection)[0]; | ||
if (type_1 === 0) { | ||
try { | ||
for (_a = __values(Object.keys(data)), _b = _a.next(); !_b.done; _b = _a.next()) { | ||
key = _b.value; | ||
if (!(key in options.projection)) { | ||
resourceOptions.attributes[key] = data[key]; | ||
} | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_b && !_b.done && (_e = _a["return"])) _e.call(_a); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
} | ||
else { | ||
try { | ||
for (_c = __values(Object.keys(options.projection)), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
key = _d.value; | ||
resourceOptions.attributes[key] = data[key]; | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_f = _c["return"])) _f.call(_c); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
} | ||
} | ||
delete resourceOptions.attributes[options.idKey]; | ||
} | ||
if (!options.relators) return [3 /*break*/, 2]; | ||
resourceOptions.attributes = helpers.projectAttributes(data); | ||
if (!helpers.relators) return [3 /*break*/, 2]; | ||
relationships_1 = {}; | ||
return [4 /*yield*/, Promise.all(Object.entries(options.relators).map(function (_a) { | ||
return [4 /*yield*/, Promise.all(Object.entries(helpers.relators).map(function (_a) { | ||
var _b = __read(_a, 2), name = _b[0], relator = _b[1]; | ||
@@ -216,5 +174,5 @@ return __awaiter(_this, void 0, void 0, function () { | ||
case 1: | ||
_g.sent(); | ||
_a.sent(); | ||
resourceOptions.relationships = relationships_1; | ||
_g.label = 2; | ||
_a.label = 2; | ||
case 2: | ||
@@ -241,3 +199,3 @@ // Handling links | ||
return __awaiter(this, void 0, void 0, function () { | ||
var o, document, relator_1, relatedData, links, meta, createIdentifier, keys_1, relators, createResource, _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, pagination, createIdentifier, keys_2, relators, createResource, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; | ||
var o, h, cache, storedDocument, document, relator_1, relatedData, links, meta, createIdentifier, keys_1, relators, createResource, _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, pagination, createIdentifier, keys_2, relators, createResource, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; | ||
var _this = this; | ||
@@ -247,4 +205,15 @@ return __generator(this, function (_w) { | ||
case 0: | ||
o = options ? merge_1["default"]({}, this.options, options) : this.options; | ||
o.relators = serializer_utils_1.normalizeRelators(o.relators); | ||
o = this.options; | ||
h = this.helpers; | ||
if (options !== undefined) { | ||
o = merge_1["default"]({}, o, options); | ||
h = new serializer_utils_1.Helpers(o); | ||
} | ||
cache = o.cache instanceof cache_1["default"] ? o.cache : this.cache; | ||
if (o.cache) { | ||
storedDocument = cache.get(data, options); | ||
if (storedDocument) { | ||
return [2 /*return*/, storedDocument]; | ||
} | ||
} | ||
document = {}; | ||
@@ -260,3 +229,3 @@ // Document versioning | ||
// Validate options. | ||
if (o.relators === undefined) { | ||
if (h.relators === undefined) { | ||
throw new TypeError("\"relators\" must be defined when using \"onlyRelationship\""); | ||
@@ -267,3 +236,3 @@ } | ||
} | ||
relator_1 = o.relators[o.onlyRelationship]; | ||
relator_1 = h.relators[o.onlyRelationship]; | ||
if (relator_1 === undefined) { | ||
@@ -282,7 +251,7 @@ throw new TypeError("\"onlyRelationship\" is not the name of any collection name among the relators listed in \"relators\""); | ||
if (relatedData === undefined) { | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
if (o.nullData || relatedData === null) { | ||
document.data = null; | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -295,3 +264,3 @@ createIdentifier = function (datum) { return relator_1.getRelatedIdentifier(datum); }; | ||
: createIdentifier(relatedData); | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -357,3 +326,3 @@ keys_1 = []; | ||
_w.label = 14; | ||
case 14: return [2 /*return*/, document]; | ||
case 14: return [2 /*return*/, cache.set(data, document, options)]; | ||
case 15: | ||
@@ -369,7 +338,7 @@ // Handle meta | ||
if (data === undefined) { | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
if (o.nullData || data === null) { | ||
document.data = null; | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -387,6 +356,6 @@ // Data-based document links | ||
document.data = Array.isArray(data) ? data.map(createIdentifier) : createIdentifier(data); | ||
return [2 /*return*/, document]; | ||
return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
keys_2 = []; | ||
relators = o.relators; | ||
relators = h.relators; | ||
createResource = function (datum) { return __awaiter(_this, void 0, void 0, function () { | ||
@@ -396,3 +365,3 @@ var resource; | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.createResource(datum, o)]; | ||
case 0: return [4 /*yield*/, this.createResource(datum, o, h)]; | ||
case 1: | ||
@@ -450,3 +419,3 @@ resource = _a.sent(); | ||
_w.label = 28; | ||
case 28: return [2 /*return*/, document]; | ||
case 28: return [2 /*return*/, cache.set(data, document, options)]; | ||
} | ||
@@ -466,2 +435,3 @@ }); | ||
onlyRelationship: false, | ||
cache: false, | ||
depth: 0, | ||
@@ -468,0 +438,0 @@ projection: null, |
@@ -8,2 +8,3 @@ import Metaizer from "./classes/metaizer"; | ||
import ErrorSerializer from "./classes/error-serializer"; | ||
import Cache from "./classes/cache"; | ||
export * from "./interfaces/error.interface"; | ||
@@ -15,4 +16,5 @@ export * from "./interfaces/relator.interface"; | ||
export * from "./interfaces/paginator.interface"; | ||
export * from "./interfaces/cache.interface"; | ||
export * from "./types/global.types"; | ||
export { Metaizer, Linker, Paginator, Relator, Serializer, JapiError, ErrorSerializer }; | ||
export { Metaizer, Linker, Paginator, Relator, Serializer, JapiError, ErrorSerializer, Cache }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -16,3 +16,3 @@ "use strict"; | ||
exports.__esModule = true; | ||
exports.ErrorSerializer = exports.JapiError = exports.Serializer = exports.Relator = exports.Paginator = exports.Linker = exports.Metaizer = void 0; | ||
exports.Cache = exports.ErrorSerializer = exports.JapiError = exports.Serializer = exports.Relator = exports.Paginator = exports.Linker = exports.Metaizer = void 0; | ||
var metaizer_1 = __importDefault(require("./classes/metaizer")); | ||
@@ -32,2 +32,4 @@ exports.Metaizer = metaizer_1["default"]; | ||
exports.ErrorSerializer = error_serializer_1["default"]; | ||
var cache_1 = __importDefault(require("./classes/cache")); | ||
exports.Cache = cache_1["default"]; | ||
__exportStar(require("./interfaces/error.interface"), exports); | ||
@@ -39,3 +41,4 @@ __exportStar(require("./interfaces/relator.interface"), exports); | ||
__exportStar(require("./interfaces/paginator.interface"), exports); | ||
__exportStar(require("./interfaces/cache.interface"), exports); | ||
__exportStar(require("./types/global.types"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -6,2 +6,3 @@ import Linker from "../classes/linker"; | ||
import { Dictionary, SingleOrArray, nullish } from "../types/global.types"; | ||
import Cache from "../classes/cache"; | ||
export interface SerializerOptions<PrimaryType extends Dictionary<any> = any> { | ||
@@ -13,3 +14,3 @@ /** | ||
*/ | ||
idKey: string; | ||
idKey: keyof PrimaryType; | ||
/** | ||
@@ -22,2 +23,9 @@ * The highest JSON API version supported. Set to `null` to omit version. | ||
/** | ||
* Enables caching of documents. If a {@linkcode Cache} is given, then the | ||
* given {@linkcode Cache} will be used. | ||
* | ||
* @default `false` | ||
*/ | ||
cache: boolean | Cache<PrimaryType>; | ||
/** | ||
* Whether to use `null` value the `data` field. | ||
@@ -24,0 +32,0 @@ * |
@@ -5,2 +5,7 @@ import Relator from "../classes/relator"; | ||
export declare function normalizeRelators<T>(relators: SerializerOptions<T>["relators"]): Record<string, Relator<T, any>> | undefined; | ||
export declare class Helpers<PrimaryType> { | ||
projectAttributes: (data: PrimaryType) => Partial<PrimaryType> | undefined; | ||
relators: Record<string, Relator<PrimaryType, any>> | undefined; | ||
constructor(options: SerializerOptions<PrimaryType>); | ||
} | ||
//# sourceMappingURL=serializer.utils.d.ts.map |
@@ -69,27 +69,28 @@ "use strict"; | ||
exports.__esModule = true; | ||
exports.normalizeRelators = exports.recurseRelators = void 0; | ||
exports.Helpers = exports.normalizeRelators = exports.recurseRelators = void 0; | ||
var relator_1 = __importDefault(require("../classes/relator")); | ||
function recurseRelators(data, relators, depth, keys) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var included, queue, i, len, _a, data_1, relators_1, _loop_1, _b, _c, relator, e_1_1; | ||
var e_1, _d; | ||
var included, queue, i, len, _a, data_1, relators_1, _loop_1, i_1, len_1; | ||
var _this = this; | ||
return __generator(this, function (_e) { | ||
switch (_e.label) { | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
included = []; | ||
queue = [[data, relators]]; | ||
_e.label = 1; | ||
queue = [[data, Object.values(relators)]]; | ||
_b.label = 1; | ||
case 1: | ||
if (!(queue.length > 0 && depth-- > 0)) return [3 /*break*/, 12]; | ||
if (!(queue.length > 0 && depth-- > 0)) return [3 /*break*/, 8]; | ||
i = 0, len = queue.length; | ||
_e.label = 2; | ||
_b.label = 2; | ||
case 2: | ||
if (!(i < len)) return [3 /*break*/, 11]; | ||
if (!(i < len)) return [3 /*break*/, 7]; | ||
_a = __read(queue[i], 2), data_1 = _a[0], relators_1 = _a[1]; | ||
_loop_1 = function (relator) { | ||
var relatedData, newData, newRelators; | ||
_loop_1 = function (i_1, len_1) { | ||
var relator, relatedData, newData, newRelators; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(data_1.map(relator.getRelatedData))]; | ||
case 0: | ||
relator = relators_1[i_1]; | ||
return [4 /*yield*/, Promise.all(data_1.map(relator.getRelatedData))]; | ||
case 1: | ||
@@ -118,3 +119,3 @@ relatedData = _a.sent(); | ||
if (newData.length > 0 && newRelators) { | ||
queue.push([newData, newRelators]); | ||
queue.push([newData, Object.values(newRelators)]); | ||
} | ||
@@ -125,33 +126,18 @@ return [2 /*return*/]; | ||
}; | ||
_e.label = 3; | ||
i_1 = 0, len_1 = relators_1.length; | ||
_b.label = 3; | ||
case 3: | ||
_e.trys.push([3, 8, 9, 10]); | ||
_b = (e_1 = void 0, __values(Object.values(relators_1))), _c = _b.next(); | ||
_e.label = 4; | ||
if (!(i_1 < len_1)) return [3 /*break*/, 6]; | ||
return [5 /*yield**/, _loop_1(i_1, len_1)]; | ||
case 4: | ||
if (!!_c.done) return [3 /*break*/, 7]; | ||
relator = _c.value; | ||
return [5 /*yield**/, _loop_1(relator)]; | ||
_b.sent(); | ||
_b.label = 5; | ||
case 5: | ||
_e.sent(); | ||
_e.label = 6; | ||
i_1++; | ||
return [3 /*break*/, 3]; | ||
case 6: | ||
_c = _b.next(); | ||
return [3 /*break*/, 4]; | ||
case 7: return [3 /*break*/, 10]; | ||
case 8: | ||
e_1_1 = _e.sent(); | ||
e_1 = { error: e_1_1 }; | ||
return [3 /*break*/, 10]; | ||
case 9: | ||
try { | ||
if (_c && !_c.done && (_d = _b["return"])) _d.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
return [7 /*endfinally*/]; | ||
case 10: | ||
i++; | ||
return [3 /*break*/, 2]; | ||
case 11: return [3 /*break*/, 1]; | ||
case 12: return [2 /*return*/, included]; | ||
case 7: return [3 /*break*/, 1]; | ||
case 8: return [2 /*return*/, included]; | ||
} | ||
@@ -163,3 +149,3 @@ }); | ||
function normalizeRelators(relators) { | ||
var e_2, _a; | ||
var e_1, _a; | ||
var normalizedRelators = {}; | ||
@@ -178,3 +164,3 @@ if (relators) { | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
@@ -184,3 +170,3 @@ try { | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
@@ -196,2 +182,49 @@ return normalizedRelators; | ||
exports.normalizeRelators = normalizeRelators; | ||
var Helpers = /** @class */ (function () { | ||
function Helpers(options) { | ||
// Relators | ||
this.relators = normalizeRelators(options.relators); | ||
// Projection | ||
if (options.projection === undefined) { | ||
this.projectAttributes = function () { return undefined; }; | ||
} | ||
else if (options.projection === null) { | ||
this.projectAttributes = function (data) { | ||
var attributes = Object.assign({}, data); | ||
delete attributes[options.idKey]; | ||
return attributes; | ||
}; | ||
} | ||
else { | ||
var projection_1 = options.projection; | ||
var type = Object.values(projection_1)[0]; | ||
if (type === 0) { | ||
this.projectAttributes = function (data) { | ||
var keys = Object.keys(data); | ||
var attributes = {}; | ||
for (var i = 0, len = keys.length; i < len; i++) { | ||
if (!(keys[i] in projection_1)) { | ||
attributes[keys[i]] = data[keys[i]]; | ||
} | ||
} | ||
delete attributes[options.idKey]; | ||
return attributes; | ||
}; | ||
} | ||
else { | ||
var keys_1 = Object.keys(projection_1); | ||
this.projectAttributes = function (data) { | ||
var attributes = {}; | ||
for (var i = 0, len = keys_1.length; i < len; i++) { | ||
attributes[keys_1[i]] = data[keys_1[i]]; | ||
} | ||
delete attributes[options.idKey]; | ||
return attributes; | ||
}; | ||
} | ||
} | ||
} | ||
return Helpers; | ||
}()); | ||
exports.Helpers = Helpers; | ||
//# sourceMappingURL=serializer.utils.js.map |
{ | ||
"name": "ts-japi", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"description": "A highly-modular (typescript-friendly)-framework agnostic library for serializing data to the JSON:API specification", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -24,2 +24,3 @@ <br /> | ||
- [Serializing Errors](#serializing-errors) | ||
- [Caching](#caching) | ||
- [Deserialization](#deserialization) | ||
@@ -63,2 +64,3 @@ - [Remarks](#remarks) | ||
- [`ErrorSerializer`](https://jun-sheaf.github.io/ts-japi/classes/errorserializer.html) with [`ErrorSerializerOptions`](https://jun-sheaf.github.io/ts-japi/interfaces/errorserializeroptions.html) | ||
- **NEW** [`Cache`](https://jun-sheaf.github.io/ts-japi/classes/cache.html) with [`CacheOptions`](https://jun-sheaf.github.io/ts-japi/interfaces/cacheoptions.html) | ||
@@ -180,3 +182,3 @@ You can check the [documentation](https://jun-sheaf.github.io/ts-japi) for a deeper insight into the usage. | ||
The [`Relator`](https://jun-sheaf.github.io/ts-japi/classes/relator.html) is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level) as well as resource-level [relationships](https://jsonapi.org/format/#document-resource-object-relationships). Its methods are not meant to be called. | ||
The [`Relator`](https://jun-sheaf.github.io/ts-japi/classes/relator.html) class is used to generate top-level [included data](https://jsonapi.org/format/#document-top-level) as well as resource-level [relationships](https://jsonapi.org/format/#document-resource-object-relationships). Its methods are not meant to be called. | ||
@@ -214,3 +216,3 @@ [`Relator`](https://jun-sheaf.github.io/ts-japi/classes/relator.html)s may also take optional [`Linker`](https://jun-sheaf.github.io/ts-japi/classes/linker.html)s (using the [`linker`](https://jun-sheaf.github.io/ts-japi/interfaces/relatoroptions.html#linkers) option) to define [relationship links](https://jsonapi.org/format/#document-resource-object-relationships) and [related resource links](https://jsonapi.org/format/#document-resource-object-related-resource-links). | ||
The [`Metaizer`](https://jun-sheaf.github.io/ts-japi/classes/metaizer.html) is used to construct generate metadata given some dependencies. There are several locations [`Metaizer`](https://jun-sheaf.github.io/ts-japi/classes/metaizer.html) can be used: | ||
The [`Metaizer`](https://jun-sheaf.github.io/ts-japi/classes/metaizer.html) class is used to construct generate metadata given some dependencies. There are several locations [`Metaizer`](https://jun-sheaf.github.io/ts-japi/classes/metaizer.html) can be used: | ||
@@ -256,3 +258,3 @@ - [`ErrorSerializerOptions.metaizers`](https://jun-sheaf.github.io/ts-japi/interfaces/errorserializeroptions.html#metaizers) | ||
The [`ErrorSerializer`](https://jun-sheaf.github.io/ts-japi/classes/errorserializer.html) is used to serialize any object considered an error (the [`attributes`](https://jun-sheaf.github.io/ts-japi/interfaces/errorserializeroptions.html#attributes) option allows you to choose what attributes to use during serialization). *Alternatively* (**recommended**), you can construct custom errors by extending the [`JapiError`](https://jun-sheaf.github.io/ts-japi/classes/japierror.html) class and use those for all server-to-client errors. | ||
The [`ErrorSerializer`](https://jun-sheaf.github.io/ts-japi/classes/errorserializer.html) class is used to serialize any object considered an error (the [`attributes`](https://jun-sheaf.github.io/ts-japi/interfaces/errorserializeroptions.html#attributes) option allows you to choose what attributes to use during serialization). *Alternatively* (**recommended**), you can construct custom errors by extending the [`JapiError`](https://jun-sheaf.github.io/ts-japi/classes/japierror.html) class and use those for all server-to-client errors. | ||
@@ -282,2 +284,8 @@ The [error serializer test](https://github.com/jun-sheaf/ts-japi/tree/master/test/error-serializer.test.ts) includes an example of the alternative solution. | ||
### Caching | ||
The [`Cache`](https://jun-sheaf.github.io/ts-japi/classes/cache.html) class can be placed in a [`Serializer`](https://jun-sheaf.github.io/ts-japi/classes/serializer.html)'s [`cache`](https://jun-sheaf.github.io/ts-japi/interfaces/serializeroptions.html#cache) option. Alternatively, setting that option to `true` will provide a default [`Cache`](https://jun-sheaf.github.io/ts-japi/classes/cache.html). | ||
The default [`Cache`](https://jun-sheaf.github.io/ts-japi/classes/cache.html) uses the basic [`Object.is`](https://jun-sheaf.github.io/ts-japi/https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) function to determine if input data are the same. If you want to adjust this, instantiate a new [`Cache`](https://jun-sheaf.github.io/ts-japi/classes/cache.html) with a [`resolver`](https://jun-sheaf.github.io/ts-japi/interfaces/cacheoptions.html#resolver). | ||
## Deserialization | ||
@@ -284,0 +292,0 @@ |
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
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
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
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
341572
324
193
4418