flagmint-react-sdk 0.3.0 → 0.5.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/dist/client.cjs CHANGED
@@ -125,10 +125,21 @@ function useFlags() {
125
125
  }
126
126
  function useFlag(key, fallback) {
127
127
  const store = useFlagmintStore();
128
- return zustand.useStore(store, (state) => {
129
- var _a;
130
- return (_a = state.flags[key]) != null ? _a : fallback;
131
- });
128
+ const client = zustand.useStore(store, (state) => state.client);
129
+ if (client) {
130
+ try {
131
+ const flagValue = client.getFlag(key, fallback);
132
+ const currentValue = store.getState().flags[key];
133
+ if (currentValue !== flagValue) {
134
+ store.getState().setFlag(key, flagValue);
135
+ }
136
+ return flagValue;
137
+ } catch (error) {
138
+ console.warn(`Failed to get flag '${key}' from client:`, error);
139
+ }
140
+ }
141
+ const cachedValue = zustand.useStore(store, (state) => state.flags[key]);
142
+ return cachedValue != null ? cachedValue : fallback;
132
143
  }
133
144
  function useFlagmintReady() {
134
145
  const store = useFlagmintStore();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store/store.ts","../src/providers/FlagmintProvider.tsx","../src/hooks/index.ts"],"names":["createStore","createContext","useMemo","useRef","FlagClient","useEffect","useContext","useStore"],"mappings":";;;;;;;;AAKO,SAAS,eAAA,CAAgB,YAAA,GAAsB,EAAC,EAAwB;AAC5E,EAAA,OAAOA,mBAAA,CAAuB,CAAC,GAAA,EAAK,GAAA,MAAS;AAAA,IAC5C,KAAA,EAAO,YAAA;AAAA,IACP,MAAA,EAAQ,IAAA;AAAA,IACR,aAAA,EAAe,KAAA;AAAA,IACf,OAAA,EAAS,KAAA;AAAA,IACT,UAAU,CAAC,KAAA,KAAU,GAAA,CAAI,EAAE,OAAO,CAAA;AAAA,IAClC,SAAS,CAAC,GAAA,EAAK,KAAA,KAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,MACvC,KAAA,EAAO,EAAE,GAAG,KAAA,CAAM,OAAO,CAAC,GAAG,GAAG,KAAA;AAAM,KACxC,CAAE,CAAA;AAAA,IACF,WAAW,CAAC,MAAA,KAAW,GAAA,CAAI,EAAE,QAAQ,CAAA;AAAA,IACrC,gBAAgB,CAAC,WAAA,KAAgB,IAAI,EAAE,aAAA,EAAe,aAAa,CAAA;AAAA,IACnE,UAAU,CAAC,KAAA,KAAU,IAAI,EAAE,OAAA,EAAS,OAAO;AAAA,GAC7C,CAAE,CAAA;AACJ;ACZO,IAAM,oBAAA,GAAuBC,oBAA0C,IAAI;AAG3E,SAAS,gBAAA,CAGd;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAe,EAAC;AAAA,EAChB,mBAAA,GAAsB;AACxB,CAAA,EAAgC;AAE9B,EAAA,MAAM,KAAA,GAAQC,cAAQ,MAAM,eAAA,CAAgB,YAAY,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAGzE,EAAA,MAAM,SAAA,GAAYC,aAAgC,IAAI,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiBA,aAAyC,IAAI,CAAA;AACpE,EAAiBA,aAAc,YAAY;AAG3C,EAAA,MAAM,OAAO,YAAuC;AAClD,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,OAAA;AAGxC,IAAA,IAAI,cAAA,CAAe,OAAA,EAAS,OAAO,cAAA,CAAe,OAAA;AAElD,IAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAU,cAAA,EAAe,GAAI,MAAM,QAAA,EAAS;AAE/D,IAAA,cAAA,CAAe,WAAW,YAAY;AACpC,MAAA,IAAI;AAEF,QAAA,MAAM,cAAA,GAAiB,IAAIC,wBAAA,CAAiB,OAAO,CAAA;AACnD,QAAA,MAAM,eAAe,KAAA,EAAM;AAG3B,QAAA,MAAM,aAAA,GAAgB;AAAA,UACpB,GAAG,cAAA;AAAA,UACH,QAAQ,EAAC;AAAA,UACT,UAAU,WAAW;AACnB,YAAA,OAAO,IAAA,CAAK,MAAA;AAAA,UACd,CAAA;AAAA;AAAA,UAEA,OAAA,EAAS,SAA2B,GAAA,EAAQ,QAAA,EAAc;AACxD,YAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAY,QAAQ,CAAA;AACzD,YAAA,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AACnB,YAAA,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AACnC,YAAA,OAAO,KAAA;AAAA,UACT,CAAA;AAAA;AAAA,UAEA,aAAA,EAAe,SAAS,OAAA,EAAY;AAClC,YAAA,cAAA,CAAe,cAAc,OAAO,CAAA;AAGpC,YAAA,UAAA,CAAW,MAAM;AAEf,cAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,CAAE,QAAQ,CAAA,GAAA,KAAO;AACtC,gBAAA,MAAM,QAAA,GAAW,cAAA,CAAe,OAAA,CAAQ,GAAU,CAAA;AAClD,gBAAA,IAAI,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,KAAM,QAAA,EAAU;AACjC,kBAAA,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,GAAI,QAAA;AACnB,kBAAA,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,GAAA,EAAK,QAAQ,CAAA;AAAA,gBACxC;AAAA,cACF,CAAC,CAAA;AAAA,YACH,GAAG,GAAG,CAAA;AAAA,UACR;AAAA,SACF;AAEA,QAAA,SAAA,CAAU,OAAA,GAAU,aAAA;AACpB,QAAA,SAAA,CAAU,aAAa,CAAA;AACvB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,QAAA,OAAO,aAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAC5D,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAA,GAAG;AAEH,IAAA,OAAO,cAAA,CAAe,OAAA;AAAA,EACxB,CAAA;AAEA,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,MAAA,IAAA,EAAK,CAAE,MAAM,CAAA,KAAA,KAAS;AACpB,QAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAAA,MACpD,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,MAAM;AAhGjB,MAAA,IAAA,EAAA,EAAA,EAAA;AAiGM,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,SAAA,CAAU,SAAQ,OAAA,KAAlB,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,CAAA;AACA,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,mBAAmB,CAAC,CAAA;AAExB,EAAA,sCACG,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,OACnC,QAAA,EACH,CAAA;AAEJ;ACtGO,SAAS,gBAAA,GAAwC;AACtD,EAAA,MAAM,KAAA,GAAQC,iBAAW,oBAAoB,CAAA;AAC7C,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,EAC3E;AACA,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,WAAA,GAAc;AAC5B,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,MAAM,SAASC,gBAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,MAAM,CAAA;AACtD,EAAA,MAAM,gBAAgBA,gBAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,aAAa,CAAA;AAEpE,EAAA,MAAM,aAAA,GAAgB,OAAO,OAAA,KAAiC;AAC5D,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,IACnD;AACA,IAAA,MAAM,MAAA,CAAO,cAAc,OAAO,CAAA;AAAA,EACpC,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACF;AAGO,SAAS,QAAA,GAAkB;AAChC,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,OAAOA,gBAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAC/C;AAGO,SAAS,OAAA,CACd,KACA,QAAA,EACG;AACH,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,OAAOA,gBAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAO;AAhDjC,IAAA,IAAA,EAAA;AAgDoC,IAAA,OAAA,CAAA,EAAA,GAAA,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,KAAf,IAAA,GAAA,EAAA,GAAoB,QAAA;AAAA,EAAA,CAAQ,CAAA;AAChE;AAGO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,OAAOA,gBAAA,CAAS,OAAO,CAAC,KAAA,KAAU,MAAM,aAAA,IAAiB,KAAA,CAAM,WAAW,IAAI,CAAA;AAChF","file":"client.cjs","sourcesContent":["'use client';\nimport { createStore, StoreApi } from \"zustand/vanilla\";\nimport { Flags, FlagStore } from \"@/types\";\n\n\nexport function createFlagStore(initialFlags: Flags = {}): StoreApi<FlagStore> {\n return createStore<FlagStore>((set, get) => ({\n flags: initialFlags,\n client: null,\n isInitialized: false,\n isReady: false,\n setFlags: (flags) => set({ flags }),\n setFlag: (key, value) => set((state) => ({\n flags: { ...state.flags, [key]: value }\n })),\n setClient: (client) => set({ client }),\n setInitialized: (initialized) => set({ isInitialized: initialized }),\n setReady: (ready) => set({ isReady: ready })\n }))\n}\n","'use client';\nimport { FlagClient } from \"flagmint-js-sdk\"\nimport { useMemo, useRef, useEffect, createContext } from \"react\"\nimport { createFlagStore } from \"@/store/store\"\nimport { FlagmintProviderProps, Flags, FlagStore } from \"@/types\"\nimport { StoreApi } from \"zustand\"\n\nexport const FlagmintStoreContext = createContext<StoreApi<FlagStore> | null>(null)\n\n\nexport function FlagmintProvider<\n T extends FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags },\n C extends Record<string, any> = Record<string, any>\n>({\n children,\n options,\n initialFlags = {},\n deferInitialization = false\n}: FlagmintProviderProps<T, C>) {\n // Create a new store instance for each provider (per-request in SSR)\n const store = useMemo(() => createFlagStore(initialFlags), [initialFlags])\n \n // Use ref to avoid recreating client on every render\n const clientRef = useRef<FlagClient<T, C> | null>(null)\n const initPromiseRef = useRef<Promise<FlagClient<T, C>> | null>(null)\n const flagsRef = useRef<Flags>(initialFlags)\n \n // Initialization function similar to Vue plugin\n const init = async (): Promise<FlagClient<T, C>> => {\n if (clientRef.current) return clientRef.current // Avoid re-init\n \n // Return existing promise if init is already in progress\n if (initPromiseRef.current) return initPromiseRef.current\n \n const { setClient, setReady, setInitialized } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create a custom FlagClient that exposes flag updates\n const originalClient = new FlagClient<T, C>(options)\n await originalClient.ready()\n \n // Create a wrapper that tracks flags internally\n const clientWrapper = {\n ...originalClient,\n _flags: {} as Flags,\n getFlags: function() {\n return this._flags\n },\n // Override getFlag to track individual flags\n getFlag: function<K extends string>(key: K, fallback?: T) {\n const value = originalClient.getFlag(key as any, fallback)\n this._flags[key] = value\n store.getState().setFlag(key, value)\n return value\n },\n // Override updateContext to trigger flag refresh\n updateContext: function(context: C) {\n originalClient.updateContext(context)\n // After context update, we should refresh our tracked flags\n // This is a limitation of the current API\n setTimeout(() => {\n // Force a re-evaluation of flags we've previously requested\n Object.keys(this._flags).forEach(key => {\n const newValue = originalClient.getFlag(key as any)\n if (this._flags[key] !== newValue) {\n this._flags[key] = newValue\n store.getState().setFlag(key, newValue)\n }\n })\n }, 100)\n }\n } as FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags }\n \n clientRef.current = clientWrapper\n setClient(clientWrapper)\n setReady(true)\n setInitialized(true)\n \n return clientWrapper\n } catch (error) {\n console.error('Failed to initialize Flagmint client:', error)\n throw error\n }\n })()\n \n return initPromiseRef.current\n }\n\n useEffect(() => {\n if (!deferInitialization) {\n init().catch(error => {\n console.error('Auto-initialization failed:', error)\n })\n }\n\n return () => {\n if (clientRef.current) {\n clientRef.current.destroy?.()\n clientRef.current = null\n initPromiseRef.current = null\n }\n }\n }, [deferInitialization])\n\n return (\n <FlagmintStoreContext.Provider value={store}>\n {children}\n </FlagmintStoreContext.Provider>\n )\n}\n","'use client';\nimport { FlagValue } from \"flagmint-js-sdk\"\nimport { useContext } from \"react\"\nimport { StoreApi, useStore } from \"zustand\"\nimport { FlagmintStoreContext } from \"@/providers/FlagmintProvider\"\nimport { FlagStore, Flags } from \"@/types\"\n\n// Helper to get the store from context\nexport function useFlagmintStore(): StoreApi<FlagStore> {\n const store = useContext(FlagmintStoreContext)\n if (!store) {\n throw new Error('useFlagmintStore must be used within a FlagmintProvider')\n }\n return store\n}\n\n// Hook to get the client instance and update context\nexport function useFlagmint() {\n const store = useFlagmintStore()\n const client = useStore(store, (state) => state.client)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n\n const updateContext = async (context: Record<string, any>) => {\n if (!client) {\n throw new Error('Flagmint client not initialized')\n }\n await client.updateContext(context)\n }\n\n return {\n client,\n isInitialized,\n updateContext\n }\n}\n\n// Hook to get all flags - only re-renders when flags change\nexport function useFlags(): Flags {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.flags)\n}\n\n// Hook to get a specific flag - only re-renders when this specific flag changes\nexport function useFlag<T extends FlagValue = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.flags[key] ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.isInitialized && state.client !== null)\n}"]}
1
+ {"version":3,"sources":["../src/store/store.ts","../src/providers/FlagmintProvider.tsx","../src/hooks/index.ts"],"names":["createStore","createContext","useMemo","useRef","FlagClient","useEffect","useContext","useStore"],"mappings":"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","file":"client.cjs","sourcesContent":["'use client';\nimport { createStore, StoreApi } from \"zustand/vanilla\";\nimport { Flags, FlagStore } from \"@/types\";\n\n\nexport function createFlagStore(initialFlags: Flags = {}): StoreApi<FlagStore> {\n return createStore<FlagStore>((set, get) => ({\n flags: initialFlags,\n client: null,\n isInitialized: false,\n isReady: false,\n setFlags: (flags) => set({ flags }),\n setFlag: (key, value) => set((state) => ({\n flags: { ...state.flags, [key]: value }\n })),\n setClient: (client) => set({ client }),\n setInitialized: (initialized) => set({ isInitialized: initialized }),\n setReady: (ready) => set({ isReady: ready })\n }))\n}\n","'use client';\nimport { FlagClient } from \"flagmint-js-sdk\"\nimport { useMemo, useRef, useEffect, createContext } from \"react\"\nimport { createFlagStore } from \"@/store/store\"\nimport { FlagmintProviderProps, Flags, FlagStore } from \"@/types\"\nimport { StoreApi } from \"zustand\"\n\nexport const FlagmintStoreContext = createContext<StoreApi<FlagStore> | null>(null)\n\n\nexport function FlagmintProvider<\n T extends FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags },\n C extends Record<string, any> = Record<string, any>\n>({\n children,\n options,\n initialFlags = {},\n deferInitialization = false\n}: FlagmintProviderProps<T, C>) {\n // Create a new store instance for each provider (per-request in SSR)\n const store = useMemo(() => createFlagStore(initialFlags), [initialFlags])\n \n // Use ref to avoid recreating client on every render\n const clientRef = useRef<FlagClient<T, C> | null>(null)\n const initPromiseRef = useRef<Promise<FlagClient<T, C>> | null>(null)\n const flagsRef = useRef<Flags>(initialFlags)\n \n // Initialization function similar to Vue plugin\n const init = async (): Promise<FlagClient<T, C>> => {\n if (clientRef.current) return clientRef.current // Avoid re-init\n \n // Return existing promise if init is already in progress\n if (initPromiseRef.current) return initPromiseRef.current\n \n const { setClient, setReady, setInitialized } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create a custom FlagClient that exposes flag updates\n const originalClient = new FlagClient<T, C>(options)\n await originalClient.ready()\n \n // Create a wrapper that tracks flags internally\n const clientWrapper = {\n ...originalClient,\n _flags: {} as Flags,\n getFlags: function() {\n return this._flags\n },\n // Override getFlag to track individual flags\n getFlag: function<K extends string>(key: K, fallback?: T) {\n const value = originalClient.getFlag(key as any, fallback)\n this._flags[key] = value\n store.getState().setFlag(key, value)\n return value\n },\n // Override updateContext to trigger flag refresh\n updateContext: function(context: C) {\n originalClient.updateContext(context)\n // After context update, we should refresh our tracked flags\n // This is a limitation of the current API\n setTimeout(() => {\n // Force a re-evaluation of flags we've previously requested\n Object.keys(this._flags).forEach(key => {\n const newValue = originalClient.getFlag(key as any)\n if (this._flags[key] !== newValue) {\n this._flags[key] = newValue\n store.getState().setFlag(key, newValue)\n }\n })\n }, 100)\n }\n } as FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags }\n \n clientRef.current = clientWrapper\n setClient(clientWrapper)\n setReady(true)\n setInitialized(true)\n \n return clientWrapper\n } catch (error) {\n console.error('Failed to initialize Flagmint client:', error)\n throw error\n }\n })()\n \n return initPromiseRef.current\n }\n\n useEffect(() => {\n if (!deferInitialization) {\n init().catch(error => {\n console.error('Auto-initialization failed:', error)\n })\n }\n\n return () => {\n if (clientRef.current) {\n clientRef.current.destroy?.()\n clientRef.current = null\n initPromiseRef.current = null\n }\n }\n }, [deferInitialization])\n\n return (\n <FlagmintStoreContext.Provider value={store}>\n {children}\n </FlagmintStoreContext.Provider>\n )\n}\n","'use client';\nimport { FlagValue } from \"flagmint-js-sdk\"\nimport { useContext } from \"react\"\nimport { StoreApi, useStore } from \"zustand\"\nimport { FlagmintStoreContext } from \"@/providers/FlagmintProvider\"\nimport { FlagStore, Flags } from \"@/types\"\n\n// Helper to get the store from context\nexport function useFlagmintStore(): StoreApi<FlagStore> {\n const store = useContext(FlagmintStoreContext)\n if (!store) {\n throw new Error('useFlagmintStore must be used within a FlagmintProvider')\n }\n return store\n}\n\n// Hook to get the client instance and update context\nexport function useFlagmint() {\n const store = useFlagmintStore()\n const client = useStore(store, (state) => state.client)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n\n const updateContext = async (context: Record<string, any>) => {\n if (!client) {\n throw new Error('Flagmint client not initialized')\n }\n await client.updateContext(context)\n }\n\n return {\n client,\n isInitialized,\n updateContext\n }\n}\n\n// Hook to get all flags - only re-renders when flags change\nexport function useFlags(): Flags {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.flags)\n}\n\n\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n const client = useStore(store, (state) => state.client)\n \n // Always try to get the latest value from client first\n if (client) {\n try {\n // Cast fallback to satisfy the client's type requirements\n const flagValue = client.getFlag(key as any, fallback as any)\n \n // Update store cache with the fresh value\n const currentValue = store.getState().flags[key]\n if (currentValue !== flagValue) {\n store.getState().setFlag(key, flagValue as FlagValue)\n }\n \n return flagValue as T\n } catch (error) {\n console.warn(`Failed to get flag '${key}' from client:`, error)\n // Fall through to store cache\n }\n }\n \n // Fallback to store cache or default\n const cachedValue = useStore(store, (state) => state.flags[key])\n return (cachedValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.isInitialized && state.client !== null)\n}"]}
package/dist/client.d.cts CHANGED
@@ -18,7 +18,7 @@ declare function useFlagmint(): {
18
18
  updateContext: (context: Record<string, any>) => Promise<void>;
19
19
  };
20
20
  declare function useFlags(): Flags;
21
- declare function useFlag<T extends FlagValue = FlagValue>(key: string, fallback?: T): T;
21
+ declare function useFlag<T = FlagValue>(key: string, fallback?: T): T;
22
22
  declare function useFlagmintReady(): boolean;
23
23
 
24
24
  export { FlagmintProvider, FlagmintStoreContext, useFlag, useFlagmint, useFlagmintReady, useFlagmintStore, useFlags };
package/dist/client.d.ts CHANGED
@@ -18,7 +18,7 @@ declare function useFlagmint(): {
18
18
  updateContext: (context: Record<string, any>) => Promise<void>;
19
19
  };
20
20
  declare function useFlags(): Flags;
21
- declare function useFlag<T extends FlagValue = FlagValue>(key: string, fallback?: T): T;
21
+ declare function useFlag<T = FlagValue>(key: string, fallback?: T): T;
22
22
  declare function useFlagmintReady(): boolean;
23
23
 
24
24
  export { FlagmintProvider, FlagmintStoreContext, useFlag, useFlagmint, useFlagmintReady, useFlagmintStore, useFlags };
package/dist/client.js CHANGED
@@ -123,10 +123,21 @@ function useFlags() {
123
123
  }
124
124
  function useFlag(key, fallback) {
125
125
  const store = useFlagmintStore();
126
- return useStore(store, (state) => {
127
- var _a;
128
- return (_a = state.flags[key]) != null ? _a : fallback;
129
- });
126
+ const client = useStore(store, (state) => state.client);
127
+ if (client) {
128
+ try {
129
+ const flagValue = client.getFlag(key, fallback);
130
+ const currentValue = store.getState().flags[key];
131
+ if (currentValue !== flagValue) {
132
+ store.getState().setFlag(key, flagValue);
133
+ }
134
+ return flagValue;
135
+ } catch (error) {
136
+ console.warn(`Failed to get flag '${key}' from client:`, error);
137
+ }
138
+ }
139
+ const cachedValue = useStore(store, (state) => state.flags[key]);
140
+ return cachedValue != null ? cachedValue : fallback;
130
141
  }
131
142
  function useFlagmintReady() {
132
143
  const store = useFlagmintStore();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store/store.ts","../src/providers/FlagmintProvider.tsx","../src/hooks/index.ts"],"names":[],"mappings":"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","file":"client.js","sourcesContent":["'use client';\nimport { createStore, StoreApi } from \"zustand/vanilla\";\nimport { Flags, FlagStore } from \"@/types\";\n\n\nexport function createFlagStore(initialFlags: Flags = {}): StoreApi<FlagStore> {\n return createStore<FlagStore>((set, get) => ({\n flags: initialFlags,\n client: null,\n isInitialized: false,\n isReady: false,\n setFlags: (flags) => set({ flags }),\n setFlag: (key, value) => set((state) => ({\n flags: { ...state.flags, [key]: value }\n })),\n setClient: (client) => set({ client }),\n setInitialized: (initialized) => set({ isInitialized: initialized }),\n setReady: (ready) => set({ isReady: ready })\n }))\n}\n","'use client';\nimport { FlagClient } from \"flagmint-js-sdk\"\nimport { useMemo, useRef, useEffect, createContext } from \"react\"\nimport { createFlagStore } from \"@/store/store\"\nimport { FlagmintProviderProps, Flags, FlagStore } from \"@/types\"\nimport { StoreApi } from \"zustand\"\n\nexport const FlagmintStoreContext = createContext<StoreApi<FlagStore> | null>(null)\n\n\nexport function FlagmintProvider<\n T extends FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags },\n C extends Record<string, any> = Record<string, any>\n>({\n children,\n options,\n initialFlags = {},\n deferInitialization = false\n}: FlagmintProviderProps<T, C>) {\n // Create a new store instance for each provider (per-request in SSR)\n const store = useMemo(() => createFlagStore(initialFlags), [initialFlags])\n \n // Use ref to avoid recreating client on every render\n const clientRef = useRef<FlagClient<T, C> | null>(null)\n const initPromiseRef = useRef<Promise<FlagClient<T, C>> | null>(null)\n const flagsRef = useRef<Flags>(initialFlags)\n \n // Initialization function similar to Vue plugin\n const init = async (): Promise<FlagClient<T, C>> => {\n if (clientRef.current) return clientRef.current // Avoid re-init\n \n // Return existing promise if init is already in progress\n if (initPromiseRef.current) return initPromiseRef.current\n \n const { setClient, setReady, setInitialized } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create a custom FlagClient that exposes flag updates\n const originalClient = new FlagClient<T, C>(options)\n await originalClient.ready()\n \n // Create a wrapper that tracks flags internally\n const clientWrapper = {\n ...originalClient,\n _flags: {} as Flags,\n getFlags: function() {\n return this._flags\n },\n // Override getFlag to track individual flags\n getFlag: function<K extends string>(key: K, fallback?: T) {\n const value = originalClient.getFlag(key as any, fallback)\n this._flags[key] = value\n store.getState().setFlag(key, value)\n return value\n },\n // Override updateContext to trigger flag refresh\n updateContext: function(context: C) {\n originalClient.updateContext(context)\n // After context update, we should refresh our tracked flags\n // This is a limitation of the current API\n setTimeout(() => {\n // Force a re-evaluation of flags we've previously requested\n Object.keys(this._flags).forEach(key => {\n const newValue = originalClient.getFlag(key as any)\n if (this._flags[key] !== newValue) {\n this._flags[key] = newValue\n store.getState().setFlag(key, newValue)\n }\n })\n }, 100)\n }\n } as FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags }\n \n clientRef.current = clientWrapper\n setClient(clientWrapper)\n setReady(true)\n setInitialized(true)\n \n return clientWrapper\n } catch (error) {\n console.error('Failed to initialize Flagmint client:', error)\n throw error\n }\n })()\n \n return initPromiseRef.current\n }\n\n useEffect(() => {\n if (!deferInitialization) {\n init().catch(error => {\n console.error('Auto-initialization failed:', error)\n })\n }\n\n return () => {\n if (clientRef.current) {\n clientRef.current.destroy?.()\n clientRef.current = null\n initPromiseRef.current = null\n }\n }\n }, [deferInitialization])\n\n return (\n <FlagmintStoreContext.Provider value={store}>\n {children}\n </FlagmintStoreContext.Provider>\n )\n}\n","'use client';\nimport { FlagValue } from \"flagmint-js-sdk\"\nimport { useContext } from \"react\"\nimport { StoreApi, useStore } from \"zustand\"\nimport { FlagmintStoreContext } from \"@/providers/FlagmintProvider\"\nimport { FlagStore, Flags } from \"@/types\"\n\n// Helper to get the store from context\nexport function useFlagmintStore(): StoreApi<FlagStore> {\n const store = useContext(FlagmintStoreContext)\n if (!store) {\n throw new Error('useFlagmintStore must be used within a FlagmintProvider')\n }\n return store\n}\n\n// Hook to get the client instance and update context\nexport function useFlagmint() {\n const store = useFlagmintStore()\n const client = useStore(store, (state) => state.client)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n\n const updateContext = async (context: Record<string, any>) => {\n if (!client) {\n throw new Error('Flagmint client not initialized')\n }\n await client.updateContext(context)\n }\n\n return {\n client,\n isInitialized,\n updateContext\n }\n}\n\n// Hook to get all flags - only re-renders when flags change\nexport function useFlags(): Flags {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.flags)\n}\n\n// Hook to get a specific flag - only re-renders when this specific flag changes\nexport function useFlag<T extends FlagValue = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.flags[key] ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.isInitialized && state.client !== null)\n}"]}
1
+ {"version":3,"sources":["../src/store/store.ts","../src/providers/FlagmintProvider.tsx","../src/hooks/index.ts"],"names":[],"mappings":";;;;;;AAKO,SAAS,eAAA,CAAgB,YAAA,GAAsB,EAAC,EAAwB;AAC5E,EAAA,OAAO,WAAA,CAAuB,CAAC,GAAA,EAAK,GAAA,MAAS;AAAA,IAC5C,KAAA,EAAO,YAAA;AAAA,IACP,MAAA,EAAQ,IAAA;AAAA,IACR,aAAA,EAAe,KAAA;AAAA,IACf,OAAA,EAAS,KAAA;AAAA,IACT,UAAU,CAAC,KAAA,KAAU,GAAA,CAAI,EAAE,OAAO,CAAA;AAAA,IAClC,SAAS,CAAC,GAAA,EAAK,KAAA,KAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,MACvC,KAAA,EAAO,EAAE,GAAG,KAAA,CAAM,OAAO,CAAC,GAAG,GAAG,KAAA;AAAM,KACxC,CAAE,CAAA;AAAA,IACF,WAAW,CAAC,MAAA,KAAW,GAAA,CAAI,EAAE,QAAQ,CAAA;AAAA,IACrC,gBAAgB,CAAC,WAAA,KAAgB,IAAI,EAAE,aAAA,EAAe,aAAa,CAAA;AAAA,IACnE,UAAU,CAAC,KAAA,KAAU,IAAI,EAAE,OAAA,EAAS,OAAO;AAAA,GAC7C,CAAE,CAAA;AACJ;ACZO,IAAM,oBAAA,GAAuB,cAA0C,IAAI;AAG3E,SAAS,gBAAA,CAGd;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAe,EAAC;AAAA,EAChB,mBAAA,GAAsB;AACxB,CAAA,EAAgC;AAE9B,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAAM,eAAA,CAAgB,YAAY,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAGzE,EAAA,MAAM,SAAA,GAAY,OAAgC,IAAI,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiB,OAAyC,IAAI,CAAA;AACpE,EAAiB,OAAc,YAAY;AAG3C,EAAA,MAAM,OAAO,YAAuC;AAClD,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,OAAO,SAAA,CAAU,OAAA;AAGxC,IAAA,IAAI,cAAA,CAAe,OAAA,EAAS,OAAO,cAAA,CAAe,OAAA;AAElD,IAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAU,cAAA,EAAe,GAAI,MAAM,QAAA,EAAS;AAE/D,IAAA,cAAA,CAAe,WAAW,YAAY;AACpC,MAAA,IAAI;AAEF,QAAA,MAAM,cAAA,GAAiB,IAAI,UAAA,CAAiB,OAAO,CAAA;AACnD,QAAA,MAAM,eAAe,KAAA,EAAM;AAG3B,QAAA,MAAM,aAAA,GAAgB;AAAA,UACpB,GAAG,cAAA;AAAA,UACH,QAAQ,EAAC;AAAA,UACT,UAAU,WAAW;AACnB,YAAA,OAAO,IAAA,CAAK,MAAA;AAAA,UACd,CAAA;AAAA;AAAA,UAEA,OAAA,EAAS,SAA2B,GAAA,EAAQ,QAAA,EAAc;AACxD,YAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAY,QAAQ,CAAA;AACzD,YAAA,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AACnB,YAAA,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AACnC,YAAA,OAAO,KAAA;AAAA,UACT,CAAA;AAAA;AAAA,UAEA,aAAA,EAAe,SAAS,OAAA,EAAY;AAClC,YAAA,cAAA,CAAe,cAAc,OAAO,CAAA;AAGpC,YAAA,UAAA,CAAW,MAAM;AAEf,cAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,CAAE,QAAQ,CAAA,GAAA,KAAO;AACtC,gBAAA,MAAM,QAAA,GAAW,cAAA,CAAe,OAAA,CAAQ,GAAU,CAAA;AAClD,gBAAA,IAAI,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,KAAM,QAAA,EAAU;AACjC,kBAAA,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA,GAAI,QAAA;AACnB,kBAAA,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,GAAA,EAAK,QAAQ,CAAA;AAAA,gBACxC;AAAA,cACF,CAAC,CAAA;AAAA,YACH,GAAG,GAAG,CAAA;AAAA,UACR;AAAA,SACF;AAEA,QAAA,SAAA,CAAU,OAAA,GAAU,aAAA;AACpB,QAAA,SAAA,CAAU,aAAa,CAAA;AACvB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,QAAA,OAAO,aAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAC5D,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAA,GAAG;AAEH,IAAA,OAAO,cAAA,CAAe,OAAA;AAAA,EACxB,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,MAAA,IAAA,EAAK,CAAE,MAAM,CAAA,KAAA,KAAS;AACpB,QAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAAA,MACpD,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,MAAM;AAhGjB,MAAA,IAAA,EAAA,EAAA,EAAA;AAiGM,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,SAAA,CAAU,SAAQ,OAAA,KAAlB,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,CAAA;AACA,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,mBAAmB,CAAC,CAAA;AAExB,EAAA,2BACG,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,OACnC,QAAA,EACH,CAAA;AAEJ;ACtGO,SAAS,gBAAA,GAAwC;AACtD,EAAA,MAAM,KAAA,GAAQ,WAAW,oBAAoB,CAAA;AAC7C,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,EAC3E;AACA,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,WAAA,GAAc;AAC5B,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,MAAM,SAAS,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,MAAM,CAAA;AACtD,EAAA,MAAM,gBAAgB,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,aAAa,CAAA;AAEpE,EAAA,MAAM,aAAA,GAAgB,OAAO,OAAA,KAAiC;AAC5D,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,IACnD;AACA,IAAA,MAAM,MAAA,CAAO,cAAc,OAAO,CAAA;AAAA,EACpC,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACF;AAGO,SAAS,QAAA,GAAkB;AAChC,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,OAAO,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAC/C;AAGO,SAAS,OAAA,CACd,KACA,QAAA,EACG;AACH,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,MAAM,SAAS,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,MAAM,CAAA;AAGtD,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,OAAA,CAAQ,GAAA,EAAY,QAAe,CAAA;AAG5D,MAAA,MAAM,YAAA,GAAe,KAAA,CAAM,QAAA,EAAS,CAAE,MAAM,GAAG,CAAA;AAC/C,MAAA,IAAI,iBAAiB,SAAA,EAAW;AAC9B,QAAA,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,GAAA,EAAK,SAAsB,CAAA;AAAA,MACtD;AAEA,MAAA,OAAO,SAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,oBAAA,EAAuB,GAAG,CAAA,cAAA,CAAA,EAAkB,KAAK,CAAA;AAAA,IAEhE;AAAA,EACF;AAGA,EAAA,MAAM,WAAA,GAAc,SAAS,KAAA,EAAO,CAAC,UAAU,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA;AAC/D,EAAA,OAAQ,WAAA,IAAA,IAAA,GAAA,WAAA,GAAe,QAAA;AACzB;AAGO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,EAAA,OAAO,QAAA,CAAS,OAAO,CAAC,KAAA,KAAU,MAAM,aAAA,IAAiB,KAAA,CAAM,WAAW,IAAI,CAAA;AAChF","file":"client.js","sourcesContent":["'use client';\nimport { createStore, StoreApi } from \"zustand/vanilla\";\nimport { Flags, FlagStore } from \"@/types\";\n\n\nexport function createFlagStore(initialFlags: Flags = {}): StoreApi<FlagStore> {\n return createStore<FlagStore>((set, get) => ({\n flags: initialFlags,\n client: null,\n isInitialized: false,\n isReady: false,\n setFlags: (flags) => set({ flags }),\n setFlag: (key, value) => set((state) => ({\n flags: { ...state.flags, [key]: value }\n })),\n setClient: (client) => set({ client }),\n setInitialized: (initialized) => set({ isInitialized: initialized }),\n setReady: (ready) => set({ isReady: ready })\n }))\n}\n","'use client';\nimport { FlagClient } from \"flagmint-js-sdk\"\nimport { useMemo, useRef, useEffect, createContext } from \"react\"\nimport { createFlagStore } from \"@/store/store\"\nimport { FlagmintProviderProps, Flags, FlagStore } from \"@/types\"\nimport { StoreApi } from \"zustand\"\n\nexport const FlagmintStoreContext = createContext<StoreApi<FlagStore> | null>(null)\n\n\nexport function FlagmintProvider<\n T extends FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags },\n C extends Record<string, any> = Record<string, any>\n>({\n children,\n options,\n initialFlags = {},\n deferInitialization = false\n}: FlagmintProviderProps<T, C>) {\n // Create a new store instance for each provider (per-request in SSR)\n const store = useMemo(() => createFlagStore(initialFlags), [initialFlags])\n \n // Use ref to avoid recreating client on every render\n const clientRef = useRef<FlagClient<T, C> | null>(null)\n const initPromiseRef = useRef<Promise<FlagClient<T, C>> | null>(null)\n const flagsRef = useRef<Flags>(initialFlags)\n \n // Initialization function similar to Vue plugin\n const init = async (): Promise<FlagClient<T, C>> => {\n if (clientRef.current) return clientRef.current // Avoid re-init\n \n // Return existing promise if init is already in progress\n if (initPromiseRef.current) return initPromiseRef.current\n \n const { setClient, setReady, setInitialized } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create a custom FlagClient that exposes flag updates\n const originalClient = new FlagClient<T, C>(options)\n await originalClient.ready()\n \n // Create a wrapper that tracks flags internally\n const clientWrapper = {\n ...originalClient,\n _flags: {} as Flags,\n getFlags: function() {\n return this._flags\n },\n // Override getFlag to track individual flags\n getFlag: function<K extends string>(key: K, fallback?: T) {\n const value = originalClient.getFlag(key as any, fallback)\n this._flags[key] = value\n store.getState().setFlag(key, value)\n return value\n },\n // Override updateContext to trigger flag refresh\n updateContext: function(context: C) {\n originalClient.updateContext(context)\n // After context update, we should refresh our tracked flags\n // This is a limitation of the current API\n setTimeout(() => {\n // Force a re-evaluation of flags we've previously requested\n Object.keys(this._flags).forEach(key => {\n const newValue = originalClient.getFlag(key as any)\n if (this._flags[key] !== newValue) {\n this._flags[key] = newValue\n store.getState().setFlag(key, newValue)\n }\n })\n }, 100)\n }\n } as FlagClient<T, C> & { _flags: Flags; getFlags: () => Flags }\n \n clientRef.current = clientWrapper\n setClient(clientWrapper)\n setReady(true)\n setInitialized(true)\n \n return clientWrapper\n } catch (error) {\n console.error('Failed to initialize Flagmint client:', error)\n throw error\n }\n })()\n \n return initPromiseRef.current\n }\n\n useEffect(() => {\n if (!deferInitialization) {\n init().catch(error => {\n console.error('Auto-initialization failed:', error)\n })\n }\n\n return () => {\n if (clientRef.current) {\n clientRef.current.destroy?.()\n clientRef.current = null\n initPromiseRef.current = null\n }\n }\n }, [deferInitialization])\n\n return (\n <FlagmintStoreContext.Provider value={store}>\n {children}\n </FlagmintStoreContext.Provider>\n )\n}\n","'use client';\nimport { FlagValue } from \"flagmint-js-sdk\"\nimport { useContext } from \"react\"\nimport { StoreApi, useStore } from \"zustand\"\nimport { FlagmintStoreContext } from \"@/providers/FlagmintProvider\"\nimport { FlagStore, Flags } from \"@/types\"\n\n// Helper to get the store from context\nexport function useFlagmintStore(): StoreApi<FlagStore> {\n const store = useContext(FlagmintStoreContext)\n if (!store) {\n throw new Error('useFlagmintStore must be used within a FlagmintProvider')\n }\n return store\n}\n\n// Hook to get the client instance and update context\nexport function useFlagmint() {\n const store = useFlagmintStore()\n const client = useStore(store, (state) => state.client)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n\n const updateContext = async (context: Record<string, any>) => {\n if (!client) {\n throw new Error('Flagmint client not initialized')\n }\n await client.updateContext(context)\n }\n\n return {\n client,\n isInitialized,\n updateContext\n }\n}\n\n// Hook to get all flags - only re-renders when flags change\nexport function useFlags(): Flags {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.flags)\n}\n\n\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n const client = useStore(store, (state) => state.client)\n \n // Always try to get the latest value from client first\n if (client) {\n try {\n // Cast fallback to satisfy the client's type requirements\n const flagValue = client.getFlag(key as any, fallback as any)\n \n // Update store cache with the fresh value\n const currentValue = store.getState().flags[key]\n if (currentValue !== flagValue) {\n store.getState().setFlag(key, flagValue as FlagValue)\n }\n \n return flagValue as T\n } catch (error) {\n console.warn(`Failed to get flag '${key}' from client:`, error)\n // Fall through to store cache\n }\n }\n \n // Fallback to store cache or default\n const cachedValue = useStore(store, (state) => state.flags[key])\n return (cachedValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n return useStore(store, (state) => state.isInitialized && state.client !== null)\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flagmint-react-sdk",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "React wrapper for flagmint-js-sdk",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -10,12 +10,12 @@
10
10
  "exports": {
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
- "import": "./dist/index.mjs",
13
+ "import": "./dist/index.js",
14
14
  "require": "./dist/index.cjs"
15
15
  },
16
16
  "./client": {
17
17
  "types": "./dist/client.d.ts",
18
- "import": "./dist/client.mjs"
18
+ "import": "./dist/client.js"
19
19
  },
20
20
  "./package.json": "./package.json"
21
21
  },