@gradual-so/sdk-react 0.0.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/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +80 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var react=require('react'),sdk=require('@gradual-so/sdk'),jsxRuntime=require('react/jsx-runtime');var l=react.createContext({gradual:null,isReady:false});function d(){let e=react.useContext(l);if(!e.gradual)throw new Error("useFlag must be used within a <GradualProvider>");return {gradual:e.gradual,isReady:e.isReady}}function g(){let{gradual:e,isReady:a}=d();return react.useMemo(()=>({identify:t=>e.identify(t),reset:()=>e.reset(),refresh:()=>e.refresh(),isReady:a}),[e,a])}function y(e,a){let{gradual:t,isReady:r}=d(),o=react.useMemo(()=>r?t.sync.get(e,{fallback:a.fallback,context:a.context}):a.fallback,[t,r,e,a.fallback,a.context]);return a.detail?{value:o,isLoading:!r,isReady:r}:o}function v({apiKey:e,environment:a,baseUrl:t,children:r}){let[o,f]=react.useState(false),n=react.useMemo(()=>sdk.createGradual({apiKey:e,environment:a,baseUrl:t}),[e,a,t]);react.useEffect(()=>{let u=true;return n.ready().then(()=>{u&&f(true);}),()=>{u=false;}},[n]);let p=react.useMemo(()=>({gradual:n,isReady:o}),[n,o]);return jsxRuntime.jsx(l,{value:p,children:r})}exports.GradualContext=l;exports.GradualProvider=v;exports.useFlag=y;exports.useGradual=g;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/hooks.ts","../src/provider.tsx"],"names":["GradualContext","createContext","useGradualContext","context","useContext","useGradual","gradual","isReady","useMemo","ctx","useFlag","key","options","value","GradualProvider","apiKey","environment","baseUrl","children","setIsReady","useState","createGradual","useEffect","mounted","jsx"],"mappings":"+GAQO,IAAMA,CAAAA,CAAiBC,mBAAAA,CAAmC,CAC/D,OAAA,CAAS,IAAA,CACT,OAAA,CAAS,KACX,CAAC,ECKD,SAASC,CAAAA,EAA4D,CACnE,IAAMC,CAAAA,CAAUC,gBAAAA,CAAWJ,CAAc,CAAA,CACzC,GAAI,CAACG,CAAAA,CAAQ,OAAA,CACX,MAAM,IAAI,KAAA,CAAM,iDAAiD,CAAA,CAEnE,OAAO,CAAE,OAAA,CAASA,CAAAA,CAAQ,OAAA,CAAS,OAAA,CAASA,CAAAA,CAAQ,OAAQ,CAC9D,CAkBO,SAASE,CAAAA,EAKd,CACA,GAAM,CAAE,OAAA,CAAAC,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAIL,CAAAA,EAAkB,CAE/C,OAAOM,aAAAA,CACL,KAAO,CACL,QAAA,CAAWC,CAAAA,EAA2BH,CAAAA,CAAQ,QAAA,CAASG,CAAG,CAAA,CAC1D,KAAA,CAAO,IAAMH,CAAAA,CAAQ,KAAA,EAAM,CAC3B,OAAA,CAAS,IAAMA,CAAAA,CAAQ,OAAA,EAAQ,CAC/B,OAAA,CAAAC,CACF,CAAA,CAAA,CACA,CAACD,CAAAA,CAASC,CAAO,CACnB,CACF,CAoCO,SAASG,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACmB,CACnB,GAAM,CAAE,OAAA,CAAAN,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAIL,CAAAA,EAAkB,CAEzCW,CAAAA,CAAQL,aAAAA,CAAQ,IACfD,CAAAA,CAGED,CAAAA,CAAQ,IAAA,CAAK,GAAA,CAAIK,CAAAA,CAAK,CAC3B,QAAA,CAAUC,CAAAA,CAAQ,QAAA,CAClB,OAAA,CAASA,CAAAA,CAAQ,OACnB,CAAC,CAAA,CALQA,CAAAA,CAAQ,QAAA,CAMhB,CAACN,CAAAA,CAASC,CAAAA,CAASI,CAAAA,CAAKC,CAAAA,CAAQ,QAAA,CAAUA,CAAAA,CAAQ,OAAO,CAAC,CAAA,CAE7D,OAAIA,CAAAA,CAAQ,MAAA,CACH,CACL,KAAA,CAAAC,CAAAA,CACA,SAAA,CAAW,CAACN,CAAAA,CACZ,OAAA,CAAAA,CACF,CAAA,CAGKM,CACT,CC9GO,SAASC,CAAAA,CAAgB,CAC9B,MAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CACF,CAAA,CAAyB,CACvB,GAAM,CAACX,CAAAA,CAASY,CAAU,CAAA,CAAIC,cAAAA,CAAS,KAAK,CAAA,CAEtCd,CAAAA,CAAUE,aAAAA,CACd,IAAMa,iBAAAA,CAAc,CAAE,MAAA,CAAAN,CAAAA,CAAQ,WAAA,CAAAC,CAAAA,CAAa,OAAA,CAAAC,CAAQ,CAAC,CAAA,CACpD,CAACF,CAAAA,CAAQC,CAAAA,CAAaC,CAAO,CAC/B,CAAA,CAEAK,eAAAA,CAAU,IAAM,CACd,IAAIC,CAAAA,CAAU,IAAA,CACd,OAAAjB,CAAAA,CAAQ,KAAA,EAAM,CAAE,IAAA,CAAK,IAAM,CACrBiB,CAAAA,EACFJ,CAAAA,CAAW,IAAI,EAEnB,CAAC,CAAA,CACM,IAAM,CACXI,CAAAA,CAAU,MACZ,CACF,CAAA,CAAG,CAACjB,CAAO,CAAC,CAAA,CAEZ,IAAMO,CAAAA,CAAQL,aAAAA,CAAQ,KAAO,CAAE,OAAA,CAAAF,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAA,CAAI,CAACD,CAAAA,CAASC,CAAO,CAAC,CAAA,CAEtE,OAAOiB,cAAAA,CAACxB,CAAAA,CAAA,CAAe,KAAA,CAAOa,CAAAA,CAAQ,QAAA,CAAAK,CAAAA,CAAS,CACjD","file":"index.cjs","sourcesContent":["import type { Gradual } from \"@gradual-so/sdk\";\nimport { createContext } from \"react\";\n\nexport interface GradualContextValue {\n gradual: Gradual | null;\n isReady: boolean;\n}\n\nexport const GradualContext = createContext<GradualContextValue>({\n gradual: null,\n isReady: false,\n});\n","import type { EvaluationContext, Gradual } from \"@gradual-so/sdk\";\nimport { useContext, useMemo } from \"react\";\nimport { GradualContext } from \"./context\";\n\nexport interface UseFlagOptions<T> {\n fallback: T;\n context?: EvaluationContext;\n detail?: boolean;\n}\n\nexport interface FlagDetail<T> {\n value: T;\n isLoading: boolean;\n isReady: boolean;\n}\n\nfunction useGradualContext(): { gradual: Gradual; isReady: boolean } {\n const context = useContext(GradualContext);\n if (!context.gradual) {\n throw new Error(\"useFlag must be used within a <GradualProvider>\");\n }\n return { gradual: context.gradual, isReady: context.isReady };\n}\n\n/**\n * Access the Gradual client for identity management\n *\n * @example\n * ```tsx\n * const { identify, reset, isReady } = useGradual()\n *\n * useEffect(() => {\n * if (user) {\n * identify({ userId: user.id, plan: user.plan })\n * } else {\n * reset()\n * }\n * }, [user])\n * ```\n */\nexport function useGradual(): {\n identify: (context: EvaluationContext) => void;\n reset: () => void;\n isReady: boolean;\n refresh: () => Promise<void>;\n} {\n const { gradual, isReady } = useGradualContext();\n\n return useMemo(\n () => ({\n identify: (ctx: EvaluationContext) => gradual.identify(ctx),\n reset: () => gradual.reset(),\n refresh: () => gradual.refresh(),\n isReady,\n }),\n [gradual, isReady]\n );\n}\n\n/**\n * Get a feature flag value with type inference\n *\n * @example\n * ```tsx\n * // Simple usage - returns value directly\n * const showBanner = useFlag('show-banner', { fallback: false })\n * const theme = useFlag('theme', { fallback: 'light' })\n *\n * // With loading state\n * const { value, isLoading } = useFlag('experiment', {\n * fallback: 'control',\n * detail: true\n * })\n *\n * // With context override\n * const enabled = useFlag('feature', {\n * fallback: false,\n * context: { itemId: item.id }\n * })\n * ```\n */\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T> & { detail: true }\n): FlagDetail<T>;\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T> & { detail?: false }\n): T;\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T>\n): T | FlagDetail<T>;\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T>\n): T | FlagDetail<T> {\n const { gradual, isReady } = useGradualContext();\n\n const value = useMemo(() => {\n if (!isReady) {\n return options.fallback;\n }\n return gradual.sync.get(key, {\n fallback: options.fallback,\n context: options.context,\n });\n }, [gradual, isReady, key, options.fallback, options.context]);\n\n if (options.detail) {\n return {\n value,\n isLoading: !isReady,\n isReady,\n };\n }\n\n return value;\n}\n","import { createGradual, type GradualOptions } from \"@gradual-so/sdk\";\nimport { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { GradualContext } from \"./context\";\n\nexport interface GradualProviderProps extends GradualOptions {\n children: ReactNode;\n}\n\nexport function GradualProvider({\n apiKey,\n environment,\n baseUrl,\n children,\n}: GradualProviderProps) {\n const [isReady, setIsReady] = useState(false);\n\n const gradual = useMemo(\n () => createGradual({ apiKey, environment, baseUrl }),\n [apiKey, environment, baseUrl]\n );\n\n useEffect(() => {\n let mounted = true;\n gradual.ready().then(() => {\n if (mounted) {\n setIsReady(true);\n }\n });\n return () => {\n mounted = false;\n };\n }, [gradual]);\n\n const value = useMemo(() => ({ gradual, isReady }), [gradual, isReady]);\n\n return <GradualContext value={value}>{children}</GradualContext>;\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Gradual, EvaluationContext, GradualOptions } from '@gradual-so/sdk';
|
|
2
|
+
export { EvaluationContext, GradualOptions } from '@gradual-so/sdk';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
interface GradualContextValue {
|
|
8
|
+
gradual: Gradual | null;
|
|
9
|
+
isReady: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const GradualContext: react.Context<GradualContextValue>;
|
|
12
|
+
|
|
13
|
+
interface UseFlagOptions<T> {
|
|
14
|
+
fallback: T;
|
|
15
|
+
context?: EvaluationContext;
|
|
16
|
+
detail?: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface FlagDetail<T> {
|
|
19
|
+
value: T;
|
|
20
|
+
isLoading: boolean;
|
|
21
|
+
isReady: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Access the Gradual client for identity management
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* const { identify, reset, isReady } = useGradual()
|
|
29
|
+
*
|
|
30
|
+
* useEffect(() => {
|
|
31
|
+
* if (user) {
|
|
32
|
+
* identify({ userId: user.id, plan: user.plan })
|
|
33
|
+
* } else {
|
|
34
|
+
* reset()
|
|
35
|
+
* }
|
|
36
|
+
* }, [user])
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function useGradual(): {
|
|
40
|
+
identify: (context: EvaluationContext) => void;
|
|
41
|
+
reset: () => void;
|
|
42
|
+
isReady: boolean;
|
|
43
|
+
refresh: () => Promise<void>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Get a feature flag value with type inference
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* // Simple usage - returns value directly
|
|
51
|
+
* const showBanner = useFlag('show-banner', { fallback: false })
|
|
52
|
+
* const theme = useFlag('theme', { fallback: 'light' })
|
|
53
|
+
*
|
|
54
|
+
* // With loading state
|
|
55
|
+
* const { value, isLoading } = useFlag('experiment', {
|
|
56
|
+
* fallback: 'control',
|
|
57
|
+
* detail: true
|
|
58
|
+
* })
|
|
59
|
+
*
|
|
60
|
+
* // With context override
|
|
61
|
+
* const enabled = useFlag('feature', {
|
|
62
|
+
* fallback: false,
|
|
63
|
+
* context: { itemId: item.id }
|
|
64
|
+
* })
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function useFlag<T>(key: string, options: UseFlagOptions<T> & {
|
|
68
|
+
detail: true;
|
|
69
|
+
}): FlagDetail<T>;
|
|
70
|
+
declare function useFlag<T>(key: string, options: UseFlagOptions<T> & {
|
|
71
|
+
detail?: false;
|
|
72
|
+
}): T;
|
|
73
|
+
declare function useFlag<T>(key: string, options: UseFlagOptions<T>): T | FlagDetail<T>;
|
|
74
|
+
|
|
75
|
+
interface GradualProviderProps extends GradualOptions {
|
|
76
|
+
children: ReactNode;
|
|
77
|
+
}
|
|
78
|
+
declare function GradualProvider({ apiKey, environment, baseUrl, children, }: GradualProviderProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
export { type FlagDetail, GradualContext, type GradualContextValue, GradualProvider, type GradualProviderProps, type UseFlagOptions, useFlag, useGradual };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Gradual, EvaluationContext, GradualOptions } from '@gradual-so/sdk';
|
|
2
|
+
export { EvaluationContext, GradualOptions } from '@gradual-so/sdk';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
interface GradualContextValue {
|
|
8
|
+
gradual: Gradual | null;
|
|
9
|
+
isReady: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const GradualContext: react.Context<GradualContextValue>;
|
|
12
|
+
|
|
13
|
+
interface UseFlagOptions<T> {
|
|
14
|
+
fallback: T;
|
|
15
|
+
context?: EvaluationContext;
|
|
16
|
+
detail?: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface FlagDetail<T> {
|
|
19
|
+
value: T;
|
|
20
|
+
isLoading: boolean;
|
|
21
|
+
isReady: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Access the Gradual client for identity management
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* const { identify, reset, isReady } = useGradual()
|
|
29
|
+
*
|
|
30
|
+
* useEffect(() => {
|
|
31
|
+
* if (user) {
|
|
32
|
+
* identify({ userId: user.id, plan: user.plan })
|
|
33
|
+
* } else {
|
|
34
|
+
* reset()
|
|
35
|
+
* }
|
|
36
|
+
* }, [user])
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function useGradual(): {
|
|
40
|
+
identify: (context: EvaluationContext) => void;
|
|
41
|
+
reset: () => void;
|
|
42
|
+
isReady: boolean;
|
|
43
|
+
refresh: () => Promise<void>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Get a feature flag value with type inference
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* // Simple usage - returns value directly
|
|
51
|
+
* const showBanner = useFlag('show-banner', { fallback: false })
|
|
52
|
+
* const theme = useFlag('theme', { fallback: 'light' })
|
|
53
|
+
*
|
|
54
|
+
* // With loading state
|
|
55
|
+
* const { value, isLoading } = useFlag('experiment', {
|
|
56
|
+
* fallback: 'control',
|
|
57
|
+
* detail: true
|
|
58
|
+
* })
|
|
59
|
+
*
|
|
60
|
+
* // With context override
|
|
61
|
+
* const enabled = useFlag('feature', {
|
|
62
|
+
* fallback: false,
|
|
63
|
+
* context: { itemId: item.id }
|
|
64
|
+
* })
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function useFlag<T>(key: string, options: UseFlagOptions<T> & {
|
|
68
|
+
detail: true;
|
|
69
|
+
}): FlagDetail<T>;
|
|
70
|
+
declare function useFlag<T>(key: string, options: UseFlagOptions<T> & {
|
|
71
|
+
detail?: false;
|
|
72
|
+
}): T;
|
|
73
|
+
declare function useFlag<T>(key: string, options: UseFlagOptions<T>): T | FlagDetail<T>;
|
|
74
|
+
|
|
75
|
+
interface GradualProviderProps extends GradualOptions {
|
|
76
|
+
children: ReactNode;
|
|
77
|
+
}
|
|
78
|
+
declare function GradualProvider({ apiKey, environment, baseUrl, children, }: GradualProviderProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
export { type FlagDetail, GradualContext, type GradualContextValue, GradualProvider, type GradualProviderProps, type UseFlagOptions, useFlag, useGradual };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {createContext,useMemo,useState,useEffect,useContext}from'react';import {createGradual}from'@gradual-so/sdk';import {jsx}from'react/jsx-runtime';var l=createContext({gradual:null,isReady:false});function d(){let e=useContext(l);if(!e.gradual)throw new Error("useFlag must be used within a <GradualProvider>");return {gradual:e.gradual,isReady:e.isReady}}function g(){let{gradual:e,isReady:a}=d();return useMemo(()=>({identify:t=>e.identify(t),reset:()=>e.reset(),refresh:()=>e.refresh(),isReady:a}),[e,a])}function y(e,a){let{gradual:t,isReady:r}=d(),o=useMemo(()=>r?t.sync.get(e,{fallback:a.fallback,context:a.context}):a.fallback,[t,r,e,a.fallback,a.context]);return a.detail?{value:o,isLoading:!r,isReady:r}:o}function v({apiKey:e,environment:a,baseUrl:t,children:r}){let[o,f]=useState(false),n=useMemo(()=>createGradual({apiKey:e,environment:a,baseUrl:t}),[e,a,t]);useEffect(()=>{let u=true;return n.ready().then(()=>{u&&f(true);}),()=>{u=false;}},[n]);let p=useMemo(()=>({gradual:n,isReady:o}),[n,o]);return jsx(l,{value:p,children:r})}export{l as GradualContext,v as GradualProvider,y as useFlag,g as useGradual};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/hooks.ts","../src/provider.tsx"],"names":["GradualContext","createContext","useGradualContext","context","useContext","useGradual","gradual","isReady","useMemo","ctx","useFlag","key","options","value","GradualProvider","apiKey","environment","baseUrl","children","setIsReady","useState","createGradual","useEffect","mounted","jsx"],"mappings":"wJAQO,IAAMA,CAAAA,CAAiBC,aAAAA,CAAmC,CAC/D,OAAA,CAAS,IAAA,CACT,OAAA,CAAS,KACX,CAAC,ECKD,SAASC,CAAAA,EAA4D,CACnE,IAAMC,CAAAA,CAAUC,UAAAA,CAAWJ,CAAc,CAAA,CACzC,GAAI,CAACG,CAAAA,CAAQ,OAAA,CACX,MAAM,IAAI,KAAA,CAAM,iDAAiD,CAAA,CAEnE,OAAO,CAAE,OAAA,CAASA,CAAAA,CAAQ,OAAA,CAAS,OAAA,CAASA,CAAAA,CAAQ,OAAQ,CAC9D,CAkBO,SAASE,CAAAA,EAKd,CACA,GAAM,CAAE,OAAA,CAAAC,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAIL,CAAAA,EAAkB,CAE/C,OAAOM,OAAAA,CACL,KAAO,CACL,QAAA,CAAWC,CAAAA,EAA2BH,CAAAA,CAAQ,QAAA,CAASG,CAAG,CAAA,CAC1D,KAAA,CAAO,IAAMH,CAAAA,CAAQ,KAAA,EAAM,CAC3B,OAAA,CAAS,IAAMA,CAAAA,CAAQ,OAAA,EAAQ,CAC/B,OAAA,CAAAC,CACF,CAAA,CAAA,CACA,CAACD,CAAAA,CAASC,CAAO,CACnB,CACF,CAoCO,SAASG,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACmB,CACnB,GAAM,CAAE,OAAA,CAAAN,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAIL,CAAAA,EAAkB,CAEzCW,CAAAA,CAAQL,OAAAA,CAAQ,IACfD,CAAAA,CAGED,CAAAA,CAAQ,IAAA,CAAK,GAAA,CAAIK,CAAAA,CAAK,CAC3B,QAAA,CAAUC,CAAAA,CAAQ,QAAA,CAClB,OAAA,CAASA,CAAAA,CAAQ,OACnB,CAAC,CAAA,CALQA,CAAAA,CAAQ,QAAA,CAMhB,CAACN,CAAAA,CAASC,CAAAA,CAASI,CAAAA,CAAKC,CAAAA,CAAQ,QAAA,CAAUA,CAAAA,CAAQ,OAAO,CAAC,CAAA,CAE7D,OAAIA,CAAAA,CAAQ,MAAA,CACH,CACL,KAAA,CAAAC,CAAAA,CACA,SAAA,CAAW,CAACN,CAAAA,CACZ,OAAA,CAAAA,CACF,CAAA,CAGKM,CACT,CC9GO,SAASC,CAAAA,CAAgB,CAC9B,MAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CACF,CAAA,CAAyB,CACvB,GAAM,CAACX,CAAAA,CAASY,CAAU,CAAA,CAAIC,QAAAA,CAAS,KAAK,CAAA,CAEtCd,CAAAA,CAAUE,OAAAA,CACd,IAAMa,aAAAA,CAAc,CAAE,MAAA,CAAAN,CAAAA,CAAQ,WAAA,CAAAC,CAAAA,CAAa,OAAA,CAAAC,CAAQ,CAAC,CAAA,CACpD,CAACF,CAAAA,CAAQC,CAAAA,CAAaC,CAAO,CAC/B,CAAA,CAEAK,SAAAA,CAAU,IAAM,CACd,IAAIC,CAAAA,CAAU,IAAA,CACd,OAAAjB,CAAAA,CAAQ,KAAA,EAAM,CAAE,IAAA,CAAK,IAAM,CACrBiB,CAAAA,EACFJ,CAAAA,CAAW,IAAI,EAEnB,CAAC,CAAA,CACM,IAAM,CACXI,CAAAA,CAAU,MACZ,CACF,CAAA,CAAG,CAACjB,CAAO,CAAC,CAAA,CAEZ,IAAMO,CAAAA,CAAQL,OAAAA,CAAQ,KAAO,CAAE,OAAA,CAAAF,CAAAA,CAAS,OAAA,CAAAC,CAAQ,CAAA,CAAA,CAAI,CAACD,CAAAA,CAASC,CAAO,CAAC,CAAA,CAEtE,OAAOiB,GAAAA,CAACxB,CAAAA,CAAA,CAAe,KAAA,CAAOa,CAAAA,CAAQ,QAAA,CAAAK,CAAAA,CAAS,CACjD","file":"index.js","sourcesContent":["import type { Gradual } from \"@gradual-so/sdk\";\nimport { createContext } from \"react\";\n\nexport interface GradualContextValue {\n gradual: Gradual | null;\n isReady: boolean;\n}\n\nexport const GradualContext = createContext<GradualContextValue>({\n gradual: null,\n isReady: false,\n});\n","import type { EvaluationContext, Gradual } from \"@gradual-so/sdk\";\nimport { useContext, useMemo } from \"react\";\nimport { GradualContext } from \"./context\";\n\nexport interface UseFlagOptions<T> {\n fallback: T;\n context?: EvaluationContext;\n detail?: boolean;\n}\n\nexport interface FlagDetail<T> {\n value: T;\n isLoading: boolean;\n isReady: boolean;\n}\n\nfunction useGradualContext(): { gradual: Gradual; isReady: boolean } {\n const context = useContext(GradualContext);\n if (!context.gradual) {\n throw new Error(\"useFlag must be used within a <GradualProvider>\");\n }\n return { gradual: context.gradual, isReady: context.isReady };\n}\n\n/**\n * Access the Gradual client for identity management\n *\n * @example\n * ```tsx\n * const { identify, reset, isReady } = useGradual()\n *\n * useEffect(() => {\n * if (user) {\n * identify({ userId: user.id, plan: user.plan })\n * } else {\n * reset()\n * }\n * }, [user])\n * ```\n */\nexport function useGradual(): {\n identify: (context: EvaluationContext) => void;\n reset: () => void;\n isReady: boolean;\n refresh: () => Promise<void>;\n} {\n const { gradual, isReady } = useGradualContext();\n\n return useMemo(\n () => ({\n identify: (ctx: EvaluationContext) => gradual.identify(ctx),\n reset: () => gradual.reset(),\n refresh: () => gradual.refresh(),\n isReady,\n }),\n [gradual, isReady]\n );\n}\n\n/**\n * Get a feature flag value with type inference\n *\n * @example\n * ```tsx\n * // Simple usage - returns value directly\n * const showBanner = useFlag('show-banner', { fallback: false })\n * const theme = useFlag('theme', { fallback: 'light' })\n *\n * // With loading state\n * const { value, isLoading } = useFlag('experiment', {\n * fallback: 'control',\n * detail: true\n * })\n *\n * // With context override\n * const enabled = useFlag('feature', {\n * fallback: false,\n * context: { itemId: item.id }\n * })\n * ```\n */\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T> & { detail: true }\n): FlagDetail<T>;\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T> & { detail?: false }\n): T;\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T>\n): T | FlagDetail<T>;\nexport function useFlag<T>(\n key: string,\n options: UseFlagOptions<T>\n): T | FlagDetail<T> {\n const { gradual, isReady } = useGradualContext();\n\n const value = useMemo(() => {\n if (!isReady) {\n return options.fallback;\n }\n return gradual.sync.get(key, {\n fallback: options.fallback,\n context: options.context,\n });\n }, [gradual, isReady, key, options.fallback, options.context]);\n\n if (options.detail) {\n return {\n value,\n isLoading: !isReady,\n isReady,\n };\n }\n\n return value;\n}\n","import { createGradual, type GradualOptions } from \"@gradual-so/sdk\";\nimport { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { GradualContext } from \"./context\";\n\nexport interface GradualProviderProps extends GradualOptions {\n children: ReactNode;\n}\n\nexport function GradualProvider({\n apiKey,\n environment,\n baseUrl,\n children,\n}: GradualProviderProps) {\n const [isReady, setIsReady] = useState(false);\n\n const gradual = useMemo(\n () => createGradual({ apiKey, environment, baseUrl }),\n [apiKey, environment, baseUrl]\n );\n\n useEffect(() => {\n let mounted = true;\n gradual.ready().then(() => {\n if (mounted) {\n setIsReady(true);\n }\n });\n return () => {\n mounted = false;\n };\n }, [gradual]);\n\n const value = useMemo(() => ({ gradual, isReady }), [gradual, isReady]);\n\n return <GradualContext value={value}>{children}</GradualContext>;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gradual-so/sdk-react",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Gradual feature flag SDK for React",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"keywords": [
|
|
27
|
+
"feature-flags",
|
|
28
|
+
"feature-toggles",
|
|
29
|
+
"gradual",
|
|
30
|
+
"react",
|
|
31
|
+
"hooks",
|
|
32
|
+
"sdk"
|
|
33
|
+
],
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/gradual-io/gradual",
|
|
37
|
+
"directory": "packages/sdk-react"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup",
|
|
41
|
+
"clean": "git clean -xdf .cache .turbo dist node_modules",
|
|
42
|
+
"dev": "tsup --watch",
|
|
43
|
+
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@gradual-so/sdk": "workspace:*"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"react": ">=18.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@gradual/tsconfig": "workspace:*",
|
|
53
|
+
"@types/react": "catalog:react",
|
|
54
|
+
"react": "catalog:react",
|
|
55
|
+
"tsup": "^8.5.1",
|
|
56
|
+
"typescript": "catalog:"
|
|
57
|
+
}
|
|
58
|
+
}
|