@launchdarkly/js-server-sdk-common
Version:
LaunchDarkly Server SDK for JavaScript - common code
127 lines • 5.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeDependencies = void 0;
const VersionedDataKinds_1 = require("../store/VersionedDataKinds");
const DependencyTracker_1 = require("./DependencyTracker");
const NamespacedDataSet_1 = require("./NamespacedDataSet");
function computeDependencies(namespace, item) {
var _a, _b;
const ret = new NamespacedDataSet_1.default();
const isFlag = namespace === VersionedDataKinds_1.default.Features.namespace;
const isSegment = namespace === VersionedDataKinds_1.default.Segments.namespace;
if (isFlag) {
const flag = item;
(_a = flag === null || flag === void 0 ? void 0 : flag.prerequisites) === null || _a === void 0 ? void 0 : _a.forEach((prereq) => {
ret.set(namespace, prereq.key, true);
});
}
if (isFlag || isSegment) {
const itemWithRuleClauses = item;
(_b = itemWithRuleClauses === null || itemWithRuleClauses === void 0 ? void 0 : itemWithRuleClauses.rules) === null || _b === void 0 ? void 0 : _b.forEach((rule) => {
var _a;
(_a = rule.clauses) === null || _a === void 0 ? void 0 : _a.forEach((clause) => {
if (clause.op === 'segmentMatch') {
clause.values.forEach((value) => {
ret.set(VersionedDataKinds_1.default.Segments.namespace, value, true);
});
}
});
});
}
return ret;
}
exports.computeDependencies = computeDependencies;
/**
* @internal
*/
class DataSourceUpdates {
constructor(_featureStore, _hasEventListeners, _onChange) {
this._featureStore = _featureStore;
this._hasEventListeners = _hasEventListeners;
this._onChange = _onChange;
this._dependencyTracker = new DependencyTracker_1.default();
}
init(allData, callback, initMetadata) {
const checkForChanges = this._hasEventListeners();
const doInit = (oldData) => {
this._featureStore.init(allData, () => {
// Defer change events so they execute after the callback.
Promise.resolve().then(() => {
this._dependencyTracker.reset();
Object.entries(allData).forEach(([namespace, items]) => {
Object.keys(items || {}).forEach((key) => {
const item = items[key];
this._dependencyTracker.updateDependenciesFrom(namespace, key, computeDependencies(namespace, item));
});
});
if (checkForChanges) {
const updatedItems = new NamespacedDataSet_1.default();
Object.keys(allData).forEach((namespace) => {
const oldDataForKind = (oldData === null || oldData === void 0 ? void 0 : oldData[namespace]) || {};
const newDataForKind = allData[namespace];
const mergedData = Object.assign(Object.assign({}, oldDataForKind), newDataForKind);
Object.keys(mergedData).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);
};
if (checkForChanges) {
this._featureStore.all(VersionedDataKinds_1.default.Features, (oldFlags) => {
this._featureStore.all(VersionedDataKinds_1.default.Segments, (oldSegments) => {
const oldData = {
[VersionedDataKinds_1.default.Features.namespace]: oldFlags,
[VersionedDataKinds_1.default.Segments.namespace]: oldSegments,
};
doInit(oldData);
});
});
}
else {
doInit();
}
}
upsert(kind, data, callback) {
const { key } = data;
const checkForChanges = this._hasEventListeners();
const doUpsert = (oldItem) => {
this._featureStore.upsert(kind, data, () => {
// Defer change events so they execute after the callback.
Promise.resolve().then(() => {
this._dependencyTracker.updateDependenciesFrom(kind.namespace, key, computeDependencies(kind.namespace, data));
if (checkForChanges) {
const updatedItems = new NamespacedDataSet_1.default();
this.addIfModified(kind.namespace, key, oldItem, data, updatedItems);
this.sendChangeEvents(updatedItems);
}
});
callback === null || callback === void 0 ? void 0 : callback();
});
};
if (checkForChanges) {
this._featureStore.get(kind, key, doUpsert);
}
else {
doUpsert();
}
}
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 = DataSourceUpdates;
//# sourceMappingURL=DataSourceUpdates.js.map