@featureflare/react 0.0.5 → 0.0.6-beta.259
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/README.md +119 -83
- package/dist/index.cjs +417 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -3
- package/dist/index.d.ts +61 -3
- package/dist/index.js +417 -68
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,234 @@
|
|
|
1
1
|
// src/provider.tsx
|
|
2
|
-
import React, { createContext, useMemo, useState } from "react";
|
|
3
|
-
import {
|
|
2
|
+
import React, { createContext, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
FeatureFlareClient
|
|
5
|
+
} from "@featureflare/sdk-js";
|
|
4
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
function resolveFeatureFlareBrowserConfig(input) {
|
|
8
|
+
const explicitEnv = input?.envKey;
|
|
9
|
+
const envFromVars = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_ENV_KEY?.trim().toLowerCase() : "";
|
|
10
|
+
const resolvedEnv = explicitEnv ?? (envFromVars === "development" || envFromVars === "staging" || envFromVars === "production" ? envFromVars : void 0);
|
|
11
|
+
const apiBaseUrl = input?.apiBaseUrl ?? (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_API_BASE_URL?.trim() : void 0);
|
|
12
|
+
const sdkKeyDevelopment = (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_DEVELOPMENT?.trim() : "") || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_DEV?.trim() : "") || "";
|
|
13
|
+
const sdkKeyStaging = (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_STAGING?.trim() : "") || "";
|
|
14
|
+
const sdkKeyProduction = (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_PRODUCTION?.trim() : "") || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_PROD?.trim() : "") || "";
|
|
15
|
+
const sdkKeyDefault = (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY?.trim() : "") || "";
|
|
16
|
+
const sdkKey = (resolvedEnv === "development" ? sdkKeyDevelopment : "") || (resolvedEnv === "staging" ? sdkKeyStaging : "") || (resolvedEnv === "production" ? sdkKeyProduction : "") || sdkKeyDefault || void 0;
|
|
17
|
+
return {
|
|
18
|
+
apiBaseUrl,
|
|
19
|
+
envKey: resolvedEnv,
|
|
20
|
+
sdkKey
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function normalizeSubscriptionOptions(options) {
|
|
24
|
+
const refreshIntervalMs = Number.isFinite(options?.refreshIntervalMs) && (options?.refreshIntervalMs ?? 0) > 0 ? Number(options?.refreshIntervalMs) : 1e4;
|
|
25
|
+
const hiddenRefreshIntervalMs = Number.isFinite(options?.hiddenRefreshIntervalMs) && (options?.hiddenRefreshIntervalMs ?? 0) > 0 ? Number(options?.hiddenRefreshIntervalMs) : Math.max(refreshIntervalMs * 6, 6e4);
|
|
26
|
+
return {
|
|
27
|
+
refreshIntervalMs,
|
|
28
|
+
hiddenRefreshIntervalMs,
|
|
29
|
+
pauseWhenHidden: options?.pauseWhenHidden ?? true,
|
|
30
|
+
enabled: options?.enabled ?? true
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function flagsToMap(flags) {
|
|
34
|
+
const map = /* @__PURE__ */ new Map();
|
|
35
|
+
for (const flag of flags) {
|
|
36
|
+
map.set(flag.key, flag.value);
|
|
37
|
+
}
|
|
38
|
+
return map;
|
|
39
|
+
}
|
|
40
|
+
function diffFlagKeys(prev, next) {
|
|
41
|
+
const changed = /* @__PURE__ */ new Set();
|
|
42
|
+
const prevMap = flagsToMap(prev);
|
|
43
|
+
const nextMap = flagsToMap(next);
|
|
44
|
+
for (const [key, value] of prevMap.entries()) {
|
|
45
|
+
if (!nextMap.has(key) || nextMap.get(key) !== value) {
|
|
46
|
+
changed.add(key);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const [key, value] of nextMap.entries()) {
|
|
50
|
+
if (!prevMap.has(key) || prevMap.get(key) !== value) {
|
|
51
|
+
changed.add(key);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return changed;
|
|
55
|
+
}
|
|
56
|
+
function createFlagsStore(client, getUser) {
|
|
57
|
+
const entries = /* @__PURE__ */ new Map();
|
|
58
|
+
let nextSubscriberId = 1;
|
|
59
|
+
const isHidden = () => typeof document !== "undefined" && document.visibilityState === "hidden";
|
|
60
|
+
const getEntry = (defaultValue) => {
|
|
61
|
+
const key = defaultValue ? "1" : "0";
|
|
62
|
+
const existing = entries.get(key);
|
|
63
|
+
if (existing) return existing;
|
|
64
|
+
const cached = client.getCachedFlags();
|
|
65
|
+
const created = {
|
|
66
|
+
defaultValue,
|
|
67
|
+
snapshot: { flags: cached.flags, loading: !cached.hasData, error: null },
|
|
68
|
+
listeners: /* @__PURE__ */ new Map(),
|
|
69
|
+
subscribers: /* @__PURE__ */ new Map(),
|
|
70
|
+
timer: null,
|
|
71
|
+
inFlight: false
|
|
72
|
+
};
|
|
73
|
+
entries.set(key, created);
|
|
74
|
+
return created;
|
|
75
|
+
};
|
|
76
|
+
const emit = (entry, changedKeys = null) => {
|
|
77
|
+
for (const { listener, flagKey } of entry.listeners.values()) {
|
|
78
|
+
if (!flagKey || changedKeys === null || changedKeys.has(flagKey)) {
|
|
79
|
+
listener();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const getEffectiveOptions = (entry) => {
|
|
84
|
+
const active = [...entry.subscribers.values()].filter((s) => s.enabled);
|
|
85
|
+
if (active.length === 0) {
|
|
86
|
+
return { enabled: false, refreshIntervalMs: 0, hiddenRefreshIntervalMs: 0, pauseWhenHidden: true };
|
|
87
|
+
}
|
|
88
|
+
const refreshIntervalMs = active.reduce((min, s) => Math.min(min, s.refreshIntervalMs), Number.POSITIVE_INFINITY);
|
|
89
|
+
const hiddenActive = active.filter((s) => !s.pauseWhenHidden);
|
|
90
|
+
const hiddenRefreshIntervalMs = hiddenActive.length > 0 ? hiddenActive.reduce((min, s) => Math.min(min, s.hiddenRefreshIntervalMs), Number.POSITIVE_INFINITY) : 0;
|
|
91
|
+
return {
|
|
92
|
+
enabled: true,
|
|
93
|
+
refreshIntervalMs: Number.isFinite(refreshIntervalMs) ? refreshIntervalMs : 1e4,
|
|
94
|
+
hiddenRefreshIntervalMs,
|
|
95
|
+
pauseWhenHidden: hiddenActive.length === 0
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
const schedule = (entry) => {
|
|
99
|
+
if (entry.timer !== null) {
|
|
100
|
+
clearTimeout(entry.timer);
|
|
101
|
+
entry.timer = null;
|
|
102
|
+
}
|
|
103
|
+
const effective = getEffectiveOptions(entry);
|
|
104
|
+
if (!effective.enabled) return;
|
|
105
|
+
if (isHidden()) {
|
|
106
|
+
if (effective.pauseWhenHidden) return;
|
|
107
|
+
entry.timer = setTimeout(() => {
|
|
108
|
+
void refresh(entry.defaultValue);
|
|
109
|
+
}, effective.hiddenRefreshIntervalMs);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
entry.timer = setTimeout(() => {
|
|
113
|
+
void refresh(entry.defaultValue);
|
|
114
|
+
}, effective.refreshIntervalMs);
|
|
115
|
+
};
|
|
116
|
+
const refresh = async (defaultValue, force = false) => {
|
|
117
|
+
const entry = getEntry(defaultValue);
|
|
118
|
+
const effective = getEffectiveOptions(entry);
|
|
119
|
+
if (!effective.enabled && !force) return;
|
|
120
|
+
if (!force && isHidden() && effective.pauseWhenHidden) {
|
|
121
|
+
schedule(entry);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (entry.inFlight) return;
|
|
125
|
+
entry.inFlight = true;
|
|
126
|
+
try {
|
|
127
|
+
const previousFlags = entry.snapshot.flags;
|
|
128
|
+
const flags = await client.flags(getUser(), defaultValue);
|
|
129
|
+
const changed = diffFlagKeys(previousFlags, flags);
|
|
130
|
+
entry.snapshot = { flags, loading: false, error: null };
|
|
131
|
+
if (changed.size > 0 || previousFlags.length === 0) {
|
|
132
|
+
emit(entry, changed);
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
136
|
+
entry.snapshot = { ...entry.snapshot, loading: false, error: message };
|
|
137
|
+
emit(entry, null);
|
|
138
|
+
} finally {
|
|
139
|
+
entry.inFlight = false;
|
|
140
|
+
schedule(entry);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const refreshNow = (defaultValue) => {
|
|
144
|
+
const entry = getEntry(defaultValue);
|
|
145
|
+
entry.snapshot = { ...entry.snapshot, loading: true, error: null };
|
|
146
|
+
emit(entry, null);
|
|
147
|
+
void refresh(defaultValue, true);
|
|
148
|
+
};
|
|
149
|
+
const subscribe = (defaultValue, listener, options, flagKey) => {
|
|
150
|
+
const entry = getEntry(defaultValue);
|
|
151
|
+
const subscriberId = nextSubscriberId;
|
|
152
|
+
nextSubscriberId += 1;
|
|
153
|
+
entry.listeners.set(subscriberId, { listener, flagKey });
|
|
154
|
+
entry.subscribers.set(subscriberId, normalizeSubscriptionOptions(options));
|
|
155
|
+
const effective = getEffectiveOptions(entry);
|
|
156
|
+
if (effective.enabled && !entry.inFlight && entry.snapshot.loading) {
|
|
157
|
+
void refresh(defaultValue);
|
|
158
|
+
} else {
|
|
159
|
+
schedule(entry);
|
|
160
|
+
}
|
|
161
|
+
return () => {
|
|
162
|
+
entry.listeners.delete(subscriberId);
|
|
163
|
+
entry.subscribers.delete(subscriberId);
|
|
164
|
+
schedule(entry);
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
const updateUser = () => {
|
|
168
|
+
for (const entry of entries.values()) {
|
|
169
|
+
entry.snapshot = { ...entry.snapshot, loading: true, error: null };
|
|
170
|
+
emit(entry, null);
|
|
171
|
+
void refresh(entry.defaultValue);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const handleVisibilityChange = () => {
|
|
175
|
+
if (isHidden()) return;
|
|
176
|
+
for (const entry of entries.values()) {
|
|
177
|
+
const effective = getEffectiveOptions(entry);
|
|
178
|
+
if (!effective.enabled) continue;
|
|
179
|
+
void refresh(entry.defaultValue);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const unsubscribeClientUpdate = typeof client.on === "function" ? client.on(
|
|
183
|
+
"update",
|
|
184
|
+
({ changedKeys }) => {
|
|
185
|
+
const changedSet = new Set(changedKeys);
|
|
186
|
+
for (const entry of entries.values()) {
|
|
187
|
+
const previous = entry.snapshot.flags;
|
|
188
|
+
const next = client.getCachedFlags().flags;
|
|
189
|
+
const diff = diffFlagKeys(previous, next);
|
|
190
|
+
if (diff.size === 0) continue;
|
|
191
|
+
const intersects = [...diff].some((key) => changedSet.has(key));
|
|
192
|
+
if (!intersects && changedSet.size > 0) continue;
|
|
193
|
+
entry.snapshot = { ...entry.snapshot, flags: next, loading: false, error: null };
|
|
194
|
+
emit(entry, diff);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
) : () => {
|
|
198
|
+
};
|
|
199
|
+
if (typeof document !== "undefined") {
|
|
200
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
201
|
+
}
|
|
202
|
+
const dispose = () => {
|
|
203
|
+
unsubscribeClientUpdate();
|
|
204
|
+
if (typeof document !== "undefined") {
|
|
205
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
206
|
+
}
|
|
207
|
+
for (const entry of entries.values()) {
|
|
208
|
+
if (entry.timer !== null) {
|
|
209
|
+
clearTimeout(entry.timer);
|
|
210
|
+
}
|
|
211
|
+
entry.timer = null;
|
|
212
|
+
entry.listeners.clear();
|
|
213
|
+
entry.subscribers.clear();
|
|
214
|
+
}
|
|
215
|
+
entries.clear();
|
|
216
|
+
};
|
|
217
|
+
return {
|
|
218
|
+
getState(defaultValue) {
|
|
219
|
+
return getEntry(defaultValue).snapshot;
|
|
220
|
+
},
|
|
221
|
+
refreshNow,
|
|
222
|
+
subscribeAll(defaultValue, listener, options) {
|
|
223
|
+
return subscribe(defaultValue, listener, options);
|
|
224
|
+
},
|
|
225
|
+
subscribeFlag(flagKey, defaultValue, listener, options) {
|
|
226
|
+
return subscribe(defaultValue, listener, options, flagKey);
|
|
227
|
+
},
|
|
228
|
+
updateUser,
|
|
229
|
+
dispose
|
|
230
|
+
};
|
|
231
|
+
}
|
|
5
232
|
var FeatureFlareContext = createContext(null);
|
|
6
233
|
function FeatureFlareProvider(props) {
|
|
7
234
|
if (props.user && !props.onUserChange) {
|
|
@@ -10,20 +237,64 @@ function FeatureFlareProvider(props) {
|
|
|
10
237
|
const [internalUser, setInternalUser] = useState(props.initialUser);
|
|
11
238
|
const user = props.user ?? internalUser;
|
|
12
239
|
const setUser = props.onUserChange ?? setInternalUser;
|
|
240
|
+
const userRef = useRef(user);
|
|
13
241
|
const client = useMemo(() => {
|
|
14
242
|
return new FeatureFlareClient({
|
|
15
243
|
apiBaseUrl: props.config.apiBaseUrl,
|
|
16
244
|
sdkKey: props.config.sdkKey,
|
|
17
245
|
projectKey: props.config.projectKey,
|
|
18
|
-
envKey: props.config.envKey
|
|
246
|
+
envKey: props.config.envKey,
|
|
247
|
+
timeoutMs: props.config.timeoutMs,
|
|
248
|
+
maxRetries: props.config.maxRetries,
|
|
249
|
+
backoffMs: props.config.backoffMs,
|
|
250
|
+
jitter: props.config.jitter,
|
|
251
|
+
cacheTtlMs: props.config.cacheTtlMs,
|
|
252
|
+
staleTtlMs: props.config.staleTtlMs,
|
|
253
|
+
bootstrap: props.config.bootstrap,
|
|
254
|
+
persistentCache: props.config.persistentCache,
|
|
255
|
+
onMetric: props.config.onMetric,
|
|
256
|
+
realtime: props.config.realtime
|
|
19
257
|
});
|
|
20
258
|
}, [
|
|
21
259
|
props.config.apiBaseUrl,
|
|
260
|
+
props.config.backoffMs,
|
|
261
|
+
props.config.bootstrap,
|
|
262
|
+
props.config.cacheTtlMs,
|
|
22
263
|
props.config.envKey,
|
|
264
|
+
props.config.jitter,
|
|
265
|
+
props.config.maxRetries,
|
|
266
|
+
props.config.onMetric,
|
|
267
|
+
props.config.persistentCache,
|
|
23
268
|
props.config.projectKey,
|
|
24
|
-
props.config.
|
|
269
|
+
props.config.realtime,
|
|
270
|
+
props.config.sdkKey,
|
|
271
|
+
props.config.staleTtlMs,
|
|
272
|
+
props.config.timeoutMs
|
|
25
273
|
]);
|
|
26
|
-
const
|
|
274
|
+
const flagsStore = useMemo(() => createFlagsStore(client, () => userRef.current), [client]);
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
userRef.current = user;
|
|
277
|
+
flagsStore.updateUser();
|
|
278
|
+
}, [flagsStore, user]);
|
|
279
|
+
useEffect(() => {
|
|
280
|
+
return () => {
|
|
281
|
+
flagsStore.dispose();
|
|
282
|
+
client.dispose();
|
|
283
|
+
};
|
|
284
|
+
}, [client, flagsStore]);
|
|
285
|
+
const value = useMemo(
|
|
286
|
+
() => ({
|
|
287
|
+
client,
|
|
288
|
+
user,
|
|
289
|
+
setUser,
|
|
290
|
+
getFlagsState: flagsStore.getState,
|
|
291
|
+
refreshFlags: flagsStore.refreshNow,
|
|
292
|
+
subscribeFlags: flagsStore.subscribeAll,
|
|
293
|
+
subscribeFlag: (flagKey, defaultValue, listener, options) => flagsStore.subscribeFlag(flagKey, defaultValue, listener, options),
|
|
294
|
+
getFlagDiagnostics: (flagKey) => client.getFlagDiagnostics(flagKey)
|
|
295
|
+
}),
|
|
296
|
+
[client, flagsStore, setUser, user]
|
|
297
|
+
);
|
|
27
298
|
return /* @__PURE__ */ jsx(FeatureFlareContext.Provider, { value, children: props.children });
|
|
28
299
|
}
|
|
29
300
|
function useFeatureFlareContext() {
|
|
@@ -33,81 +304,159 @@ function useFeatureFlareContext() {
|
|
|
33
304
|
}
|
|
34
305
|
|
|
35
306
|
// src/hooks.ts
|
|
36
|
-
import { useEffect, useMemo as useMemo2, useRef
|
|
307
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useSyncExternalStore } from "react";
|
|
308
|
+
var EMPTY_FLAGS_STATE = { flags: [], loading: true, error: null };
|
|
309
|
+
function userFingerprint(user) {
|
|
310
|
+
if (!user) return "";
|
|
311
|
+
return JSON.stringify({
|
|
312
|
+
id: user.id ?? "",
|
|
313
|
+
key: user.key ?? "",
|
|
314
|
+
email: user.email ?? "",
|
|
315
|
+
meta: user.meta ?? {}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
function mapFlags(flags) {
|
|
319
|
+
const values = {};
|
|
320
|
+
for (const flag of flags) {
|
|
321
|
+
values[flag.key] = flag.value;
|
|
322
|
+
}
|
|
323
|
+
return values;
|
|
324
|
+
}
|
|
37
325
|
function useFeatureFlareUser() {
|
|
38
326
|
const { user, setUser } = useFeatureFlareContext();
|
|
39
327
|
return [user, setUser];
|
|
40
328
|
}
|
|
329
|
+
function useFlag(flagKey, defaultValue = false) {
|
|
330
|
+
const { subscribeFlag, getFlagsState, refreshFlags } = useFeatureFlareContext();
|
|
331
|
+
useEffect2(() => {
|
|
332
|
+
refreshFlags(defaultValue);
|
|
333
|
+
}, [defaultValue, refreshFlags]);
|
|
334
|
+
const subscribe = useMemo2(
|
|
335
|
+
() => (onStoreChange) => subscribeFlag(flagKey, defaultValue, onStoreChange),
|
|
336
|
+
[defaultValue, flagKey, subscribeFlag]
|
|
337
|
+
);
|
|
338
|
+
const state = useSyncExternalStore(subscribe, () => getFlagsState(defaultValue), () => EMPTY_FLAGS_STATE);
|
|
339
|
+
const value = state.flags.find((entry) => entry.key === flagKey)?.value ?? defaultValue;
|
|
340
|
+
return {
|
|
341
|
+
value,
|
|
342
|
+
loading: state.loading,
|
|
343
|
+
error: state.error
|
|
344
|
+
};
|
|
345
|
+
}
|
|
41
346
|
function useBoolFlag(flagKey, defaultValue = false) {
|
|
42
|
-
|
|
43
|
-
const [state, setState] = useState2({ value: defaultValue, loading: true, error: null });
|
|
44
|
-
const userId = user.id ?? user.key ?? "";
|
|
45
|
-
const key = useMemo2(() => `${flagKey}:${userId}`, [flagKey, userId]);
|
|
46
|
-
const lastKey = useRef("");
|
|
47
|
-
useEffect(() => {
|
|
48
|
-
let cancelled = false;
|
|
49
|
-
const nextKey = key;
|
|
50
|
-
lastKey.current = nextKey;
|
|
51
|
-
setState((s) => ({ ...s, loading: true, error: null }));
|
|
52
|
-
(async () => {
|
|
53
|
-
try {
|
|
54
|
-
const v = await client.bool(flagKey, user, defaultValue);
|
|
55
|
-
if (cancelled) return;
|
|
56
|
-
if (lastKey.current !== nextKey) return;
|
|
57
|
-
setState({ value: v, loading: false, error: null });
|
|
58
|
-
} catch (e) {
|
|
59
|
-
if (cancelled) return;
|
|
60
|
-
if (lastKey.current !== nextKey) return;
|
|
61
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
62
|
-
setState({ value: defaultValue, loading: false, error: msg });
|
|
63
|
-
}
|
|
64
|
-
})();
|
|
65
|
-
return () => {
|
|
66
|
-
cancelled = true;
|
|
67
|
-
};
|
|
68
|
-
}, [client, defaultValue, flagKey, key, user]);
|
|
69
|
-
return state;
|
|
347
|
+
return useFlag(flagKey, defaultValue);
|
|
70
348
|
}
|
|
71
|
-
function
|
|
72
|
-
const {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
setState({ values, loading: false, errors });
|
|
99
|
-
})();
|
|
100
|
-
return () => {
|
|
101
|
-
cancelled = true;
|
|
349
|
+
function useFlags(defaultValueOrInputOrKeys = false, optionsOrDefaultValue = {}) {
|
|
350
|
+
const { subscribeFlags, subscribeFlag, getFlagsState, refreshFlags, setUser } = useFeatureFlareContext();
|
|
351
|
+
if (Array.isArray(defaultValueOrInputOrKeys)) {
|
|
352
|
+
const keys = [...defaultValueOrInputOrKeys].map((key) => key.trim()).filter(Boolean);
|
|
353
|
+
const defaultValue2 = typeof optionsOrDefaultValue === "boolean" ? optionsOrDefaultValue : false;
|
|
354
|
+
useEffect2(() => {
|
|
355
|
+
refreshFlags(defaultValue2);
|
|
356
|
+
}, [defaultValue2, refreshFlags]);
|
|
357
|
+
const subscribe2 = useMemo2(
|
|
358
|
+
() => (onStoreChange) => {
|
|
359
|
+
const unsubs = keys.map((key) => subscribeFlag(key, defaultValue2, onStoreChange));
|
|
360
|
+
return () => {
|
|
361
|
+
for (const unsub of unsubs) unsub();
|
|
362
|
+
};
|
|
363
|
+
},
|
|
364
|
+
[defaultValue2, keys, subscribeFlag]
|
|
365
|
+
);
|
|
366
|
+
const state = useSyncExternalStore(subscribe2, () => getFlagsState(defaultValue2), () => EMPTY_FLAGS_STATE);
|
|
367
|
+
const values = mapFlags(state.flags);
|
|
368
|
+
const filtered = {};
|
|
369
|
+
for (const key of keys) {
|
|
370
|
+
filtered[key] = values[key] ?? defaultValue2;
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
values: filtered,
|
|
374
|
+
loading: state.loading,
|
|
375
|
+
errors: state.error ? { __global: state.error } : {}
|
|
102
376
|
};
|
|
103
|
-
}
|
|
104
|
-
|
|
377
|
+
}
|
|
378
|
+
const parsed = useMemo2(() => {
|
|
379
|
+
if (typeof defaultValueOrInputOrKeys === "boolean") {
|
|
380
|
+
return {
|
|
381
|
+
...typeof optionsOrDefaultValue === "object" && optionsOrDefaultValue !== null ? optionsOrDefaultValue : {},
|
|
382
|
+
defaultValue: defaultValueOrInputOrKeys
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
return defaultValueOrInputOrKeys ?? {};
|
|
386
|
+
}, [defaultValueOrInputOrKeys, optionsOrDefaultValue]);
|
|
387
|
+
const defaultValue = parsed.defaultValue ?? false;
|
|
388
|
+
const normalizedOptions = useMemo2(
|
|
389
|
+
() => ({
|
|
390
|
+
enabled: parsed.enabled ?? true,
|
|
391
|
+
refreshIntervalMs: parsed.refreshIntervalMs,
|
|
392
|
+
hiddenRefreshIntervalMs: parsed.hiddenRefreshIntervalMs,
|
|
393
|
+
pauseWhenHidden: parsed.pauseWhenHidden ?? true
|
|
394
|
+
}),
|
|
395
|
+
[parsed.enabled, parsed.hiddenRefreshIntervalMs, parsed.pauseWhenHidden, parsed.refreshIntervalMs]
|
|
396
|
+
);
|
|
397
|
+
const appliedUserRef = useRef2("");
|
|
398
|
+
const parsedUserFingerprint = useMemo2(() => userFingerprint(parsed.user), [parsed.user]);
|
|
399
|
+
useEffect2(() => {
|
|
400
|
+
if (!parsed.user) return;
|
|
401
|
+
if (appliedUserRef.current === parsedUserFingerprint) return;
|
|
402
|
+
setUser(parsed.user);
|
|
403
|
+
appliedUserRef.current = parsedUserFingerprint;
|
|
404
|
+
}, [parsed.user, parsedUserFingerprint, setUser]);
|
|
405
|
+
useEffect2(() => {
|
|
406
|
+
if (normalizedOptions.enabled === false) return;
|
|
407
|
+
refreshFlags(defaultValue);
|
|
408
|
+
}, [defaultValue, normalizedOptions.enabled, parsedUserFingerprint, refreshFlags]);
|
|
409
|
+
const subscribe = useMemo2(
|
|
410
|
+
() => (onStoreChange) => subscribeFlags(defaultValue, onStoreChange, normalizedOptions),
|
|
411
|
+
[defaultValue, normalizedOptions, subscribeFlags]
|
|
412
|
+
);
|
|
413
|
+
return useSyncExternalStore(subscribe, () => getFlagsState(defaultValue), () => EMPTY_FLAGS_STATE);
|
|
414
|
+
}
|
|
415
|
+
function useBoolFlags(flagKeysOrDefaultValue = false, optionsOrDefaultValue = {}) {
|
|
416
|
+
if (Array.isArray(flagKeysOrDefaultValue)) {
|
|
417
|
+
const defaultValue = typeof optionsOrDefaultValue === "boolean" ? optionsOrDefaultValue : false;
|
|
418
|
+
return useFlags(flagKeysOrDefaultValue, defaultValue);
|
|
419
|
+
}
|
|
420
|
+
const state = useFlags(
|
|
421
|
+
flagKeysOrDefaultValue,
|
|
422
|
+
typeof optionsOrDefaultValue === "object" && optionsOrDefaultValue !== null ? optionsOrDefaultValue : {}
|
|
423
|
+
);
|
|
424
|
+
return {
|
|
425
|
+
values: mapFlags(state.flags),
|
|
426
|
+
loading: state.loading,
|
|
427
|
+
errors: state.error ? { __global: state.error } : {}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function useFlagDiagnostics(flagKey, defaultValue = false) {
|
|
431
|
+
const { getFlagDiagnostics, subscribeFlag } = useFeatureFlareContext();
|
|
432
|
+
const subscribe = useMemo2(
|
|
433
|
+
() => (onStoreChange) => subscribeFlag(flagKey, defaultValue, onStoreChange),
|
|
434
|
+
[defaultValue, flagKey, subscribeFlag]
|
|
435
|
+
);
|
|
436
|
+
const metadata = useSyncExternalStore(
|
|
437
|
+
subscribe,
|
|
438
|
+
() => getFlagDiagnostics(flagKey),
|
|
439
|
+
() => null
|
|
440
|
+
);
|
|
441
|
+
return {
|
|
442
|
+
source: metadata?.source ?? "unknown",
|
|
443
|
+
reason: metadata?.reason ?? "unknown",
|
|
444
|
+
isStale: metadata?.isStale ?? false,
|
|
445
|
+
updatedAt: metadata?.updatedAt,
|
|
446
|
+
staleAt: metadata?.staleAt,
|
|
447
|
+
expiresAt: metadata?.expiresAt,
|
|
448
|
+
latencyMs: metadata?.latencyMs
|
|
449
|
+
};
|
|
105
450
|
}
|
|
106
451
|
export {
|
|
107
452
|
FeatureFlareProvider,
|
|
453
|
+
resolveFeatureFlareBrowserConfig,
|
|
108
454
|
useBoolFlag,
|
|
109
455
|
useBoolFlags,
|
|
110
456
|
useFeatureFlareContext,
|
|
111
|
-
useFeatureFlareUser
|
|
457
|
+
useFeatureFlareUser,
|
|
458
|
+
useFlag,
|
|
459
|
+
useFlagDiagnostics,
|
|
460
|
+
useFlags
|
|
112
461
|
};
|
|
113
462
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import React, { createContext, useMemo, useState } from 'react';\nimport { FeatureFlareClient, type FeatureFlareUserPayload } from '@featureflare/sdk-js';\n\ntype FeatureFlareReactConfig = {\n /** Optional: explicit FeatureFlare API base URL. */\n apiBaseUrl?: string;\n /** Recommended: use a client key (featureflare_cli_...). */\n sdkKey?: string;\n /** Legacy/insecure browser mode: uses /api/v1/eval (no sdkKey). */\n projectKey?: string;\n envKey?: string;\n};\n\ntype FeatureFlareContextValue = {\n client: FeatureFlareClient;\n user: FeatureFlareUserPayload;\n setUser: (next: FeatureFlareUserPayload) => void;\n};\n\nconst FeatureFlareContext = createContext<FeatureFlareContextValue | null>(null);\n\nexport function FeatureFlareProvider(props: {\n config: FeatureFlareReactConfig;\n initialUser: FeatureFlareUserPayload;\n user?: FeatureFlareUserPayload;\n onUserChange?: (next: FeatureFlareUserPayload) => void;\n children: React.ReactNode;\n}) {\n if (props.user && !props.onUserChange) {\n throw new Error('FeatureFlareProvider: when providing `user`, also provide `onUserChange` (controlled mode).');\n }\n\n const [internalUser, setInternalUser] = useState<FeatureFlareUserPayload>(props.initialUser);\n const user = props.user ?? internalUser;\n const setUser = props.onUserChange ?? setInternalUser;\n\n const client = useMemo(() => {\n return new FeatureFlareClient({\n apiBaseUrl: props.config.apiBaseUrl,\n sdkKey: props.config.sdkKey,\n projectKey: props.config.projectKey,\n envKey: props.config.envKey\n });\n }, [\n props.config.apiBaseUrl,\n props.config.envKey,\n props.config.projectKey,\n props.config.sdkKey\n ]);\n\n const value = useMemo(() => ({ client, user, setUser }), [client, user]);\n return <FeatureFlareContext.Provider value={value}>{props.children}</FeatureFlareContext.Provider>;\n}\n\nexport function useFeatureFlareContext(): FeatureFlareContextValue {\n const ctx = React.useContext(FeatureFlareContext);\n if (!ctx) throw new Error('useFeatureFlareContext must be used within <FeatureFlareProvider>.');\n return ctx;\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { FeatureFlareUserPayload } from '@featureflare/sdk-js';\nimport { useFeatureFlareContext } from './provider.js';\n\ntype BoolFlagState = {\n value: boolean;\n loading: boolean;\n error: string | null;\n};\n\ntype BoolFlagsState = {\n values: Record<string, boolean>;\n loading: boolean;\n errors: Record<string, string>;\n};\n\nexport function useFeatureFlareUser(): [FeatureFlareUserPayload, (next: FeatureFlareUserPayload) => void] {\n const { user, setUser } = useFeatureFlareContext();\n return [user, setUser];\n}\n\nexport function useBoolFlag(flagKey: string, defaultValue = false): BoolFlagState {\n const { client, user } = useFeatureFlareContext();\n const [state, setState] = useState<BoolFlagState>({ value: defaultValue, loading: true, error: null });\n const userId = user.id ?? user.key ?? '';\n const key = useMemo(() => `${flagKey}:${userId}`, [flagKey, userId]);\n const lastKey = useRef<string>('');\n\n useEffect(() => {\n let cancelled = false;\n const nextKey = key;\n lastKey.current = nextKey;\n setState((s) => ({ ...s, loading: true, error: null }));\n\n (async () => {\n try {\n const v = await client.bool(flagKey, user, defaultValue);\n if (cancelled) return;\n if (lastKey.current !== nextKey) return;\n setState({ value: v, loading: false, error: null });\n } catch (e) {\n if (cancelled) return;\n if (lastKey.current !== nextKey) return;\n const msg = e instanceof Error ? e.message : String(e);\n setState({ value: defaultValue, loading: false, error: msg });\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [client, defaultValue, flagKey, key, user]);\n\n return state;\n}\n\nexport function useBoolFlags(flagKeys: string[], defaultValue = false): BoolFlagsState {\n const { client, user } = useFeatureFlareContext();\n const sortedKeys = useMemo(() => [...flagKeys].map((k) => k.trim()).filter(Boolean).sort(), [flagKeys]);\n const userId = user.id ?? user.key ?? '';\n const key = useMemo(() => `${sortedKeys.join(',')}:${userId}`, [sortedKeys, userId]);\n const [state, setState] = useState<BoolFlagsState>({ values: {}, loading: true, errors: {} });\n const lastKey = useRef<string>('');\n\n useEffect(() => {\n let cancelled = false;\n const nextKey = key;\n lastKey.current = nextKey;\n setState({ values: {}, loading: true, errors: {} });\n\n (async () => {\n const values: Record<string, boolean> = {};\n const errors: Record<string, string> = {};\n await Promise.all(\n sortedKeys.map(async (flagKey) => {\n try {\n values[flagKey] = await client.bool(flagKey, user, defaultValue);\n } catch (e) {\n values[flagKey] = defaultValue;\n errors[flagKey] = e instanceof Error ? e.message : String(e);\n }\n })\n );\n\n if (cancelled) return;\n if (lastKey.current !== nextKey) return;\n setState({ values, loading: false, errors });\n })();\n\n return () => {\n cancelled = true;\n };\n }, [client, defaultValue, key, sortedKeys, user]);\n\n return state;\n}\n"],"mappings":"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","names":["useMemo","useState","useState","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import React, { createContext, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n FeatureFlareClient,\n type FeatureFlareBootstrapPayload,\n type FeatureFlareEvaluationMetadata,\n type FeatureFlareMetricName,\n type FeatureFlareMetricTags,\n type FeatureFlarePersistentCacheAdapter,\n type FeatureFlareUserPayload\n} from '@featureflare/sdk-js';\n\nexport type FeatureFlareEnvironmentKey = 'development' | 'staging' | 'production';\n\nexport type FeatureFlareReactConfig = {\n /** Optional: explicit FeatureFlare API base URL. */\n apiBaseUrl?: string;\n /** Recommended: use a client key (featureflare_cli_...). */\n sdkKey?: string;\n /** Legacy/insecure browser mode: uses /api/v1/eval (no sdkKey). */\n projectKey?: string;\n envKey?: FeatureFlareEnvironmentKey | string;\n timeoutMs?: number;\n maxRetries?: number;\n backoffMs?: number;\n jitter?: number;\n cacheTtlMs?: number;\n staleTtlMs?: number;\n bootstrap?: FeatureFlareBootstrapPayload;\n persistentCache?: FeatureFlarePersistentCacheAdapter;\n onMetric?: (metricName: FeatureFlareMetricName, value: number, tags?: FeatureFlareMetricTags) => void;\n realtime?: {\n enabled?: boolean;\n pollingIntervalMs?: number;\n ssePath?: string;\n };\n};\n\nexport function resolveFeatureFlareBrowserConfig(input?: {\n envKey?: FeatureFlareEnvironmentKey;\n apiBaseUrl?: string;\n}): FeatureFlareReactConfig {\n const explicitEnv = input?.envKey;\n const envFromVars =\n typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_ENV_KEY?.trim().toLowerCase() : '';\n\n const resolvedEnv: FeatureFlareEnvironmentKey | undefined =\n explicitEnv ??\n (envFromVars === 'development' || envFromVars === 'staging' || envFromVars === 'production'\n ? envFromVars\n : undefined);\n\n const apiBaseUrl =\n input?.apiBaseUrl ??\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_API_BASE_URL?.trim() : undefined);\n\n const sdkKeyDevelopment =\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_DEVELOPMENT?.trim() : '') ||\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_DEV?.trim() : '') ||\n '';\n const sdkKeyStaging =\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_STAGING?.trim() : '') || '';\n const sdkKeyProduction =\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_PRODUCTION?.trim() : '') ||\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY_PROD?.trim() : '') ||\n '';\n const sdkKeyDefault =\n (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FEATUREFLARE_CLIENT_KEY?.trim() : '') || '';\n\n const sdkKey =\n (resolvedEnv === 'development' ? sdkKeyDevelopment : '') ||\n (resolvedEnv === 'staging' ? sdkKeyStaging : '') ||\n (resolvedEnv === 'production' ? sdkKeyProduction : '') ||\n sdkKeyDefault ||\n undefined;\n\n return {\n apiBaseUrl,\n envKey: resolvedEnv,\n sdkKey\n };\n}\n\ntype FeatureFlareContextValue = {\n client: FeatureFlareClient;\n user: FeatureFlareUserPayload;\n setUser: (next: FeatureFlareUserPayload) => void;\n getFlagsState: (defaultValue: boolean) => FlagsState;\n refreshFlags: (defaultValue: boolean) => void;\n subscribeFlags: (\n defaultValue: boolean,\n listener: () => void,\n options?: FlagsSubscriptionOptions\n ) => () => void;\n subscribeFlag: (\n flagKey: string,\n defaultValue: boolean,\n listener: () => void,\n options?: FlagsSubscriptionOptions\n ) => () => void;\n getFlagDiagnostics: (flagKey: string) => FeatureFlareEvaluationMetadata | null;\n};\n\nexport type FlagsState = {\n flags: Array<{ key: string; value: boolean }>;\n loading: boolean;\n error: string | null;\n};\n\nexport type FlagsSubscriptionOptions = {\n refreshIntervalMs?: number;\n hiddenRefreshIntervalMs?: number;\n pauseWhenHidden?: boolean;\n enabled?: boolean;\n};\n\ntype NormalizedFlagsSubscriptionOptions = {\n refreshIntervalMs: number;\n hiddenRefreshIntervalMs: number;\n pauseWhenHidden: boolean;\n enabled: boolean;\n};\n\ntype ListenerEntry = {\n listener: () => void;\n flagKey?: string;\n};\n\ntype FlagsStoreEntry = {\n defaultValue: boolean;\n snapshot: FlagsState;\n listeners: Map<number, ListenerEntry>;\n subscribers: Map<number, NormalizedFlagsSubscriptionOptions>;\n timer: ReturnType<typeof setTimeout> | null;\n inFlight: boolean;\n};\n\nfunction normalizeSubscriptionOptions(options?: FlagsSubscriptionOptions): NormalizedFlagsSubscriptionOptions {\n const refreshIntervalMs =\n Number.isFinite(options?.refreshIntervalMs) && (options?.refreshIntervalMs ?? 0) > 0\n ? Number(options?.refreshIntervalMs)\n : 10000;\n const hiddenRefreshIntervalMs =\n Number.isFinite(options?.hiddenRefreshIntervalMs) && (options?.hiddenRefreshIntervalMs ?? 0) > 0\n ? Number(options?.hiddenRefreshIntervalMs)\n : Math.max(refreshIntervalMs * 6, 60000);\n\n return {\n refreshIntervalMs,\n hiddenRefreshIntervalMs,\n pauseWhenHidden: options?.pauseWhenHidden ?? true,\n enabled: options?.enabled ?? true\n };\n}\n\nfunction flagsToMap(flags: Array<{ key: string; value: boolean }>): Map<string, boolean> {\n const map = new Map<string, boolean>();\n for (const flag of flags) {\n map.set(flag.key, flag.value);\n }\n return map;\n}\n\nfunction diffFlagKeys(prev: Array<{ key: string; value: boolean }>, next: Array<{ key: string; value: boolean }>): Set<string> {\n const changed = new Set<string>();\n const prevMap = flagsToMap(prev);\n const nextMap = flagsToMap(next);\n\n for (const [key, value] of prevMap.entries()) {\n if (!nextMap.has(key) || nextMap.get(key) !== value) {\n changed.add(key);\n }\n }\n\n for (const [key, value] of nextMap.entries()) {\n if (!prevMap.has(key) || prevMap.get(key) !== value) {\n changed.add(key);\n }\n }\n\n return changed;\n}\n\nfunction createFlagsStore(client: FeatureFlareClient, getUser: () => FeatureFlareUserPayload) {\n const entries = new Map<string, FlagsStoreEntry>();\n let nextSubscriberId = 1;\n\n const isHidden = () => typeof document !== 'undefined' && document.visibilityState === 'hidden';\n\n const getEntry = (defaultValue: boolean): FlagsStoreEntry => {\n const key = defaultValue ? '1' : '0';\n const existing = entries.get(key);\n if (existing) return existing;\n\n const cached = client.getCachedFlags();\n const created: FlagsStoreEntry = {\n defaultValue,\n snapshot: { flags: cached.flags, loading: !cached.hasData, error: null },\n listeners: new Map(),\n subscribers: new Map(),\n timer: null,\n inFlight: false\n };\n entries.set(key, created);\n return created;\n };\n\n const emit = (entry: FlagsStoreEntry, changedKeys: Set<string> | null = null) => {\n for (const { listener, flagKey } of entry.listeners.values()) {\n if (!flagKey || changedKeys === null || changedKeys.has(flagKey)) {\n listener();\n }\n }\n };\n\n const getEffectiveOptions = (entry: FlagsStoreEntry) => {\n const active = [...entry.subscribers.values()].filter((s) => s.enabled);\n if (active.length === 0) {\n return { enabled: false as const, refreshIntervalMs: 0, hiddenRefreshIntervalMs: 0, pauseWhenHidden: true };\n }\n\n const refreshIntervalMs = active.reduce((min, s) => Math.min(min, s.refreshIntervalMs), Number.POSITIVE_INFINITY);\n const hiddenActive = active.filter((s) => !s.pauseWhenHidden);\n const hiddenRefreshIntervalMs =\n hiddenActive.length > 0\n ? hiddenActive.reduce((min, s) => Math.min(min, s.hiddenRefreshIntervalMs), Number.POSITIVE_INFINITY)\n : 0;\n\n return {\n enabled: true as const,\n refreshIntervalMs: Number.isFinite(refreshIntervalMs) ? refreshIntervalMs : 10000,\n hiddenRefreshIntervalMs,\n pauseWhenHidden: hiddenActive.length === 0\n };\n };\n\n const schedule = (entry: FlagsStoreEntry) => {\n if (entry.timer !== null) {\n clearTimeout(entry.timer);\n entry.timer = null;\n }\n\n const effective = getEffectiveOptions(entry);\n if (!effective.enabled) return;\n\n if (isHidden()) {\n if (effective.pauseWhenHidden) return;\n entry.timer = setTimeout(() => {\n void refresh(entry.defaultValue);\n }, effective.hiddenRefreshIntervalMs);\n return;\n }\n\n entry.timer = setTimeout(() => {\n void refresh(entry.defaultValue);\n }, effective.refreshIntervalMs);\n };\n\n const refresh = async (defaultValue: boolean, force = false) => {\n const entry = getEntry(defaultValue);\n const effective = getEffectiveOptions(entry);\n if (!effective.enabled && !force) return;\n\n if (!force && isHidden() && effective.pauseWhenHidden) {\n schedule(entry);\n return;\n }\n\n if (entry.inFlight) return;\n entry.inFlight = true;\n\n try {\n const previousFlags = entry.snapshot.flags;\n const flags = await client.flags(getUser(), defaultValue);\n const changed = diffFlagKeys(previousFlags, flags);\n entry.snapshot = { flags, loading: false, error: null };\n if (changed.size > 0 || previousFlags.length === 0) {\n emit(entry, changed);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n entry.snapshot = { ...entry.snapshot, loading: false, error: message };\n emit(entry, null);\n } finally {\n entry.inFlight = false;\n schedule(entry);\n }\n };\n\n const refreshNow = (defaultValue: boolean) => {\n const entry = getEntry(defaultValue);\n entry.snapshot = { ...entry.snapshot, loading: true, error: null };\n emit(entry, null);\n void refresh(defaultValue, true);\n };\n\n const subscribe = (\n defaultValue: boolean,\n listener: () => void,\n options?: FlagsSubscriptionOptions,\n flagKey?: string\n ): (() => void) => {\n const entry = getEntry(defaultValue);\n const subscriberId = nextSubscriberId;\n nextSubscriberId += 1;\n\n entry.listeners.set(subscriberId, { listener, flagKey });\n entry.subscribers.set(subscriberId, normalizeSubscriptionOptions(options));\n\n const effective = getEffectiveOptions(entry);\n if (effective.enabled && !entry.inFlight && entry.snapshot.loading) {\n void refresh(defaultValue);\n } else {\n schedule(entry);\n }\n\n return () => {\n entry.listeners.delete(subscriberId);\n entry.subscribers.delete(subscriberId);\n schedule(entry);\n };\n };\n\n const updateUser = () => {\n for (const entry of entries.values()) {\n entry.snapshot = { ...entry.snapshot, loading: true, error: null };\n emit(entry, null);\n void refresh(entry.defaultValue);\n }\n };\n\n const handleVisibilityChange = () => {\n if (isHidden()) return;\n for (const entry of entries.values()) {\n const effective = getEffectiveOptions(entry);\n if (!effective.enabled) continue;\n void refresh(entry.defaultValue);\n }\n };\n\n const unsubscribeClientUpdate =\n typeof (client as { on?: unknown }).on === 'function'\n ? (client as { on: (event: 'update', listener: (payload: { changedKeys: string[] }) => void) => () => void }).on(\n 'update',\n ({ changedKeys }) => {\n const changedSet = new Set(changedKeys);\n for (const entry of entries.values()) {\n const previous = entry.snapshot.flags;\n const next = client.getCachedFlags().flags;\n const diff = diffFlagKeys(previous, next);\n if (diff.size === 0) continue;\n const intersects = [...diff].some((key) => changedSet.has(key));\n if (!intersects && changedSet.size > 0) continue;\n entry.snapshot = { ...entry.snapshot, flags: next, loading: false, error: null };\n emit(entry, diff);\n }\n }\n )\n : () => {};\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', handleVisibilityChange);\n }\n\n const dispose = () => {\n unsubscribeClientUpdate();\n if (typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n }\n for (const entry of entries.values()) {\n if (entry.timer !== null) {\n clearTimeout(entry.timer);\n }\n entry.timer = null;\n entry.listeners.clear();\n entry.subscribers.clear();\n }\n entries.clear();\n };\n\n return {\n getState(defaultValue: boolean): FlagsState {\n return getEntry(defaultValue).snapshot;\n },\n refreshNow,\n subscribeAll(defaultValue: boolean, listener: () => void, options?: FlagsSubscriptionOptions) {\n return subscribe(defaultValue, listener, options);\n },\n subscribeFlag(flagKey: string, defaultValue: boolean, listener: () => void, options?: FlagsSubscriptionOptions) {\n return subscribe(defaultValue, listener, options, flagKey);\n },\n updateUser,\n dispose\n };\n}\n\nconst FeatureFlareContext = createContext<FeatureFlareContextValue | null>(null);\n\nexport function FeatureFlareProvider(props: {\n config: FeatureFlareReactConfig;\n initialUser: FeatureFlareUserPayload;\n user?: FeatureFlareUserPayload;\n onUserChange?: (next: FeatureFlareUserPayload) => void;\n children: React.ReactNode;\n}) {\n if (props.user && !props.onUserChange) {\n throw new Error('FeatureFlareProvider: when providing `user`, also provide `onUserChange` (controlled mode).');\n }\n\n const [internalUser, setInternalUser] = useState<FeatureFlareUserPayload>(props.initialUser);\n const user = props.user ?? internalUser;\n const setUser = props.onUserChange ?? setInternalUser;\n const userRef = useRef<FeatureFlareUserPayload>(user);\n\n const client = useMemo(() => {\n return new FeatureFlareClient({\n apiBaseUrl: props.config.apiBaseUrl,\n sdkKey: props.config.sdkKey,\n projectKey: props.config.projectKey,\n envKey: props.config.envKey,\n timeoutMs: props.config.timeoutMs,\n maxRetries: props.config.maxRetries,\n backoffMs: props.config.backoffMs,\n jitter: props.config.jitter,\n cacheTtlMs: props.config.cacheTtlMs,\n staleTtlMs: props.config.staleTtlMs,\n bootstrap: props.config.bootstrap,\n persistentCache: props.config.persistentCache,\n onMetric: props.config.onMetric,\n realtime: props.config.realtime\n });\n }, [\n props.config.apiBaseUrl,\n props.config.backoffMs,\n props.config.bootstrap,\n props.config.cacheTtlMs,\n props.config.envKey,\n props.config.jitter,\n props.config.maxRetries,\n props.config.onMetric,\n props.config.persistentCache,\n props.config.projectKey,\n props.config.realtime,\n props.config.sdkKey,\n props.config.staleTtlMs,\n props.config.timeoutMs\n ]);\n\n const flagsStore = useMemo(() => createFlagsStore(client, () => userRef.current), [client]);\n\n useEffect(() => {\n userRef.current = user;\n flagsStore.updateUser();\n }, [flagsStore, user]);\n\n useEffect(() => {\n return () => {\n flagsStore.dispose();\n client.dispose();\n };\n }, [client, flagsStore]);\n\n const value = useMemo(\n () => ({\n client,\n user,\n setUser,\n getFlagsState: flagsStore.getState,\n refreshFlags: flagsStore.refreshNow,\n subscribeFlags: flagsStore.subscribeAll,\n subscribeFlag: (flagKey: string, defaultValue: boolean, listener: () => void, options?: FlagsSubscriptionOptions) =>\n flagsStore.subscribeFlag(flagKey, defaultValue, listener, options),\n getFlagDiagnostics: (flagKey: string) => client.getFlagDiagnostics(flagKey)\n }),\n [client, flagsStore, setUser, user]\n );\n return <FeatureFlareContext.Provider value={value}>{props.children}</FeatureFlareContext.Provider>;\n}\n\nexport function useFeatureFlareContext(): FeatureFlareContextValue {\n const ctx = React.useContext(FeatureFlareContext);\n if (!ctx) throw new Error('useFeatureFlareContext must be used within <FeatureFlareProvider>.');\n return ctx;\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport type { FeatureFlareEvaluationMetadata, FeatureFlareUserPayload } from '@featureflare/sdk-js';\nimport { useFeatureFlareContext, type FlagsState, type FlagsSubscriptionOptions } from './provider.js';\n\ntype BoolFlagState = {\n value: boolean;\n loading: boolean;\n error: string | null;\n};\n\ntype BoolFlagsState = {\n values: Record<string, boolean>;\n loading: boolean;\n errors: Record<string, string>;\n};\n\ntype UseFlagsOptions = FlagsSubscriptionOptions;\n\ntype UseFlagsInput = UseFlagsOptions & {\n defaultValue?: boolean;\n user?: FeatureFlareUserPayload;\n};\n\nexport type FlagDiagnostics = {\n source: FeatureFlareEvaluationMetadata['source'] | 'unknown';\n reason: FeatureFlareEvaluationMetadata['reason'] | 'unknown';\n isStale: boolean;\n updatedAt?: number;\n staleAt?: number;\n expiresAt?: number;\n latencyMs?: number;\n};\n\nconst EMPTY_FLAGS_STATE: FlagsState = { flags: [], loading: true, error: null };\n\nfunction userFingerprint(user?: FeatureFlareUserPayload): string {\n if (!user) return '';\n return JSON.stringify({\n id: user.id ?? '',\n key: user.key ?? '',\n email: user.email ?? '',\n meta: user.meta ?? {}\n });\n}\n\nfunction mapFlags(flags: Array<{ key: string; value: boolean }>): Record<string, boolean> {\n const values: Record<string, boolean> = {};\n for (const flag of flags) {\n values[flag.key] = flag.value;\n }\n return values;\n}\n\nexport function useFeatureFlareUser(): [FeatureFlareUserPayload, (next: FeatureFlareUserPayload) => void] {\n const { user, setUser } = useFeatureFlareContext();\n return [user, setUser];\n}\n\nexport function useFlag(flagKey: string, defaultValue = false): BoolFlagState {\n const { subscribeFlag, getFlagsState, refreshFlags } = useFeatureFlareContext();\n\n useEffect(() => {\n refreshFlags(defaultValue);\n }, [defaultValue, refreshFlags]);\n\n const subscribe = useMemo(\n () =>\n (onStoreChange: () => void) =>\n subscribeFlag(flagKey, defaultValue, onStoreChange),\n [defaultValue, flagKey, subscribeFlag]\n );\n\n const state = useSyncExternalStore(subscribe, () => getFlagsState(defaultValue), () => EMPTY_FLAGS_STATE);\n const value = state.flags.find((entry) => entry.key === flagKey)?.value ?? defaultValue;\n\n return {\n value,\n loading: state.loading,\n error: state.error\n };\n}\n\nexport function useBoolFlag(flagKey: string, defaultValue = false): BoolFlagState {\n return useFlag(flagKey, defaultValue);\n}\n\nexport function useFlags(flagKeys: string[], defaultValue?: boolean): BoolFlagsState;\nexport function useFlags(input?: UseFlagsInput): FlagsState;\nexport function useFlags(defaultValue?: boolean, options?: UseFlagsOptions): FlagsState;\nexport function useFlags(\n defaultValueOrInputOrKeys: boolean | UseFlagsInput | string[] = false,\n optionsOrDefaultValue: UseFlagsOptions | boolean = {}\n): FlagsState | BoolFlagsState {\n const { subscribeFlags, subscribeFlag, getFlagsState, refreshFlags, setUser } = useFeatureFlareContext();\n\n if (Array.isArray(defaultValueOrInputOrKeys)) {\n const keys = [...defaultValueOrInputOrKeys].map((key) => key.trim()).filter(Boolean);\n const defaultValue =\n typeof optionsOrDefaultValue === 'boolean' ? optionsOrDefaultValue : false;\n\n useEffect(() => {\n refreshFlags(defaultValue);\n }, [defaultValue, refreshFlags]);\n\n const subscribe = useMemo(\n () =>\n (onStoreChange: () => void) => {\n const unsubs = keys.map((key) => subscribeFlag(key, defaultValue, onStoreChange));\n return () => {\n for (const unsub of unsubs) unsub();\n };\n },\n [defaultValue, keys, subscribeFlag]\n );\n\n const state = useSyncExternalStore(subscribe, () => getFlagsState(defaultValue), () => EMPTY_FLAGS_STATE);\n const values = mapFlags(state.flags);\n const filtered: Record<string, boolean> = {};\n for (const key of keys) {\n filtered[key] = values[key] ?? defaultValue;\n }\n\n return {\n values: filtered,\n loading: state.loading,\n errors: state.error ? { __global: state.error } : {}\n };\n }\n\n const parsed = useMemo<UseFlagsInput>(() => {\n if (typeof defaultValueOrInputOrKeys === 'boolean') {\n return {\n ...(typeof optionsOrDefaultValue === 'object' && optionsOrDefaultValue !== null ? optionsOrDefaultValue : {}),\n defaultValue: defaultValueOrInputOrKeys\n };\n }\n return defaultValueOrInputOrKeys ?? {};\n }, [defaultValueOrInputOrKeys, optionsOrDefaultValue]);\n\n const defaultValue = parsed.defaultValue ?? false;\n\n const normalizedOptions = useMemo<UseFlagsOptions>(\n () => ({\n enabled: parsed.enabled ?? true,\n refreshIntervalMs: parsed.refreshIntervalMs,\n hiddenRefreshIntervalMs: parsed.hiddenRefreshIntervalMs,\n pauseWhenHidden: parsed.pauseWhenHidden ?? true\n }),\n [parsed.enabled, parsed.hiddenRefreshIntervalMs, parsed.pauseWhenHidden, parsed.refreshIntervalMs]\n );\n\n const appliedUserRef = useRef<string>('');\n const parsedUserFingerprint = useMemo(() => userFingerprint(parsed.user), [parsed.user]);\n\n useEffect(() => {\n if (!parsed.user) return;\n if (appliedUserRef.current === parsedUserFingerprint) return;\n setUser(parsed.user);\n appliedUserRef.current = parsedUserFingerprint;\n }, [parsed.user, parsedUserFingerprint, setUser]);\n\n useEffect(() => {\n if (normalizedOptions.enabled === false) return;\n refreshFlags(defaultValue);\n }, [defaultValue, normalizedOptions.enabled, parsedUserFingerprint, refreshFlags]);\n\n const subscribe = useMemo(\n () =>\n (onStoreChange: () => void) =>\n subscribeFlags(defaultValue, onStoreChange, normalizedOptions),\n [defaultValue, normalizedOptions, subscribeFlags]\n );\n\n return useSyncExternalStore(subscribe, () => getFlagsState(defaultValue), () => EMPTY_FLAGS_STATE);\n}\n\nexport function useBoolFlags(flagKeys: string[], defaultValue?: boolean): BoolFlagsState;\nexport function useBoolFlags(defaultValue?: boolean, options?: UseFlagsOptions): BoolFlagsState;\nexport function useBoolFlags(\n flagKeysOrDefaultValue: string[] | boolean = false,\n optionsOrDefaultValue: UseFlagsOptions | boolean = {}\n): BoolFlagsState {\n if (Array.isArray(flagKeysOrDefaultValue)) {\n const defaultValue =\n typeof optionsOrDefaultValue === 'boolean' ? optionsOrDefaultValue : false;\n return useFlags(flagKeysOrDefaultValue, defaultValue);\n }\n\n const state = useFlags(\n flagKeysOrDefaultValue,\n typeof optionsOrDefaultValue === 'object' && optionsOrDefaultValue !== null\n ? optionsOrDefaultValue\n : {}\n ) as FlagsState;\n return {\n values: mapFlags(state.flags),\n loading: state.loading,\n errors: state.error ? { __global: state.error } : {}\n };\n}\n\nexport function useFlagDiagnostics(flagKey: string, defaultValue = false): FlagDiagnostics {\n const { getFlagDiagnostics, subscribeFlag } = useFeatureFlareContext();\n\n const subscribe = useMemo(\n () =>\n (onStoreChange: () => void) =>\n subscribeFlag(flagKey, defaultValue, onStoreChange),\n [defaultValue, flagKey, subscribeFlag]\n );\n\n const metadata = useSyncExternalStore(\n subscribe,\n () => getFlagDiagnostics(flagKey),\n () => null\n );\n\n return {\n source: metadata?.source ?? 'unknown',\n reason: metadata?.reason ?? 'unknown',\n isStale: metadata?.isStale ?? false,\n updatedAt: metadata?.updatedAt,\n staleAt: metadata?.staleAt,\n expiresAt: metadata?.expiresAt,\n latencyMs: metadata?.latencyMs\n };\n}\n"],"mappings":"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","names":["useEffect","useMemo","useRef","useEffect","useMemo","defaultValue","subscribe","useRef"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@featureflare/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6-beta.259",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"react-dom": ">=18"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@featureflare/sdk-js": "0.0.
|
|
36
|
+
"@featureflare/sdk-js": "0.0.6-beta.259"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^22.10.2",
|
|
40
|
-
"@types/react": "^
|
|
41
|
-
"@types/react-dom": "^
|
|
40
|
+
"@types/react": "^19.0.0",
|
|
41
|
+
"@types/react-dom": "^19.0.0",
|
|
42
42
|
"eslint": "^9.16.0",
|
|
43
43
|
"prettier": "^3.4.2",
|
|
44
44
|
"tsup": "^8.3.5",
|