@bluealba/pae-feature-flags 1.0.0-feature-initial-feature-flags-poc-1233

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 (50) hide show
  1. package/README.md +239 -0
  2. package/dist/core/index.d.ts +5 -0
  3. package/dist/core/index.d.ts.map +1 -0
  4. package/dist/core/index.js +21 -0
  5. package/dist/core/index.js.map +1 -0
  6. package/dist/core/types.d.ts +63 -0
  7. package/dist/core/types.d.ts.map +1 -0
  8. package/dist/core/types.js +16 -0
  9. package/dist/core/types.js.map +1 -0
  10. package/dist/index.d.ts +54 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +73 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/nestjs/FeatureFlagsClient.d.ts +99 -0
  15. package/dist/nestjs/FeatureFlagsClient.d.ts.map +1 -0
  16. package/dist/nestjs/FeatureFlagsClient.js +173 -0
  17. package/dist/nestjs/FeatureFlagsClient.js.map +1 -0
  18. package/dist/nestjs/FeatureFlagsModule.d.ts +79 -0
  19. package/dist/nestjs/FeatureFlagsModule.d.ts.map +1 -0
  20. package/dist/nestjs/FeatureFlagsModule.js +98 -0
  21. package/dist/nestjs/FeatureFlagsModule.js.map +1 -0
  22. package/dist/nestjs/index.d.ts +20 -0
  23. package/dist/nestjs/index.d.ts.map +1 -0
  24. package/dist/nestjs/index.js +36 -0
  25. package/dist/nestjs/index.js.map +1 -0
  26. package/dist/react/FeatureFlagGuard.d.ts +60 -0
  27. package/dist/react/FeatureFlagGuard.d.ts.map +1 -0
  28. package/dist/react/FeatureFlagGuard.js +48 -0
  29. package/dist/react/FeatureFlagGuard.js.map +1 -0
  30. package/dist/react/FeatureFlagsProvider.d.ts +102 -0
  31. package/dist/react/FeatureFlagsProvider.d.ts.map +1 -0
  32. package/dist/react/FeatureFlagsProvider.js +194 -0
  33. package/dist/react/FeatureFlagsProvider.js.map +1 -0
  34. package/dist/react/index.d.ts +10 -0
  35. package/dist/react/index.d.ts.map +1 -0
  36. package/dist/react/index.js +19 -0
  37. package/dist/react/index.js.map +1 -0
  38. package/dist/react/useFeatureFlag.d.ts +26 -0
  39. package/dist/react/useFeatureFlag.d.ts.map +1 -0
  40. package/dist/react/useFeatureFlag.js +91 -0
  41. package/dist/react/useFeatureFlag.js.map +1 -0
  42. package/dist/react/useFeatureFlags.d.ts +38 -0
  43. package/dist/react/useFeatureFlags.d.ts.map +1 -0
  44. package/dist/react/useFeatureFlags.js +49 -0
  45. package/dist/react/useFeatureFlags.js.map +1 -0
  46. package/dist/react/useVariant.d.ts +48 -0
  47. package/dist/react/useVariant.d.ts.map +1 -0
  48. package/dist/react/useVariant.js +108 -0
  49. package/dist/react/useVariant.js.map +1 -0
  50. package/package.json +43 -0
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ /**
3
+ * FeatureFlagsProvider
4
+ *
5
+ * A React Context provider that manages feature flag state with prefetching and caching capabilities.
6
+ * This provider should wrap your application or a section of it to provide feature flag access to child components.
7
+ *
8
+ * Features:
9
+ * - Prefetches specified flags on mount
10
+ * - Optional automatic refresh at configurable intervals
11
+ * - Caches flag values for efficient access
12
+ * - Provides both boolean flags and multivariant flags
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <FeatureFlagsProvider
17
+ * gatewayUrl="/api"
18
+ * prefetchFlags={['new-ui', 'beta-feature']}
19
+ * refreshInterval={60000}
20
+ * >
21
+ * <App />
22
+ * </FeatureFlagsProvider>
23
+ * ```
24
+ */
25
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ var desc = Object.getOwnPropertyDescriptor(m, k);
28
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
29
+ desc = { enumerable: true, get: function() { return m[k]; } };
30
+ }
31
+ Object.defineProperty(o, k2, desc);
32
+ }) : (function(o, m, k, k2) {
33
+ if (k2 === undefined) k2 = k;
34
+ o[k2] = m[k];
35
+ }));
36
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
37
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
38
+ }) : function(o, v) {
39
+ o["default"] = v;
40
+ });
41
+ var __importStar = (this && this.__importStar) || (function () {
42
+ var ownKeys = function(o) {
43
+ ownKeys = Object.getOwnPropertyNames || function (o) {
44
+ var ar = [];
45
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
46
+ return ar;
47
+ };
48
+ return ownKeys(o);
49
+ };
50
+ return function (mod) {
51
+ if (mod && mod.__esModule) return mod;
52
+ var result = {};
53
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
54
+ __setModuleDefault(result, mod);
55
+ return result;
56
+ };
57
+ })();
58
+ Object.defineProperty(exports, "__esModule", { value: true });
59
+ exports.FeatureFlagsProvider = exports.FeatureFlagsContext = void 0;
60
+ const react_1 = __importStar(require("react"));
61
+ /**
62
+ * Default context value
63
+ */
64
+ const defaultContextValue = {
65
+ flags: new Map(),
66
+ variants: new Map(),
67
+ isLoading: false,
68
+ error: null,
69
+ checkFlag: () => false,
70
+ getVariant: () => null,
71
+ refresh: async () => { },
72
+ };
73
+ /**
74
+ * React Context for feature flags
75
+ */
76
+ exports.FeatureFlagsContext = (0, react_1.createContext)(defaultContextValue);
77
+ /**
78
+ * Provider component for feature flags
79
+ */
80
+ const FeatureFlagsProvider = ({ gatewayUrl = '', prefetchFlags = [], refreshInterval, children, }) => {
81
+ const [flags, setFlags] = (0, react_1.useState)(new Map());
82
+ const [variants, setVariants] = (0, react_1.useState)(new Map());
83
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
84
+ const [error, setError] = (0, react_1.useState)(null);
85
+ /**
86
+ * Fetch flags from the gateway API
87
+ */
88
+ const fetchFlags = (0, react_1.useCallback)(async (flagNames) => {
89
+ if (flagNames.length === 0) {
90
+ return;
91
+ }
92
+ setIsLoading(true);
93
+ setError(null);
94
+ try {
95
+ const url = `${gatewayUrl}/feature-flags/evaluate`;
96
+ const response = await fetch(url, {
97
+ method: 'POST',
98
+ headers: {
99
+ 'Content-Type': 'application/json',
100
+ },
101
+ body: JSON.stringify({ flags: flagNames }),
102
+ credentials: 'include', // Include cookies for authentication
103
+ });
104
+ if (!response.ok) {
105
+ throw new Error(`Failed to fetch feature flags: ${response.status} ${response.statusText}`);
106
+ }
107
+ const data = await response.json();
108
+ const evaluations = data.flags;
109
+ // Update flags map
110
+ const newFlags = new Map();
111
+ const newVariants = new Map();
112
+ // Handle both Map and Record response formats
113
+ const entries = evaluations instanceof Map ? Array.from(evaluations.entries()) : Object.entries(evaluations);
114
+ entries.forEach(([flagName, evaluation]) => {
115
+ newFlags.set(flagName, evaluation.enabled);
116
+ if (evaluation.variant !== undefined) {
117
+ newVariants.set(flagName, {
118
+ variant: evaluation.variant || null,
119
+ payload: evaluation.payload,
120
+ });
121
+ }
122
+ });
123
+ setFlags(newFlags);
124
+ setVariants(newVariants);
125
+ }
126
+ catch (err) {
127
+ const error = err instanceof Error ? err : new Error('Unknown error fetching feature flags');
128
+ setError(error);
129
+ console.error('Error fetching feature flags:', error);
130
+ }
131
+ finally {
132
+ setIsLoading(false);
133
+ }
134
+ }, [gatewayUrl]);
135
+ /**
136
+ * Refresh all prefetched flags
137
+ */
138
+ const refresh = (0, react_1.useCallback)(async () => {
139
+ if (prefetchFlags.length > 0) {
140
+ await fetchFlags(prefetchFlags);
141
+ }
142
+ }, [prefetchFlags, fetchFlags]);
143
+ /**
144
+ * Initial prefetch on mount
145
+ */
146
+ (0, react_1.useEffect)(() => {
147
+ if (prefetchFlags.length > 0) {
148
+ fetchFlags(prefetchFlags);
149
+ }
150
+ }, [prefetchFlags, fetchFlags]);
151
+ /**
152
+ * Set up automatic refresh interval
153
+ */
154
+ (0, react_1.useEffect)(() => {
155
+ if (refreshInterval && refreshInterval > 0 && prefetchFlags.length > 0) {
156
+ const intervalId = setInterval(() => {
157
+ fetchFlags(prefetchFlags);
158
+ }, refreshInterval);
159
+ return () => {
160
+ clearInterval(intervalId);
161
+ };
162
+ }
163
+ }, [refreshInterval, prefetchFlags, fetchFlags]);
164
+ /**
165
+ * Check if a flag is enabled from cache
166
+ */
167
+ const checkFlag = (0, react_1.useCallback)((flagName, defaultValue = false) => {
168
+ var _a;
169
+ return (_a = flags.get(flagName)) !== null && _a !== void 0 ? _a : defaultValue;
170
+ }, [flags]);
171
+ /**
172
+ * Get variant from cache
173
+ */
174
+ const getVariant = (0, react_1.useCallback)((flagName) => {
175
+ var _a;
176
+ return (_a = variants.get(flagName)) !== null && _a !== void 0 ? _a : null;
177
+ }, [variants]);
178
+ /**
179
+ * Memoized context value
180
+ */
181
+ const contextValue = (0, react_1.useMemo)(() => ({
182
+ flags,
183
+ variants,
184
+ isLoading,
185
+ error,
186
+ checkFlag,
187
+ getVariant,
188
+ refresh,
189
+ }), [flags, variants, isLoading, error, checkFlag, getVariant, refresh]);
190
+ return (react_1.default.createElement(exports.FeatureFlagsContext.Provider, { value: contextValue }, children));
191
+ };
192
+ exports.FeatureFlagsProvider = FeatureFlagsProvider;
193
+ exports.FeatureFlagsProvider.displayName = 'FeatureFlagsProvider';
194
+ //# sourceMappingURL=FeatureFlagsProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagsProvider.js","sourceRoot":"","sources":["../../src/react/FeatureFlagsProvider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * React implementation for feature flags
3
+ * @module react
4
+ */
5
+ export { FeatureFlagsProvider, FeatureFlagsContext, type FeatureFlagsProviderProps, type FeatureFlagsContextValue } from './FeatureFlagsProvider';
6
+ export { useFeatureFlag } from './useFeatureFlag';
7
+ export { useFeatureFlags } from './useFeatureFlags';
8
+ export { useVariant, type UseVariantResult } from './useVariant';
9
+ export { FeatureFlagGuard, type FeatureFlagGuardProps } from './FeatureFlagGuard';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,KAAK,yBAAyB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClJ,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * React implementation for feature flags
4
+ * @module react
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.FeatureFlagGuard = exports.useVariant = exports.useFeatureFlags = exports.useFeatureFlag = exports.FeatureFlagsContext = exports.FeatureFlagsProvider = void 0;
8
+ var FeatureFlagsProvider_1 = require("./FeatureFlagsProvider");
9
+ Object.defineProperty(exports, "FeatureFlagsProvider", { enumerable: true, get: function () { return FeatureFlagsProvider_1.FeatureFlagsProvider; } });
10
+ Object.defineProperty(exports, "FeatureFlagsContext", { enumerable: true, get: function () { return FeatureFlagsProvider_1.FeatureFlagsContext; } });
11
+ var useFeatureFlag_1 = require("./useFeatureFlag");
12
+ Object.defineProperty(exports, "useFeatureFlag", { enumerable: true, get: function () { return useFeatureFlag_1.useFeatureFlag; } });
13
+ var useFeatureFlags_1 = require("./useFeatureFlags");
14
+ Object.defineProperty(exports, "useFeatureFlags", { enumerable: true, get: function () { return useFeatureFlags_1.useFeatureFlags; } });
15
+ var useVariant_1 = require("./useVariant");
16
+ Object.defineProperty(exports, "useVariant", { enumerable: true, get: function () { return useVariant_1.useVariant; } });
17
+ var FeatureFlagGuard_1 = require("./FeatureFlagGuard");
18
+ Object.defineProperty(exports, "FeatureFlagGuard", { enumerable: true, get: function () { return FeatureFlagGuard_1.FeatureFlagGuard; } });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAkJ;AAAzI,4HAAA,oBAAoB,OAAA;AAAE,2HAAA,mBAAmB,OAAA;AAClD,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,2CAAiE;AAAxD,wGAAA,UAAU,OAAA;AACnB,uDAAkF;AAAzE,oHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * useFeatureFlag Hook
3
+ *
4
+ * A React hook for evaluating a single boolean feature flag.
5
+ * This hook first checks if the flag is in the prefetched cache (from FeatureFlagsProvider).
6
+ * If not found in cache, it fetches the flag individually from the API.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * function MyComponent() {
11
+ * const isNewUIEnabled = useFeatureFlag('new-ui', false);
12
+ *
13
+ * return isNewUIEnabled ? <NewUI /> : <OldUI />;
14
+ * }
15
+ * ```
16
+ */
17
+ /**
18
+ * Hook for evaluating a single boolean feature flag
19
+ *
20
+ * @param flagName - Name of the feature flag to evaluate
21
+ * @param defaultValue - Default value to use if flag cannot be evaluated (default: false)
22
+ * @param gatewayUrl - Base URL for the gateway API (default: '')
23
+ * @returns Boolean indicating whether the flag is enabled
24
+ */
25
+ export declare function useFeatureFlag(flagName: string, defaultValue?: boolean, gatewayUrl?: string): boolean;
26
+ //# sourceMappingURL=useFeatureFlag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFeatureFlag.d.ts","sourceRoot":"","sources":["../../src/react/useFeatureFlag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,OAAe,EAC7B,UAAU,GAAE,MAAW,GACtB,OAAO,CAqET"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * useFeatureFlag Hook
4
+ *
5
+ * A React hook for evaluating a single boolean feature flag.
6
+ * This hook first checks if the flag is in the prefetched cache (from FeatureFlagsProvider).
7
+ * If not found in cache, it fetches the flag individually from the API.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * function MyComponent() {
12
+ * const isNewUIEnabled = useFeatureFlag('new-ui', false);
13
+ *
14
+ * return isNewUIEnabled ? <NewUI /> : <OldUI />;
15
+ * }
16
+ * ```
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.useFeatureFlag = useFeatureFlag;
20
+ const react_1 = require("react");
21
+ const FeatureFlagsProvider_1 = require("./FeatureFlagsProvider");
22
+ /**
23
+ * Hook for evaluating a single boolean feature flag
24
+ *
25
+ * @param flagName - Name of the feature flag to evaluate
26
+ * @param defaultValue - Default value to use if flag cannot be evaluated (default: false)
27
+ * @param gatewayUrl - Base URL for the gateway API (default: '')
28
+ * @returns Boolean indicating whether the flag is enabled
29
+ */
30
+ function useFeatureFlag(flagName, defaultValue = false, gatewayUrl = '') {
31
+ const context = (0, react_1.useContext)(FeatureFlagsProvider_1.FeatureFlagsContext);
32
+ const [flagValue, setFlagValue] = (0, react_1.useState)(defaultValue);
33
+ const [isInitialized, setIsInitialized] = (0, react_1.useState)(false);
34
+ (0, react_1.useEffect)(() => {
35
+ // First, check if the flag is in the prefetched cache
36
+ const cachedValue = context.checkFlag(flagName, null);
37
+ if (cachedValue !== null && cachedValue !== undefined) {
38
+ // Flag is in cache, use it
39
+ setFlagValue(cachedValue);
40
+ setIsInitialized(true);
41
+ return;
42
+ }
43
+ // Flag not in cache, fetch it individually
44
+ let isMounted = true;
45
+ const fetchFlag = async () => {
46
+ var _a;
47
+ try {
48
+ const url = `${gatewayUrl}/feature-flags/${encodeURIComponent(flagName)}?defaultValue=${defaultValue}`;
49
+ const response = await fetch(url, {
50
+ method: 'GET',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ },
54
+ credentials: 'include', // Include cookies for authentication
55
+ });
56
+ if (!response.ok) {
57
+ console.warn(`Failed to fetch feature flag '${flagName}': ${response.status} ${response.statusText}`);
58
+ if (isMounted) {
59
+ setFlagValue(defaultValue);
60
+ setIsInitialized(true);
61
+ }
62
+ return;
63
+ }
64
+ const data = await response.json();
65
+ if (isMounted) {
66
+ setFlagValue((_a = data.enabled) !== null && _a !== void 0 ? _a : defaultValue);
67
+ setIsInitialized(true);
68
+ }
69
+ }
70
+ catch (error) {
71
+ console.error(`Error fetching feature flag '${flagName}':`, error);
72
+ if (isMounted) {
73
+ setFlagValue(defaultValue);
74
+ setIsInitialized(true);
75
+ }
76
+ }
77
+ };
78
+ fetchFlag();
79
+ return () => {
80
+ isMounted = false;
81
+ };
82
+ }, [flagName, defaultValue, gatewayUrl, context]);
83
+ // Return cached value if available, otherwise return the fetched value
84
+ // If not initialized yet, return default value
85
+ if (!isInitialized && context.flags.size === 0) {
86
+ return defaultValue;
87
+ }
88
+ const cachedValue = context.checkFlag(flagName, null);
89
+ return cachedValue !== null && cachedValue !== undefined ? cachedValue : flagValue;
90
+ }
91
+ //# sourceMappingURL=useFeatureFlag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFeatureFlag.js","sourceRoot":"","sources":["../../src/react/useFeatureFlag.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * useFeatureFlags Hook
3
+ *
4
+ * A React hook for accessing the full feature flags context.
5
+ * This hook provides access to all prefetched flags, variants, loading state,
6
+ * and utility functions for checking flags and refreshing the cache.
7
+ *
8
+ * This hook MUST be used within a FeatureFlagsProvider.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * function MyComponent() {
13
+ * const { flags, checkFlag, refresh, isLoading } = useFeatureFlags();
14
+ *
15
+ * const handleRefresh = async () => {
16
+ * await refresh();
17
+ * };
18
+ *
19
+ * return (
20
+ * <div>
21
+ * <button onClick={handleRefresh} disabled={isLoading}>
22
+ * Refresh Flags
23
+ * </button>
24
+ * <div>Total flags: {flags.size}</div>
25
+ * </div>
26
+ * );
27
+ * }
28
+ * ```
29
+ */
30
+ import { type FeatureFlagsContextValue } from './FeatureFlagsProvider';
31
+ /**
32
+ * Hook for accessing the feature flags context
33
+ *
34
+ * @throws Error if used outside of FeatureFlagsProvider
35
+ * @returns The full feature flags context
36
+ */
37
+ export declare function useFeatureFlags(): FeatureFlagsContextValue;
38
+ //# sourceMappingURL=useFeatureFlags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFeatureFlags.d.ts","sourceRoot":"","sources":["../../src/react/useFeatureFlags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAuB,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE5F;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,wBAAwB,CAW1D"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * useFeatureFlags Hook
4
+ *
5
+ * A React hook for accessing the full feature flags context.
6
+ * This hook provides access to all prefetched flags, variants, loading state,
7
+ * and utility functions for checking flags and refreshing the cache.
8
+ *
9
+ * This hook MUST be used within a FeatureFlagsProvider.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * function MyComponent() {
14
+ * const { flags, checkFlag, refresh, isLoading } = useFeatureFlags();
15
+ *
16
+ * const handleRefresh = async () => {
17
+ * await refresh();
18
+ * };
19
+ *
20
+ * return (
21
+ * <div>
22
+ * <button onClick={handleRefresh} disabled={isLoading}>
23
+ * Refresh Flags
24
+ * </button>
25
+ * <div>Total flags: {flags.size}</div>
26
+ * </div>
27
+ * );
28
+ * }
29
+ * ```
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.useFeatureFlags = useFeatureFlags;
33
+ const react_1 = require("react");
34
+ const FeatureFlagsProvider_1 = require("./FeatureFlagsProvider");
35
+ /**
36
+ * Hook for accessing the feature flags context
37
+ *
38
+ * @throws Error if used outside of FeatureFlagsProvider
39
+ * @returns The full feature flags context
40
+ */
41
+ function useFeatureFlags() {
42
+ const context = (0, react_1.useContext)(FeatureFlagsProvider_1.FeatureFlagsContext);
43
+ if (!context) {
44
+ throw new Error('useFeatureFlags must be used within a FeatureFlagsProvider. ' +
45
+ 'Wrap your component tree with <FeatureFlagsProvider> to use this hook.');
46
+ }
47
+ return context;
48
+ }
49
+ //# sourceMappingURL=useFeatureFlags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFeatureFlags.js","sourceRoot":"","sources":["../../src/react/useFeatureFlags.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;AAWH,0CAWC;AApBD,iCAAmC;AACnC,iEAA4F;AAE5F;;;;;GAKG;AACH,SAAgB,eAAe;IAC7B,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,0CAAmB,CAAC,CAAC;IAEhD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,8DAA8D;YAC9D,wEAAwE,CACzE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * useVariant Hook
3
+ *
4
+ * A React hook for getting the variant value of a multivariant feature flag.
5
+ * This hook first checks if the variant is in the prefetched cache (from FeatureFlagsProvider).
6
+ * If not found in cache, it fetches the variant individually from the API.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * function MyComponent() {
11
+ * const { variant, payload, isLoading } = useVariant('checkout-flow');
12
+ *
13
+ * if (isLoading) return <Spinner />;
14
+ *
15
+ * if (variant === 'new-checkout') {
16
+ * return <NewCheckout config={payload} />;
17
+ * }
18
+ *
19
+ * return <OldCheckout />;
20
+ * }
21
+ * ```
22
+ */
23
+ /**
24
+ * Return type for the useVariant hook
25
+ */
26
+ export interface UseVariantResult {
27
+ /**
28
+ * The selected variant name, or null if no variant is selected
29
+ */
30
+ variant: string | null;
31
+ /**
32
+ * The payload data associated with the variant
33
+ */
34
+ payload: unknown;
35
+ /**
36
+ * Whether the variant is currently being loaded
37
+ */
38
+ isLoading: boolean;
39
+ }
40
+ /**
41
+ * Hook for getting the variant value of a multivariant feature flag
42
+ *
43
+ * @param flagName - Name of the feature flag
44
+ * @param gatewayUrl - Base URL for the gateway API (default: '')
45
+ * @returns Object containing variant, payload, and loading state
46
+ */
47
+ export declare function useVariant(flagName: string, gatewayUrl?: string): UseVariantResult;
48
+ //# sourceMappingURL=useVariant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVariant.d.ts","sourceRoot":"","sources":["../../src/react/useVariant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAW,GACtB,gBAAgB,CAmFlB"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * useVariant Hook
4
+ *
5
+ * A React hook for getting the variant value of a multivariant feature flag.
6
+ * This hook first checks if the variant is in the prefetched cache (from FeatureFlagsProvider).
7
+ * If not found in cache, it fetches the variant individually from the API.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * function MyComponent() {
12
+ * const { variant, payload, isLoading } = useVariant('checkout-flow');
13
+ *
14
+ * if (isLoading) return <Spinner />;
15
+ *
16
+ * if (variant === 'new-checkout') {
17
+ * return <NewCheckout config={payload} />;
18
+ * }
19
+ *
20
+ * return <OldCheckout />;
21
+ * }
22
+ * ```
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.useVariant = useVariant;
26
+ const react_1 = require("react");
27
+ const FeatureFlagsProvider_1 = require("./FeatureFlagsProvider");
28
+ /**
29
+ * Hook for getting the variant value of a multivariant feature flag
30
+ *
31
+ * @param flagName - Name of the feature flag
32
+ * @param gatewayUrl - Base URL for the gateway API (default: '')
33
+ * @returns Object containing variant, payload, and loading state
34
+ */
35
+ function useVariant(flagName, gatewayUrl = '') {
36
+ const context = (0, react_1.useContext)(FeatureFlagsProvider_1.FeatureFlagsContext);
37
+ const [variant, setVariant] = (0, react_1.useState)(null);
38
+ const [payload, setPayload] = (0, react_1.useState)(undefined);
39
+ const [isLoading, setIsLoading] = (0, react_1.useState)(true);
40
+ (0, react_1.useEffect)(() => {
41
+ // First, check if the variant is in the prefetched cache
42
+ const cachedVariant = context.getVariant(flagName);
43
+ if (cachedVariant !== null) {
44
+ // Variant is in cache, use it
45
+ setVariant(cachedVariant.variant);
46
+ setPayload(cachedVariant.payload);
47
+ setIsLoading(false);
48
+ return;
49
+ }
50
+ // Variant not in cache, fetch it individually
51
+ let isMounted = true;
52
+ const fetchVariant = async () => {
53
+ setIsLoading(true);
54
+ try {
55
+ const url = `${gatewayUrl}/feature-flags/${encodeURIComponent(flagName)}/variant`;
56
+ const response = await fetch(url, {
57
+ method: 'GET',
58
+ headers: {
59
+ 'Content-Type': 'application/json',
60
+ },
61
+ credentials: 'include', // Include cookies for authentication
62
+ });
63
+ if (!response.ok) {
64
+ console.warn(`Failed to fetch variant for flag '${flagName}': ${response.status} ${response.statusText}`);
65
+ if (isMounted) {
66
+ setVariant(null);
67
+ setPayload(undefined);
68
+ setIsLoading(false);
69
+ }
70
+ return;
71
+ }
72
+ const data = await response.json();
73
+ if (isMounted) {
74
+ setVariant(data.variant || null);
75
+ setPayload(data.payload);
76
+ setIsLoading(false);
77
+ }
78
+ }
79
+ catch (error) {
80
+ console.error(`Error fetching variant for flag '${flagName}':`, error);
81
+ if (isMounted) {
82
+ setVariant(null);
83
+ setPayload(undefined);
84
+ setIsLoading(false);
85
+ }
86
+ }
87
+ };
88
+ fetchVariant();
89
+ return () => {
90
+ isMounted = false;
91
+ };
92
+ }, [flagName, gatewayUrl, context]);
93
+ // Return cached variant if available, otherwise return the fetched variant
94
+ const cachedVariant = context.getVariant(flagName);
95
+ if (cachedVariant !== null) {
96
+ return {
97
+ variant: cachedVariant.variant,
98
+ payload: cachedVariant.payload,
99
+ isLoading: false,
100
+ };
101
+ }
102
+ return {
103
+ variant,
104
+ payload,
105
+ isLoading,
106
+ };
107
+ }
108
+ //# sourceMappingURL=useVariant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVariant.js","sourceRoot":"","sources":["../../src/react/useVariant.ts"],"names":[],"mappings":"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"}