@berish/serber
Version:
Serializable and deserializable adaptive adapter with plugins
124 lines • 7.14 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const linq_1 = require("@berish/linq");
const pathof_1 = require("@berish/pathof");
const typeof_1 = require("@berish/typeof");
const const_1 = require("../const");
const getKeys_1 = require("../getKeys");
const paths_1 = require("../paths");
const typeLoopObj = '_s_loop_object_';
exports.loopObjectPlugin = {
isForSerialize: obj => {
return typeof_1.default(obj) === 'object';
},
isForDeserialize: obj => {
return typeof_1.default(obj) === 'object';
},
beforeSerialize: (obj, params) => {
params[const_1.SERBER_PATH_SYMBOL] = params[const_1.SERBER_PATH_SYMBOL] || [];
params[const_1.SERBER_KEY_SYMBOL] = params[const_1.SERBER_KEY_SYMBOL] || '';
params[const_1.SERBER_LOOP_OBJECT_DATA_SYMBOL] = params[const_1.SERBER_LOOP_OBJECT_DATA_SYMBOL] || new WeakMap();
},
serialize: (obj, params) => {
const serialized = {};
const path = params[const_1.SERBER_PATH_SYMBOL];
const weakSet = params[const_1.SERBER_LOOP_OBJECT_DATA_SYMBOL];
const serber = params[const_1.SERBER_INSTANCE_SYMBOL];
const loopPath = weakSet.get(obj);
if (loopPath && !paths_1.equalPaths(path, loopPath)) {
return { type: '_s_loop_object_', path: paths_1.relativePath(path, loopPath) };
}
if (!loopPath)
weakSet.set(obj, path);
const keys = getKeys_1.getKeys(obj);
for (const key of keys) {
if (obj[key] && typeof obj[key] === 'object' && !weakSet.has(obj[key]))
weakSet.set(obj[key], path.concat(key));
}
for (const key of keys) {
const newParams = Object.assign(Object.assign({}, params), { [const_1.SERBER_PARENT_OBJECT_SYMBOL]: obj, [const_1.SERBER_KEY_SYMBOL]: key, [const_1.SERBER_PATH_SYMBOL]: path.concat(key) });
const subSerialized = serber.serialize(obj[key], newParams);
Object.assign(serialized, { [key]: subSerialized });
}
return serialized;
},
serializeAsync: (obj, params) => __awaiter(void 0, void 0, void 0, function* () {
const serialized = {};
const path = params[const_1.SERBER_PATH_SYMBOL];
const weakSet = params[const_1.SERBER_LOOP_OBJECT_DATA_SYMBOL];
const serber = params[const_1.SERBER_INSTANCE_SYMBOL];
const loopPath = weakSet.get(obj);
if (loopPath && !paths_1.equalPaths(path, loopPath)) {
return { type: '_s_loop_object_', path: paths_1.relativePath(path, loopPath) };
}
if (!loopPath)
weakSet.set(obj, path);
const keys = getKeys_1.getKeys(obj);
for (const key of keys) {
if (obj[key] && typeof obj[key] === 'object' && !weakSet.has(obj[key]))
weakSet.set(obj[key], path.concat(key));
}
for (const key of keys) {
const newParams = Object.assign(Object.assign({}, params), { [const_1.SERBER_PARENT_OBJECT_SYMBOL]: obj, [const_1.SERBER_KEY_SYMBOL]: key, [const_1.SERBER_PATH_SYMBOL]: path.concat(key) });
const subSerialized = yield serber.serializeAsync(obj[key], newParams);
Object.assign(serialized, { [key]: subSerialized });
}
return serialized;
}),
beforeDeserialize: (obj, params) => {
params[const_1.SERBER_PATH_SYMBOL] = params[const_1.SERBER_PATH_SYMBOL] || [];
params[const_1.SERBER_KEY_SYMBOL] = params[const_1.SERBER_KEY_SYMBOL] || '';
params[const_1.SERBER_LOOP_OBJECT_DATA_REVERT_SYMBOL] = params[const_1.SERBER_LOOP_OBJECT_DATA_REVERT_SYMBOL] || linq_1.default.from();
},
deserialize: (obj, params) => {
const serber = params[const_1.SERBER_INSTANCE_SYMBOL];
const deserialized = {};
if ('type' in obj && obj.type === '_s_loop_object_') {
const relativePathByAbsolute = paths_1.getAbsolutePathByRelative(params[const_1.SERBER_PATH_SYMBOL].slice(0, params[const_1.SERBER_PATH_SYMBOL].length - 1), obj.path);
params[const_1.SERBER_LOOP_OBJECT_DATA_REVERT_SYMBOL].push([relativePathByAbsolute, params[const_1.SERBER_PATH_SYMBOL]]);
return deserialized;
}
const keys = getKeys_1.getKeys(obj);
for (const key of keys) {
const newParams = Object.assign(Object.assign({}, params), { parent: deserialized, [const_1.SERBER_PARENT_OBJECT_SYMBOL]: obj, [const_1.SERBER_KEY_SYMBOL]: key, [const_1.SERBER_PATH_SYMBOL]: params[const_1.SERBER_PATH_SYMBOL].concat(key) });
const result = serber.deserialize(obj[key], newParams);
Object.assign(deserialized, { [key]: result });
}
return deserialized;
},
deserializeAsync: (obj, params) => __awaiter(void 0, void 0, void 0, function* () {
const serber = params[const_1.SERBER_INSTANCE_SYMBOL];
const deserialized = {};
if ('type' in obj && obj.type === '_s_loop_object_') {
const relativePathByAbsolute = paths_1.getAbsolutePathByRelative(params[const_1.SERBER_PATH_SYMBOL].slice(0, params[const_1.SERBER_PATH_SYMBOL].length - 1), obj.path);
params[const_1.SERBER_LOOP_OBJECT_DATA_REVERT_SYMBOL].push([relativePathByAbsolute, params[const_1.SERBER_PATH_SYMBOL]]);
return deserialized;
}
const keys = getKeys_1.getKeys(obj);
for (const key of keys) {
const newParams = Object.assign(Object.assign({}, params), { parent: deserialized, [const_1.SERBER_PARENT_OBJECT_SYMBOL]: obj, [const_1.SERBER_KEY_SYMBOL]: key, [const_1.SERBER_PATH_SYMBOL]: params[const_1.SERBER_PATH_SYMBOL].concat(key) });
const result = yield serber.deserializeAsync(obj[key], newParams);
Object.assign(deserialized, { [key]: result });
}
return deserialized;
}),
afterDeserialize: (obj, result, params) => {
if (params[const_1.SERBER_ROOT_OBJECT_SYMBOL] === obj) {
for (const [path, localPath] of params[const_1.SERBER_LOOP_OBJECT_DATA_REVERT_SYMBOL]) {
const globalReferenceForSearch = path.reduce((prev, current) => prev(current), pathof_1.of(result));
const globalReferenceForChange = localPath.reduce((prev, current) => prev(current), pathof_1.of(result));
globalReferenceForChange.set(globalReferenceForSearch.get());
}
}
},
};
//# sourceMappingURL=loopObject.js.map