@syncable/core
Version:
167 lines • 6.26 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const mobx_1 = require("mobx");
class SyncableContainer {
constructor(adapter) {
this.adapter = adapter;
this.typeToIdToSyncableMapMap = mobx_1.observable.map();
this.typeToIdToSyncableObjectMapMap = mobx_1.observable.map();
}
buildSyncableDict(refDict) {
return lodash_1.default.mapValues(refDict, ref => Array.isArray(ref)
? ref.map(ref => this.requireSyncable(ref))
: this.requireSyncable(ref));
}
buildSyncableObjectDict(refDict) {
return lodash_1.default.mapValues(refDict, ref => Array.isArray(ref)
? ref.map(ref => this.requireSyncableObject(ref))
: this.requireSyncableObject(ref));
}
getSyncables(type) {
let typeToIdToSyncableMapMap = this.typeToIdToSyncableMapMap;
if (type) {
let syncableMap = typeToIdToSyncableMapMap.get(type);
if (!syncableMap) {
return [];
}
return Array.from(syncableMap.values());
}
else {
return lodash_1.default.flatten(Array.from(typeToIdToSyncableMapMap.values()).map(map => Array.from(map.values())));
}
}
getSyncable({ type, id, }) {
let syncableMap = this.typeToIdToSyncableMapMap.get(type);
return syncableMap && syncableMap.get(id);
}
requireSyncable(ref) {
let syncable = this.getSyncable(ref);
if (!syncable) {
throw new Error(`Syncable "${JSON.stringify(ref)}" not added to context`);
}
return syncable;
}
existsSyncable({ type, id }) {
let syncableMap = this.typeToIdToSyncableMapMap.get(type);
return !!syncableMap && syncableMap.has(id);
}
getSyncableObjects(type) {
let typeToIdToSyncableMapMap = this.typeToIdToSyncableMapMap;
if (type) {
let syncableMap = typeToIdToSyncableMapMap.get(type);
if (!syncableMap) {
return [];
}
return Array.from(syncableMap.keys()).map(id => this.requireSyncableObject({ type, id }));
}
else {
return lodash_1.default.flatten(Array.from(typeToIdToSyncableMapMap).map(([type, map]) => Array.from(map.keys()).map(id => this.requireSyncableObject({ type, id }))));
}
}
getSyncableObject(ref) {
let { type, id } = ref;
let typeToIdToSyncableObjectMapMap = this.typeToIdToSyncableObjectMapMap;
let syncableObjectMap = typeToIdToSyncableObjectMapMap.get(type);
let object;
if (syncableObjectMap) {
object = syncableObjectMap.get(id);
if (object) {
return object;
}
}
else {
syncableObjectMap = mobx_1.observable.map([], { deep: false });
typeToIdToSyncableObjectMapMap.set(type, syncableObjectMap);
}
object = this.adapter.instantiateByRef(ref, this);
if (!object) {
return undefined;
}
syncableObjectMap.set(id, object);
return object;
}
requireSyncableObject(ref) {
let object = this.getSyncableObject(ref);
if (!object) {
throw new Error(`Syncable "${JSON.stringify(ref)}" not added to context`);
}
return object;
}
/**
* Add a syncable, please notice that it won't change the reference of the
* originally stored syncable. Instead, differences will be applied to it.
*/
addSyncable(snapshot, clock) {
snapshot = lodash_1.default.cloneDeep(snapshot);
let { _id: id, _type: type } = snapshot;
let typeToIdToSyncableMapMap = this.typeToIdToSyncableMapMap;
let syncableMap = typeToIdToSyncableMapMap.get(type);
if (!syncableMap) {
syncableMap = mobx_1.observable.map([], { deep: false });
typeToIdToSyncableMapMap.set(type, syncableMap);
}
let syncable = syncableMap.get(id);
if (syncable) {
if (clock === undefined || clock > syncable._clock) {
syncableMap.set(id, snapshot);
}
}
else {
syncableMap.set(id, snapshot);
}
}
updateMatchingSyncable(snapshot, clock) {
snapshot = lodash_1.default.cloneDeep(snapshot);
let { _id: id, _type: type } = snapshot;
let typeToIdToSyncableMapMap = this.typeToIdToSyncableMapMap;
let syncableMap = typeToIdToSyncableMapMap.get(type);
if (!syncableMap) {
return;
}
let syncable = syncableMap.get(id);
if (syncable) {
if (clock === undefined || clock > syncable._clock) {
syncableMap.set(id, snapshot);
}
}
}
removeSyncable({ type, id }) {
let typeToIdToSyncableMapMap = this.typeToIdToSyncableMapMap;
let typeToIdToSyncableObjectMapMap = this.typeToIdToSyncableObjectMapMap;
let syncableMap = typeToIdToSyncableMapMap.get(type);
let syncable = syncableMap && syncableMap.get(id);
if (!syncable) {
return;
}
let syncableObjectMap = typeToIdToSyncableObjectMapMap.get(type);
if (syncableObjectMap) {
syncableObjectMap.delete(id);
}
syncableMap.delete(id);
}
clear() {
clearMapOrSetMap(this.typeToIdToSyncableMapMap);
clearMapOrSetMap(this.typeToIdToSyncableObjectMapMap);
function clearMapOrSetMap(mapMap) {
for (let map of Array.from(mapMap.values())) {
map.clear();
}
}
}
}
tslib_1.__decorate([
mobx_1.action
], SyncableContainer.prototype, "addSyncable", null);
tslib_1.__decorate([
mobx_1.action
], SyncableContainer.prototype, "updateMatchingSyncable", null);
tslib_1.__decorate([
mobx_1.action
], SyncableContainer.prototype, "removeSyncable", null);
tslib_1.__decorate([
mobx_1.action
], SyncableContainer.prototype, "clear", null);
exports.SyncableContainer = SyncableContainer;
//# sourceMappingURL=syncable-container.js.map