Skip to content

Commit 0d1ba87

Browse files
refactor: add getAll method to segment caches and refactor datetime transformation to not mutate FF definitions
1 parent 134869e commit 0d1ba87

File tree

5 files changed

+45
-8
lines changed

5 files changed

+45
-8
lines changed

src/evaluator/convertions/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1+
import { IBetweenMatcherData } from '../../dtos/types';
2+
13
export function zeroSinceHH(millisSinceEpoch: number): number {
24
return new Date(millisSinceEpoch).setUTCHours(0, 0, 0, 0);
35
}
46

57
export function zeroSinceSS(millisSinceEpoch: number): number {
68
return new Date(millisSinceEpoch).setUTCSeconds(0, 0);
79
}
10+
11+
export function betweenDateTimeTransform(betweenMatcherData: IBetweenMatcherData): IBetweenMatcherData {
12+
return {
13+
dataType: betweenMatcherData.dataType,
14+
start: zeroSinceSS(betweenMatcherData.start),
15+
end: zeroSinceSS(betweenMatcherData.end)
16+
};
17+
}

src/evaluator/matchersTransform/index.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { matcherTypes, matcherTypesMapper, matcherDataTypes } from '../matchers/
33
import { segmentTransform } from './segment';
44
import { whitelistTransform } from './whitelist';
55
import { numericTransform } from './unaryNumeric';
6-
import { zeroSinceHH, zeroSinceSS } from '../convertions';
6+
import { zeroSinceHH, zeroSinceSS, betweenDateTimeTransform } from '../convertions';
77
import { IBetweenMatcherData, IInLargeSegmentMatcherData, IInSegmentMatcherData, ISplitMatcher, IUnaryNumericMatcherData } from '../../dtos/types';
88
import { IMatcherDto } from '../types';
99

@@ -32,7 +32,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
3232
let type = matcherTypesMapper(matcherType);
3333
// As default input data type we use string (even for ALL_KEYS)
3434
let dataType = matcherDataTypes.STRING;
35-
let value = undefined;
35+
let value;
3636

3737
if (type === matcherTypes.IN_SEGMENT) {
3838
value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData);
@@ -60,8 +60,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
6060
dataType = matcherDataTypes.NUMBER;
6161

6262
if (value.dataType === 'DATETIME') {
63-
value.start = zeroSinceSS(value.start);
64-
value.end = zeroSinceSS(value.end);
63+
value = betweenDateTimeTransform(value);
6564
dataType = matcherDataTypes.DATETIME;
6665
}
6766
} else if (type === matcherTypes.BETWEEN_SEMVER) {

src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
105105
return item && JSON.parse(item);
106106
}
107107

108+
getAll(): IRBSegment[] {
109+
return this.getNames().map(key => this.get(key)!);
110+
}
111+
108112
contains(names: Set<string>): boolean {
109113
const namesArray = setToArray(names);
110114
const namesInStorage = this.getNames();

src/storages/inMemory/RBSegmentsCacheInMemory.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ export class RBSegmentsCacheInMemory implements IRBSegmentsCacheSync {
5151
return this.cache[name] || null;
5252
}
5353

54+
getAll(): IRBSegment[] {
55+
return this.getNames().map(key => this.get(key)!);
56+
}
57+
5458
contains(names: Set<string>): boolean {
5559
const namesArray = setToArray(names);
5660
const namesInStorage = this.getNames();

src/storages/types.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import SplitIO from '../../types/splitio';
2-
import { MaybeThenable, ISplit, IRBSegment, IMySegmentsResponse } from '../dtos/types';
2+
import { MaybeThenable, ISplit, IRBSegment, IMySegmentsResponse, IMembershipsResponse, ISegmentChangesResponse, ISplitChangesResponse } from '../dtos/types';
33
import { MySegmentsData } from '../sync/polling/types';
44
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
55
import { ISettings } from '../types';
@@ -235,6 +235,7 @@ export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase {
235235
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): boolean,
236236
get(name: string): IRBSegment | null,
237237
getChangeNumber(): number,
238+
getAll(): IRBSegment[],
238239
clear(): void,
239240
contains(names: Set<string>): boolean,
240241
// 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<
465466
telemetry?: TTelemetryCache,
466467
uniqueKeys: TUniqueKeysCache,
467468
destroy(): void | Promise<void>,
468-
shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this
469+
shared?: (matchingKey: string, onReadyCb?: (error?: any) => void) => this
469470
}
470471

471472
export interface IStorageSync extends IStorageBase<
@@ -496,15 +497,16 @@ export interface IStorageAsync extends IStorageBase<
496497

497498
/** StorageFactory */
498499

499-
export type DataLoader = (storage: IStorageSync, matchingKey: string) => void
500-
501500
export interface IStorageFactoryParams {
502501
settings: ISettings,
503502
/**
504503
* Error-first callback invoked when the storage is ready to be used. An error means that the storage failed to connect and shouldn't be used.
505504
* It is meant for emitting SDK_READY event in consumer mode, and waiting before using the storage in the synchronizer.
506505
*/
507506
onReadyCb: (error?: any) => void,
507+
/**
508+
* For emitting SDK_READY_FROM_CACHE event in consumer mode with Redis to allow immediate evaluations
509+
*/
508510
onReadyFromCacheCb: () => void,
509511
}
510512

@@ -518,3 +520,21 @@ export type IStorageAsyncFactory = SplitIO.StorageAsyncFactory & {
518520
readonly type: SplitIO.StorageType,
519521
(params: IStorageFactoryParams): IStorageAsync
520522
}
523+
524+
export type RolloutPlan = {
525+
/**
526+
* Feature flags and rule-based segments.
527+
*/
528+
splitChanges: ISplitChangesResponse;
529+
/**
530+
* Optional map of matching keys to their memberships.
531+
*/
532+
memberships?: {
533+
[matchingKey: string]: IMembershipsResponse;
534+
};
535+
/**
536+
* Optional list of standard segments.
537+
* This property is ignored if `memberships` is provided.
538+
*/
539+
segmentChanges?: ISegmentChangesResponse[];
540+
};

0 commit comments

Comments
 (0)