unleash-server
Version:
Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.
92 lines • 3.71 kB
JavaScript
import { DELTA_EVENT_TYPES, } from './client-feature-toggle-delta-types.js';
export class DeltaCache {
constructor(hydrationEvent, maxLength = 20) {
this.events = [];
this.hydrationEvent = hydrationEvent;
this.maxLength = maxLength;
this.addBaseEventFromHydration(hydrationEvent);
}
addBaseEventFromHydration(hydrationEvent) {
const lastFeature = hydrationEvent.features[hydrationEvent.features.length - 1];
if (!lastFeature) {
return;
}
this.addEvents([
{
eventId: hydrationEvent.eventId,
type: 'feature-updated',
feature: lastFeature,
},
]);
}
addEvents(events) {
this.events = [...this.events, ...events];
this.updateHydrationEvent(events);
while (this.events.length > this.maxLength) {
this.events.shift();
}
}
getEvents() {
return this.events;
}
isMissingRevision(revisionId) {
return !this.events.some((event) => event.eventId === revisionId);
}
getHydrationEvent() {
return this.hydrationEvent;
}
updateHydrationEvent(events) {
for (const appliedEvent of events) {
switch (appliedEvent.type) {
case DELTA_EVENT_TYPES.FEATURE_UPDATED: {
const featureIndex = this.hydrationEvent.features.findIndex((feature) => feature.name === appliedEvent.feature.name);
if (featureIndex > -1) {
this.hydrationEvent.features[featureIndex] =
appliedEvent.feature;
}
else {
this.hydrationEvent.features.push(appliedEvent.feature);
}
break;
}
case DELTA_EVENT_TYPES.FEATURE_REMOVED: {
this.hydrationEvent.features =
this.hydrationEvent.features.filter((feature) => feature.name !== appliedEvent.featureName);
break;
}
case DELTA_EVENT_TYPES.SEGMENT_UPDATED: {
const segmentIndex = this.hydrationEvent.segments.findIndex((segment) => segment.id === appliedEvent.segment.id);
if (segmentIndex > -1) {
this.hydrationEvent.segments[segmentIndex] =
appliedEvent.segment;
}
else {
this.hydrationEvent.segments.push(appliedEvent.segment);
}
break;
}
case DELTA_EVENT_TYPES.SEGMENT_REMOVED: {
this.hydrationEvent.segments =
this.hydrationEvent.segments.filter((segment) => segment.id !== appliedEvent.segmentId);
break;
}
}
this.hydrationEvent.eventId = appliedEvent.eventId;
}
// small perf hit here but this is a cold path and this is absolutely critical to ensure
// that down stream Edge instances receive the data in predictable orders because that
// affects how they calculate their etags
this.sortHydrationEvent();
}
sortHydrationEvent() {
this.hydrationEvent.features.sort((a, b) => a.name.localeCompare(b.name));
this.hydrationEvent.segments.sort((a, b) => {
const byName = a.name.localeCompare(b.name);
if (byName !== 0) {
return byName;
}
return a.id - b.id;
});
}
}
//# sourceMappingURL=delta-cache.js.map