@ablestack/rdo
Version:
A library to facilitate building and running graphs of Reactive Domain Objects - connecting JSON data sources to reactive client applications
125 lines • 7.27 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphSynchronizer = void 0;
const _1 = require(".");
const event_emitter_1 = require("./infrastructure/event-emitter");
const logger_1 = require("./infrastructure/logger");
const mutable_node_cache_1 = require("./infrastructure/mutable-node-cache");
const rdo_node_wrapper_factory_1 = require("./rdo-node-wrappers/rdo-node-wrapper-factory");
const node_tracker_1 = require("./infrastructure/node-tracker");
const logger = logger_1.Logger.make('GraphSynchronizer');
/**
*
*
* @export
* @class GraphSynchronizer
*/
class GraphSynchronizer {
// ------------------------------------------------------------------------------------------------------------------
// CONSTRUCTOR
// ------------------------------------------------------------------------------------------------------------------
constructor(options) {
// ------------------------------------------------------------------------------------------------------------------
// PRIVATE METHODS
// ------------------------------------------------------------------------------------------------------------------
/**
*
*/
this.wrapRdoNode = ({ sourceNodeTypePath, sourceNodeInstancePath, sourceNode, sourceNodeItemKey, rdoNode, rdoNodeItemKey, wrappedParentRdoNode, }) => {
const matchingNodeOptions = this._targetedOptionNodePathsMap.get(sourceNodeTypePath);
const wrappedSourceNode = this._sourceNodeWrapperFactory.make({ sourceNodeTypePath, sourceNodeInstancePath, value: sourceNode, key: sourceNodeItemKey, matchingNodeOptions });
const wrappedRdoNode = this._rdoNodeWrapperFactory.make({ value: rdoNode, key: rdoNodeItemKey, mutableNodeCache: this._mutableNodeCache, wrappedParentRdoNode, wrappedSourceNode, matchingNodeOptions });
return wrappedRdoNode;
};
/**
*
*/
this.syncChildNode = ({ wrappedParentRdoNode, rdoNodeItemKey, sourceNodeItemKey }) => {
logger.trace(`stepIntoChildNodeAndSync (${rdoNodeItemKey}) - enter`);
let changed = false;
// RdoNode
const rdoNodeItemValue = wrappedParentRdoNode.getRdoNodeItem(rdoNodeItemKey);
if (rdoNodeItemValue === undefined) {
logger.trace(`rdoNodeItemValue was null, for key: ${rdoNodeItemKey} in path ${this._nodeTracker.getSourceNodeInstancePath()}. Skipping`);
return false;
}
// SourceNode
const sourceNode = wrappedParentRdoNode.getSourceNodeItem(sourceNodeItemKey);
if (sourceNode === undefined) {
logger.trace(`Could not find child sourceNode with key ${sourceNodeItemKey} in path ${this._nodeTracker.getSourceNodeInstancePath()}. Skipping`, wrappedParentRdoNode.wrappedSourceNode);
return false;
}
// Node traversal tracking - step-in
this._nodeTracker.pushSourceNodeInstancePathOntoStack(sourceNodeItemKey, wrappedParentRdoNode.wrappedSourceNode.typeInfo.kind);
// Wrap Node
const wrappedRdoNode = this.wrapRdoNode({
sourceNodeTypePath: this._nodeTracker.getSourceNodePath(),
sourceNodeInstancePath: this._nodeTracker.getSourceNodeInstancePath(),
sourceNode,
rdoNode: rdoNodeItemValue,
wrappedParentRdoNode: wrappedParentRdoNode,
rdoNodeItemKey,
sourceNodeItemKey,
});
// Test to see if node should be ignored, if not, synchronize
if (wrappedRdoNode.ignore) {
logger.trace(`stepIntoChildNodeAndSync (${rdoNodeItemKey}) - ignore node`);
changed = false;
}
else {
logger.trace(`running smartSync on (${this._nodeTracker.getSourceNodePath()})`);
changed = wrappedRdoNode.smartSync();
}
// Node traversal tracking - step-out
this._nodeTracker.popSourceNodeInstancePathFromStack(wrappedParentRdoNode.wrappedSourceNode.typeInfo.kind);
return changed;
};
this._eventEmitter = new event_emitter_1.EventEmitter();
this.DefaultEqualityComparer = (options === null || options === void 0 ? void 0 : options.customEqualityComparer) || _1.comparers.valueGraph;
this._globalNodeOptions = options === null || options === void 0 ? void 0 : options.globalNodeOptions;
this._targetedOptionNodePathsMap = new Map();
this._targetedOptionMatchersArray = new Array();
this._mutableNodeCache = new mutable_node_cache_1.MutableNodeCache();
this._nodeTracker = new node_tracker_1.NodeTracker();
if (options === null || options === void 0 ? void 0 : options.targetedNodeOptions) {
options === null || options === void 0 ? void 0 : options.targetedNodeOptions.forEach((targetedNodeOptionsItem) => {
if (targetedNodeOptionsItem.sourceNodeMatcher.nodePath)
this._targetedOptionNodePathsMap.set(targetedNodeOptionsItem.sourceNodeMatcher.nodePath, targetedNodeOptionsItem);
this._targetedOptionMatchersArray.push(targetedNodeOptionsItem);
});
}
this._sourceNodeWrapperFactory = new _1.SourceNodeWrapperFactory({ globalNodeOptions: this._globalNodeOptions });
this._rdoNodeWrapperFactory = new rdo_node_wrapper_factory_1.RdoNodeWrapperFactory({
eventEmitter: this._eventEmitter,
syncChildNode: this.syncChildNode,
globalNodeOptions: this._globalNodeOptions,
wrapRdoNode: this.wrapRdoNode,
defaultEqualityComparer: this.DefaultEqualityComparer,
targetedOptionMatchersArray: this._targetedOptionMatchersArray,
});
}
// ------------------------------------------------------------------------------------------------------------------
// PUBLIC METHODS
// ------------------------------------------------------------------------------------------------------------------
/**
*
*/
smartSync({ rootSourceNode, rootRdo }) {
if (!rootSourceNode || !rootRdo) {
logger.warn('smartSync - sourceObject or RDO was null. Exiting', { rootSourceNode, rootRdo });
return;
}
logger.trace('smartSync - sync traversal of object tree starting at root', { rootSourceNode, rootRdo });
const wrappedRdoNode = this.wrapRdoNode({ sourceNodeTypePath: '', sourceNodeInstancePath: '', rdoNode: rootRdo, sourceNode: rootSourceNode });
wrappedRdoNode.smartSync();
logger.trace('smartSync - object tree sync traversal completed', { rootSourceNode, rootRdo });
}
subscribeToNodeChanges(func) {
this._eventEmitter.subscribe('nodeChange', func);
}
unsubscribeToNodeChanges(func) {
this._eventEmitter.unsubscribe('nodeChange', func);
}
}
exports.GraphSynchronizer = GraphSynchronizer;
//# sourceMappingURL=graphSynchronizer.js.map