@flipfeatureflag/core 0.1.5 → 0.1.7
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.
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +47 -16
- package/dist/index.mjs +47 -16
- package/package.json +1 -1
- package/src/client.ts +55 -18
package/dist/index.d.mts
CHANGED
|
@@ -102,6 +102,10 @@ declare class FlipFlagClient {
|
|
|
102
102
|
private metricsTimer?;
|
|
103
103
|
private metricsBuffer;
|
|
104
104
|
private context;
|
|
105
|
+
private started;
|
|
106
|
+
private refreshInFlight?;
|
|
107
|
+
private pendingFlagKeys;
|
|
108
|
+
private pendingFullRefresh;
|
|
105
109
|
constructor(options: FlipFlagClientOptions);
|
|
106
110
|
start(): Promise<void>;
|
|
107
111
|
stop(): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -102,6 +102,10 @@ declare class FlipFlagClient {
|
|
|
102
102
|
private metricsTimer?;
|
|
103
103
|
private metricsBuffer;
|
|
104
104
|
private context;
|
|
105
|
+
private started;
|
|
106
|
+
private refreshInFlight?;
|
|
107
|
+
private pendingFlagKeys;
|
|
108
|
+
private pendingFullRefresh;
|
|
105
109
|
constructor(options: FlipFlagClientOptions);
|
|
106
110
|
start(): Promise<void>;
|
|
107
111
|
stop(): void;
|
package/dist/index.js
CHANGED
|
@@ -139,6 +139,9 @@ var FlipFlagClient = class {
|
|
|
139
139
|
this.status = { ready: false };
|
|
140
140
|
this.evaluations = /* @__PURE__ */ new Map();
|
|
141
141
|
this.metricsBuffer = new MetricsBuffer();
|
|
142
|
+
this.started = false;
|
|
143
|
+
this.pendingFlagKeys = /* @__PURE__ */ new Set();
|
|
144
|
+
this.pendingFullRefresh = false;
|
|
142
145
|
if (!options.url) {
|
|
143
146
|
throw new Error("flipFeatureFlag SDK requires url");
|
|
144
147
|
}
|
|
@@ -159,6 +162,10 @@ var FlipFlagClient = class {
|
|
|
159
162
|
});
|
|
160
163
|
}
|
|
161
164
|
async start() {
|
|
165
|
+
if (this.started) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this.started = true;
|
|
162
169
|
await this.refresh();
|
|
163
170
|
if (!this.options.disableRefresh) {
|
|
164
171
|
this.refreshTimer = setInterval(() => {
|
|
@@ -180,6 +187,7 @@ var FlipFlagClient = class {
|
|
|
180
187
|
clearInterval(this.metricsTimer);
|
|
181
188
|
this.metricsTimer = void 0;
|
|
182
189
|
}
|
|
190
|
+
this.started = false;
|
|
183
191
|
}
|
|
184
192
|
on(event, listener) {
|
|
185
193
|
this.emitter.on(event, listener);
|
|
@@ -223,7 +231,9 @@ var FlipFlagClient = class {
|
|
|
223
231
|
if (cached) {
|
|
224
232
|
return this.recordEvaluation(flagKey, cached);
|
|
225
233
|
}
|
|
226
|
-
|
|
234
|
+
if (!this.options.disableRefresh) {
|
|
235
|
+
void this.refresh([flagKey]);
|
|
236
|
+
}
|
|
227
237
|
return this.recordEvaluation(flagKey, {
|
|
228
238
|
value: defaultValue,
|
|
229
239
|
variationKey: "default",
|
|
@@ -238,25 +248,46 @@ var FlipFlagClient = class {
|
|
|
238
248
|
return evaluation;
|
|
239
249
|
}
|
|
240
250
|
async refresh(flagKeys) {
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
context: this.context,
|
|
245
|
-
flagKeys
|
|
246
|
-
});
|
|
247
|
-
this.applyEvaluate(response);
|
|
248
|
-
if (!this.status.ready) {
|
|
249
|
-
this.status.ready = true;
|
|
250
|
-
this.emitter.emit("ready");
|
|
251
|
+
if (flagKeys && flagKeys.length > 0) {
|
|
252
|
+
for (const key of flagKeys) {
|
|
253
|
+
this.pendingFlagKeys.add(key);
|
|
251
254
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
255
|
+
} else {
|
|
256
|
+
this.pendingFullRefresh = true;
|
|
257
|
+
}
|
|
258
|
+
if (this.refreshInFlight) {
|
|
259
|
+
return this.refreshInFlight;
|
|
256
260
|
}
|
|
261
|
+
this.refreshInFlight = (async () => {
|
|
262
|
+
const shouldFull = this.pendingFullRefresh;
|
|
263
|
+
const keys = shouldFull ? void 0 : Array.from(this.pendingFlagKeys);
|
|
264
|
+
this.pendingFlagKeys.clear();
|
|
265
|
+
this.pendingFullRefresh = false;
|
|
266
|
+
try {
|
|
267
|
+
const response = await this.http.evaluate({
|
|
268
|
+
env: this.options.env,
|
|
269
|
+
context: this.context,
|
|
270
|
+
flagKeys: keys
|
|
271
|
+
});
|
|
272
|
+
this.applyEvaluate(response);
|
|
273
|
+
if (!this.status.ready) {
|
|
274
|
+
this.status.ready = true;
|
|
275
|
+
this.emitter.emit("ready");
|
|
276
|
+
}
|
|
277
|
+
this.emitter.emit("update");
|
|
278
|
+
} catch (error) {
|
|
279
|
+
this.status.error = error;
|
|
280
|
+
this.emitter.emit("error", error);
|
|
281
|
+
} finally {
|
|
282
|
+
this.refreshInFlight = void 0;
|
|
283
|
+
}
|
|
284
|
+
if (this.pendingFullRefresh || this.pendingFlagKeys.size > 0) {
|
|
285
|
+
return this.refresh();
|
|
286
|
+
}
|
|
287
|
+
})();
|
|
288
|
+
return this.refreshInFlight;
|
|
257
289
|
}
|
|
258
290
|
applyEvaluate(response) {
|
|
259
|
-
this.evaluations.clear();
|
|
260
291
|
for (const [key, evaluation] of Object.entries(response.flags)) {
|
|
261
292
|
this.evaluations.set(key, evaluation);
|
|
262
293
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -113,6 +113,9 @@ var FlipFlagClient = class {
|
|
|
113
113
|
this.status = { ready: false };
|
|
114
114
|
this.evaluations = /* @__PURE__ */ new Map();
|
|
115
115
|
this.metricsBuffer = new MetricsBuffer();
|
|
116
|
+
this.started = false;
|
|
117
|
+
this.pendingFlagKeys = /* @__PURE__ */ new Set();
|
|
118
|
+
this.pendingFullRefresh = false;
|
|
116
119
|
if (!options.url) {
|
|
117
120
|
throw new Error("flipFeatureFlag SDK requires url");
|
|
118
121
|
}
|
|
@@ -133,6 +136,10 @@ var FlipFlagClient = class {
|
|
|
133
136
|
});
|
|
134
137
|
}
|
|
135
138
|
async start() {
|
|
139
|
+
if (this.started) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this.started = true;
|
|
136
143
|
await this.refresh();
|
|
137
144
|
if (!this.options.disableRefresh) {
|
|
138
145
|
this.refreshTimer = setInterval(() => {
|
|
@@ -154,6 +161,7 @@ var FlipFlagClient = class {
|
|
|
154
161
|
clearInterval(this.metricsTimer);
|
|
155
162
|
this.metricsTimer = void 0;
|
|
156
163
|
}
|
|
164
|
+
this.started = false;
|
|
157
165
|
}
|
|
158
166
|
on(event, listener) {
|
|
159
167
|
this.emitter.on(event, listener);
|
|
@@ -197,7 +205,9 @@ var FlipFlagClient = class {
|
|
|
197
205
|
if (cached) {
|
|
198
206
|
return this.recordEvaluation(flagKey, cached);
|
|
199
207
|
}
|
|
200
|
-
|
|
208
|
+
if (!this.options.disableRefresh) {
|
|
209
|
+
void this.refresh([flagKey]);
|
|
210
|
+
}
|
|
201
211
|
return this.recordEvaluation(flagKey, {
|
|
202
212
|
value: defaultValue,
|
|
203
213
|
variationKey: "default",
|
|
@@ -212,25 +222,46 @@ var FlipFlagClient = class {
|
|
|
212
222
|
return evaluation;
|
|
213
223
|
}
|
|
214
224
|
async refresh(flagKeys) {
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
context: this.context,
|
|
219
|
-
flagKeys
|
|
220
|
-
});
|
|
221
|
-
this.applyEvaluate(response);
|
|
222
|
-
if (!this.status.ready) {
|
|
223
|
-
this.status.ready = true;
|
|
224
|
-
this.emitter.emit("ready");
|
|
225
|
+
if (flagKeys && flagKeys.length > 0) {
|
|
226
|
+
for (const key of flagKeys) {
|
|
227
|
+
this.pendingFlagKeys.add(key);
|
|
225
228
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
} else {
|
|
230
|
+
this.pendingFullRefresh = true;
|
|
231
|
+
}
|
|
232
|
+
if (this.refreshInFlight) {
|
|
233
|
+
return this.refreshInFlight;
|
|
230
234
|
}
|
|
235
|
+
this.refreshInFlight = (async () => {
|
|
236
|
+
const shouldFull = this.pendingFullRefresh;
|
|
237
|
+
const keys = shouldFull ? void 0 : Array.from(this.pendingFlagKeys);
|
|
238
|
+
this.pendingFlagKeys.clear();
|
|
239
|
+
this.pendingFullRefresh = false;
|
|
240
|
+
try {
|
|
241
|
+
const response = await this.http.evaluate({
|
|
242
|
+
env: this.options.env,
|
|
243
|
+
context: this.context,
|
|
244
|
+
flagKeys: keys
|
|
245
|
+
});
|
|
246
|
+
this.applyEvaluate(response);
|
|
247
|
+
if (!this.status.ready) {
|
|
248
|
+
this.status.ready = true;
|
|
249
|
+
this.emitter.emit("ready");
|
|
250
|
+
}
|
|
251
|
+
this.emitter.emit("update");
|
|
252
|
+
} catch (error) {
|
|
253
|
+
this.status.error = error;
|
|
254
|
+
this.emitter.emit("error", error);
|
|
255
|
+
} finally {
|
|
256
|
+
this.refreshInFlight = void 0;
|
|
257
|
+
}
|
|
258
|
+
if (this.pendingFullRefresh || this.pendingFlagKeys.size > 0) {
|
|
259
|
+
return this.refresh();
|
|
260
|
+
}
|
|
261
|
+
})();
|
|
262
|
+
return this.refreshInFlight;
|
|
231
263
|
}
|
|
232
264
|
applyEvaluate(response) {
|
|
233
|
-
this.evaluations.clear();
|
|
234
265
|
for (const [key, evaluation] of Object.entries(response.flags)) {
|
|
235
266
|
this.evaluations.set(key, evaluation);
|
|
236
267
|
}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -26,6 +26,10 @@ export class FlipFlagClient {
|
|
|
26
26
|
private metricsTimer?: ReturnType<typeof setInterval>;
|
|
27
27
|
private metricsBuffer = new MetricsBuffer();
|
|
28
28
|
private context: SdkContext;
|
|
29
|
+
private started = false;
|
|
30
|
+
private refreshInFlight?: Promise<void>;
|
|
31
|
+
private pendingFlagKeys = new Set<string>();
|
|
32
|
+
private pendingFullRefresh = false;
|
|
29
33
|
|
|
30
34
|
constructor(options: FlipFlagClientOptions) {
|
|
31
35
|
if (!options.url) {
|
|
@@ -52,6 +56,10 @@ export class FlipFlagClient {
|
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
async start(): Promise<void> {
|
|
59
|
+
if (this.started) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.started = true;
|
|
55
63
|
await this.refresh();
|
|
56
64
|
|
|
57
65
|
if (!this.options.disableRefresh) {
|
|
@@ -76,6 +84,7 @@ export class FlipFlagClient {
|
|
|
76
84
|
clearInterval(this.metricsTimer);
|
|
77
85
|
this.metricsTimer = undefined;
|
|
78
86
|
}
|
|
87
|
+
this.started = false;
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
on(event: FlipFlagEvent, listener: FlipFlagListener) {
|
|
@@ -129,7 +138,9 @@ export class FlipFlagClient {
|
|
|
129
138
|
return this.recordEvaluation(flagKey, cached);
|
|
130
139
|
}
|
|
131
140
|
|
|
132
|
-
|
|
141
|
+
if (!this.options.disableRefresh) {
|
|
142
|
+
void this.refresh([flagKey]);
|
|
143
|
+
}
|
|
133
144
|
return this.recordEvaluation(flagKey, {
|
|
134
145
|
value: defaultValue,
|
|
135
146
|
variationKey: "default",
|
|
@@ -145,29 +156,55 @@ export class FlipFlagClient {
|
|
|
145
156
|
return evaluation;
|
|
146
157
|
}
|
|
147
158
|
|
|
148
|
-
private async refresh(flagKeys?: string[]) {
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
context: this.context,
|
|
153
|
-
flagKeys,
|
|
154
|
-
});
|
|
155
|
-
this.applyEvaluate(response);
|
|
156
|
-
|
|
157
|
-
if (!this.status.ready) {
|
|
158
|
-
this.status.ready = true;
|
|
159
|
-
this.emitter.emit("ready");
|
|
159
|
+
private async refresh(flagKeys?: string[]): Promise<void> {
|
|
160
|
+
if (flagKeys && flagKeys.length > 0) {
|
|
161
|
+
for (const key of flagKeys) {
|
|
162
|
+
this.pendingFlagKeys.add(key);
|
|
160
163
|
}
|
|
164
|
+
} else {
|
|
165
|
+
this.pendingFullRefresh = true;
|
|
166
|
+
}
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
this.status.error = error as Error;
|
|
165
|
-
this.emitter.emit("error", error);
|
|
168
|
+
if (this.refreshInFlight) {
|
|
169
|
+
return this.refreshInFlight;
|
|
166
170
|
}
|
|
171
|
+
|
|
172
|
+
this.refreshInFlight = (async () => {
|
|
173
|
+
const shouldFull = this.pendingFullRefresh;
|
|
174
|
+
const keys = shouldFull ? undefined : Array.from(this.pendingFlagKeys);
|
|
175
|
+
this.pendingFlagKeys.clear();
|
|
176
|
+
this.pendingFullRefresh = false;
|
|
177
|
+
|
|
178
|
+
try {
|
|
179
|
+
const response = await this.http.evaluate({
|
|
180
|
+
env: this.options.env,
|
|
181
|
+
context: this.context,
|
|
182
|
+
flagKeys: keys,
|
|
183
|
+
});
|
|
184
|
+
this.applyEvaluate(response);
|
|
185
|
+
|
|
186
|
+
if (!this.status.ready) {
|
|
187
|
+
this.status.ready = true;
|
|
188
|
+
this.emitter.emit("ready");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
this.emitter.emit("update");
|
|
192
|
+
} catch (error) {
|
|
193
|
+
this.status.error = error as Error;
|
|
194
|
+
this.emitter.emit("error", error);
|
|
195
|
+
} finally {
|
|
196
|
+
this.refreshInFlight = undefined;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (this.pendingFullRefresh || this.pendingFlagKeys.size > 0) {
|
|
200
|
+
return this.refresh();
|
|
201
|
+
}
|
|
202
|
+
})();
|
|
203
|
+
|
|
204
|
+
return this.refreshInFlight;
|
|
167
205
|
}
|
|
168
206
|
|
|
169
207
|
private applyEvaluate(response: SdkEvaluateResponse) {
|
|
170
|
-
this.evaluations.clear();
|
|
171
208
|
for (const [key, evaluation] of Object.entries(response.flags)) {
|
|
172
209
|
this.evaluations.set(key, evaluation);
|
|
173
210
|
}
|