flagmint-react-sdk 0.7.3 → 0.7.5
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 +0 -3
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +0 -3
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +0 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/client.cjs
CHANGED
|
@@ -13,7 +13,6 @@ function createFlagStore(initialFlags = {}) {
|
|
|
13
13
|
isInitialized: false,
|
|
14
14
|
isReady: false,
|
|
15
15
|
setFlags: (flags) => {
|
|
16
|
-
console.log("Updating store flags:", flags);
|
|
17
16
|
set({ flags: { ...flags } });
|
|
18
17
|
},
|
|
19
18
|
setFlag: (key, value) => set((state) => ({
|
|
@@ -46,7 +45,6 @@ function FlagmintProvider({
|
|
|
46
45
|
const initialClientFlags = client.getFlags();
|
|
47
46
|
setFlags(initialClientFlags);
|
|
48
47
|
const unsubscribe = client.subscribe((updatedFlags) => {
|
|
49
|
-
console.log("FlagmintProvider - flags updated:", updatedFlags);
|
|
50
48
|
const currentStore = store.getState();
|
|
51
49
|
currentStore.setFlags(updatedFlags);
|
|
52
50
|
});
|
|
@@ -55,7 +53,6 @@ function FlagmintProvider({
|
|
|
55
53
|
setClient(client);
|
|
56
54
|
setReady(true);
|
|
57
55
|
setInitialized(true);
|
|
58
|
-
console.log("FlagmintProvider - initialized with flags:", initialClientFlags);
|
|
59
56
|
return client;
|
|
60
57
|
} catch (error) {
|
|
61
58
|
console.error("Failed to initialize Flagmint client:", error);
|
package/dist/client.cjs.map
CHANGED
|
@@ -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":"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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) => {\n console.log('Updating store flags:', flags)\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n console.log('FlagmintProvider - flags updated:', updatedFlags)\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n console.log('FlagmintProvider - initialized with flags:', initialClientFlags)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\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) => {\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\n}"]}
|
package/dist/client.js
CHANGED
|
@@ -11,7 +11,6 @@ function createFlagStore(initialFlags = {}) {
|
|
|
11
11
|
isInitialized: false,
|
|
12
12
|
isReady: false,
|
|
13
13
|
setFlags: (flags) => {
|
|
14
|
-
console.log("Updating store flags:", flags);
|
|
15
14
|
set({ flags: { ...flags } });
|
|
16
15
|
},
|
|
17
16
|
setFlag: (key, value) => set((state) => ({
|
|
@@ -44,7 +43,6 @@ function FlagmintProvider({
|
|
|
44
43
|
const initialClientFlags = client.getFlags();
|
|
45
44
|
setFlags(initialClientFlags);
|
|
46
45
|
const unsubscribe = client.subscribe((updatedFlags) => {
|
|
47
|
-
console.log("FlagmintProvider - flags updated:", updatedFlags);
|
|
48
46
|
const currentStore = store.getState();
|
|
49
47
|
currentStore.setFlags(updatedFlags);
|
|
50
48
|
});
|
|
@@ -53,7 +51,6 @@ function FlagmintProvider({
|
|
|
53
51
|
setClient(client);
|
|
54
52
|
setReady(true);
|
|
55
53
|
setInitialized(true);
|
|
56
|
-
console.log("FlagmintProvider - initialized with flags:", initialClientFlags);
|
|
57
54
|
return client;
|
|
58
55
|
} catch (error) {
|
|
59
56
|
console.error("Failed to initialize Flagmint client:", error);
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,MAAA,OAAA,CAAQ,GAAA,CAAI,yBAAyB,KAAK,CAAA;AAC1C,MAAA,GAAA,CAAI,EAAE,KAAA,EAAO,EAAE,GAAG,KAAA,IAAS,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,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;ACfO,IAAM,oBAAA,GAAuB,cAA0C,IAAI;AAc3E,SAAS,gBAAA,CAGd;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAe,EAAC;AAAA,EAChB,mBAAA,GAAsB;AACxB,CAAA,EAAgC;AAE9B,EAAA,MAAM,QAAQ,OAAA,CAAQ,MAAM,gBAAgB,YAAY,CAAA,EAAG,EAAE,CAAA;AAG7D,EAAA,MAAM,SAAA,GAAY,OAAgC,IAAI,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiB,OAAyC,IAAI,CAAA;AACpE,EAAA,MAAM,cAAA,GAAiB,OAA4B,IAAI,CAAA;AAGvD,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,gBAAgB,QAAA,EAAS,GAAI,MAAM,QAAA,EAAS;AAEzE,IAAA,cAAA,CAAe,WAAW,YAAY;AACpC,MAAA,IAAI;AAEF,QAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAiB,OAAO,CAAA;AAG3C,QAAA,MAAM,OAAO,KAAA,EAAM;AAGnB,QAAA,MAAM,kBAAA,GAAqB,OAAO,QAAA,EAAS;AAC3C,QAAA,QAAA,CAAS,kBAAkB,CAAA;AAG3B,QAAA,MAAM,WAAA,GAAc,MAAA,CAAO,SAAA,CAAU,CAAC,YAAA,KAAwB;AAC5D,UAAA,OAAA,CAAQ,GAAA,CAAI,qCAAqC,YAAY,CAAA;AAE7D,UAAA,MAAM,YAAA,GAAe,MAAM,QAAA,EAAS;AACpC,UAAA,YAAA,CAAa,SAAS,YAAY,CAAA;AAAA,QACpC,CAAC,CAAA;AAED,QAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,QAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,QAAA,SAAA,CAAU,MAAM,CAAA;AAChB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,QAAA,OAAA,CAAQ,GAAA,CAAI,8CAA8C,kBAAkB,CAAA;AAE5E,QAAA,OAAO,MAAA;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;AA7FjB,MAAA,IAAA,EAAA,EAAA,EAAA;AA+FM,MAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,QAAA,cAAA,CAAe,OAAA,EAAQ;AACvB,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAGA,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;AC1GO,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;AAG/B,EAAA,MAAM,SAAA,GAAY,SAAS,KAAA,EAAO,CAAC,UAAU,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA;AAG7D,EAAA,OAAQ,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,QAAA;AACvB;AAGO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAG/B,EAAA,MAAM,UAAU,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,OAAO,CAAA;AACxD,EAAA,MAAM,gBAAgB,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,aAAa,CAAA;AAEpE,EAAA,OAAO,OAAA,IAAW,aAAA;AACpB","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) => {\n console.log('Updating store flags:', flags)\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n console.log('FlagmintProvider - flags updated:', updatedFlags)\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n console.log('FlagmintProvider - initialized with flags:', initialClientFlags)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\n}"]}
|
|
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) => {\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\n}"]}
|
package/dist/index.cjs
CHANGED
|
@@ -14,7 +14,6 @@ function createFlagStore(initialFlags = {}) {
|
|
|
14
14
|
isInitialized: false,
|
|
15
15
|
isReady: false,
|
|
16
16
|
setFlags: (flags) => {
|
|
17
|
-
console.log("Updating store flags:", flags);
|
|
18
17
|
set({ flags: { ...flags } });
|
|
19
18
|
},
|
|
20
19
|
setFlag: (key, value) => set((state) => ({
|
|
@@ -47,7 +46,6 @@ function FlagmintProvider({
|
|
|
47
46
|
const initialClientFlags = client.getFlags();
|
|
48
47
|
setFlags(initialClientFlags);
|
|
49
48
|
const unsubscribe = client.subscribe((updatedFlags) => {
|
|
50
|
-
console.log("FlagmintProvider - flags updated:", updatedFlags);
|
|
51
49
|
const currentStore = store.getState();
|
|
52
50
|
currentStore.setFlags(updatedFlags);
|
|
53
51
|
});
|
|
@@ -56,7 +54,6 @@ function FlagmintProvider({
|
|
|
56
54
|
setClient(client);
|
|
57
55
|
setReady(true);
|
|
58
56
|
setInitialized(true);
|
|
59
|
-
console.log("FlagmintProvider - initialized with flags:", initialClientFlags);
|
|
60
57
|
return client;
|
|
61
58
|
} catch (error) {
|
|
62
59
|
console.error("Failed to initialize Flagmint client:", error);
|
package/dist/index.cjs.map
CHANGED
|
@@ -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":"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","file":"index.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) => {\n console.log('Updating store flags:', flags)\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n console.log('FlagmintProvider - flags updated:', updatedFlags)\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n console.log('FlagmintProvider - initialized with flags:', initialClientFlags)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\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":";;;;;;;;;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,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,MAAA,GAAA,CAAI,EAAE,KAAA,EAAO,EAAE,GAAG,KAAA,IAAS,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,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;ACdO,IAAM,oBAAA,GAAuBC,oBAA0C,IAAI;AAc3E,SAAS,gBAAA,CAGd;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAe,EAAC;AAAA,EAChB,mBAAA,GAAsB;AACxB,CAAA,EAAgC;AAE9B,EAAA,MAAM,QAAQC,aAAA,CAAQ,MAAM,gBAAgB,YAAY,CAAA,EAAG,EAAE,CAAA;AAG7D,EAAA,MAAM,SAAA,GAAYC,aAAgC,IAAI,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiBA,aAAyC,IAAI,CAAA;AACpE,EAAA,MAAM,cAAA,GAAiBA,aAA4B,IAAI,CAAA;AAGvD,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,gBAAgB,QAAA,EAAS,GAAI,MAAM,QAAA,EAAS;AAEzE,IAAA,cAAA,CAAe,WAAW,YAAY;AACpC,MAAA,IAAI;AAEF,QAAA,MAAM,MAAA,GAAS,IAAIC,wBAAA,CAAiB,OAAO,CAAA;AAG3C,QAAA,MAAM,OAAO,KAAA,EAAM;AAGnB,QAAA,MAAM,kBAAA,GAAqB,OAAO,QAAA,EAAS;AAC3C,QAAA,QAAA,CAAS,kBAAkB,CAAA;AAG3B,QAAA,MAAM,WAAA,GAAc,MAAA,CAAO,SAAA,CAAU,CAAC,YAAA,KAAwB;AAE5D,UAAA,MAAM,YAAA,GAAe,MAAM,QAAA,EAAS;AACpC,UAAA,YAAA,CAAa,SAAS,YAAY,CAAA;AAAA,QACpC,CAAC,CAAA;AAED,QAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,QAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,QAAA,SAAA,CAAU,MAAM,CAAA;AAChB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,QAAA,OAAO,MAAA;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;AA1FjB,MAAA,IAAA,EAAA,EAAA,EAAA;AA4FM,MAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,QAAA,cAAA,CAAe,OAAA,EAAQ;AACvB,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAGA,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;ACvGO,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;AAG/B,EAAA,MAAM,SAAA,GAAYA,iBAAS,KAAA,EAAO,CAAC,UAAU,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA;AAG7D,EAAA,OAAQ,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,QAAA;AACvB;AAGO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAG/B,EAAA,MAAM,UAAUA,gBAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,OAAO,CAAA;AACxD,EAAA,MAAM,gBAAgBA,gBAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,aAAa,CAAA;AAEpE,EAAA,OAAO,OAAA,IAAW,aAAA;AACpB","file":"index.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) => {\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\n}"]}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,6 @@ function createFlagStore(initialFlags = {}) {
|
|
|
12
12
|
isInitialized: false,
|
|
13
13
|
isReady: false,
|
|
14
14
|
setFlags: (flags) => {
|
|
15
|
-
console.log("Updating store flags:", flags);
|
|
16
15
|
set({ flags: { ...flags } });
|
|
17
16
|
},
|
|
18
17
|
setFlag: (key, value) => set((state) => ({
|
|
@@ -45,7 +44,6 @@ function FlagmintProvider({
|
|
|
45
44
|
const initialClientFlags = client.getFlags();
|
|
46
45
|
setFlags(initialClientFlags);
|
|
47
46
|
const unsubscribe = client.subscribe((updatedFlags) => {
|
|
48
|
-
console.log("FlagmintProvider - flags updated:", updatedFlags);
|
|
49
47
|
const currentStore = store.getState();
|
|
50
48
|
currentStore.setFlags(updatedFlags);
|
|
51
49
|
});
|
|
@@ -54,7 +52,6 @@ function FlagmintProvider({
|
|
|
54
52
|
setClient(client);
|
|
55
53
|
setReady(true);
|
|
56
54
|
setInitialized(true);
|
|
57
|
-
console.log("FlagmintProvider - initialized with flags:", initialClientFlags);
|
|
58
55
|
return client;
|
|
59
56
|
} catch (error) {
|
|
60
57
|
console.error("Failed to initialize Flagmint client:", error);
|
package/dist/index.js.map
CHANGED
|
@@ -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":"index.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) => {\n console.log('Updating store flags:', flags)\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n console.log('FlagmintProvider - flags updated:', updatedFlags)\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n console.log('FlagmintProvider - initialized with flags:', initialClientFlags)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\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,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,MAAA,GAAA,CAAI,EAAE,KAAA,EAAO,EAAE,GAAG,KAAA,IAAS,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,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;ACdO,IAAM,oBAAA,GAAuB,cAA0C,IAAI;AAc3E,SAAS,gBAAA,CAGd;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAe,EAAC;AAAA,EAChB,mBAAA,GAAsB;AACxB,CAAA,EAAgC;AAE9B,EAAA,MAAM,QAAQ,OAAA,CAAQ,MAAM,gBAAgB,YAAY,CAAA,EAAG,EAAE,CAAA;AAG7D,EAAA,MAAM,SAAA,GAAY,OAAgC,IAAI,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiB,OAAyC,IAAI,CAAA;AACpE,EAAA,MAAM,cAAA,GAAiB,OAA4B,IAAI,CAAA;AAGvD,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,gBAAgB,QAAA,EAAS,GAAI,MAAM,QAAA,EAAS;AAEzE,IAAA,cAAA,CAAe,WAAW,YAAY;AACpC,MAAA,IAAI;AAEF,QAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAiB,OAAO,CAAA;AAG3C,QAAA,MAAM,OAAO,KAAA,EAAM;AAGnB,QAAA,MAAM,kBAAA,GAAqB,OAAO,QAAA,EAAS;AAC3C,QAAA,QAAA,CAAS,kBAAkB,CAAA;AAG3B,QAAA,MAAM,WAAA,GAAc,MAAA,CAAO,SAAA,CAAU,CAAC,YAAA,KAAwB;AAE5D,UAAA,MAAM,YAAA,GAAe,MAAM,QAAA,EAAS;AACpC,UAAA,YAAA,CAAa,SAAS,YAAY,CAAA;AAAA,QACpC,CAAC,CAAA;AAED,QAAA,cAAA,CAAe,OAAA,GAAU,WAAA;AAEzB,QAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,QAAA,SAAA,CAAU,MAAM,CAAA;AAChB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,QAAA,OAAO,MAAA;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;AA1FjB,MAAA,IAAA,EAAA,EAAA,EAAA;AA4FM,MAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,QAAA,cAAA,CAAe,OAAA,EAAQ;AACvB,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAGA,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;ACvGO,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;AAG/B,EAAA,MAAM,SAAA,GAAY,SAAS,KAAA,EAAO,CAAC,UAAU,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA;AAG7D,EAAA,OAAQ,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,QAAA;AACvB;AAGO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,MAAM,QAAQ,gBAAA,EAAiB;AAG/B,EAAA,MAAM,UAAU,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,OAAO,CAAA;AACxD,EAAA,MAAM,gBAAgB,QAAA,CAAS,KAAA,EAAO,CAAC,KAAA,KAAU,MAAM,aAAa,CAAA;AAEpE,EAAA,OAAO,OAAA,IAAW,aAAA;AACpB","file":"index.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) => {\n set({ flags: { ...flags } })\n },\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/**\n * Provides the Flagmint flag store to React components and keeps it synced with FlagClient updates.\n * Lifecycle overview:\n * - App loads → FlagClient constructed → initialize() begins.\n * - Cached flags applied → subscribers notified → React renders cached values.\n * - Transport set up → initial fetch → store updated → subscribers notified.\n * - Subsequent server updates propagate via client.subscribe to re-render consumers.\n * - When context changes (updateContext), flags are re-fetched and the store is refreshed.\n *\n * @param props Component props: children, client options, optional initial flags, and deferInitialization flag.\n * @returns A provider that supplies the flag store context to its children.\n */\nexport function FlagmintProvider<\n T extends FlagClient<T, C>,\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), [])\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 unsubscribeRef = useRef<(() => void) | null>(null)\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, setFlags } = store.getState()\n \n initPromiseRef.current = (async () => {\n try {\n // Create the FlagClient\n const client = new FlagClient<T, C>(options)\n \n // Wait for client to be ready\n await client.ready()\n \n // Get initial flags from client\n const initialClientFlags = client.getFlags()\n setFlags(initialClientFlags)\n \n // Subscribe to flag changes - THIS IS THE KEY FIX\n const unsubscribe = client.subscribe((updatedFlags: Flags) => {\n // Get fresh reference each time\n const currentStore = store.getState();\n currentStore.setFlags(updatedFlags);\n })\n \n unsubscribeRef.current = unsubscribe\n \n clientRef.current = client\n setClient(client)\n setReady(true)\n setInitialized(true)\n \n return client\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 // Unsubscribe from flag changes\n if (unsubscribeRef.current) {\n unsubscribeRef.current()\n unsubscribeRef.current = null\n }\n \n // Destroy client\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// Simplified useFlag - just read from the reactive store\nexport function useFlag<T = FlagValue>(\n key: string,\n fallback?: T\n): T {\n const store = useFlagmintStore()\n \n // Subscribe to this specific flag in the store\n const flagValue = useStore(store, (state) => state.flags[key])\n \n // Return the flag value or fallback\n return (flagValue ?? fallback) as T\n}\n\n// Hook to check if the client is ready\nexport function useFlagmintReady(): boolean {\n const store = useFlagmintStore()\n \n // Subscribe to both isReady and isInitialized\n const isReady = useStore(store, (state) => state.isReady)\n const isInitialized = useStore(store, (state) => state.isInitialized)\n \n return isReady && isInitialized\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flagmint-react-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "React wrapper for flagmint-js-sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"zustand": "^4.4.0",
|
|
35
|
-
"flagmint-js-sdk": "1.0.
|
|
35
|
+
"flagmint-js-sdk": "1.0.12"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"tsup": "^8.0.0",
|