@launchdarkly/js-server-sdk-common
Version:
LaunchDarkly Server SDK for JavaScript - common code
96 lines • 4.53 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const VersionedDataKinds_1 = require("../store/VersionedDataKinds");
const DataSourceUpdates_1 = require("./DataSourceUpdates");
const DependencyTracker_1 = require("./DependencyTracker");
const NamespacedDataSet_1 = require("./NamespacedDataSet");
/**
* @internal
*/
class TransactionalDataSourceUpdates {
constructor(_featureStore, _hasEventListeners, _onChange) {
this._featureStore = _featureStore;
this._hasEventListeners = _hasEventListeners;
this._onChange = _onChange;
this._dependencyTracker = new DependencyTracker_1.default();
}
init(allData, callback, initMetadata) {
this.applyChanges(true, allData, callback, initMetadata); // basis is true for init
}
upsert(kind, data, callback) {
this.applyChanges(false, // basis is false for upserts
{
[kind.namespace]: {
[data.key]: data,
},
}, callback);
}
applyChanges(basis, data, callback, initMetadata, selector) {
const checkForChanges = this._hasEventListeners();
const doApplyChanges = (oldData) => {
this._featureStore.applyChanges(basis, data, () => {
// Defer change events so they execute after the callback.
Promise.resolve().then(() => {
if (basis) {
this._dependencyTracker.reset();
}
Object.entries(data).forEach(([namespace, items]) => {
Object.keys(items || {}).forEach((key) => {
const item = items[key];
this._dependencyTracker.updateDependenciesFrom(namespace, key, (0, DataSourceUpdates_1.computeDependencies)(namespace, item));
});
});
if (checkForChanges) {
const updatedItems = new NamespacedDataSet_1.default();
Object.keys(data).forEach((namespace) => {
const oldDataForKind = oldData[namespace];
const newDataForKind = data[namespace];
let iterateData;
if (basis) {
// for basis, need to iterate on all keys
iterateData = Object.assign(Object.assign({}, oldDataForKind), newDataForKind);
}
else {
// for non basis, only need to iterate on keys in incoming data
iterateData = Object.assign({}, newDataForKind);
}
Object.keys(iterateData).forEach((key) => {
this.addIfModified(namespace, key, oldDataForKind && oldDataForKind[key], newDataForKind && newDataForKind[key], updatedItems);
});
});
this.sendChangeEvents(updatedItems);
}
});
callback === null || callback === void 0 ? void 0 : callback();
}, initMetadata, selector);
};
let oldData = {};
if (checkForChanges) {
// record old data before making changes to use for change calculations
this._featureStore.all(VersionedDataKinds_1.default.Features, (oldFlags) => {
this._featureStore.all(VersionedDataKinds_1.default.Segments, (oldSegments) => {
oldData = {
[VersionedDataKinds_1.default.Features.namespace]: oldFlags,
[VersionedDataKinds_1.default.Segments.namespace]: oldSegments,
};
});
});
}
doApplyChanges(oldData);
}
addIfModified(namespace, key, oldValue, newValue, toDataSet) {
if (newValue && oldValue && newValue.version <= oldValue.version) {
return;
}
this._dependencyTracker.updateModifiedItems(toDataSet, namespace, key);
}
sendChangeEvents(dataSet) {
dataSet.enumerate((namespace, key) => {
if (namespace === VersionedDataKinds_1.default.Features.namespace) {
this._onChange(key);
}
});
}
}
exports.default = TransactionalDataSourceUpdates;
//# sourceMappingURL=TransactionalDataSourceUpdates.js.map
;