@terreno/rtk 0.19.0 → 0.20.1

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 CHANGED
@@ -95,3 +95,9 @@ const {socket, isSocketConnected} = useSocketConnection({
95
95
  - `generateTags` - RTK Query tag generator for cache invalidation
96
96
  - `ListResponse`, `populateId` - Mongoose list response utilities
97
97
 
98
+ ## Feature flags (OpenFeature)
99
+
100
+ `useFeatureFlags` and **`useTerrenoFeatureFlags`** wire Terreno’s `GET /feature-flags/flagConfiguration` into OpenFeature. Peer dependencies: **`@openfeature/react-sdk`** and **`@openfeature/web-sdk`** (install them in your app; do not rely on transitive copies).
101
+
102
+ Full upgrade steps (backend + frontend + SDK regen) live in the **Terreno root README**: [Feature flags: OpenFeature migration](../README.md#feature-flags-openfeature-migration).
103
+
@@ -118,7 +118,7 @@ export declare const useGetVersionCheckQuery: <R extends Record<string, any> = i
118
118
  isFetching: false;
119
119
  isSuccess: false;
120
120
  isError: false;
121
- }, "error" | "data" | "fulfilledTimeStamp" | "currentData" | "isFetching" | "isSuccess"> & {
121
+ }, "error" | "data" | "fulfilledTimeStamp" | "isFetching" | "isSuccess" | "currentData"> & {
122
122
  isSuccess: true;
123
123
  isFetching: false;
124
124
  error: undefined;
@@ -256,7 +256,7 @@ export declare const useGetVersionCheckQuery: <R extends Record<string, any> = i
256
256
  isFetching: false;
257
257
  isSuccess: false;
258
258
  isError: false;
259
- }, "error" | "data" | "fulfilledTimeStamp" | "currentData" | "isFetching" | "isSuccess"> & {
259
+ }, "error" | "data" | "fulfilledTimeStamp" | "isFetching" | "isSuccess" | "currentData"> & {
260
260
  isSuccess: true;
261
261
  isFetching: false;
262
262
  error: undefined;
@@ -395,7 +395,7 @@ export declare const useGetVersionCheckQuery: <R extends Record<string, any> = i
395
395
  isFetching: false;
396
396
  isSuccess: false;
397
397
  isError: false;
398
- }, "error" | "data" | "fulfilledTimeStamp" | "currentData" | "isFetching" | "isSuccess"> & {
398
+ }, "error" | "data" | "fulfilledTimeStamp" | "isFetching" | "isSuccess" | "currentData"> & {
399
399
  isSuccess: true;
400
400
  isFetching: false;
401
401
  error: undefined;
@@ -527,7 +527,7 @@ export declare const useGetVersionCheckQuery: <R extends Record<string, any> = i
527
527
  isFetching: false;
528
528
  isSuccess: false;
529
529
  isError: false;
530
- }, "error" | "data" | "fulfilledTimeStamp" | "currentData" | "isFetching" | "isSuccess"> & {
530
+ }, "error" | "data" | "fulfilledTimeStamp" | "isFetching" | "isSuccess" | "currentData"> & {
531
531
  isSuccess: true;
532
532
  isFetching: false;
533
533
  error: undefined;
package/dist/index.d.ts CHANGED
@@ -18,5 +18,6 @@ export * from "./useFeatureFlags";
18
18
  export * from "./useOfflineStatus";
19
19
  export * from "./useRealtimeDebug";
20
20
  export * from "./useServerStatus";
21
+ export * from "./useTerrenoFeatureFlags";
21
22
  export * from "./useUpgradeCheck";
22
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -18,5 +18,6 @@ export * from "./useFeatureFlags";
18
18
  export * from "./useOfflineStatus";
19
19
  export * from "./useRealtimeDebug";
20
20
  export * from "./useServerStatus";
21
+ export * from "./useTerrenoFeatureFlags";
21
22
  export * from "./useUpgradeCheck";
22
23
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openFeatureReactSdkSpike.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openFeatureReactSdkSpike.test.d.ts","sourceRoot":"","sources":["../src/openFeatureReactSdkSpike.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
2
+ import { OpenFeatureProvider, useBooleanFlagValue } from "@openfeature/react-sdk";
3
+ import { NOOP_PROVIDER, OpenFeature, TypedInMemoryProvider } from "@openfeature/web-sdk";
4
+ import { renderHook, waitFor } from "@testing-library/react-native";
5
+ import React from "react";
6
+ const SPIKE_DOMAIN = "openfeature-rn-spike";
7
+ describe("@openfeature/react-sdk with React Native test renderer", () => {
8
+ beforeEach(async () => {
9
+ await OpenFeature.setProviderAndWait(SPIKE_DOMAIN, new TypedInMemoryProvider({
10
+ "demo-flag": {
11
+ defaultVariant: "on",
12
+ disabled: false,
13
+ variants: { off: false, on: true },
14
+ },
15
+ }));
16
+ });
17
+ afterEach(async () => {
18
+ await OpenFeature.setProviderAndWait(SPIKE_DOMAIN, NOOP_PROVIDER);
19
+ });
20
+ it("exposes useBooleanFlagValue when wrapped by OpenFeatureProvider", async () => {
21
+ const { result } = renderHook(() => useBooleanFlagValue("demo-flag", false), {
22
+ wrapper: ({ children }) => React.createElement(OpenFeatureProvider, { domain: SPIKE_DOMAIN }, children),
23
+ });
24
+ await waitFor(() => {
25
+ expect(result.current).toBe(true);
26
+ });
27
+ });
28
+ });
29
+ //# sourceMappingURL=openFeatureReactSdkSpike.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openFeatureReactSdkSpike.test.js","sourceRoot":"","sources":["../src/openFeatureReactSdkSpike.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAC,MAAM,UAAU,CAAC;AACrE,OAAO,EAAC,mBAAmB,EAAE,mBAAmB,EAAC,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAC,aAAa,EAAE,WAAW,EAAE,qBAAqB,EAAC,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAC,UAAU,EAAE,OAAO,EAAC,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAE5C,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;IACtE,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,WAAW,CAAC,kBAAkB,CAClC,YAAY,EACZ,IAAI,qBAAqB,CAAC;YACxB,WAAW,EAAE;gBACX,cAAc,EAAE,IAAI;gBACpB,QAAQ,EAAE,KAAK;gBACf,QAAQ,EAAE,EAAC,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAC;aACjC;SACF,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,WAAW,CAAC,kBAAkB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,EAAC,MAAM,EAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;YACzE,OAAO,EAAE,CAAC,EAAC,QAAQ,EAA8B,EAAE,EAAE,CACnD,KAAK,CAAC,aAAa,CAAC,mBAAmB,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,EAAE,QAAQ,CAAC;SAC7E,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -4,17 +4,17 @@ interface FlagValues {
4
4
  }
5
5
  type FlagsApi = Api<any, any, any, any>;
6
6
  interface UseFeatureFlagsResult {
7
+ error: unknown;
7
8
  flags: FlagValues;
8
9
  getFlag: (key: string) => boolean;
9
10
  getVariant: (key: string) => string | null;
10
11
  isLoading: boolean;
11
- error: unknown;
12
12
  refetch: () => void;
13
13
  }
14
14
  /**
15
15
  * Creates feature flag accessors from an RTK Query API instance.
16
16
  *
17
- * Injects a `GET {basePath}/evaluate` endpoint into the API and returns
17
+ * Injects a `GET {basePath}/flagConfiguration` endpoint into the API and returns
18
18
  * accessors for reading flag values. Fetches once on mount and caches via
19
19
  * RTK Query. Both `api` and `basePath` should be stable references.
20
20
  *
@@ -27,29 +27,29 @@ interface UseFeatureFlagsResult {
27
27
  * ```
28
28
  */
29
29
  export interface UseFeatureFlagsOptions {
30
- /**
31
- * Base path for the feature-flags endpoint. Defaults to "/feature-flags".
32
- */
33
30
  basePath?: string;
34
- /**
35
- * When true, the underlying evaluate query is not fired. Use this to avoid
36
- * fetching before the user is authenticated.
37
- */
31
+ domain?: string;
38
32
  skip?: boolean;
33
+ socket?: {
34
+ off: (event: string, handler: (...args: unknown[]) => void) => void;
35
+ on: (event: string, handler: (...args: unknown[]) => void) => void;
36
+ } | null;
37
+ socketEventName?: string;
38
+ userId?: string | null;
39
39
  }
40
40
  interface ResolvedFeatureFlagsOptions {
41
41
  basePath: string;
42
+ domain: string;
42
43
  skip: boolean;
44
+ socket?: UseFeatureFlagsOptions["socket"];
45
+ socketEventName?: string;
46
+ userId?: string | null;
43
47
  }
44
48
  /**
45
49
  * Normalizes the legacy-compatible `basePathOrOptions` argument into a
46
- * `{basePath, skip}` pair with defaults applied.
47
- *
48
- * - `undefined` -> `{basePath: "/feature-flags", skip: false}`
49
- * - `string` -> `{basePath: <string>, skip: false}` (legacy form)
50
- * - `object` -> `{basePath: opts.basePath ?? "/feature-flags", skip: opts.skip ?? false}`
50
+ * `{basePath, skip, ...}` pair with defaults applied.
51
51
  */
52
52
  export declare const resolveFeatureFlagsOptions: (basePathOrOptions?: string | UseFeatureFlagsOptions) => ResolvedFeatureFlagsOptions;
53
- export declare function useFeatureFlags(api: FlagsApi, basePathOrOptions?: string | UseFeatureFlagsOptions): UseFeatureFlagsResult;
53
+ export declare const useFeatureFlags: (api: FlagsApi, basePathOrOptions?: string | UseFeatureFlagsOptions) => UseFeatureFlagsResult;
54
54
  export {};
55
55
  //# sourceMappingURL=useFeatureFlags.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFeatureFlags.d.ts","sourceRoot":"","sources":["../src/useFeatureFlags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,8BAA8B,CAAC;AAGtD,UAAU,UAAU;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACxC;AAGD,KAAK,QAAQ,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAuCxC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,2BAA2B;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GACrC,oBAAoB,MAAM,GAAG,sBAAsB,KAClD,2BAMF,CAAC;AAIF,wBAAgB,eAAe,CAC7B,GAAG,EAAE,QAAQ,EACb,iBAAiB,CAAC,EAAE,MAAM,GAAG,sBAAsB,GAClD,qBAAqB,CAyEvB"}
1
+ {"version":3,"file":"useFeatureFlags.d.ts","sourceRoot":"","sources":["../src/useFeatureFlags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,8BAA8B,CAAC;AAItD,UAAU,UAAU;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACxC;AAGD,KAAK,QAAQ,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAExC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE;QACP,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;QACpE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;KACpE,GAAG,IAAI,CAAC;IACT,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,UAAU,2BAA2B;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,oBAAoB,MAAM,GAAG,sBAAsB,KAClD,2BAaF,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,KAAK,QAAQ,EACb,oBAAoB,MAAM,GAAG,sBAAsB,KAClD,qBAoGF,CAAC"}
@@ -1,107 +1,94 @@
1
- import { useCallback, useEffect, useRef } from "react";
2
- /**
3
- * Cache the enhanced api per (api, basePath). `injectEndpoints` logs a console
4
- * error in development whenever an endpoint with the same name is re-injected
5
- * with `overrideExisting: false`, so calling it on every render of every
6
- * consumer would flood the console. WeakMap-by-api lets the GC reclaim entries
7
- * when the api object is unreachable.
8
- */
9
- const enhancedApiCache = new WeakMap();
10
- const getEnhancedApi = (api, basePath) => {
11
- let byBase = enhancedApiCache.get(api);
12
- if (!byBase) {
13
- byBase = new Map();
14
- enhancedApiCache.set(api, byBase);
15
- }
16
- const cached = byBase.get(basePath);
17
- if (cached) {
18
- return cached;
19
- }
20
- const enhanced = api.injectEndpoints({
21
- endpoints: (builder) => ({
22
- evaluateFeatureFlags: builder.query({
23
- query: () => ({
24
- method: "GET",
25
- url: `${basePath}/evaluate`,
26
- }),
27
- }),
28
- }),
29
- overrideExisting: false,
30
- });
31
- byBase.set(basePath, enhanced);
32
- return enhanced;
33
- };
1
+ import { useCallback, useEffect, useMemo, useRef } from "react";
2
+ import { useTerrenoFeatureFlags } from "./useTerrenoFeatureFlags";
34
3
  /**
35
4
  * Normalizes the legacy-compatible `basePathOrOptions` argument into a
36
- * `{basePath, skip}` pair with defaults applied.
37
- *
38
- * - `undefined` -> `{basePath: "/feature-flags", skip: false}`
39
- * - `string` -> `{basePath: <string>, skip: false}` (legacy form)
40
- * - `object` -> `{basePath: opts.basePath ?? "/feature-flags", skip: opts.skip ?? false}`
5
+ * `{basePath, skip, ...}` pair with defaults applied.
41
6
  */
42
7
  export const resolveFeatureFlagsOptions = (basePathOrOptions) => {
43
- const { basePath = "/feature-flags", skip = false } = typeof basePathOrOptions === "string"
8
+ const raw = typeof basePathOrOptions === "string"
44
9
  ? { basePath: basePathOrOptions, skip: false }
45
10
  : (basePathOrOptions ?? {});
46
- return { basePath, skip };
11
+ return {
12
+ basePath: raw.basePath ?? "/feature-flags",
13
+ domain: raw.domain ?? "feature-flags",
14
+ skip: raw.skip ?? false,
15
+ socket: raw.socket,
16
+ socketEventName: raw.socketEventName,
17
+ userId: raw.userId,
18
+ };
47
19
  };
48
- // Overloaded signature preserves backwards compatibility with callers that
49
- // pass a string basePath as the second argument.
50
- export function useFeatureFlags(api, basePathOrOptions) {
51
- const { basePath, skip } = resolveFeatureFlagsOptions(basePathOrOptions);
52
- const enhancedApi = getEnhancedApi(api, basePath);
53
- const useEvaluateQuery = enhancedApi.useEvaluateFeatureFlagsQuery;
54
- const { data, isLoading, error, refetch } = useEvaluateQuery(undefined, { skip });
55
- const evaluateStartedAtRef = useRef(null);
56
- const flags = data ?? {};
57
- // Log when evaluate request enters loading state so client timing can be measured.
20
+ export const useFeatureFlags = (api, basePathOrOptions) => {
21
+ const { basePath, domain, skip, socket, socketEventName, userId } = resolveFeatureFlagsOptions(basePathOrOptions);
22
+ const { client, error, flags: rawFlags, isLoading, refetch, } = useTerrenoFeatureFlags(api, {
23
+ basePath,
24
+ domain,
25
+ skip,
26
+ socket,
27
+ socketEventName,
28
+ userId,
29
+ });
30
+ const fetchStartedAtRef = useRef(null);
58
31
  useEffect(() => {
59
- if (!isLoading || evaluateStartedAtRef.current !== null) {
32
+ if (!isLoading || fetchStartedAtRef.current !== null) {
60
33
  return;
61
34
  }
62
- evaluateStartedAtRef.current = Date.now();
63
- console.debug("[feature-flags] evaluate request started", {
35
+ fetchStartedAtRef.current = Date.now();
36
+ console.debug("[feature-flags] flagConfiguration request started", {
64
37
  basePath,
65
38
  });
66
39
  }, [basePath, isLoading]);
67
- // Log evaluate success with duration and number of resolved flag values.
68
40
  useEffect(() => {
69
- if (!data || evaluateStartedAtRef.current === null) {
41
+ if (!error || fetchStartedAtRef.current === null) {
70
42
  return;
71
43
  }
72
- const durationMs = Date.now() - evaluateStartedAtRef.current;
73
- evaluateStartedAtRef.current = null;
74
- console.debug("[feature-flags] evaluate request completed", {
44
+ const durationMs = Date.now() - fetchStartedAtRef.current;
45
+ fetchStartedAtRef.current = null;
46
+ console.debug("[feature-flags] flagConfiguration request failed", {
75
47
  basePath,
76
48
  durationMs,
77
- evaluatedFlagCount: Object.keys(flags).length,
78
- evaluatedFlags: flags,
49
+ error,
79
50
  });
80
- }, [basePath, data, flags]);
81
- // Log evaluate failures with duration so request issues can be correlated.
51
+ }, [basePath, error]);
52
+ const flatFlags = useMemo(() => {
53
+ const out = {};
54
+ for (const [key, def] of Object.entries(rawFlags)) {
55
+ const value = def.variants[def.defaultVariant];
56
+ out[key] = value ?? null;
57
+ }
58
+ return out;
59
+ }, [rawFlags]);
82
60
  useEffect(() => {
83
- if (!error || evaluateStartedAtRef.current === null) {
61
+ if (Object.keys(flatFlags).length === 0 || fetchStartedAtRef.current === null) {
62
+ return;
63
+ }
64
+ if (isLoading) {
84
65
  return;
85
66
  }
86
- const durationMs = Date.now() - evaluateStartedAtRef.current;
87
- evaluateStartedAtRef.current = null;
88
- console.debug("[feature-flags] evaluate request failed", {
67
+ const durationMs = Date.now() - fetchStartedAtRef.current;
68
+ fetchStartedAtRef.current = null;
69
+ console.debug("[feature-flags] flagConfiguration request completed", {
89
70
  basePath,
90
71
  durationMs,
91
- error,
72
+ evaluatedFlagCount: Object.keys(flatFlags).length,
73
+ evaluatedFlags: flatFlags,
92
74
  });
93
- }, [basePath, error]);
75
+ }, [basePath, flatFlags, isLoading]);
94
76
  const getFlag = useCallback((key) => {
95
- const value = flags[key];
96
- return value === true;
97
- }, [flags]);
77
+ return client.getBooleanValue(key, false);
78
+ }, [client]);
98
79
  const getVariant = useCallback((key) => {
99
- const value = flags[key];
100
- if (typeof value === "string") {
101
- return value;
80
+ if (!rawFlags[key]) {
81
+ return null;
82
+ }
83
+ const value = client.getStringValue(key, "");
84
+ if (value === "") {
85
+ return null;
102
86
  }
103
- return null;
104
- }, [flags]);
105
- return { error, flags, getFlag, getVariant, isLoading, refetch };
106
- }
87
+ return value;
88
+ }, [client, rawFlags]);
89
+ const stableRefetch = useCallback(() => {
90
+ void refetch();
91
+ }, [refetch]);
92
+ return { error, flags: flatFlags, getFlag, getVariant, isLoading, refetch: stableRefetch };
93
+ };
107
94
  //# sourceMappingURL=useFeatureFlags.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFeatureFlags.js","sourceRoot":"","sources":["../src/useFeatureFlags.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFeatureFlags.js","sourceRoot":"","sources":["../src/useFeatureFlags.ts"],"names":[],"mappings":"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"}