@featbit/js-client-sdk 3.0.13 → 3.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +301 -301
  3. package/dist/esm/IFbClientCore.d.ts +1 -1
  4. package/dist/esm/IFbClientCore.d.ts.map +1 -1
  5. package/dist/esm/version.d.ts +1 -1
  6. package/dist/esm/version.js +1 -1
  7. package/dist/umd/{featbit-js-client-sdk-3.0.13.js → featbit-js-client-sdk-3.0.14.js} +2 -2
  8. package/dist/umd/featbit-js-client-sdk-3.0.14.js.map +1 -0
  9. package/dist/umd/featbit-js-client-sdk.js +1 -1
  10. package/dist/umd/featbit-js-client-sdk.js.map +1 -1
  11. package/package.json +46 -46
  12. package/src/Configuration.ts +232 -232
  13. package/src/Context.ts +61 -61
  14. package/src/FbClientBuilder.ts +167 -167
  15. package/src/FbClientCore.ts +405 -405
  16. package/src/IContextProperty.ts +3 -3
  17. package/src/IDataKind.ts +11 -11
  18. package/src/IFbClient.ts +29 -29
  19. package/src/IFbClientCore.ts +290 -290
  20. package/src/IVersionedData.ts +18 -18
  21. package/src/bootstrap/IBootstrapProvider.ts +4 -4
  22. package/src/bootstrap/JsonBootstrapProvider.ts +34 -34
  23. package/src/bootstrap/NullBootstrapProvider.ts +20 -20
  24. package/src/bootstrap/index.ts +2 -2
  25. package/src/constants.ts +1 -1
  26. package/src/data-sources/DataSourceUpdates.ts +116 -116
  27. package/src/data-sources/createStreamListeners.ts +67 -67
  28. package/src/data-sources/index.ts +1 -1
  29. package/src/data-sync/DataSyncMode.ts +3 -3
  30. package/src/data-sync/IDataSynchronizer.ts +15 -15
  31. package/src/data-sync/IRequestor.ts +10 -10
  32. package/src/data-sync/NullDataSynchronizer.ts +14 -14
  33. package/src/data-sync/PollingDataSynchronizer.ts +125 -125
  34. package/src/data-sync/Requestor.ts +61 -61
  35. package/src/data-sync/WebSocketDataSynchronizer.ts +77 -77
  36. package/src/data-sync/index.ts +8 -8
  37. package/src/data-sync/types.ts +19 -19
  38. package/src/data-sync/utils.ts +31 -31
  39. package/src/errors.ts +47 -47
  40. package/src/evaluation/EvalResult.ts +35 -35
  41. package/src/evaluation/Evaluator.ts +26 -26
  42. package/src/evaluation/IEvalDetail.ts +23 -23
  43. package/src/evaluation/ReasonKinds.ts +9 -9
  44. package/src/evaluation/data/IFlag.ts +29 -29
  45. package/src/evaluation/index.ts +4 -4
  46. package/src/events/DefaultEventProcessor.ts +83 -83
  47. package/src/events/DefaultEventQueue.ts +49 -49
  48. package/src/events/DefaultEventSender.ts +73 -73
  49. package/src/events/DefaultEventSerializer.ts +11 -11
  50. package/src/events/EventDispatcher.ts +127 -127
  51. package/src/events/EventSerializer.ts +4 -4
  52. package/src/events/IEventProcessor.ts +8 -8
  53. package/src/events/IEventQueue.ts +16 -16
  54. package/src/events/IEventSender.ts +13 -13
  55. package/src/events/NullEventProcessor.ts +15 -15
  56. package/src/events/event.ts +129 -129
  57. package/src/events/index.ts +11 -11
  58. package/src/index.ts +21 -21
  59. package/src/integrations/TestLogger.ts +24 -24
  60. package/src/integrations/index.ts +1 -1
  61. package/src/integrations/test_data/FlagBuilder.ts +59 -59
  62. package/src/integrations/test_data/TestData.ts +57 -57
  63. package/src/integrations/test_data/TestDataSynchronizer.ts +49 -49
  64. package/src/integrations/test_data/index.ts +4 -4
  65. package/src/logging/BasicLogger.ts +108 -108
  66. package/src/logging/IBasicLoggerOptions.ts +46 -46
  67. package/src/logging/ILogger.ts +49 -49
  68. package/src/logging/LogLevel.ts +8 -8
  69. package/src/logging/SafeLogger.ts +69 -69
  70. package/src/logging/format.ts +154 -154
  71. package/src/logging/index.ts +5 -5
  72. package/src/options/ClientContext.ts +39 -39
  73. package/src/options/IClientContext.ts +53 -53
  74. package/src/options/IOptions.ts +123 -123
  75. package/src/options/IUser.ts +6 -6
  76. package/src/options/IValidatedOptions.ts +29 -29
  77. package/src/options/OptionMessages.ts +35 -35
  78. package/src/options/UserBuilder.ts +35 -35
  79. package/src/options/Validators.ts +300 -300
  80. package/src/options/index.ts +7 -7
  81. package/src/platform/IInfo.ts +102 -102
  82. package/src/platform/IPlatform.ts +20 -20
  83. package/src/platform/IStore.ts +112 -112
  84. package/src/platform/IWebSocket.ts +22 -22
  85. package/src/platform/browser/BrowserInfo.ts +24 -24
  86. package/src/platform/browser/BrowserPlatform.ts +19 -19
  87. package/src/platform/browser/BrowserRequests.ts +6 -6
  88. package/src/platform/browser/BrowserWebSocket.ts +147 -147
  89. package/src/platform/browser/FbClient.ts +65 -65
  90. package/src/platform/browser/LocalStorageStore.ts +59 -59
  91. package/src/platform/index.ts +11 -11
  92. package/src/platform/requests.ts +76 -76
  93. package/src/store/BaseStore.ts +125 -125
  94. package/src/store/DataKinds.ts +6 -6
  95. package/src/store/IDataSourceUpdates.ts +68 -68
  96. package/src/store/InMemoryStore.ts +36 -36
  97. package/src/store/index.ts +5 -5
  98. package/src/store/serialization.ts +52 -52
  99. package/src/store/store.ts +37 -37
  100. package/src/utils/Emits.ts +75 -75
  101. package/src/utils/EventEmitter.ts +128 -128
  102. package/src/utils/IEventEmitter.ts +14 -14
  103. package/src/utils/Regex.ts +21 -21
  104. package/src/utils/ValueConverters.ts +55 -55
  105. package/src/utils/canonicalizeUri.ts +3 -3
  106. package/src/utils/debounce.ts +33 -33
  107. package/src/utils/http.ts +40 -40
  108. package/src/utils/index.ts +5 -5
  109. package/src/utils/isNullOrUndefined.ts +2 -2
  110. package/src/utils/serializeUser.ts +27 -27
  111. package/src/utils/sleep.ts +5 -5
  112. package/src/version.ts +1 -1
  113. package/dist/umd/featbit-js-client-sdk-3.0.13.js.map +0 -1
@@ -1,130 +1,130 @@
1
- import { IUser } from "../options/IUser";
2
- import { IVariation } from "../evaluation/data/IFlag";
3
-
4
- export interface IEvent {
5
- hash: string;
6
- }
7
-
8
- export class AsyncEvent implements IEvent {
9
- private readonly isCompletedPromise?: Promise<AsyncEvent>;
10
- private resolveFn?: (value: AsyncEvent) => void;
11
- timestamp = (new Date()).getTime();
12
-
13
- get hash(): string {
14
- return this.timestamp.toString();
15
- }
16
-
17
- constructor() {
18
- this.isCompletedPromise = new Promise<AsyncEvent>((resolve) => {
19
- this.resolveFn = resolve;
20
- });
21
- }
22
-
23
- waitForCompletion(): Promise<AsyncEvent> {
24
- return this.isCompletedPromise!;
25
- }
26
-
27
- complete() {
28
- this.resolveFn?.(this);
29
- }
30
- }
31
-
32
- export class FlushEvent extends AsyncEvent {
33
- }
34
-
35
- export class ShutdownEvent extends AsyncEvent {
36
- }
37
-
38
- export class PayloadEvent implements IEvent {
39
- timestamp = (new Date()).getTime();
40
-
41
- get hash(): string {
42
- return this.timestamp.toString();
43
- }
44
-
45
- toPayload(): any {
46
- };
47
- }
48
-
49
- export class MetricEvent extends PayloadEvent {
50
- constructor(
51
- public user: IUser,
52
- public eventName: string,
53
- public appType: string,
54
- public metricValue: number
55
- ) {
56
- super();
57
- }
58
-
59
- private userPayload() {
60
- return {
61
- keyId: this.user.keyId,
62
- name: this.user.name,
63
- customizedProperties: this.user.customizedProperties
64
- }
65
- }
66
-
67
- toPayload(): any {
68
- return {
69
- user: this.userPayload(),
70
- metrics: [{
71
- route: 'index/metric',
72
- timestamp: this.timestamp,
73
- numericValue: this.metricValue,
74
- appType: this.appType,
75
- eventName: this.eventName,
76
- type: 'CustomEvent'
77
- }]
78
- }
79
- }
80
-
81
- get hash(): string {
82
- const payload = this.toPayload();
83
- const hasObject = {
84
- user: payload.user,
85
- metrics: payload.metrics.map((m: any) => ({...m, timestamp: undefined}))
86
- }
87
- return JSON.stringify(hasObject);
88
- }
89
- }
90
-
91
- export class EvalEvent extends PayloadEvent {
92
- constructor(
93
- public user: IUser,
94
- public flagKey: string,
95
- public variation: IVariation,
96
- public sendToExperiment: boolean
97
- ) {
98
- super();
99
- }
100
-
101
- private userPayload() {
102
- return {
103
- keyId: this.user.keyId,
104
- name: this.user.name,
105
- customizedProperties: this.user.customizedProperties
106
- }
107
- }
108
-
109
- toPayload(): any {
110
- return {
111
- user: this.userPayload(),
112
- variations: [{
113
- featureFlagKey: this.flagKey,
114
- sendToExperiment: this.sendToExperiment,
115
- timestamp: this.timestamp,
116
- variation: this.variation
117
- }]
118
- }
119
- }
120
-
121
- get hash(): string {
122
- const payload = this.toPayload();
123
- const hasObject = {
124
- user: payload.user,
125
- variations: payload.variations.map((m: any) => ({...m, timestamp: undefined}))
126
- }
127
-
128
- return JSON.stringify(hasObject);
129
- }
1
+ import { IUser } from "../options/IUser";
2
+ import { IVariation } from "../evaluation/data/IFlag";
3
+
4
+ export interface IEvent {
5
+ hash: string;
6
+ }
7
+
8
+ export class AsyncEvent implements IEvent {
9
+ private readonly isCompletedPromise?: Promise<AsyncEvent>;
10
+ private resolveFn?: (value: AsyncEvent) => void;
11
+ timestamp = (new Date()).getTime();
12
+
13
+ get hash(): string {
14
+ return this.timestamp.toString();
15
+ }
16
+
17
+ constructor() {
18
+ this.isCompletedPromise = new Promise<AsyncEvent>((resolve) => {
19
+ this.resolveFn = resolve;
20
+ });
21
+ }
22
+
23
+ waitForCompletion(): Promise<AsyncEvent> {
24
+ return this.isCompletedPromise!;
25
+ }
26
+
27
+ complete() {
28
+ this.resolveFn?.(this);
29
+ }
30
+ }
31
+
32
+ export class FlushEvent extends AsyncEvent {
33
+ }
34
+
35
+ export class ShutdownEvent extends AsyncEvent {
36
+ }
37
+
38
+ export class PayloadEvent implements IEvent {
39
+ timestamp = (new Date()).getTime();
40
+
41
+ get hash(): string {
42
+ return this.timestamp.toString();
43
+ }
44
+
45
+ toPayload(): any {
46
+ };
47
+ }
48
+
49
+ export class MetricEvent extends PayloadEvent {
50
+ constructor(
51
+ public user: IUser,
52
+ public eventName: string,
53
+ public appType: string,
54
+ public metricValue: number
55
+ ) {
56
+ super();
57
+ }
58
+
59
+ private userPayload() {
60
+ return {
61
+ keyId: this.user.keyId,
62
+ name: this.user.name,
63
+ customizedProperties: this.user.customizedProperties
64
+ }
65
+ }
66
+
67
+ toPayload(): any {
68
+ return {
69
+ user: this.userPayload(),
70
+ metrics: [{
71
+ route: 'index/metric',
72
+ timestamp: this.timestamp,
73
+ numericValue: this.metricValue,
74
+ appType: this.appType,
75
+ eventName: this.eventName,
76
+ type: 'CustomEvent'
77
+ }]
78
+ }
79
+ }
80
+
81
+ get hash(): string {
82
+ const payload = this.toPayload();
83
+ const hasObject = {
84
+ user: payload.user,
85
+ metrics: payload.metrics.map((m: any) => ({...m, timestamp: undefined}))
86
+ }
87
+ return JSON.stringify(hasObject);
88
+ }
89
+ }
90
+
91
+ export class EvalEvent extends PayloadEvent {
92
+ constructor(
93
+ public user: IUser,
94
+ public flagKey: string,
95
+ public variation: IVariation,
96
+ public sendToExperiment: boolean
97
+ ) {
98
+ super();
99
+ }
100
+
101
+ private userPayload() {
102
+ return {
103
+ keyId: this.user.keyId,
104
+ name: this.user.name,
105
+ customizedProperties: this.user.customizedProperties
106
+ }
107
+ }
108
+
109
+ toPayload(): any {
110
+ return {
111
+ user: this.userPayload(),
112
+ variations: [{
113
+ featureFlagKey: this.flagKey,
114
+ sendToExperiment: this.sendToExperiment,
115
+ timestamp: this.timestamp,
116
+ variation: this.variation
117
+ }]
118
+ }
119
+ }
120
+
121
+ get hash(): string {
122
+ const payload = this.toPayload();
123
+ const hasObject = {
124
+ user: payload.user,
125
+ variations: payload.variations.map((m: any) => ({...m, timestamp: undefined}))
126
+ }
127
+
128
+ return JSON.stringify(hasObject);
129
+ }
130
130
  }
@@ -1,11 +1,11 @@
1
- export * from './DefaultEventProcessor';
2
- export * from './DefaultEventQueue';
3
- export * from './DefaultEventSender';
4
- export * from './DefaultEventSerializer';
5
- export * from './event';
6
- export * from './EventDispatcher';
7
- export * from './EventSerializer';
8
- export * from './IEventProcessor';
9
- export * from './IEventQueue';
10
- export * from './IEventSender';
11
- export * from './NullEventProcessor';
1
+ export * from './DefaultEventProcessor';
2
+ export * from './DefaultEventQueue';
3
+ export * from './DefaultEventSender';
4
+ export * from './DefaultEventSerializer';
5
+ export * from './event';
6
+ export * from './EventDispatcher';
7
+ export * from './EventSerializer';
8
+ export * from './IEventProcessor';
9
+ export * from './IEventQueue';
10
+ export * from './IEventSender';
11
+ export * from './NullEventProcessor';
package/src/index.ts CHANGED
@@ -1,21 +1,21 @@
1
- export * from './bootstrap';
2
- export * from './data-sources';
3
- export * from './evaluation';
4
- export * from './events';
5
- export * from './logging';
6
- export * from './options';
7
- export * from './platform';
8
- export * from './store';
9
- export * from './data-sync';
10
- export * from './utils';
11
-
12
- export * from './Configuration';
13
- export * from './constants';
14
- export * from './Context';
15
- export * from './errors';
16
- export * from './FbClientBuilder';
17
- export * from './IContextProperty';
18
- export * from './IDataKind';
19
- export * from './IFbClient';
20
- export * from './IVersionedData';
21
- export * from './FbClientCore';
1
+ export * from './bootstrap';
2
+ export * from './data-sources';
3
+ export * from './evaluation';
4
+ export * from './events';
5
+ export * from './logging';
6
+ export * from './options';
7
+ export * from './platform';
8
+ export * from './store';
9
+ export * from './data-sync';
10
+ export * from './utils';
11
+
12
+ export * from './Configuration';
13
+ export * from './constants';
14
+ export * from './Context';
15
+ export * from './errors';
16
+ export * from './FbClientBuilder';
17
+ export * from './IContextProperty';
18
+ export * from './IDataKind';
19
+ export * from './IFbClient';
20
+ export * from './IVersionedData';
21
+ export * from './FbClientCore';
@@ -1,25 +1,25 @@
1
- import { ILogger } from "../logging/ILogger";
2
-
3
- export class TestLogger implements ILogger {
4
- public logs: string[] = [];
5
-
6
- error(...args: any[]): void {
7
- this.logs.push(args.join(' '));
8
- }
9
-
10
- warn(...args: any[]): void {
11
- this.logs.push(args.join(' '));
12
- }
13
-
14
- info(...args: any[]): void {
15
- this.logs.push(args.join(' '));
16
- }
17
-
18
- debug(...args: any[]): void {
19
- this.logs.push(args.join(' '));
20
- }
21
-
22
- reset() {
23
- this.logs = [];
24
- }
1
+ import { ILogger } from "../logging/ILogger";
2
+
3
+ export class TestLogger implements ILogger {
4
+ public logs: string[] = [];
5
+
6
+ error(...args: any[]): void {
7
+ this.logs.push(args.join(' '));
8
+ }
9
+
10
+ warn(...args: any[]): void {
11
+ this.logs.push(args.join(' '));
12
+ }
13
+
14
+ info(...args: any[]): void {
15
+ this.logs.push(args.join(' '));
16
+ }
17
+
18
+ debug(...args: any[]): void {
19
+ this.logs.push(args.join(' '));
20
+ }
21
+
22
+ reset() {
23
+ this.logs = [];
24
+ }
25
25
  }
@@ -1,2 +1,2 @@
1
- export * from './test_data';
1
+ export * from './test_data';
2
2
  export { TestLogger } from './TestLogger';
@@ -1,60 +1,60 @@
1
- // used only by tests
2
- import { IFlag, VariationDataType, IVariation, FlagValue } from "../../evaluation/data/IFlag";
3
-
4
- export class FlagBuilder {
5
- private _id: string = `xxxxx-${new Date().getTime()}-xxxxxx`;
6
- private _key?: string;
7
- private _version?: number;
8
- private _variationType: VariationDataType = VariationDataType.empty;
9
- private _sendToExperiment: boolean = false;
10
- private _variation: FlagValue = '';
11
- private _variations: IVariation[] = [];
12
-
13
- id(id: string): FlagBuilder {
14
- this._id = id;
15
- return this;
16
- }
17
-
18
- key(key: string): FlagBuilder {
19
- this._key = key;
20
- return this;
21
- }
22
-
23
- version(version: number): FlagBuilder {
24
- this._version = version
25
- return this;
26
- }
27
-
28
- sendToExperiment(val: boolean): FlagBuilder {
29
- this._sendToExperiment = val
30
- return this;
31
- }
32
-
33
- variation(variation: FlagValue): FlagBuilder {
34
- this._variation = variation
35
- return this;
36
- }
37
-
38
- variationType(variationType: VariationDataType): FlagBuilder {
39
- this._variationType = variationType
40
- return this;
41
- }
42
-
43
- variations(variations: IVariation[]): FlagBuilder {
44
- this._variations = variations
45
- return this;
46
- }
47
-
48
- build(): IFlag {
49
- return {
50
- id: this._id!,
51
- key: this._key!,
52
- version: this._version!,
53
- variationType: this._variationType,
54
- variations: this._variations,
55
- sendToExperiment: this._sendToExperiment,
56
- variation: this._variation,
57
- timestamp: new Date().getTime()
58
- };
59
- }
1
+ // used only by tests
2
+ import { IFlag, VariationDataType, IVariation, FlagValue } from "../../evaluation/data/IFlag";
3
+
4
+ export class FlagBuilder {
5
+ private _id: string = `xxxxx-${new Date().getTime()}-xxxxxx`;
6
+ private _key?: string;
7
+ private _version?: number;
8
+ private _variationType: VariationDataType = VariationDataType.empty;
9
+ private _sendToExperiment: boolean = false;
10
+ private _variation: FlagValue = '';
11
+ private _variations: IVariation[] = [];
12
+
13
+ id(id: string): FlagBuilder {
14
+ this._id = id;
15
+ return this;
16
+ }
17
+
18
+ key(key: string): FlagBuilder {
19
+ this._key = key;
20
+ return this;
21
+ }
22
+
23
+ version(version: number): FlagBuilder {
24
+ this._version = version
25
+ return this;
26
+ }
27
+
28
+ sendToExperiment(val: boolean): FlagBuilder {
29
+ this._sendToExperiment = val
30
+ return this;
31
+ }
32
+
33
+ variation(variation: FlagValue): FlagBuilder {
34
+ this._variation = variation
35
+ return this;
36
+ }
37
+
38
+ variationType(variationType: VariationDataType): FlagBuilder {
39
+ this._variationType = variationType
40
+ return this;
41
+ }
42
+
43
+ variations(variations: IVariation[]): FlagBuilder {
44
+ this._variations = variations
45
+ return this;
46
+ }
47
+
48
+ build(): IFlag {
49
+ return {
50
+ id: this._id!,
51
+ key: this._key!,
52
+ version: this._version!,
53
+ variationType: this._variationType,
54
+ variations: this._variations,
55
+ sendToExperiment: this._sendToExperiment,
56
+ variation: this._variation,
57
+ timestamp: new Date().getTime()
58
+ };
59
+ }
60
60
  }
@@ -1,58 +1,58 @@
1
- import { IFlag } from "../../evaluation/data/IFlag";
2
- import TestDataSynchronizer from "./TestDataSynchronizer";
3
- import { IClientContext } from "../../options/IClientContext";
4
- import { IDataSourceUpdates } from "../../store/IDataSourceUpdates";
5
- import { VoidFunction } from "../../utils/VoidFunction";
6
- import { createStreamListeners } from "../../data-sources/createStreamListeners";
7
- import { IStore } from "../../platform/IStore";
8
- import DataKinds from "../../store/DataKinds";
9
-
10
- export default class TestData {
11
- private currentFlags: IFlag[] = [];
12
-
13
- private dataSynchronizer: TestDataSynchronizer | undefined;
14
-
15
- private store: IStore = {} as IStore;
16
-
17
- /**
18
- * Get a factory for update processors that will be attached to this TestData instance.
19
- * @returns An update processor factory.
20
- */
21
- getFactory() {
22
- // Provides an arrow function to prevent needed to bind the method to
23
- // maintain `this`.
24
- return (
25
- clientContext: IClientContext,
26
- store: IStore,
27
- dataSourceUpdates: IDataSourceUpdates,
28
- initSuccessHandler: VoidFunction,
29
- _errorHandler?: (e: Error) => void,
30
- ) => {
31
- this.store = store;
32
-
33
- const listeners = createStreamListeners(
34
- dataSourceUpdates,
35
- clientContext.logger,
36
- {
37
- put: initSuccessHandler,
38
- },
39
- );
40
-
41
- this.dataSynchronizer = new TestDataSynchronizer(
42
- dataSourceUpdates,
43
- Object.values(this.currentFlags),
44
- () => {},
45
- listeners,
46
- );
47
-
48
- return this.dataSynchronizer;
49
- }
50
- }
51
-
52
- update(flag: IFlag): Promise<void> {
53
- const oldVersion = this.store.get(DataKinds.Flags, flag.id)?.version || 0;
54
- const newFlag = { ...flag, version: oldVersion + 1, key: flag.id };
55
-
56
- return this.dataSynchronizer!.upsert(DataKinds.Flags, newFlag);
57
- }
1
+ import { IFlag } from "../../evaluation/data/IFlag";
2
+ import TestDataSynchronizer from "./TestDataSynchronizer";
3
+ import { IClientContext } from "../../options/IClientContext";
4
+ import { IDataSourceUpdates } from "../../store/IDataSourceUpdates";
5
+ import { VoidFunction } from "../../utils/VoidFunction";
6
+ import { createStreamListeners } from "../../data-sources/createStreamListeners";
7
+ import { IStore } from "../../platform/IStore";
8
+ import DataKinds from "../../store/DataKinds";
9
+
10
+ export default class TestData {
11
+ private currentFlags: IFlag[] = [];
12
+
13
+ private dataSynchronizer: TestDataSynchronizer | undefined;
14
+
15
+ private store: IStore = {} as IStore;
16
+
17
+ /**
18
+ * Get a factory for update processors that will be attached to this TestData instance.
19
+ * @returns An update processor factory.
20
+ */
21
+ getFactory() {
22
+ // Provides an arrow function to prevent needed to bind the method to
23
+ // maintain `this`.
24
+ return (
25
+ clientContext: IClientContext,
26
+ store: IStore,
27
+ dataSourceUpdates: IDataSourceUpdates,
28
+ initSuccessHandler: VoidFunction,
29
+ _errorHandler?: (e: Error) => void,
30
+ ) => {
31
+ this.store = store;
32
+
33
+ const listeners = createStreamListeners(
34
+ dataSourceUpdates,
35
+ clientContext.logger,
36
+ {
37
+ put: initSuccessHandler,
38
+ },
39
+ );
40
+
41
+ this.dataSynchronizer = new TestDataSynchronizer(
42
+ dataSourceUpdates,
43
+ Object.values(this.currentFlags),
44
+ () => {},
45
+ listeners,
46
+ );
47
+
48
+ return this.dataSynchronizer;
49
+ }
50
+ }
51
+
52
+ update(flag: IFlag): Promise<void> {
53
+ const oldVersion = this.store.get(DataKinds.Flags, flag.id)?.version || 0;
54
+ const newFlag = { ...flag, version: oldVersion + 1, key: flag.id };
55
+
56
+ return this.dataSynchronizer!.upsert(DataKinds.Flags, newFlag);
57
+ }
58
58
  }