UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

357 lines 24.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { isUndefined } from '../isUndefined'; import { coerceArray } from '../coerceArray'; import { toBoolean } from '../toBoolean'; import { isFunction } from '../isFunction'; /** * Each plugin that wants to add support for entities should extend this interface. * @abstract * @template State, P */ var /** * Each plugin that wants to add support for entities should extend this interface. * @abstract * @template State, P */ EntityCollectionPlugin = /** @class */ (function () { function EntityCollectionPlugin(query, entityIds) { this.query = query; this.entityIds = entityIds; this.entities = new Map(); } /** * Get the entity plugin instance. */ /** * Get the entity plugin instance. * @protected * @param {?} id * @return {?} */ EntityCollectionPlugin.prototype.getEntity = /** * Get the entity plugin instance. * @protected * @param {?} id * @return {?} */ function (id) { return this.entities.get(id); }; /** * Whether the entity plugin exist. */ /** * Whether the entity plugin exist. * @protected * @param {?} id * @return {?} */ EntityCollectionPlugin.prototype.hasEntity = /** * Whether the entity plugin exist. * @protected * @param {?} id * @return {?} */ function (id) { return this.entities.has(id); }; /** * Remove the entity plugin instance. */ /** * Remove the entity plugin instance. * @protected * @param {?} id * @return {?} */ EntityCollectionPlugin.prototype.removeEntity = /** * Remove the entity plugin instance. * @protected * @param {?} id * @return {?} */ function (id) { this.destroy(id); return this.entities.delete(id); }; /** * Set the entity plugin instance. */ /** * Set the entity plugin instance. * @protected * @param {?} id * @param {?} plugin * @return {?} */ EntityCollectionPlugin.prototype.createEntity = /** * Set the entity plugin instance. * @protected * @param {?} id * @param {?} plugin * @return {?} */ function (id, plugin) { return this.entities.set(id, plugin); }; /** * If the user passes `entityIds` we take them; otherwise, we take all. */ /** * If the user passes `entityIds` we take them; otherwise, we take all. * @protected * @return {?} */ EntityCollectionPlugin.prototype.getIds = /** * If the user passes `entityIds` we take them; otherwise, we take all. * @protected * @return {?} */ function () { return isUndefined(this.entityIds) ? this.query.getValue().ids : coerceArray(this.entityIds); }; /** * When you call one of the plugin methods, you can pass id/ids or undefined which means all. */ /** * When you call one of the plugin methods, you can pass id/ids or undefined which means all. * @protected * @param {?=} ids * @return {?} */ EntityCollectionPlugin.prototype.resolvedIds = /** * When you call one of the plugin methods, you can pass id/ids or undefined which means all. * @protected * @param {?=} ids * @return {?} */ function (ids) { return isUndefined(ids) ? this.getIds() : coerceArray(ids); }; /** * Call this method when you want to activate the plugin on init or when you need to listen to add/remove of entities dynamically. * * For example in your plugin you may do the following: * * this.query.select(state => state.ids).pipe(skip(1)).subscribe(ids => this.activate(ids)); */ /** * Call this method when you want to activate the plugin on init or when you need to listen to add/remove of entities dynamically. * * For example in your plugin you may do the following: * * this.query.select(state => state.ids).pipe(skip(1)).subscribe(ids => this.activate(ids)); * @protected * @param {?} ids * @param {?=} actions * @return {?} */ EntityCollectionPlugin.prototype.rebase = /** * Call this method when you want to activate the plugin on init or when you need to listen to add/remove of entities dynamically. * * For example in your plugin you may do the following: * * this.query.select(state => state.ids).pipe(skip(1)).subscribe(ids => this.activate(ids)); * @protected * @param {?} ids * @param {?=} actions * @return {?} */ function (ids, actions) { var _this = this; if (actions === void 0) { actions = {}; } /** * * If the user passes `entityIds` & we have new ids check if we need to add/remove instances. * * This phase will be called only upon update. */ if (toBoolean(ids)) { /** * Which means all */ if (isUndefined(this.entityIds)) { for (var i = 0, len = ids.length; i < len; i++) { /** @type {?} */ var entityId = ids[i]; if (this.hasEntity(entityId) === false) { isFunction(actions.beforeAdd) && actions.beforeAdd(entityId); /** @type {?} */ var plugin = this.instantiatePlugin(entityId); this.entities.set(entityId, plugin); isFunction(actions.afterAdd) && actions.afterAdd(plugin); } } this.entities.forEach((/** * @param {?} plugin * @param {?} entityId * @return {?} */ function (plugin, entityId) { if (ids.indexOf(entityId) === -1) { isFunction(actions.beforeRemove) && actions.beforeRemove(plugin); _this.removeEntity(entityId); } })); } else { /** * Which means the user passes specific ids * @type {?} */ var _ids = coerceArray(this.entityIds); for (var i = 0, len = _ids.length; i < len; i++) { /** @type {?} */ var entityId = _ids[i]; /** The Entity in current ids and doesn't exist, add it. */ if (ids.indexOf(entityId) > -1 && this.hasEntity(entityId) === false) { isFunction(actions.beforeAdd) && actions.beforeAdd(entityId); /** @type {?} */ var plugin = this.instantiatePlugin(entityId); this.entities.set(entityId, plugin); isFunction(actions.afterAdd) && actions.afterAdd(plugin); } else { this.entities.forEach((/** * @param {?} plugin * @param {?} entityId * @return {?} */ function (plugin, entityId) { /** The Entity not in current ids and exists, remove it. */ if (ids.indexOf(entityId) === -1 && _this.hasEntity(entityId) === true) { isFunction(actions.beforeRemove) && actions.beforeRemove(plugin); _this.removeEntity(entityId); } })); } } } } else { /** * Otherwise, start with the provided ids or all. */ this.getIds().forEach((/** * @param {?} id * @return {?} */ function (id) { if (!_this.hasEntity(id)) _this.createEntity(id, _this.instantiatePlugin(id)); })); } }; /** * Listen for add/remove entities. */ /** * Listen for add/remove entities. * @protected * @return {?} */ EntityCollectionPlugin.prototype.selectIds = /** * Listen for add/remove entities. * @protected * @return {?} */ function () { return this.query.select((/** * @param {?} state * @return {?} */ function (state) { return state.ids; })); }; /** * Base method for activation, you can override it if you need to. */ /** * Base method for activation, you can override it if you need to. * @protected * @param {?=} ids * @return {?} */ EntityCollectionPlugin.prototype.activate = /** * Base method for activation, you can override it if you need to. * @protected * @param {?=} ids * @return {?} */ function (ids) { this.rebase(ids); }; /** * Loop over each id and invoke the plugin method. */ /** * Loop over each id and invoke the plugin method. * @protected * @param {?} ids * @param {?} cb * @return {?} */ EntityCollectionPlugin.prototype.forEachId = /** * Loop over each id and invoke the plugin method. * @protected * @param {?} ids * @param {?} cb * @return {?} */ function (ids, cb) { /** @type {?} */ var _ids = this.resolvedIds(ids); for (var i = 0, len = _ids.length; i < len; i++) { /** @type {?} */ var id = _ids[i]; if (this.hasEntity(id)) { cb(this.getEntity(id)); } } }; return EntityCollectionPlugin; }()); /** * Each plugin that wants to add support for entities should extend this interface. * @abstract * @template State, P */ export { EntityCollectionPlugin }; if (false) { /** * @type {?} * @protected */ EntityCollectionPlugin.prototype.entities; /** * @type {?} * @protected */ EntityCollectionPlugin.prototype.query; /** * @type {?} * @private */ EntityCollectionPlugin.prototype.entityIds; /** * This method is responsible for plugin instantiation. * * For example: * return new StateHistory(this.query, this.params, id) as P; * @abstract * @protected * @param {?} id * @return {?} */ EntityCollectionPlugin.prototype.instantiatePlugin = function (id) { }; /** * This method is responsible for cleaning. * @abstract * @param {?=} id * @return {?} */ EntityCollectionPlugin.prototype.destroy = function (id) { }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5Q29sbGVjdGlvblBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BkYXRvcmFtYS9ha2l0YS8iLCJzb3VyY2VzIjpbInNyYy9wbHVnaW5zL2VudGl0eUNvbGxlY3Rpb25QbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUdBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7QUFTM0M7Ozs7OztJQUdFLGdDQUFnQyxLQUF5QixFQUFVLFNBQW9DO1FBQXZFLFVBQUssR0FBTCxLQUFLLENBQW9CO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBMkI7UUFGN0YsYUFBUSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBRXNELENBQUM7SUFFM0c7O09BRUc7Ozs7Ozs7SUFDTywwQ0FBUzs7Ozs7O0lBQW5CLFVBQW9CLEVBQW9CO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVEOztPQUVHOzs7Ozs7O0lBQ08sMENBQVM7Ozs7OztJQUFuQixVQUFvQixFQUFvQjtRQUN0QyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7T0FFRzs7Ozs7OztJQUNPLDZDQUFZOzs7Ozs7SUFBdEIsVUFBdUIsRUFBb0I7UUFDekMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRzs7Ozs7Ozs7SUFDTyw2Q0FB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LFVBQUEsS0FBSyxJQUFJLE9BQUEsS0FBSyxDQUFDLEdBQUcsRUFBVCxDQUFTLEVBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQ7O09BRUc7Ozs7Ozs7SUFDTyx5Q0FBUTs7Ozs7O0lBQWxCLFVBQW1CLEdBQVc7UUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBZUQ7O09BRUc7Ozs7Ozs7O0lBQ08sMENBQVM7Ozs7Ozs7SUFBbkIsVUFBb0IsR0FBOEIsRUFBRSxFQUFzQjs7WUFDbEUsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDO1FBRWxDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O2dCQUN6QyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNsQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQ3RCLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDeEI7U0FDRjtJQUNILENBQUM7SUFDSCw2QkFBQztBQUFELENBQUMsQUE3SkQsSUE2SkM7Ozs7Ozs7Ozs7OztJQTVKQywwQ0FBb0Q7Ozs7O0lBRTlCLHVDQUFtQzs7Ozs7SUFBRSwyQ0FBNEM7Ozs7Ozs7Ozs7O0lBc0l2Ryx1RUFBOEQ7Ozs7Ozs7SUFLOUQsNkRBQStDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgRW50aXR5U3RhdGUsIE9yQXJyYXksIGdldElEVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IFF1ZXJ5RW50aXR5IH0gZnJvbSAnLi4vcXVlcnlFbnRpdHknO1xuaW1wb3J0IHsgaXNVbmRlZmluZWQgfSBmcm9tICcuLi9pc1VuZGVmaW5lZCc7XG5pbXBvcnQgeyBjb2VyY2VBcnJheSB9IGZyb20gJy4uL2NvZXJjZUFycmF5JztcbmltcG9ydCB7IHRvQm9vbGVhbiB9IGZyb20gJy4uL3RvQm9vbGVhbic7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnLi4vaXNGdW5jdGlvbic7XG5cbmV4cG9ydCB0eXBlIFJlYmFzZUFjdGlvbjxQID0gYW55PiA9IChwbHVnaW46IFApID0+IGFueTtcblxuZXhwb3J0IHR5cGUgUmViYXNlQWN0aW9uczxQID0gYW55PiA9IHsgYmVmb3JlUmVtb3ZlPzogUmViYXNlQWN0aW9uOyBiZWZvcmVBZGQ/OiBSZWJhc2VBY3Rpb247IGFmdGVyQWRkPzogUmViYXNlQWN0aW9uIH07XG5cbi8qKlxuICogRWFjaCBwbHVnaW4gdGhhdCB3YW50cyB0byBhZGQgc3VwcG9ydCBmb3IgZW50aXRpZXMgc2hvdWxkIGV4dGVuZCB0aGlzIGludGVyZmFjZS5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEVudGl0eUNvbGxlY3Rpb25QbHVnaW48U3RhdGUgZXh0ZW5kcyBFbnRpdHlTdGF0ZSwgUD4ge1xuICBwcm90ZWN0ZWQgZW50aXRpZXMgPSBuZXcgTWFwPGdldElEVHlwZTxTdGF0ZT4sIFA+KCk7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBxdWVyeTogUXVlcnlFbnRpdHk8U3RhdGU+LCBwcml2YXRlIGVudGl0eUlkczogT3JBcnJheTxnZXRJRFR5cGU8U3RhdGU+Pikge31cblxuICAvKipcbiAgICogR2V0IHRoZSBlbnRpdHkgcGx1Z2luIGluc3RhbmNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldEVudGl0eShpZDogZ2V0SURUeXBlPFN0YXRlPik6IFAge1xuICAgIHJldHVybiB0aGlzLmVudGl0aWVzLmdldChpZCk7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZW50aXR5IHBsdWdpbiBleGlzdC5cbiAgICovXG4gIHByb3RlY3RlZCBoYXNFbnRpdHkoaWQ6IGdldElEVHlwZTxTdGF0ZT4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lbnRpdGllcy5oYXMoaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgZW50aXR5IHBsdWdpbiBpbnN0YW5jZS5cbiAgICovXG4gIHByb3RlY3RlZCByZW1vdmVFbnRpdHkoaWQ6IGdldElEVHlwZTxTdGF0ZT4pIHtcbiAgICB0aGlzLmRlc3Ryb3koaWQpO1xuICAgIHJldHVybiB0aGlzLmVudGl0aWVzLmRlbGV0ZShpZCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBlbnRpdHkgcGx1Z2luIGluc3RhbmNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZUVudGl0eShpZDogZ2V0SURUeXBlPFN0YXRlPiwgcGx1Z2luOiBQKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXRpZXMuc2V0KGlkLCBwbHVnaW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIHRoZSB1c2VyIHBhc3NlcyBgZW50aXR5SWRzYCB3ZSB0YWtlIHRoZW07IG90aGVyd2lzZSwgd2UgdGFrZSBhbGwuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0SWRzKCk6IGFueSB7XG4gICAgcmV0dXJuIGlzVW5kZWZpbmVkKHRoaXMuZW50aXR5SWRzKSA/IHRoaXMucXVlcnkuZ2V0VmFsdWUoKS5pZHMgOiBjb2VyY2VBcnJheSh0aGlzLmVudGl0eUlkcyk7XG4gIH1cblxuICAvKipcbiAgICogV2hlbiB5b3UgY2FsbCBvbmUgb2YgdGhlIHBsdWdpbiBtZXRob2RzLCB5b3UgY2FuIHBhc3MgaWQvaWRzIG9yIHVuZGVmaW5lZCB3aGljaCBtZWFucyBhbGwuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVzb2x2ZWRJZHMoaWRzPyk6IGdldElEVHlwZTxTdGF0ZT5bXSB7XG4gICAgcmV0dXJuIGlzVW5kZWZpbmVkKGlkcykgPyB0aGlzLmdldElkcygpIDogY29lcmNlQXJyYXkoaWRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsIHRoaXMgbWV0aG9kIHdoZW4geW91IHdhbnQgdG8gYWN0aXZhdGUgdGhlIHBsdWdpbiBvbiBpbml0IG9yIHdoZW4geW91IG5lZWQgdG8gbGlzdGVuIHRvIGFkZC9yZW1vdmUgb2YgZW50aXRpZXMgZHluYW1pY2FsbHkuXG4gICAqXG4gICAqIEZvciBleGFtcGxlIGluIHlvdXIgcGx1Z2luIHlvdSBtYXkgZG8gdGhlIGZvbGxvd2luZzpcbiAgICpcbiAgICogdGhpcy5xdWVyeS5zZWxlY3Qoc3RhdGUgPT4gc3RhdGUuaWRzKS5waXBlKHNraXAoMSkpLnN1YnNjcmliZShpZHMgPT4gdGhpcy5hY3RpdmF0ZShpZHMpKTtcbiAgICovXG4gIHByb3RlY3RlZCByZWJhc2UoaWRzOiBnZXRJRFR5cGU8U3RhdGU+W10sIGFjdGlvbnM6IFJlYmFzZUFjdGlvbnM8UD4gPSB7fSkge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogSWYgdGhlIHVzZXIgcGFzc2VzIGBlbnRpdHlJZHNgICYgd2UgaGF2ZSBuZXcgaWRzIGNoZWNrIGlmIHdlIG5lZWQgdG8gYWRkL3JlbW92ZSBpbnN0YW5jZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIHBoYXNlIHdpbGwgYmUgY2FsbGVkIG9ubHkgdXBvbiB1cGRhdGUuXG4gICAgICovXG4gICAgaWYgKHRvQm9vbGVhbihpZHMpKSB7XG4gICAgICAvKipcbiAgICAgICAqIFdoaWNoIG1lYW5zIGFsbFxuICAgICAgICovXG4gICAgICBpZiAoaXNVbmRlZmluZWQodGhpcy5lbnRpdHlJZHMpKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBpZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBlbnRpdHlJZCA9IGlkc1tpXTtcbiAgICAgICAgICBpZiAodGhpcy5oYXNFbnRpdHkoZW50aXR5SWQpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgaXNGdW5jdGlvbihhY3Rpb25zLmJlZm9yZUFkZCkgJiYgYWN0aW9ucy5iZWZvcmVBZGQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3QgcGx1Z2luID0gdGhpcy5pbnN0YW50aWF0ZVBsdWdpbihlbnRpdHlJZCk7XG4gICAgICAgICAgICB0aGlzLmVudGl0aWVzLnNldChlbnRpdHlJZCwgcGx1Z2luKTtcbiAgICAgICAgICAgIGlzRnVuY3Rpb24oYWN0aW9ucy5hZnRlckFkZCkgJiYgYWN0aW9ucy5hZnRlckFkZChwbHVnaW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZW50aXRpZXMuZm9yRWFjaCgocGx1Z2luLCBlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgIGlmIChpZHMuaW5kZXhPZihlbnRpdHlJZCkgPT09IC0xKSB7XG4gICAgICAgICAgICBpc0Z1bmN0aW9uKGFjdGlvbnMuYmVmb3JlUmVtb3ZlKSAmJiBhY3Rpb25zLmJlZm9yZVJlbW92ZShwbHVnaW4pO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVFbnRpdHkoZW50aXR5SWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hpY2ggbWVhbnMgdGhlIHVzZXIgcGFzc2VzIHNwZWNpZmljIGlkc1xuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgX2lkcyA9IGNvZXJjZUFycmF5KHRoaXMuZW50aXR5SWRzKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IF9pZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBlbnRpdHlJZCA9IF9pZHNbaV07XG4gICAgICAgICAgLyoqIFRoZSBFbnRpdHkgaW4gY3VycmVudCBpZHMgYW5kIGRvZXNuJ3QgZXhpc3QsIGFkZCBpdC4gKi9cbiAgICAgICAgICBpZiAoaWRzLmluZGV4T2YoZW50aXR5SWQpID4gLTEgJiYgdGhpcy5oYXNFbnRpdHkoZW50aXR5SWQpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgaXNGdW5jdGlvbihhY3Rpb25zLmJlZm9yZUFkZCkgJiYgYWN0aW9ucy5iZWZvcmVBZGQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3QgcGx1Z2luID0gdGhpcy5pbnN0YW50aWF0ZVBsdWdpbihlbnRpdHlJZCk7XG4gICAgICAgICAgICB0aGlzLmVudGl0aWVzLnNldChlbnRpdHlJZCwgcGx1Z2luKTtcbiAgICAgICAgICAgIGlzRnVuY3Rpb24oYWN0aW9ucy5hZnRlckFkZCkgJiYgYWN0aW9ucy5hZnRlckFkZChwbHVnaW4pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmVudGl0aWVzLmZvckVhY2goKHBsdWdpbiwgZW50aXR5SWQpID0+IHtcbiAgICAgICAgICAgICAgLyoqIFRoZSBFbnRpdHkgbm90IGluIGN1cnJlbnQgaWRzIGFuZCBleGlzdHMsIHJlbW92ZSBpdC4gKi9cbiAgICAgICAgICAgICAgaWYgKGlkcy5pbmRleE9mKGVudGl0eUlkKSA9PT0gLTEgJiYgdGhpcy5oYXNFbnRpdHkoZW50aXR5SWQpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgaXNGdW5jdGlvbihhY3Rpb25zLmJlZm9yZVJlbW92ZSkgJiYgYWN0aW9ucy5iZWZvcmVSZW1vdmUocGx1Z2luKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUVudGl0eShlbnRpdHlJZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvKipcbiAgICAgICAqIE90aGVyd2lzZSwgc3RhcnQgd2l0aCB0aGUgcHJvdmlkZWQgaWRzIG9yIGFsbC5cbiAgICAgICAqL1xuICAgICAgdGhpcy5nZXRJZHMoKS5mb3JFYWNoKGlkID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmhhc0VudGl0eShpZCkpIHRoaXMuY3JlYXRlRW50aXR5KGlkLCB0aGlzLmluc3RhbnRpYXRlUGx1Z2luKGlkKSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuIGZvciBhZGQvcmVtb3ZlIGVudGl0aWVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNlbGVjdElkcygpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5LnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5pZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJhc2UgbWV0aG9kIGZvciBhY3RpdmF0aW9uLCB5b3UgY2FuIG92ZXJyaWRlIGl0IGlmIHlvdSBuZWVkIHRvLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFjdGl2YXRlKGlkcz86IGFueVtdKSB7XG4gICAgdGhpcy5yZWJhc2UoaWRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3IgcGx1Z2luIGluc3RhbnRpYXRpb24uXG4gICAqXG4gICAqIEZvciBleGFtcGxlOlxuICAgKiByZXR1cm4gbmV3IFN0YXRlSGlzdG9yeSh0aGlzLnF1ZXJ5LCB0aGlzLnBhcmFtcywgaWQpIGFzIFA7XG4gICAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW5zdGFudGlhdGVQbHVnaW4oaWQ6IGdldElEVHlwZTxTdGF0ZT4pOiBQO1xuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3IgY2xlYW5pbmcuXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgZGVzdHJveShpZD86IGdldElEVHlwZTxTdGF0ZT4pO1xuXG4gIC8qKlxuICAgKiBMb29wIG92ZXIgZWFjaCBpZCBhbmQgaW52b2tlIHRoZSBwbHVnaW4gbWV0aG9kLlxuICAgKi9cbiAgcHJvdGVjdGVkIGZvckVhY2hJZChpZHM6IE9yQXJyYXk8Z2V0SURUeXBlPFN0YXRlPj4sIGNiOiAoZW50aXR5OiBQKSA9PiBhbnkpIHtcbiAgICBjb25zdCBfaWRzID0gdGhpcy5yZXNvbHZlZElkcyhpZHMpO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IF9pZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGNvbnN0IGlkID0gX2lkc1tpXTtcbiAgICAgIGlmICh0aGlzLmhhc0VudGl0eShpZCkpIHtcbiAgICAgICAgY2IodGhpcy5nZXRFbnRpdHkoaWQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==