diff --git a/src/evaluator/convertions/index.ts b/src/evaluator/convertions/index.ts index 7d7384d7..acad8017 100644 --- a/src/evaluator/convertions/index.ts +++ b/src/evaluator/convertions/index.ts @@ -1,3 +1,5 @@ +import { IBetweenMatcherData } from '../../dtos/types'; + export function zeroSinceHH(millisSinceEpoch: number): number { return new Date(millisSinceEpoch).setUTCHours(0, 0, 0, 0); } @@ -5,3 +7,11 @@ export function zeroSinceHH(millisSinceEpoch: number): number { export function zeroSinceSS(millisSinceEpoch: number): number { return new Date(millisSinceEpoch).setUTCSeconds(0, 0); } + +export function betweenDateTimeTransform(betweenMatcherData: IBetweenMatcherData): IBetweenMatcherData { + return { + dataType: betweenMatcherData.dataType, + start: zeroSinceSS(betweenMatcherData.start), + end: zeroSinceSS(betweenMatcherData.end) + }; +} diff --git a/src/evaluator/matchersTransform/index.ts b/src/evaluator/matchersTransform/index.ts index 6219c4dc..075ea9f0 100644 --- a/src/evaluator/matchersTransform/index.ts +++ b/src/evaluator/matchersTransform/index.ts @@ -3,7 +3,7 @@ import { matcherTypes, matcherTypesMapper, matcherDataTypes } from '../matchers/ import { segmentTransform } from './segment'; import { whitelistTransform } from './whitelist'; import { numericTransform } from './unaryNumeric'; -import { zeroSinceHH, zeroSinceSS } from '../convertions'; +import { zeroSinceHH, zeroSinceSS, betweenDateTimeTransform } from '../convertions'; import { IBetweenMatcherData, IInLargeSegmentMatcherData, IInSegmentMatcherData, ISplitMatcher, IUnaryNumericMatcherData } from '../../dtos/types'; import { IMatcherDto } from '../types'; @@ -32,7 +32,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] { let type = matcherTypesMapper(matcherType); // As default input data type we use string (even for ALL_KEYS) let dataType = matcherDataTypes.STRING; - let value = undefined; + let value; if (type === matcherTypes.IN_SEGMENT) { value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData); @@ -60,8 +60,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] { dataType = matcherDataTypes.NUMBER; if (value.dataType === 'DATETIME') { - value.start = zeroSinceSS(value.start); - value.end = zeroSinceSS(value.end); + value = betweenDateTimeTransform(value); dataType = matcherDataTypes.DATETIME; } } else if (type === matcherTypes.BETWEEN_SEMVER) { diff --git a/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts b/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts index 37f6ad8e..cfc68cf5 100644 --- a/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +++ b/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts @@ -105,6 +105,10 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync { return item && JSON.parse(item); } + getAll(): IRBSegment[] { + return this.getNames().map(key => this.get(key)!); + } + contains(names: Set): boolean { const namesArray = setToArray(names); const namesInStorage = this.getNames(); diff --git a/src/storages/inMemory/RBSegmentsCacheInMemory.ts b/src/storages/inMemory/RBSegmentsCacheInMemory.ts index 568b0deb..2b876202 100644 --- a/src/storages/inMemory/RBSegmentsCacheInMemory.ts +++ b/src/storages/inMemory/RBSegmentsCacheInMemory.ts @@ -51,6 +51,10 @@ export class RBSegmentsCacheInMemory implements IRBSegmentsCacheSync { return this.cache[name] || null; } + getAll(): IRBSegment[] { + return this.getNames().map(key => this.get(key)!); + } + contains(names: Set): boolean { const namesArray = setToArray(names); const namesInStorage = this.getNames(); diff --git a/src/storages/types.ts b/src/storages/types.ts index 8e93daca..97664de5 100644 --- a/src/storages/types.ts +++ b/src/storages/types.ts @@ -235,6 +235,7 @@ export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase { update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): boolean, get(name: string): IRBSegment | null, getChangeNumber(): number, + getAll(): IRBSegment[], clear(): void, contains(names: Set): boolean, // Used only for smart pausing in client-side standalone. Returns true if the storage contains a RBSegment using segments or large segments matchers @@ -465,7 +466,7 @@ export interface IStorageBase< telemetry?: TTelemetryCache, uniqueKeys: TUniqueKeysCache, destroy(): void | Promise, - shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this + shared?: (matchingKey: string, onReadyCb?: (error?: any) => void) => this } export interface IStorageSync extends IStorageBase< @@ -505,6 +506,9 @@ export interface IStorageFactoryParams { * It is meant for emitting SDK_READY event in consumer mode, and waiting before using the storage in the synchronizer. */ onReadyCb: (error?: any) => void, + /** + * For emitting SDK_READY_FROM_CACHE event in consumer mode with Redis to allow immediate evaluations + */ onReadyFromCacheCb: () => void, }