UNPKG

unleash-server

Version:

Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.

90 lines 3.61 kB
import EventEmitter from 'events'; import { mapFeatureForClient, mapSegmentsForClient, } from '../playground/offline-unleash-client.js'; import { ALL_ENVS, DEFAULT_ENV } from '../../util/constants.js'; import { UPDATE_REVISION } from '../feature-toggle/configuration-revision-service.js'; export class GlobalFrontendApiCache extends EventEmitter { constructor(config, segmentReadModel, clientFeatureToggleReadModel, configurationRevisionService) { super(); this.featuresByEnvironment = {}; this.segments = []; this.status = 'starting'; this.logger = config.getLogger('global-frontend-api-cache.ts'); this.clientFeatureToggleReadModel = clientFeatureToggleReadModel; this.configurationRevisionService = configurationRevisionService; this.segmentReadModel = segmentReadModel; this.onUpdateRevisionEvent = this.onUpdateRevisionEvent.bind(this); this.refreshData(); this.configurationRevisionService.on(UPDATE_REVISION, this.onUpdateRevisionEvent); } getSegment(id) { return this.segments.find((segment) => segment.id === id); } getToggle(name, token) { const features = this.getTogglesByEnvironment(this.environmentNameForToken(token)); return features[name]; } getToggles(token) { const features = this.getTogglesByEnvironment(this.environmentNameForToken(token)); return this.filterTogglesByProjects(features, token.projects); } filterTogglesByProjects(features, projects) { if (projects.includes('*')) { return Object.values(features); } return Object.values(features).filter((feature) => feature.project && projects.includes(feature.project)); } getTogglesByEnvironment(environment) { const features = this.featuresByEnvironment[environment]; if (features == null) return {}; return features; } // TODO: fetch only relevant projects/environments based on tokens async refreshData() { try { this.featuresByEnvironment = await this.getAllFeatures(); this.segments = await this.getAllSegments(); if (this.status === 'starting') { this.status = 'ready'; this.emit('ready'); } else if (this.status === 'ready' || this.status === 'updated') { this.status = 'updated'; this.emit('updated'); } } catch (e) { this.logger.error('Cannot load data for token', e); } } async getAllFeatures() { const features = await this.clientFeatureToggleReadModel.getAll(); return this.mapFeatures(features); } async getAllSegments() { return mapSegmentsForClient(await this.segmentReadModel.getAll()); } async onUpdateRevisionEvent() { await this.refreshData(); } environmentNameForToken(token) { if (token.environment === ALL_ENVS) { return DEFAULT_ENV; } return token.environment; } mapFeatures(features) { const entries = Object.entries(features).map(([key, value]) => [ key, Object.fromEntries(Object.entries(value).map(([innerKey, innerValue]) => [ innerKey, mapFeatureForClient({ ...innerValue, stale: innerValue.stale || false, }), ])), ]); return Object.fromEntries(entries); } } //# sourceMappingURL=global-frontend-api-cache.js.map