Skip to content

Commit 7c17d03

Browse files
committed
fix: remove fallbackFeatures. Use featureOverrides or boostrapFeatureDefinitions
1 parent 7c600eb commit 7c17d03

File tree

1 file changed

+17
-62
lines changed

1 file changed

+17
-62
lines changed

packages/node-sdk/src/client.ts

Lines changed: 17 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ export class BucketClient {
108108
refetchInterval: number;
109109
staleWarningInterval: number;
110110
headers: Record<string, string>;
111-
fallbackFeatures?: Record<keyof TypedFeatures, RawFeature>;
112111
featureOverrides: FeatureOverridesFn;
113112
offline: boolean;
114113
fetchFeatures: boolean;
@@ -143,7 +142,6 @@ export class BucketClient {
143142
* @param options.httpClient - The HTTP client to use for sending requests (optional).
144143
* @param options.logLevel - The log level to use for logging (optional).
145144
* @param options.offline - Whether to run in offline mode (optional).
146-
* @param options.fallbackFeatures - The fallback features to use if the feature is not found (optional).
147145
* @param options.batchOptions - The options for the batch buffer (optional).
148146
* @param options.featureOverrides - The feature overrides to use for the client (optional).
149147
* @param options.configFile - The path to the config file (optional).
@@ -173,12 +171,6 @@ export class BucketClient {
173171
options.httpClient === undefined || isObject(options.httpClient),
174172
"httpClient must be an object",
175173
);
176-
ok(
177-
options.fallbackFeatures === undefined ||
178-
Array.isArray(options.fallbackFeatures) ||
179-
isObject(options.fallbackFeatures),
180-
"fallbackFeatures must be an array or object",
181-
);
182174
ok(
183175
options.batchOptions === undefined || isObject(options.batchOptions),
184176
"batchOptions must be an object",
@@ -214,42 +206,6 @@ export class BucketClient {
214206
options.logLevel ?? config?.logLevel ?? "INFO",
215207
);
216208

217-
// todo: deprecate fallback features in favour of a more operationally
218-
// friendly way of setting fall backs.
219-
const fallbackFeatures = Array.isArray(options.fallbackFeatures)
220-
? options.fallbackFeatures.reduce(
221-
(acc, key) => {
222-
acc[key as keyof TypedFeatures] = {
223-
isEnabled: true,
224-
key,
225-
};
226-
return acc;
227-
},
228-
{} as Record<keyof TypedFeatures, RawFeature>,
229-
)
230-
: isObject(options.fallbackFeatures)
231-
? Object.entries(options.fallbackFeatures).reduce(
232-
(acc, [key, fallback]) => {
233-
acc[key as keyof TypedFeatures] = {
234-
isEnabled:
235-
typeof fallback === "object"
236-
? fallback.isEnabled
237-
: !!fallback,
238-
key,
239-
config:
240-
typeof fallback === "object" && fallback.config
241-
? {
242-
key: fallback.config.key,
243-
payload: fallback.config.payload,
244-
}
245-
: undefined,
246-
};
247-
return acc;
248-
},
249-
{} as Record<keyof TypedFeatures, RawFeature>,
250-
)
251-
: undefined;
252-
253209
this.rateLimiter = newRateLimiter(
254210
FEATURE_EVENT_RATE_LIMITER_WINDOW_SIZE_MS,
255211
);
@@ -271,7 +227,6 @@ export class BucketClient {
271227
refetchInterval: FEATURES_REFETCH_MS,
272228
fetchFeatures: options.fetchFeatures ?? true,
273229
staleWarningInterval: FEATURES_REFETCH_MS * 5,
274-
fallbackFeatures: fallbackFeatures,
275230
featureOverrides:
276231
typeof config.featureOverrides === "function"
277232
? config.featureOverrides
@@ -300,6 +255,13 @@ export class BucketClient {
300255
return res;
301256
},
302257
);
258+
259+
if (this._config.offline) {
260+
this.logger.info("running in offline mode");
261+
this.featuresCache.set({
262+
features: [],
263+
});
264+
}
303265
}
304266

305267
/**
@@ -475,7 +437,7 @@ export class BucketClient {
475437
**/
476438
public bootstrapFeatureDefinitions(features: FeaturesAPIResponse) {
477439
this.featuresCache.set(features);
478-
this.logger.info("Bootstrapped feature definitions");
440+
this.logger.debug("bootstrapped feature definitions");
479441
}
480442

481443
/**
@@ -936,23 +898,16 @@ export class BucketClient {
936898
checkContextWithTracking(options);
937899

938900
void this.syncContext(options);
939-
let featureDefinitions: FeaturesAPIResponse["features"];
940901

941-
if (this._config.offline) {
942-
featureDefinitions = [];
943-
} else {
944-
const fetchedFeatures = this.featuresCache.get();
945-
if (!fetchedFeatures) {
946-
this.logger.warn(
947-
"failed to use feature definitions, there are none cached yet. Using fallback features.",
948-
);
949-
return this._config.fallbackFeatures || {};
950-
}
951-
952-
featureDefinitions = fetchedFeatures.features;
902+
const featureDefinitions = this.featuresCache.get();
903+
if (!featureDefinitions) {
904+
this.logger.warn(
905+
"No feature definitions available. `getFeatures` will return empty and `getFeature(key)` will have `isEnabled: false`. Did you forget to call `initialize()`?",
906+
);
907+
return {};
953908
}
954-
955-
const featureMap = featureDefinitions.reduce(
909+
const features = featureDefinitions.features;
910+
const featureMap = features.reduce(
956911
(acc, f) => {
957912
acc[f.key] = f;
958913
return acc;
@@ -962,7 +917,7 @@ export class BucketClient {
962917

963918
const { enableTracking = true, meta: _, ...context } = options;
964919

965-
const evaluated = featureDefinitions.map((feature) =>
920+
const evaluated = features.map((feature) =>
966921
evaluateFeatureRules({
967922
featureKey: feature.key,
968923
rules: feature.targeting.rules.map((r) => ({ ...r, value: true })),

0 commit comments

Comments
 (0)