@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
64 lines (54 loc) • 2.94 kB
text/typescript
import { IDefinitionsCacheAsync } from './types';
import { IDefinition } from '../dtos/types';
import { objectAssign } from '../utils/lang/objectAssign';
/**
* This class provides a skeletal implementation of the IDefinitionsCacheAsync interface
* to minimize the effort required to implement this interface.
*/
export abstract class AbstractDefinitionsCacheAsync implements IDefinitionsCacheAsync {
protected abstract add(definition: IDefinition): Promise<boolean>
protected abstract remove(name: string): Promise<boolean>
protected abstract setChangeNumber(changeNumber: number): Promise<boolean | void>
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): Promise<boolean> {
return Promise.all([
this.setChangeNumber(changeNumber),
Promise.all(toAdd.map(addedFF => this.add(addedFF))),
Promise.all(toRemove.map(removedFF => this.remove(removedFF)))
]).then(([, added, removed]) => {
return added.some(result => result) || removed.some(result => result);
});
}
abstract get(name: string): Promise<IDefinition | null>
abstract getMany(names: string[]): Promise<Record<string, IDefinition | null>>
abstract getChangeNumber(): Promise<number>
abstract getAll(): Promise<IDefinition[]>
abstract getNames(): Promise<string[]>
abstract getNamesBySets(sets: string[]): Promise<Set<string>[]>
abstract trafficTypeExists(trafficType: string): Promise<boolean>
abstract clear(): Promise<boolean | void>
// @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
// noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
usesSegments(): Promise<boolean> {
return Promise.resolve(true);
}
/**
* Kill `name` definition and set `defaultTreatment` and `changeNumber`.
* Used for SPLIT_KILL push notifications.
*
* @returns a promise that is resolved once the definition kill operation is performed. The fulfillment value is a boolean: `true` if the operation succeeded updating the definition or `false` if no definition is updated,
* for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
* The promise will never be rejected.
*/
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean> {
return this.get(name).then(definition => {
if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
const newDefinition = objectAssign({}, definition);
newDefinition.killed = true;
newDefinition.defaultTreatment = defaultTreatment;
newDefinition.changeNumber = changeNumber;
return this.add(newDefinition);
}
return false;
}).catch(() => false);
}
}