@orbit/coordinator
Version:
A coordinator and set of coordination strategies for managing data flow and keeping @orbit/data sources in sync.
128 lines • 16.8 kB
JavaScript
import { Orbit } from '@orbit/core';
import { objectValues } from '@orbit/utils';
const { assert } = Orbit;
export var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["None"] = 0] = "None";
LogLevel[LogLevel["Errors"] = 1] = "Errors";
LogLevel[LogLevel["Warnings"] = 2] = "Warnings";
LogLevel[LogLevel["Info"] = 3] = "Info";
})(LogLevel || (LogLevel = {}));
/**
* The Coordinator class manages a set of sources to which it applies a set of
* coordination strategies.
*/
export class Coordinator {
constructor(options = {}) {
this._sources = {};
this._strategies = {};
if (options.sources) {
options.sources.forEach((source) => this.addSource(source));
}
if (options.strategies) {
options.strategies.forEach((strategy) => this.addStrategy(strategy));
}
this._defaultActivationOptions = options.defaultActivationOptions || {};
if (this._defaultActivationOptions.logLevel === undefined) {
this._defaultActivationOptions.logLevel = LogLevel.Info;
}
}
addSource(source) {
const name = source.name;
if (name) {
assert(`A source named '${name}' has already been added to this coordinator.`, !this._sources[name]);
assert(`A coordinator's sources can not be changed while it is active.`, !this._activated);
this._sources[name] = source;
}
else {
assert(`Sources require a 'name' to be added to a coordinator.`, !!name);
}
}
removeSource(name) {
let source = this._sources[name];
assert(`Source '${name}' has not been added to this coordinator.`, !!source);
assert(`A coordinator's sources can not be changed while it is active.`, !this._activated);
delete this._sources[name];
}
getSource(name) {
return this._sources[name];
}
get sources() {
return objectValues(this._sources);
}
get sourceNames() {
return Object.keys(this._sources);
}
addStrategy(strategy) {
const name = strategy.name;
assert(`A strategy named '${name}' has already been added to this coordinator.`, !this._strategies[name]);
assert(`A coordinator's strategies can not be changed while it is active.`, !this._activated);
this._strategies[name] = strategy;
}
removeStrategy(name) {
let strategy = this._strategies[name];
assert(`Strategy '${name}' has not been added to this coordinator.`, !!strategy);
assert(`A coordinator's strategies can not be changed while it is active.`, !this._activated);
delete this._strategies[name];
}
getStrategy(name) {
return this._strategies[name];
}
get strategies() {
return objectValues(this._strategies);
}
get strategyNames() {
return Object.keys(this._strategies);
}
get activated() {
return this._activated;
}
async activate(options = {}) {
if (!this._activated) {
this._activated = this._activate(options);
}
await this._activated;
}
async deactivate() {
if (this._activated) {
await this._activated;
await this._deactivate();
}
this._activated = undefined;
}
async _activate(options = {}) {
if (options.logLevel === undefined) {
options.logLevel = this._defaultActivationOptions.logLevel;
}
this._currentActivationOptions = options;
for (let strategy of this.strategies) {
await strategy.activate(this, options);
}
for (let strategy of this.strategies) {
await strategy.beforeSourceActivation();
}
for (let source of this.sources) {
await source.activate();
}
for (let strategy of this.strategies) {
await strategy.afterSourceActivation();
}
}
async _deactivate() {
const strategies = this.strategies.reverse();
const sources = this.sources.reverse();
for (let strategy of strategies) {
await strategy.beforeSourceDeactivation();
}
for (let source of sources) {
await source.deactivate();
}
for (let strategy of strategies) {
await strategy.afterSourceDeactivation();
}
for (let strategy of strategies) {
await strategy.deactivate();
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29vcmRpbmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29vcmRpbmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVwQyxPQUFPLEVBQVEsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBR2xELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFRekIsTUFBTSxDQUFOLElBQVksUUFLWDtBQUxELFdBQVksUUFBUTtJQUNsQix1Q0FBSSxDQUFBO0lBQ0osMkNBQU0sQ0FBQTtJQUNOLCtDQUFRLENBQUE7SUFDUix1Q0FBSSxDQUFBO0FBQ04sQ0FBQyxFQUxXLFFBQVEsS0FBUixRQUFRLFFBS25CO0FBTUQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFPdEIsWUFBWSxVQUE4QixFQUFFO1FBQzFDLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1FBRXRCLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRTtZQUNuQixPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQzdEO1FBRUQsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFO1lBQ3RCLE9BQU8sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FDdEU7UUFFRCxJQUFJLENBQUMseUJBQXlCLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixJQUFJLEVBQUUsQ0FBQztRQUV4RSxJQUFJLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFO1lBQ3pELElB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QUM7UUFDN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV2QyxLQUFLLElBQUksUUFBUSxJQUFJLFVBQVUsRUFBRTtZQUMvQixNQUFNLFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1NBQzNDO1FBRUQsS0FBSyxJQUFJLE1BQU0sSUFBSSxPQUFPLEVBQUU7WUFDMUIsTUFBTSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDM0I7UUFFRCxLQUFLLElBQUksUUFBUSxJQUFJLFVBQVUsRUFBRTtZQUMvQixNQUFNLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1NBQzFDO1FBRUQsS0FBSyxJQUFJLFFBQVEsSUFBSSxVQUFVLEVBQUU7WUFDL0IsTUFBTSxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDN0I7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcmJpdCB9IGZyb20gJ0BvcmJpdC9jb3JlJztcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gJ0BvcmJpdC9kYXRhJztcbmltcG9ydCB7IERpY3QsIG9iamVjdFZhbHVlcyB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBTdHJhdGVneSB9IGZyb20gJy4vc3RyYXRlZ3knO1xuXG5jb25zdCB7IGFzc2VydCB9ID0gT3JiaXQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29vcmRpbmF0b3JPcHRpb25zIHtcbiAgc291cmNlcz86IFNvdXJjZVtdO1xuICBzdHJhdGVnaWVzPzogU3RyYXRlZ3lbXTtcbiAgZGVmYXVsdEFjdGl2YXRpb25PcHRpb25zPzogQWN0aXZhdGlvbk9wdGlvbnM7XG59XG5cbmV4cG9ydCBlbnVtIExvZ0xldmVsIHtcbiAgTm9uZSxcbiAgRXJyb3JzLFxuICBXYXJuaW5ncyxcbiAgSW5mb1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjdGl2YXRpb25PcHRpb25zIHtcbiAgbG9nTGV2ZWw/OiBMb2dMZXZlbDtcbn1cblxuLyoqXG4gKiBUaGUgQ29vcmRpbmF0b3IgY2xhc3MgbWFuYWdlcyBhIHNldCBvZiBzb3VyY2VzIHRvIHdoaWNoIGl0IGFwcGxpZXMgYSBzZXQgb2ZcbiAqIGNvb3JkaW5hdGlvbiBzdHJhdGVnaWVzLlxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0b3Ige1xuICBwcm90ZWN0ZWQgX3NvdXJjZXM6IERpY3Q8U291cmNlPjtcbiAgcHJvdGVjdGVkIF9zdHJhdGVnaWVzOiBEaWN0PFN0cmF0ZWd5PjtcbiAgcHJvdGVjdGVkIF9hY3RpdmF0ZWQ/OiBQcm9taXNlPHZvaWQ+O1xuICBwcm90ZWN0ZWQgX2RlZmF1bHRBY3RpdmF0aW9uT3B0aW9uczogQWN0aXZhdGlvbk9wdGlvbnM7XG4gIHByb3RlY3RlZCBfY3VycmVudEFjdGl2YXRpb25PcHRpb25zPzogQWN0aXZhdGlvbk9wdGlvbnM7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogQ29vcmRpbmF0b3JPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLl9zb3VyY2VzID0ge307XG4gICAgdGhpcy5fc3RyYXRlZ2llcyA9IHt9O1xuXG4gICAgaWYgKG9wdGlvbnMuc291cmNlcykge1xuICAgICAgb3B0aW9ucy5zb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4gdGhpcy5hZGRTb3VyY2Uoc291cmNlKSk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc3RyYXRlZ2llcykge1xuICAgICAgb3B0aW9ucy5zdHJhdGVnaWVzLmZvckVhY2goKHN0cmF0ZWd5KSA9PiB0aGlzLmFkZFN0cmF0ZWd5KHN0cmF0ZWd5KSk7XG4gICAgfVxuXG4gICAgdGhpcy5fZGVmYXVsdEFjdGl2YXRpb25PcHRpb25zID0gb3B0aW9ucy5kZWZhdWx0QWN0aXZhdGlvbk9wdGlvbnMgfHwge307XG5cbiAgICBpZiAodGhpcy5fZGVmYXVsdEFjdGl2YXRpb25PcHRpb25zLmxvZ0xldmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX2RlZmF1bHRBY3RpdmF0aW9uT3B0aW9ucy5sb2dMZXZlbCA9IExvZ0xldmVsLkluZm87XG4gICAgfVxuICB9XG5cbiAgYWRkU291cmNlKHNvdXJjZTogU291cmNlKTogdm9pZCB7XG4gICAgY29uc3QgbmFtZSA9IHNvdXJjZS5uYW1lO1xuICAgIGlmIChuYW1lKSB7XG4gICAgICBhc3NlcnQoXG4gICAgICAgIGBBIHNvdXJjZSBuYW1lZCAnJHtuYW1lfScgaGFzIGFscmVhZHkgYmVlbiBhZGRlZCB0byB0aGlzIGNvb3JkaW5hdG9yLmAsXG4gICAgICAgICF0aGlzLl9zb3VyY2VzW25hbWVdXG4gICAgICApO1xuICAgICAgYXNzZXJ0KFxuICAgICAgICBgQSBjb29yZGluYXRvcidzIHNvdXJjZXMgY2FuIG5vdCBiZSBjaGFuZ2VkIHdoaWxlIGl0IGlzIGFjdGl2ZS5gLFxuICAgICAgICAhdGhpcy5fYWN0aXZhdGVkXG4gICAgICApO1xuICAgICAgdGhpcy5fc291cmNlc1tuYW1lXSA9IHNvdXJjZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KGBTb3VyY2VzIHJlcXVpcmUgYSAnbmFtZScgdG8gYmUgYWRkZWQgdG8gYSBjb29yZGluYXRvci5gLCAhIW5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZVNvdXJjZShuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgc291cmNlID0gdGhpcy5fc291cmNlc1tuYW1lXTtcblxuICAgIGFzc2VydChcbiAgICAgIGBTb3VyY2UgJyR7bmFtZX0nIGhhcyBub3QgYmVlbiBhZGRlZCB0byB0aGlzIGNvb3JkaW5hdG9yLmAsXG4gICAgICAhIXNvdXJjZVxuICAgICk7XG4gICAgYXNzZXJ0KFxuICAgICAgYEEgY29vcmRpbmF0b3IncyBzb3VyY2VzIGNhbiBub3QgYmUgY2hhbmdlZCB3aGlsZSBpdCBpcyBhY3RpdmUuYCxcbiAgICAgICF0aGlzLl9hY3RpdmF0ZWRcbiAgICApO1xuXG4gICAgZGVsZXRlIHRoaXMuX3NvdXJjZXNbbmFtZV07XG4gIH1cblxuICBnZXRTb3VyY2U8VCBleHRlbmRzIFNvdXJjZSA9IFNvdXJjZT4obmFtZTogc3RyaW5nKTogVCB7XG4gICAgcmV0dXJuIHRoaXMuX3NvdXJjZXNbbmFtZV0gYXMgVDtcbiAgfVxuXG4gIGdldCBzb3VyY2VzKCk6IFNvdXJjZVtdIHtcbiAgICByZXR1cm4gb2JqZWN0VmFsdWVzKHRoaXMuX3NvdXJjZXMpO1xuICB9XG5cbiAgZ2V0IHNvdXJjZU5hbWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fc291cmNlcyk7XG4gIH1cblxuICBhZGRTdHJhdGVneShzdHJhdGVneTogU3RyYXRlZ3kpOiB2b2lkIHtcbiAgICBjb25zdCBuYW1lID0gc3RyYXRlZ3kubmFtZTtcblxuICAgIGFzc2VydChcbiAgICAgIGBBIHN0cmF0ZWd5IG5hbWVkICcke25hbWV9JyBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkIHRvIHRoaXMgY29vcmRpbmF0b3IuYCxcbiAgICAgICF0aGlzLl9zdHJhdGVnaWVzW25hbWVdXG4gICAgKTtcbiAgICBhc3NlcnQoXG4gICAgICBgQSBjb29yZGluYXRvcidzIHN0cmF0ZWdpZXMgY2FuIG5vdCBiZSBjaGFuZ2VkIHdoaWxlIGl0IGlzIGFjdGl2ZS5gLFxuICAgICAgIXRoaXMuX2FjdGl2YXRlZFxuICAgICk7XG5cbiAgICB0aGlzLl9zdHJhdGVnaWVzW25hbWVdID0gc3RyYXRlZ3k7XG4gIH1cblxuICByZW1vdmVTdHJhdGVneShuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgc3RyYXRlZ3kgPSB0aGlzLl9zdHJhdGVnaWVzW25hbWVdO1xuXG4gICAgYXNzZXJ0KFxuICAgICAgYFN0cmF0ZWd5ICcke25hbWV9JyBoYXMgbm90IGJlZW4gYWRkZWQgdG8gdGhpcyBjb29yZGluYXRvci5gLFxuICAgICAgISFzdHJhdGVneVxuICAgICk7XG4gICAgYXNzZXJ0KFxuICAgICAgYEEgY29vcmRpbmF0b3IncyBzdHJhdGVnaWVzIGNhbiBub3QgYmUgY2hhbmdlZCB3aGlsZSBpdCBpcyBhY3RpdmUuYCxcbiAgICAgICF0aGlzLl9hY3RpdmF0ZWRcbiAgICApO1xuXG4gICAgZGVsZXRlIHRoaXMuX3N0cmF0ZWdpZXNbbmFtZV07XG4gIH1cblxuICBnZXRTdHJhdGVneTxUIGV4dGVuZHMgU3RyYXRlZ3kgPSBTdHJhdGVneT4obmFtZTogc3RyaW5nKTogVCB7XG4gICAgcmV0dXJuIHRoaXMuX3N0cmF0ZWdpZXNbbmFtZV0gYXMgVDtcbiAgfVxuXG4gIGdldCBzdHJhdGVnaWVzKCk6IFN0cmF0ZWd5W10ge1xuICAgIHJldHVybiBvYmplY3RWYWx1ZXModGhpcy5fc3RyYXRlZ2llcyk7XG4gIH1cblxuICBnZXQgc3RyYXRlZ3lOYW1lcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3N0cmF0ZWdpZXMpO1xuICB9XG5cbiAgZ2V0IGFjdGl2YXRlZCgpOiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZhdGVkO1xuICB9XG5cbiAgYXN5bmMgYWN0aXZhdGUob3B0aW9uczogQWN0aXZhdGlvbk9wdGlvbnMgPSB7fSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5fYWN0aXZhdGVkKSB7XG4gICAgICB0aGlzLl9hY3RpdmF0ZWQgPSB0aGlzLl9hY3RpdmF0ZShvcHRpb25zKTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5fYWN0aXZhdGVkO1xuICB9XG5cbiAgYXN5bmMgZGVhY3RpdmF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5fYWN0aXZhdGVkKSB7XG4gICAgICBhd2FpdCB0aGlzLl9hY3RpdmF0ZWQ7XG4gICAgICBhd2FpdCB0aGlzLl9kZWFjdGl2YXRlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYWN0aXZhdGVkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIF9hY3RpdmF0ZShvcHRpb25zOiBBY3RpdmF0aW9uT3B0aW9ucyA9IHt9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKG9wdGlvbnMubG9nTGV2ZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucy5sb2dMZXZlbCA9IHRoaXMuX2RlZmF1bHRBY3RpdmF0aW9uT3B0aW9ucy5sb2dMZXZlbDtcbiAgICB9XG5cbiAgICB0aGlzLl9jdXJyZW50QWN0aXZhdGlvbk9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgZm9yIChsZXQgc3RyYXRlZ3kgb2YgdGhpcy5zdHJhdGVnaWVzKSB7XG4gICAgICBhd2FpdCBzdHJhdGVneS5hY3RpdmF0ZSh0aGlzLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBzdHJhdGVneSBvZiB0aGlzLnN0cmF0ZWdpZXMpIHtcbiAgICAgIGF3YWl0IHN0cmF0ZWd5LmJlZm9yZVNvdXJjZUFjdGl2YXRpb24oKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBzb3VyY2Ugb2YgdGhpcy5zb3VyY2VzKSB7XG4gICAgICBhd2FpdCBzb3VyY2UuYWN0aXZhdGUoKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBzdHJhdGVneSBvZiB0aGlzLnN0cmF0ZWdpZXMpIHtcbiAgICAgIGF3YWl0IHN0cmF0ZWd5LmFmdGVyU291cmNlQWN0aXZhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBfZGVhY3RpdmF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdHJhdGVnaWVzID0gdGhpcy5zdHJhdGVnaWVzLnJldmVyc2UoKTtcbiAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5zb3VyY2VzLnJldmVyc2UoKTtcblxuICAgIGZvciAobGV0IHN0cmF0ZWd5IG9mIHN0cmF0ZWdpZXMpIHtcbiAgICAgIGF3YWl0IHN0cmF0ZWd5LmJlZm9yZVNvdXJjZURlYWN0aXZhdGlvbigpO1xuICAgIH1cblxuICAgIGZvciAobGV0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgICBhd2FpdCBzb3VyY2UuZGVhY3RpdmF0ZSgpO1xuICAgIH1cblxuICAgIGZvciAobGV0IHN0cmF0ZWd5IG9mIHN0cmF0ZWdpZXMpIHtcbiAgICAgIGF3YWl0IHN0cmF0ZWd5LmFmdGVyU291cmNlRGVhY3RpdmF0aW9uKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgc3RyYXRlZ3kgb2Ygc3RyYXRlZ2llcykge1xuICAgICAgYXdhaXQgc3RyYXRlZ3kuZGVhY3RpdmF0ZSgpO1xuICAgIH1cbiAgfVxufVxuIl19