@omniretail/omniflags-react 1.0.0

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 ADDED
@@ -0,0 +1,120 @@
1
+ # @omniretail/omniflags-react
2
+
3
+ React SDK for OmniFlags.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @omniretail/omniflags-react
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ Wrap your app with `OmniFlagsProvider` and use the hooks anywhere below it.
14
+
15
+ ```tsx
16
+ import { OmniFlagsProvider, useFlag } from "@omniretail/omniflags-react";
17
+
18
+ function App() {
19
+ return (
20
+ <OmniFlagsProvider sdkKey="your-sdk-key">
21
+ <MyApp />
22
+ </OmniFlagsProvider>
23
+ );
24
+ }
25
+
26
+ function MyApp() {
27
+ const darkMode = useFlag("store.dark-mode");
28
+ return <div className={darkMode ? "dark" : "light"}>...</div>;
29
+ }
30
+ ```
31
+
32
+ ## Provider
33
+
34
+ ```tsx
35
+ <OmniFlagsProvider sdkKey="your-sdk-key">
36
+ {children}
37
+ </OmniFlagsProvider>
38
+ ```
39
+
40
+ | Prop | Type | Description |
41
+ |------|------|-------------|
42
+ | `sdkKey` | `string` | **Required.** SDK key from the OmniFlags dashboard. |
43
+
44
+ ## Hooks
45
+
46
+ ### `useFlag`
47
+
48
+ Evaluates a boolean flag.
49
+
50
+ ```tsx
51
+ const enabled = useFlag("store.show-banner");
52
+ const enabled = useFlag("store.show-banner", { customerId: "cust-123" }); // with context
53
+ const enabled = useFlag("store.show-banner", undefined, false); // custom default
54
+ ```
55
+
56
+ ### `useFlagValue`
57
+
58
+ Returns the typed value of a flag.
59
+
60
+ ```tsx
61
+ const theme = useFlagValue<string>("store.theme", "light");
62
+ const limit = useFlagValue<number>("store.item-limit", 10);
63
+ const theme = useFlagValue<string>("store.theme", "light", { businessId: "biz-456" }); // with context
64
+ ```
65
+
66
+ ### `useFlagVariant`
67
+
68
+ Returns the full evaluation result — value, variant, reason, and which rule matched.
69
+
70
+ ```tsx
71
+ const result = useFlagVariant("store.show-banner");
72
+ // result.value, result.variant, result.reason, result.ruleId, result.errorCode
73
+ ```
74
+
75
+ ### `useFlagLoading`
76
+
77
+ Returns the current loading state of the flag client.
78
+
79
+ ```tsx
80
+ const { isFetching, isLoading, origin, error } = useFlagLoading();
81
+ ```
82
+
83
+ | Field | Type | Description |
84
+ |-------|------|-------------|
85
+ | `isFetching` | `boolean` | A network request is in flight. |
86
+ | `isLoading` | `boolean` | No flags have been loaded yet (first fetch pending). |
87
+ | `origin` | `FlagOrigin` | Where the current flags came from: `"NONE"`, `"CACHE"`, or `"SERVER"`. |
88
+ | `error` | `Error \| null` | The last fetch error, or `null`. |
89
+
90
+ ```tsx
91
+ function FlagGate({ children }: { children: React.ReactNode }) {
92
+ const { isLoading } = useFlagLoading();
93
+ if (isLoading) return <Spinner />;
94
+ return <>{children}</>;
95
+ }
96
+ ```
97
+
98
+ ### `useOmniFlags`
99
+
100
+ Low-level access to the underlying client and ready state.
101
+
102
+ ```tsx
103
+ const { client, ready } = useOmniFlags();
104
+ ```
105
+
106
+ ## Context
107
+
108
+ Context is passed per evaluation call — customer, business, branch, country, etc. There is no persistent context state.
109
+
110
+ ```tsx
111
+ function Banner({ customerId, businessId }: Props) {
112
+ const ctx = { customerId, businessId };
113
+ const show = useFlag("store.show-banner", ctx);
114
+ return show ? <Banner /> : null;
115
+ }
116
+ ```
117
+
118
+ ## Flag keys
119
+
120
+ Keys are namespaced by project: `{projectKey}.{flagKey}`. Find the full flag key in the OmniFlags dashboard on the flag detail page.
@@ -0,0 +1,7 @@
1
+ import type { OmniFlagsClient } from "@omniretail/omniflags-core";
2
+ export interface OmniFlagsContextValue {
3
+ client: OmniFlagsClient;
4
+ ready: boolean;
5
+ }
6
+ export declare const OmniFlagsContext: import("react").Context<OmniFlagsContextValue | null>;
7
+ export declare function useOmniFlagsContext(): OmniFlagsContextValue;
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from "react";
2
+ export const OmniFlagsContext = createContext(null);
3
+ export function useOmniFlagsContext() {
4
+ const ctx = useContext(OmniFlagsContext);
5
+ if (!ctx) {
6
+ throw new Error("useOmniFlags* hooks must be used inside <OmniFlagsProvider>");
7
+ }
8
+ return ctx;
9
+ }
10
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAQlD,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAA+B,IAAI,CAAC,CAAC;AAElF,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { EvaluationContext, EvaluationResult, LoadingState } from "@omniretail/omniflags-core";
2
+ /**
3
+ * Returns the current loading state — whether flags are fetching, where they
4
+ * came from (NONE / CACHE / SERVER), and the last fetch error if any.
5
+ */
6
+ export declare function useFlagLoading(): LoadingState;
7
+ /**
8
+ * Get the full OmniFlags client and ready state.
9
+ */
10
+ export declare function useOmniFlags(): {
11
+ client: import("@omniretail/omniflags-core").OmniFlagsClient;
12
+ ready: boolean;
13
+ };
14
+ /**
15
+ * Evaluate a boolean flag.
16
+ * Only re-renders when the value for this specific flag changes.
17
+ */
18
+ export declare function useFlag(flagKey: string, context?: EvaluationContext, defaultValue?: boolean): boolean;
19
+ /**
20
+ * Evaluate a flag and return its typed value.
21
+ * Only re-renders when the value for this specific flag changes.
22
+ * Best used with primitive values (string, number, boolean).
23
+ */
24
+ export declare function useFlagValue<T = unknown>(flagKey: string, defaultValue: T, context?: EvaluationContext): T;
25
+ /**
26
+ * Evaluate a flag and return the full evaluation result (variant, reason, etc.).
27
+ * Only re-renders when the variant or reason changes.
28
+ */
29
+ export declare function useFlagVariant(flagKey: string, context?: EvaluationContext): EvaluationResult;
package/dist/hooks.js ADDED
@@ -0,0 +1,89 @@
1
+ import { useState, useEffect, useRef } from "react";
2
+ import { useOmniFlagsContext } from "./context.js";
3
+ /**
4
+ * Returns the current loading state — whether flags are fetching, where they
5
+ * came from (NONE / CACHE / SERVER), and the last fetch error if any.
6
+ */
7
+ export function useFlagLoading() {
8
+ const { client } = useOmniFlagsContext();
9
+ const [state, setState] = useState(() => client.loadingState);
10
+ useEffect(() => {
11
+ const unsub = client.on("PROVIDER_LOADING_STATE_CHANGED", () => {
12
+ setState(client.loadingState);
13
+ });
14
+ return unsub;
15
+ }, [client]);
16
+ return state;
17
+ }
18
+ /**
19
+ * Get the full OmniFlags client and ready state.
20
+ */
21
+ export function useOmniFlags() {
22
+ const { client, ready } = useOmniFlagsContext();
23
+ return { client, ready };
24
+ }
25
+ /**
26
+ * Evaluate a boolean flag.
27
+ * Only re-renders when the value for this specific flag changes.
28
+ */
29
+ export function useFlag(flagKey, context, defaultValue = false) {
30
+ const { client } = useOmniFlagsContext();
31
+ const contextRef = useRef(context);
32
+ contextRef.current = context;
33
+ const [value, setValue] = useState(() => client.isEnabled(flagKey, context, defaultValue));
34
+ useEffect(() => {
35
+ const update = () => {
36
+ const next = client.isEnabled(flagKey, contextRef.current, defaultValue);
37
+ setValue((prev) => (prev === next ? prev : next));
38
+ };
39
+ update(); // re-evaluate immediately in case flagKey or defaultValue changed
40
+ const unsubReady = client.on("PROVIDER_READY", update);
41
+ const unsubChange = client.on("PROVIDER_CONFIGURATION_CHANGED", update);
42
+ return () => { unsubReady(); unsubChange(); };
43
+ }, [client, flagKey, defaultValue]);
44
+ return value;
45
+ }
46
+ /**
47
+ * Evaluate a flag and return its typed value.
48
+ * Only re-renders when the value for this specific flag changes.
49
+ * Best used with primitive values (string, number, boolean).
50
+ */
51
+ export function useFlagValue(flagKey, defaultValue, context) {
52
+ const { client } = useOmniFlagsContext();
53
+ const contextRef = useRef(context);
54
+ contextRef.current = context;
55
+ const [value, setValue] = useState(() => client.getValue(flagKey, context, defaultValue));
56
+ useEffect(() => {
57
+ const update = () => {
58
+ const next = client.getValue(flagKey, contextRef.current, defaultValue);
59
+ setValue((prev) => (Object.is(prev, next) ? prev : next));
60
+ };
61
+ update();
62
+ const unsubReady = client.on("PROVIDER_READY", update);
63
+ const unsubChange = client.on("PROVIDER_CONFIGURATION_CHANGED", update);
64
+ return () => { unsubReady(); unsubChange(); };
65
+ }, [client, flagKey, defaultValue]);
66
+ return value;
67
+ }
68
+ /**
69
+ * Evaluate a flag and return the full evaluation result (variant, reason, etc.).
70
+ * Only re-renders when the variant or reason changes.
71
+ */
72
+ export function useFlagVariant(flagKey, context) {
73
+ const { client } = useOmniFlagsContext();
74
+ const contextRef = useRef(context);
75
+ contextRef.current = context;
76
+ const [result, setResult] = useState(() => client.getVariant(flagKey, context));
77
+ useEffect(() => {
78
+ const update = () => {
79
+ const next = client.getVariant(flagKey, contextRef.current);
80
+ setResult((prev) => (prev.variant === next.variant && prev.reason === next.reason ? prev : next));
81
+ };
82
+ update();
83
+ const unsubReady = client.on("PROVIDER_READY", update);
84
+ const unsubChange = client.on("PROVIDER_CONFIGURATION_CHANGED", update);
85
+ return () => { unsubReady(); unsubChange(); };
86
+ }, [client, flagKey]);
87
+ return result;
88
+ }
89
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { OmniFlagsProvider } from "./provider.js";
2
+ export type { OmniFlagsProviderProps } from "./provider.js";
3
+ export { useOmniFlags, useFlag, useFlagValue, useFlagVariant, useFlagLoading } from "./hooks.js";
4
+ export { OmniFlagsContext } from "./context.js";
5
+ export type { OmniFlagsContextValue } from "./context.js";
6
+ export type { EvaluationContext, EvaluationResult, FlagConfig, FlagOrigin, Hook, LoadingState, ProviderEvent, } from "@omniretail/omniflags-core";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { OmniFlagsProvider } from "./provider.js";
2
+ export { useOmniFlags, useFlag, useFlagValue, useFlagVariant, useFlagLoading } from "./hooks.js";
3
+ export { OmniFlagsContext } from "./context.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React, { type ReactNode } from "react";
2
+ export interface OmniFlagsProviderProps {
3
+ sdkKey: string;
4
+ children?: ReactNode;
5
+ }
6
+ export declare function OmniFlagsProvider({ sdkKey, children, ...rest }: OmniFlagsProviderProps): React.FunctionComponentElement<React.ProviderProps<import("./context.js").OmniFlagsContextValue | null>>;
@@ -0,0 +1,21 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { OmniFlagsClient } from "@omniretail/omniflags-core";
3
+ import { OmniFlagsContext } from "./context.js";
4
+ export function OmniFlagsProvider({ sdkKey, children, ...rest }) {
5
+ const provider = rest.provider;
6
+ const [ready, setReady] = useState(false);
7
+ const [client] = useState(() => new OmniFlagsClient({ sdkKey, provider }));
8
+ useEffect(() => {
9
+ let mounted = true;
10
+ client.waitForReady().then(() => {
11
+ if (mounted)
12
+ setReady(true);
13
+ });
14
+ return () => {
15
+ mounted = false;
16
+ void client.shutdown();
17
+ };
18
+ }, [client]);
19
+ return React.createElement(OmniFlagsContext.Provider, { value: { client, ready } }, children);
20
+ }
21
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAYhD,MAAM,UAAU,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAA0B;IACrF,MAAM,QAAQ,GAAI,IAAsB,CAAC,QAAQ,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAE3E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,MAAM,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,OAAO;gBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,OAAO,GAAG,KAAK,CAAC;YAChB,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,KAAK,CAAC,aAAa,CACxB,gBAAgB,CAAC,QAAQ,EACzB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAC5B,QAAQ,CACT,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@omniretail/omniflags-react",
3
+ "version": "1.0.0",
4
+ "description": "OmniFlags React SDK — provider + hooks for feature flags",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": ["dist"],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest"
19
+ },
20
+ "peerDependencies": {
21
+ "react": "^18.0.0 || ^19.0.0"
22
+ },
23
+ "dependencies": {
24
+ "@omniretail/omniflags-core": "file:../core"
25
+ },
26
+ "devDependencies": {
27
+ "@testing-library/react": "^16.0.0",
28
+ "@types/react": "^18.2.0",
29
+ "jsdom": "^25.0.0",
30
+ "react": "^18.3.0",
31
+ "react-dom": "^18.3.0",
32
+ "typescript": "^5.4.0",
33
+ "vitest": "^2.0.0"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "keywords": ["feature-flags", "omniflags", "react"],
39
+ "license": "MIT"
40
+ }