@featureflare/sdk-js 0.0.5 → 0.0.6-beta.259

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,6 +27,9 @@ const featureflare = new FeatureFlareClient({
27
27
 
28
28
  const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);
29
29
  console.log(enabled);
30
+
31
+ const detailed = await featureflare.evaluate('new-nav', { id: 'user-123' }, false);
32
+ console.log(detailed.value, detailed.metadata.reason, detailed.metadata.source);
30
33
  ```
31
34
 
32
35
  ### Environment Variables
@@ -35,12 +38,50 @@ The SDK automatically reads from environment variables if `sdkKey` is not provid
35
38
 
36
39
  - `FEATUREFLARE_CLIENT_KEY` - Client SDK key (for browser/mobile)
37
40
  - `FEATUREFLARE_SERVER_KEY` - Server SDK key (for backend)
41
+ - `FEATUREFLARE_ENV_KEY` - Expected environment key binding (`development`, `staging`, `production`, etc.)
38
42
 
39
43
  ```typescript
40
44
  // In Node.js, this will use FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY from env
41
45
  const featureflare = new FeatureFlareClient();
42
46
  ```
43
47
 
48
+ ### Resilience options (cache/retry/timeout/bootstrap)
49
+
50
+ ```typescript
51
+ const featureflare = new FeatureFlareClient({
52
+ sdkKey: 'featureflare_cli_...',
53
+ timeoutMs: 3000,
54
+ maxRetries: 2,
55
+ backoffMs: 200,
56
+ jitter: 0.25,
57
+ cacheTtlMs: 60_000,
58
+ staleTtlMs: 10_000,
59
+ bootstrap: {
60
+ flags: { 'new-nav': true },
61
+ killSwitches: ['dangerous-flow']
62
+ },
63
+ realtime: {
64
+ // optional: enabled defaults to true (SSE primary, polling fallback)
65
+ pollingIntervalMs: 15_000,
66
+ ssePath: '/api/v1/sdk/stream'
67
+ }
68
+ });
69
+ ```
70
+
71
+ - Cache-first evaluation order: fresh cache → stale cache (+ async revalidate) → bootstrap/persistent cache → default.
72
+ - `bool(...)` and `evaluate(...)` are outage-safe and return deterministic defaults for expected network failures.
73
+ - Hard kill switches have highest precedence and return `false` even when the API is unreachable.
74
+ - Realtime updates are enabled by default: SSE is primary transport; polling is used automatically as fallback when SSE is unavailable.
75
+
76
+ To explicitly disable realtime updates:
77
+
78
+ ```typescript
79
+ const featureflare = new FeatureFlareClient({
80
+ sdkKey: 'featureflare_cli_...',
81
+ realtime: { enabled: false }
82
+ });
83
+ ```
84
+
44
85
  ### API Base URL
45
86
 
46
87
  The SDK automatically determines the API base URL:
@@ -94,6 +135,8 @@ new FeatureFlareClient(options?: FeatureFlareClientOptions)
94
135
  - `projectKey?: string` - Legacy: project key (requires `envKey`). Not recommended.
95
136
  - `envKey?: string` - Environment key (default: `'production'`). Only used with `projectKey`.
96
137
 
138
+ When using `sdkKey`, `envKey` is sent as an expected environment binding. The API rejects requests if the key's actual environment does not match `envKey`.
139
+
97
140
  #### Methods
98
141
 
99
142
  ##### `bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>`
@@ -106,23 +149,42 @@ Evaluates a boolean feature flag for a user.
106
149
 
107
150
  Returns `Promise<boolean>` - The flag value for the user.
108
151
 
152
+ ##### `evaluate(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<{ value: boolean; metadata: ... }>`
153
+
154
+ Evaluates a flag with diagnostics metadata:
155
+
156
+ - `reason`: `fresh_cache | stale_cache | bootstrap | default | network | kill_switch`
157
+ - `isStale`
158
+ - `latencyMs`
159
+ - `source`, `updatedAt`, `staleAt`, `expiresAt`
160
+
109
161
  **Example:**
110
162
 
111
163
  ```typescript
112
164
  const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);
113
165
  ```
114
166
 
167
+ ##### `flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Record<string, boolean>>`
168
+
169
+ Fetches all boolean flags for the provided user.
170
+
171
+ - `user`: User payload with `id` or `key` (required)
172
+ - `defaultValue`: Default value to apply for missing/offline evaluations (default: `false`)
173
+
174
+ Returns `Promise<Record<string, boolean>>` - A map of `flagKey -> value`.
175
+
176
+ **Example:**
177
+
178
+ ```typescript
179
+ const allFlags = await featureflare.flags({ id: 'user-123' }, false);
180
+ ```
181
+
115
182
  ## Error Handling
116
183
 
117
- If the API request fails (network error, non-2xx status), the SDK returns the `defaultValue`. Network errors (DNS, timeout, connection refused) will throw; wrap calls in `try/catch` if you want to handle them.
184
+ `bool(...)` and `evaluate(...)` are non-throwing for expected outage/network states. If the API request fails, the SDK falls back to stale/bootstrap/persistent/default values deterministically.
118
185
 
119
186
  ```typescript
120
- try {
121
- const enabled = await featureflare.bool('flag', user, false);
122
- } catch (error) {
123
- // Handle network errors
124
- console.error('Failed to evaluate flag:', error);
125
- }
187
+ const enabled = await featureflare.bool('flag', user, false);
126
188
  ```
127
189
 
128
190
  ## SDK Keys
@@ -134,6 +196,10 @@ Each environment has two SDK keys:
134
196
 
135
197
  Get your SDK keys from your FeatureFlare Console → Environments.
136
198
 
199
+ ## Security: Client-side flags are not authorization
200
+
201
+ Client keys can be extracted from your frontend bundle. **Never gate truly sensitive operations solely with client-evaluated flags**—enforce authorization on your backend. Use client keys for non-sensitive UI toggles (e.g. feature visibility, A/B tests). For access control, billing gates, or data protection, always validate on the server.
202
+
137
203
  ## License
138
204
 
139
205
  MIT