flagmint-react-sdk 0.4.0 → 0.6.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/index.d.cts CHANGED
@@ -26,6 +26,8 @@ interface FlagStore {
26
26
  }
27
27
  interface FlagmintProviderProps {
28
28
  children: ReactNode;
29
+ createClient?: () => CoreClientLike;
30
+ client: CoreClientLike;
29
31
  initialFlags?: Flags;
30
32
  }
31
33
  interface FlagmintProviderProps<T = unknown, C extends Record<string, any> = Record<string, any>> {
package/dist/index.d.ts CHANGED
@@ -26,6 +26,8 @@ interface FlagStore {
26
26
  }
27
27
  interface FlagmintProviderProps {
28
28
  children: ReactNode;
29
+ createClient?: () => CoreClientLike;
30
+ client: CoreClientLike;
29
31
  initialFlags?: Flags;
30
32
  }
31
33
  interface FlagmintProviderProps<T = unknown, C extends Record<string, any> = Record<string, any>> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flagmint-react-sdk",
3
- "version": "0.4.0",
3
+ "version": "0.6.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.js",
13
+ "import": "./dist/index.mjs",
14
14
  "require": "./dist/index.cjs"
15
15
  },
16
16
  "./client": {
17
17
  "types": "./dist/client.d.ts",
18
- "import": "./dist/client.js"
18
+ "import": "./dist/client.mjs"
19
19
  },
20
20
  "./package.json": "./package.json"
21
21
  },
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "zustand": "^4.4.0",
35
- "flagmint-js-sdk": "*"
35
+ "flagmint-js-sdk": "1.0.11"
36
36
  },
37
37
  "devDependencies": {
38
38
  "tsup": "^8.0.0",
package/README.md DELETED
@@ -1,609 +0,0 @@
1
- # flagmint-react-sdk
2
-
3
- A React wrapper for [flagmint-js-sdk](https://www.npmjs.com/package/flagmint-js-sdk) that provides React-specific hooks and context with fine-grained reactivity powered by Zustand.
4
-
5
- ## ✨ Features
6
-
7
- - 🎯 **Fine-grained reactivity** - Only components using specific flags re-render when those flags change
8
- - 🚀 **SSR-safe** - No global state leakage between server requests
9
- - 📦 **TypeScript support** - Full type safety with generics for flag values and context
10
- - 🔀 **Dual export strategy** - Separate server-safe types and client-only hooks
11
- - ⚡ **Auto-initialization** - Direct integration with FlagClient from flagmint-js-sdk
12
- - 🔐 **Deferred initialization** - Perfect for authentication flows
13
- - 📱 **Framework agnostic** - Works with Next.js, Remix, Vite, and more
14
-
15
- ## 📦 Installation
16
-
17
- ```bash
18
- npm install react-flagmint flagmint-js-sdk
19
- # or
20
- pnpm add react-flagmint flagmint-js-sdk
21
- # or
22
- yarn add react-flagmint flagmint-js-sdk
23
- ```
24
-
25
- ## 🚀 Quick Start
26
-
27
- ### 1. Basic Setup
28
-
29
- ```tsx
30
- // app/providers.tsx (Next.js App Router)
31
- 'use client'
32
- import { FlagmintProvider } from 'react-flagmint/client'
33
-
34
- export default function Providers({ children }: { children: React.ReactNode }) {
35
- return (
36
- <FlagmintProvider
37
- options={{
38
- apiKey: process.env.NEXT_PUBLIC_FLAGMINT_API_KEY!,
39
- transportMode: 'websocket',
40
- context: {
41
- userId: 'user-123',
42
- plan: 'premium'
43
- }
44
- }}
45
- >
46
- {children}
47
- </FlagmintProvider>
48
- )
49
- }
50
- ```
51
-
52
- ```tsx
53
- // app/layout.tsx
54
- import Providers from './providers'
55
-
56
- export default function RootLayout({
57
- children,
58
- }: {
59
- children: React.ReactNode
60
- }) {
61
- return (
62
- <html>
63
- <body>
64
- <Providers>
65
- {children}
66
- </Providers>
67
- </body>
68
- </html>
69
- )
70
- }
71
- ```
72
-
73
- ### 2. Using Flags in Components
74
-
75
- ```tsx
76
- // components/FeatureComponent.tsx
77
- 'use client'
78
- import { useFlag, useFlags, useFlagmintReady } from 'react-flagmint/client'
79
-
80
- export default function FeatureComponent() {
81
- const showNewFeature = useFlag('new-dashboard', false)
82
- const userPlan = useFlag('user-plan', 'free')
83
- const isReady = useFlagmintReady()
84
-
85
- if (!isReady) {
86
- return <div>Loading flags...</div>
87
- }
88
-
89
- return (
90
- <div>
91
- {showNewFeature && <NewDashboard />}
92
- <div>Current plan: {userPlan}</div>
93
- </div>
94
- )
95
- }
96
- ```
97
-
98
- ## 📚 API Reference
99
-
100
- ### FlagmintProvider
101
-
102
- The provider component that initializes the FlagClient and provides flag context to your app.
103
-
104
- ```tsx
105
- <FlagmintProvider
106
- options={FlagClientOptions}
107
- initialFlags={{}}
108
- deferInitialization={false}
109
- >
110
- {children}
111
- </FlagmintProvider>
112
- ```
113
-
114
- #### Props
115
-
116
- | Prop | Type | Default | Description |
117
- |------|------|---------|-------------|
118
- | `options` | `FlagClientOptions` | Required | Configuration for the FlagClient |
119
- | `initialFlags` | `Flags` | `{}` | Initial flag values for SSR/hydration |
120
- | `deferInitialization` | `boolean` | `false` | If true, wait for manual initialization |
121
-
122
- #### FlagClientOptions
123
-
124
- ```tsx
125
- interface FlagClientOptions<C extends Record<string, any> = Record<string, any>> {
126
- apiKey: string
127
- context?: C
128
- transportMode?: 'auto' | 'websocket' | 'long-polling'
129
- enableOfflineCache?: boolean
130
- persistContext?: boolean
131
- onError?: (error: Error) => void
132
- previewMode?: boolean
133
- rawFlags?: Record<string, FlagValue>
134
- deferInitialization?: boolean
135
- }
136
- ```
137
-
138
- ### Hooks
139
-
140
- #### useFlag(key, fallback?)
141
-
142
- Get a specific flag value with fine-grained reactivity.
143
-
144
- ```tsx
145
- const showFeature = useFlag('feature-name', false)
146
- const userTier = useFlag('user-tier', 'free')
147
- const config = useFlag('app-config', { theme: 'light' })
148
- ```
149
-
150
- **Parameters:**
151
- - `key: string` - The flag key
152
- - `fallback?: T` - Default value if flag is not found
153
-
154
- **Returns:** The flag value or fallback
155
-
156
- #### useFlags()
157
-
158
- Get all currently loaded flags.
159
-
160
- ```tsx
161
- const allFlags = useFlags()
162
- console.log(allFlags) // { 'feature-a': true, 'user-tier': 'pro' }
163
- ```
164
-
165
- **Returns:** Object containing all loaded flags
166
-
167
- #### useFlagmint()
168
-
169
- Get access to the FlagClient instance and utilities.
170
-
171
- ```tsx
172
- const { client, isReady, isInitialized, updateContext } = useFlagmint()
173
-
174
- // Update user context
175
- await updateContext({ userId: 'new-user', plan: 'enterprise' })
176
- ```
177
-
178
- **Returns:**
179
- ```tsx
180
- {
181
- client: FlagClient | null
182
- isReady: boolean
183
- isInitialized: boolean
184
- updateContext: (context: Record<string, any>) => Promise<void>
185
- }
186
- ```
187
-
188
- #### useFlagmintReady()
189
-
190
- Check if the FlagClient is ready to serve flags.
191
-
192
- ```tsx
193
- const isReady = useFlagmintReady()
194
-
195
- if (!isReady) {
196
- return <LoadingSpinner />
197
- }
198
- ```
199
-
200
- #### useFlagClient()
201
-
202
- Get direct access to the FlagClient instance.
203
-
204
- ```tsx
205
- const client = useFlagClient<MyFlagTypes>()
206
- const specificFlag = client?.getFlag('feature-x', false)
207
- ```
208
-
209
- ## 🔧 Usage Patterns
210
-
211
- ### 1. Auto-initialization (Default)
212
-
213
- Best when user context is available immediately:
214
-
215
- ```tsx
216
- function App() {
217
- return (
218
- <FlagmintProvider
219
- options={{
220
- apiKey: 'your-api-key',
221
- context: {
222
- userId: getCurrentUser().id,
223
- plan: getCurrentUser().plan
224
- }
225
- }}
226
- >
227
- <Dashboard />
228
- </FlagmintProvider>
229
- )
230
- }
231
- ```
232
-
233
- ### 2. Deferred Initialization
234
-
235
- Perfect for authentication flows:
236
-
237
- ```tsx
238
- // Provider with deferred initialization
239
- <FlagmintProvider
240
- options={{
241
- apiKey: 'your-api-key',
242
- context: {} // Empty initially
243
- }}
244
- deferInitialization={true}
245
- >
246
- <App />
247
- </FlagmintProvider>
248
-
249
- // Login component
250
- function LoginPage() {
251
- const { updateContext } = useFlagmint()
252
-
253
- const handleLogin = async (user) => {
254
- // First update context with user info
255
- await updateContext({
256
- userId: user.id,
257
- plan: user.plan,
258
- locale: user.locale
259
- })
260
-
261
- // Flags are now available with user context
262
- navigate('/dashboard')
263
- }
264
-
265
- return <LoginForm onLogin={handleLogin} />
266
- }
267
- ```
268
-
269
- ### 3. TypeScript Usage
270
-
271
- Define your flag types for better type safety:
272
-
273
- ```tsx
274
- // types/flags.ts
275
- export interface AppFlags {
276
- 'show-beta-feature': boolean
277
- 'user-plan': 'free' | 'pro' | 'enterprise'
278
- 'theme-config': {
279
- primaryColor: string
280
- darkMode: boolean
281
- }
282
- }
283
-
284
- export interface UserContext {
285
- userId: string
286
- plan: string
287
- locale: string
288
- }
289
-
290
- // components/TypedComponent.tsx
291
- import { useFlag } from 'react-flagmint/client'
292
- import type { AppFlags } from '../types/flags'
293
-
294
- export default function TypedComponent() {
295
- // TypeScript knows this returns boolean
296
- const showBeta = useFlag<AppFlags['show-beta-feature']>('show-beta-feature', false)
297
-
298
- // TypeScript knows this returns the union type
299
- const plan = useFlag<AppFlags['user-plan']>('user-plan', 'free')
300
-
301
- return (
302
- <div>
303
- {showBeta && <BetaFeature />}
304
- <div>Plan: {plan}</div>
305
- </div>
306
- )
307
- }
308
- ```
309
-
310
- ### 4. Server-Side Rendering (SSR)
311
-
312
- #### Next.js App Router
313
-
314
- ```tsx
315
- // app/providers.tsx
316
- 'use client'
317
- import { FlagmintProvider } from 'react-flagmint/client'
318
-
319
- export default function Providers({ children, initialFlags = {} }) {
320
- return (
321
- <FlagmintProvider
322
- options={{
323
- apiKey: process.env.NEXT_PUBLIC_FLAGMINT_API_KEY!,
324
- transportMode: 'websocket'
325
- }}
326
- initialFlags={initialFlags}
327
- >
328
- {children}
329
- </FlagmintProvider>
330
- )
331
- }
332
-
333
- // app/page.tsx
334
- import { FlagClient } from 'flagmint-js-sdk'
335
- import Providers from './providers'
336
- import ClientComponent from './ClientComponent'
337
-
338
- export default async function Page() {
339
- // Optionally preload flags on server
340
- let initialFlags = {}
341
-
342
- try {
343
- const serverClient = new FlagClient({
344
- apiKey: process.env.FLAGMINT_API_KEY!,
345
- context: { server: true }
346
- })
347
- await serverClient.ready()
348
- initialFlags = await serverClient.getFlags() // If this method exists
349
- } catch (error) {
350
- console.warn('Failed to load initial flags:', error)
351
- }
352
-
353
- return (
354
- <Providers initialFlags={initialFlags}>
355
- <ClientComponent />
356
- </Providers>
357
- )
358
- }
359
- ```
360
-
361
- ### 5. Context Updates
362
-
363
- Update user context dynamically:
364
-
365
- ```tsx
366
- function UserSettings() {
367
- const { updateContext } = useFlagmint()
368
- const currentTheme = useFlag('user-theme', 'light')
369
-
370
- const handleThemeChange = async (newTheme: string) => {
371
- // Update context - flags will be re-evaluated
372
- await updateContext({ theme: newTheme })
373
- }
374
-
375
- const handlePlanUpgrade = async (newPlan: string) => {
376
- await updateContext({ plan: newPlan })
377
- // Component will re-render with new plan-based flags
378
- }
379
-
380
- return (
381
- <div>
382
- <ThemeSelector onChange={handleThemeChange} />
383
- <PlanUpgrade onUpgrade={handlePlanUpgrade} />
384
- </div>
385
- )
386
- }
387
- ```
388
-
389
- ### 6. Loading States
390
-
391
- Handle loading states gracefully:
392
-
393
- ```tsx
394
- function FeaturePage() {
395
- const isReady = useFlagmintReady()
396
- const showPremiumFeature = useFlag('premium-feature', false)
397
-
398
- if (!isReady) {
399
- return (
400
- <div className="loading-container">
401
- <Spinner />
402
- <p>Loading personalized features...</p>
403
- </div>
404
- )
405
- }
406
-
407
- return (
408
- <div>
409
- <h1>Features</h1>
410
- {showPremiumFeature ? (
411
- <PremiumFeature />
412
- ) : (
413
- <UpgradeBanner />
414
- )}
415
- </div>
416
- )
417
- }
418
- ```
419
-
420
- ### 7. Error Handling
421
-
422
- ```tsx
423
- <FlagmintProvider
424
- options={{
425
- apiKey: 'your-api-key',
426
- onError: (error) => {
427
- console.error('Flagmint error:', error)
428
- // Send to error reporting service
429
- errorReporting.captureException(error)
430
- }
431
- }}
432
- >
433
- <App />
434
- </FlagmintProvider>
435
- ```
436
-
437
- ## 🏗️ Framework Examples
438
-
439
- ### Next.js (App Router)
440
-
441
- ```tsx
442
- // app/layout.tsx
443
- import Providers from './providers'
444
-
445
- export default function RootLayout({ children }) {
446
- return (
447
- <html lang="en">
448
- <body>
449
- <Providers>{children}</Providers>
450
- </body>
451
- </html>
452
- )
453
- }
454
-
455
- // app/providers.tsx
456
- 'use client'
457
- import { FlagmintProvider } from 'react-flagmint/client'
458
-
459
- export default function Providers({ children }) {
460
- return (
461
- <FlagmintProvider
462
- options={{
463
- apiKey: process.env.NEXT_PUBLIC_FLAGMINT_API_KEY!,
464
- transportMode: 'long-polling'
465
- }}
466
- >
467
- {children}
468
- </FlagmintProvider>
469
- )
470
- }
471
- ```
472
-
473
- ### Vite + React
474
-
475
- ```tsx
476
- // src/main.tsx
477
- import React from 'react'
478
- import ReactDOM from 'react-dom/client'
479
- import { FlagmintProvider } from 'react-flagmint/client'
480
- import App from './App'
481
-
482
- ReactDOM.createRoot(document.getElementById('root')!).render(
483
- <React.StrictMode>
484
- <FlagmintProvider
485
- options={{
486
- apiKey: import.meta.env.VITE_FLAGMINT_API_KEY,
487
- transportMode: 'websocket'
488
- }}
489
- >
490
- <App />
491
- </FlagmintProvider>
492
- </React.StrictMode>
493
- )
494
- ```
495
-
496
- ### Remix
497
-
498
- ```tsx
499
- // app/root.tsx
500
- import { FlagmintProvider } from 'react-flagmint/client'
501
-
502
- export default function App() {
503
- return (
504
- <html>
505
- <head>
506
- <Meta />
507
- <Links />
508
- </head>
509
- <body>
510
- <FlagmintProvider
511
- options={{
512
- apiKey: process.env.FLAGMINT_API_KEY!,
513
- transportMode: 'long-polling'
514
- }}
515
- >
516
- <Outlet />
517
- </FlagmintProvider>
518
- <Scripts />
519
- </body>
520
- </html>
521
- )
522
- }
523
- ```
524
-
525
- ## ⚡ Performance
526
-
527
- ### Fine-grained Reactivity
528
-
529
- Only components that use specific flags will re-render when those flags change:
530
-
531
- ```tsx
532
- // ✅ Good: Only re-renders when 'feature-a' changes
533
- function ComponentA() {
534
- const featureA = useFlag('feature-a', false)
535
- return <div>{featureA && <FeatureA />}</div>
536
- }
537
-
538
- // ✅ Good: Only re-renders when 'feature-b' changes
539
- function ComponentB() {
540
- const featureB = useFlag('feature-b', false)
541
- return <div>{featureB && <FeatureB />}</div>
542
- }
543
-
544
- // ❌ Avoid: Re-renders when ANY flag changes
545
- function ComponentAll() {
546
- const allFlags = useFlags()
547
- return <div>{allFlags['feature-a'] && <FeatureA />}</div>
548
- }
549
- ```
550
-
551
- ### Bundle Size
552
-
553
- - **react-flagmint**: ~3KB gzipped
554
- - **zustand**: ~2KB gzipped
555
- - **Total overhead**: ~5KB gzipped
556
-
557
- ## 🔧 Development
558
-
559
- ### Local Development
560
-
561
- ```bash
562
- # Clone the monorepo
563
- git clone <repo-url>
564
- cd flagmint-monorepo
565
-
566
- # Install dependencies
567
- pnpm install
568
-
569
- # Build the library
570
- pnpm --filter react-flagmint build
571
-
572
- # Run the Next.js example
573
- pnpm dev:next
574
- ```
575
-
576
- ### Testing
577
-
578
- ```bash
579
- # Run tests
580
- pnpm test
581
-
582
- # Type checking
583
- pnpm typecheck
584
-
585
- # Lint
586
- pnpm lint
587
- ```
588
-
589
- ## 📄 License
590
-
591
- MIT
592
-
593
- ## 🤝 Contributing
594
-
595
- 1. Fork the repository
596
- 2. Create a feature branch
597
- 3. Make your changes
598
- 4. Add tests
599
- 5. Submit a pull request
600
-
601
- ## 📞 Support
602
-
603
- - 📧 Email: support@flagmint.com
604
- - 🐛 Issues: [GitHub Issues](https://github.com/jtad009/flagmint-react-sdk/issues)
605
- - 📖 Docs: [Documentation](https://docs.flagmint.com)
606
-
607
- ---
608
-
609
- **Made with ❤️ by the Flagmint team**
package/dist/client.cjs DELETED
@@ -1,146 +0,0 @@
1
- 'use strict';
2
-
3
- var flagmintJsSdk = require('flagmint-js-sdk');
4
- var react = require('react');
5
- var vanilla = require('zustand/vanilla');
6
- var jsxRuntime = require('react/jsx-runtime');
7
- var zustand = require('zustand');
8
-
9
- function createFlagStore(initialFlags = {}) {
10
- return vanilla.createStore((set, get) => ({
11
- flags: initialFlags,
12
- client: null,
13
- isInitialized: false,
14
- isReady: false,
15
- setFlags: (flags) => set({ flags }),
16
- setFlag: (key, value) => set((state) => ({
17
- flags: { ...state.flags, [key]: value }
18
- })),
19
- setClient: (client) => set({ client }),
20
- setInitialized: (initialized) => set({ isInitialized: initialized }),
21
- setReady: (ready) => set({ isReady: ready })
22
- }));
23
- }
24
- var FlagmintStoreContext = react.createContext(null);
25
- function FlagmintProvider({
26
- children,
27
- options,
28
- initialFlags = {},
29
- deferInitialization = false
30
- }) {
31
- const store = react.useMemo(() => createFlagStore(initialFlags), [initialFlags]);
32
- const clientRef = react.useRef(null);
33
- const initPromiseRef = react.useRef(null);
34
- react.useRef(initialFlags);
35
- const init = async () => {
36
- if (clientRef.current) return clientRef.current;
37
- if (initPromiseRef.current) return initPromiseRef.current;
38
- const { setClient, setReady, setInitialized } = store.getState();
39
- initPromiseRef.current = (async () => {
40
- try {
41
- const originalClient = new flagmintJsSdk.FlagClient(options);
42
- await originalClient.ready();
43
- const clientWrapper = {
44
- ...originalClient,
45
- _flags: {},
46
- getFlags: function() {
47
- return this._flags;
48
- },
49
- // Override getFlag to track individual flags
50
- getFlag: function(key, fallback) {
51
- const value = originalClient.getFlag(key, fallback);
52
- this._flags[key] = value;
53
- store.getState().setFlag(key, value);
54
- return value;
55
- },
56
- // Override updateContext to trigger flag refresh
57
- updateContext: function(context) {
58
- originalClient.updateContext(context);
59
- setTimeout(() => {
60
- Object.keys(this._flags).forEach((key) => {
61
- const newValue = originalClient.getFlag(key);
62
- if (this._flags[key] !== newValue) {
63
- this._flags[key] = newValue;
64
- store.getState().setFlag(key, newValue);
65
- }
66
- });
67
- }, 100);
68
- }
69
- };
70
- clientRef.current = clientWrapper;
71
- setClient(clientWrapper);
72
- setReady(true);
73
- setInitialized(true);
74
- return clientWrapper;
75
- } catch (error) {
76
- console.error("Failed to initialize Flagmint client:", error);
77
- throw error;
78
- }
79
- })();
80
- return initPromiseRef.current;
81
- };
82
- react.useEffect(() => {
83
- if (!deferInitialization) {
84
- init().catch((error) => {
85
- console.error("Auto-initialization failed:", error);
86
- });
87
- }
88
- return () => {
89
- var _a, _b;
90
- if (clientRef.current) {
91
- (_b = (_a = clientRef.current).destroy) == null ? void 0 : _b.call(_a);
92
- clientRef.current = null;
93
- initPromiseRef.current = null;
94
- }
95
- };
96
- }, [deferInitialization]);
97
- return /* @__PURE__ */ jsxRuntime.jsx(FlagmintStoreContext.Provider, { value: store, children });
98
- }
99
- function useFlagmintStore() {
100
- const store = react.useContext(FlagmintStoreContext);
101
- if (!store) {
102
- throw new Error("useFlagmintStore must be used within a FlagmintProvider");
103
- }
104
- return store;
105
- }
106
- function useFlagmint() {
107
- const store = useFlagmintStore();
108
- const client = zustand.useStore(store, (state) => state.client);
109
- const isInitialized = zustand.useStore(store, (state) => state.isInitialized);
110
- const updateContext = async (context) => {
111
- if (!client) {
112
- throw new Error("Flagmint client not initialized");
113
- }
114
- await client.updateContext(context);
115
- };
116
- return {
117
- client,
118
- isInitialized,
119
- updateContext
120
- };
121
- }
122
- function useFlags() {
123
- const store = useFlagmintStore();
124
- return zustand.useStore(store, (state) => state.flags);
125
- }
126
- function useFlag(key, fallback) {
127
- const store = useFlagmintStore();
128
- return zustand.useStore(store, (state) => {
129
- var _a;
130
- return (_a = state.flags[key]) != null ? _a : fallback;
131
- });
132
- }
133
- function useFlagmintReady() {
134
- const store = useFlagmintStore();
135
- return zustand.useStore(store, (state) => state.isInitialized && state.client !== null);
136
- }
137
-
138
- exports.FlagmintProvider = FlagmintProvider;
139
- exports.FlagmintStoreContext = FlagmintStoreContext;
140
- exports.useFlag = useFlag;
141
- exports.useFlagmint = useFlagmint;
142
- exports.useFlagmintReady = useFlagmintReady;
143
- exports.useFlagmintStore = useFlagmintStore;
144
- exports.useFlags = useFlags;
145
- //# sourceMappingURL=client.cjs.map
146
- //# sourceMappingURL=client.cjs.map
@@ -1 +0,0 @@
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// 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}"]}
package/dist/client.d.cts DELETED
@@ -1,24 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as react from 'react';
3
- import * as flagmint_js_sdk from 'flagmint-js-sdk';
4
- import { FlagClient, FlagValue } from 'flagmint-js-sdk';
5
- import { FlagStore, Flags, FlagmintProviderProps } from './index.cjs';
6
- import { StoreApi } from 'zustand';
7
-
8
- declare const FlagmintStoreContext: react.Context<StoreApi<FlagStore> | null>;
9
- declare function FlagmintProvider<T extends FlagClient<T, C> & {
10
- _flags: Flags;
11
- getFlags: () => Flags;
12
- }, C extends Record<string, any> = Record<string, any>>({ children, options, initialFlags, deferInitialization }: FlagmintProviderProps<T, C>): react_jsx_runtime.JSX.Element;
13
-
14
- declare function useFlagmintStore(): StoreApi<FlagStore>;
15
- declare function useFlagmint(): {
16
- client: flagmint_js_sdk.FlagClient<any, any> | null;
17
- isInitialized: boolean;
18
- updateContext: (context: Record<string, any>) => Promise<void>;
19
- };
20
- declare function useFlags(): Flags;
21
- declare function useFlag<T extends FlagValue = FlagValue>(key: string, fallback?: T): T;
22
- declare function useFlagmintReady(): boolean;
23
-
24
- export { FlagmintProvider, FlagmintStoreContext, useFlag, useFlagmint, useFlagmintReady, useFlagmintStore, useFlags };
package/dist/client.d.ts DELETED
@@ -1,24 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as react from 'react';
3
- import * as flagmint_js_sdk from 'flagmint-js-sdk';
4
- import { FlagClient, FlagValue } from 'flagmint-js-sdk';
5
- import { FlagStore, Flags, FlagmintProviderProps } from './index.js';
6
- import { StoreApi } from 'zustand';
7
-
8
- declare const FlagmintStoreContext: react.Context<StoreApi<FlagStore> | null>;
9
- declare function FlagmintProvider<T extends FlagClient<T, C> & {
10
- _flags: Flags;
11
- getFlags: () => Flags;
12
- }, C extends Record<string, any> = Record<string, any>>({ children, options, initialFlags, deferInitialization }: FlagmintProviderProps<T, C>): react_jsx_runtime.JSX.Element;
13
-
14
- declare function useFlagmintStore(): StoreApi<FlagStore>;
15
- declare function useFlagmint(): {
16
- client: flagmint_js_sdk.FlagClient<any, any> | null;
17
- isInitialized: boolean;
18
- updateContext: (context: Record<string, any>) => Promise<void>;
19
- };
20
- declare function useFlags(): Flags;
21
- declare function useFlag<T extends FlagValue = FlagValue>(key: string, fallback?: T): T;
22
- declare function useFlagmintReady(): boolean;
23
-
24
- export { FlagmintProvider, FlagmintStoreContext, useFlag, useFlagmint, useFlagmintReady, useFlagmintStore, useFlags };
package/dist/client.js DELETED
@@ -1,138 +0,0 @@
1
- import { FlagClient } from 'flagmint-js-sdk';
2
- import { createContext, useMemo, useRef, useEffect, useContext } from 'react';
3
- import { createStore } from 'zustand/vanilla';
4
- import { jsx } from 'react/jsx-runtime';
5
- import { useStore } from 'zustand';
6
-
7
- function createFlagStore(initialFlags = {}) {
8
- return createStore((set, get) => ({
9
- flags: initialFlags,
10
- client: null,
11
- isInitialized: false,
12
- isReady: false,
13
- setFlags: (flags) => set({ flags }),
14
- setFlag: (key, value) => set((state) => ({
15
- flags: { ...state.flags, [key]: value }
16
- })),
17
- setClient: (client) => set({ client }),
18
- setInitialized: (initialized) => set({ isInitialized: initialized }),
19
- setReady: (ready) => set({ isReady: ready })
20
- }));
21
- }
22
- var FlagmintStoreContext = createContext(null);
23
- function FlagmintProvider({
24
- children,
25
- options,
26
- initialFlags = {},
27
- deferInitialization = false
28
- }) {
29
- const store = useMemo(() => createFlagStore(initialFlags), [initialFlags]);
30
- const clientRef = useRef(null);
31
- const initPromiseRef = useRef(null);
32
- useRef(initialFlags);
33
- const init = async () => {
34
- if (clientRef.current) return clientRef.current;
35
- if (initPromiseRef.current) return initPromiseRef.current;
36
- const { setClient, setReady, setInitialized } = store.getState();
37
- initPromiseRef.current = (async () => {
38
- try {
39
- const originalClient = new FlagClient(options);
40
- await originalClient.ready();
41
- const clientWrapper = {
42
- ...originalClient,
43
- _flags: {},
44
- getFlags: function() {
45
- return this._flags;
46
- },
47
- // Override getFlag to track individual flags
48
- getFlag: function(key, fallback) {
49
- const value = originalClient.getFlag(key, fallback);
50
- this._flags[key] = value;
51
- store.getState().setFlag(key, value);
52
- return value;
53
- },
54
- // Override updateContext to trigger flag refresh
55
- updateContext: function(context) {
56
- originalClient.updateContext(context);
57
- setTimeout(() => {
58
- Object.keys(this._flags).forEach((key) => {
59
- const newValue = originalClient.getFlag(key);
60
- if (this._flags[key] !== newValue) {
61
- this._flags[key] = newValue;
62
- store.getState().setFlag(key, newValue);
63
- }
64
- });
65
- }, 100);
66
- }
67
- };
68
- clientRef.current = clientWrapper;
69
- setClient(clientWrapper);
70
- setReady(true);
71
- setInitialized(true);
72
- return clientWrapper;
73
- } catch (error) {
74
- console.error("Failed to initialize Flagmint client:", error);
75
- throw error;
76
- }
77
- })();
78
- return initPromiseRef.current;
79
- };
80
- useEffect(() => {
81
- if (!deferInitialization) {
82
- init().catch((error) => {
83
- console.error("Auto-initialization failed:", error);
84
- });
85
- }
86
- return () => {
87
- var _a, _b;
88
- if (clientRef.current) {
89
- (_b = (_a = clientRef.current).destroy) == null ? void 0 : _b.call(_a);
90
- clientRef.current = null;
91
- initPromiseRef.current = null;
92
- }
93
- };
94
- }, [deferInitialization]);
95
- return /* @__PURE__ */ jsx(FlagmintStoreContext.Provider, { value: store, children });
96
- }
97
- function useFlagmintStore() {
98
- const store = useContext(FlagmintStoreContext);
99
- if (!store) {
100
- throw new Error("useFlagmintStore must be used within a FlagmintProvider");
101
- }
102
- return store;
103
- }
104
- function useFlagmint() {
105
- const store = useFlagmintStore();
106
- const client = useStore(store, (state) => state.client);
107
- const isInitialized = useStore(store, (state) => state.isInitialized);
108
- const updateContext = async (context) => {
109
- if (!client) {
110
- throw new Error("Flagmint client not initialized");
111
- }
112
- await client.updateContext(context);
113
- };
114
- return {
115
- client,
116
- isInitialized,
117
- updateContext
118
- };
119
- }
120
- function useFlags() {
121
- const store = useFlagmintStore();
122
- return useStore(store, (state) => state.flags);
123
- }
124
- function useFlag(key, fallback) {
125
- const store = useFlagmintStore();
126
- return useStore(store, (state) => {
127
- var _a;
128
- return (_a = state.flags[key]) != null ? _a : fallback;
129
- });
130
- }
131
- function useFlagmintReady() {
132
- const store = useFlagmintStore();
133
- return useStore(store, (state) => state.isInitialized && state.client !== null);
134
- }
135
-
136
- export { FlagmintProvider, FlagmintStoreContext, useFlag, useFlagmint, useFlagmintReady, useFlagmintStore, useFlags };
137
- //# sourceMappingURL=client.js.map
138
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
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}"]}